📄 util.c
字号:
/* * util.c - utility function implementation * * Copyright (C) 2000, 2001 Stefan Jahn <stefan@lkcc.org> * Copyright (C) 2000 Raimund Jacob <raimi@lkcc.org> * Copyright (C) 1999 Martin Grabmueller <mgrabmue@cs.tu-berlin.de> * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this package; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * $Id: util.c,v 1.23 2001/09/27 15:47:36 ela Exp $ * */#if HAVE_CONFIG_H# include <config.h>#endif#ifdef _AIX# undef _NO_PROTO# ifndef _USE_IRS# define _USE_IRS 1# endif# define _XOPEN_SOURCE_EXTENDED 1# define _ALL_SOURCE 1#endif /* _AIX */#define _GNU_SOURCE#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <time.h>#include <errno.h>#if HAVE_SYS_TIME_H# include <sys/time.h>#endif#if HAVE_SYS_RESOURCE_H && !defined (__MINGW32__)# include <sys/resource.h>#endif#if HAVE_UNISTD_H# include <unistd.h>#endif#if HAVE_STRINGS_H# include <strings.h>#endif#ifndef __MINGW32__# include <netdb.h>#endif#ifdef __MINGW32__# include <winsock2.h>#endif#if HAVE_SYS_UTSNAME_H# include <sys/utsname.h>#endif#include "libserveez/alloc.h"#include "libserveez/snprintf.h"#include "libserveez/boot.h"#include "libserveez/windoze.h"#include "libserveez/util.h"/* * Level of the logging interfaces verbosity: * 0 - only fatal error messages * 1 - error messages * 2 - warnings * 3 - informational messages * 4 - debugging output * Levels always imply numerically lesser levels. */static char log_level[][16] = { "fatal", "error", "warning", "notice", "debug"};/* * This is the file all log messages are written to. Change it with a * call to @code{svz_log_setfile()}. By default, all log messages are written * to @code{stderr}. */static FILE *svz_logfile = NULL;/* * Print a message to the log system. @var{level} specifies the prefix. */voidsvz_log (int level, const char *format, ...){ va_list args; time_t tm; struct tm *t; if (level > svz_config.verbosity || svz_logfile == NULL || feof (svz_logfile) || ferror (svz_logfile)) return; tm = time (NULL); t = localtime (&tm); fprintf (svz_logfile, "[%4d/%02d/%02d %02d:%02d:%02d] %s: ", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, log_level[level]); va_start (args, format); vfprintf (svz_logfile, format, args); va_end (args); fflush (svz_logfile);}/* * Set the file stream @var{file} to the log file all messages are printed * to. Could also be @code{stdout} or @code{stderr}. */voidsvz_log_setfile (FILE * file){ svz_logfile = file;}#define MAX_DUMP_LINE 16 /* bytes per line *//* * Dump a @var{buffer} with the length @var{len} to the file stream @var{out}. * You can specify a description in @var{action}. The hexadecimal text * representation of the given buffer will be either cut at @var{len} or * @var{max}. @var{from} is a numerical identifier of the buffers creator. */intsvz_hexdump (FILE *out, /* output FILE stream */ char *action, /* hex dump description */ int from, /* who created the dumped data */ char *buffer, /* the buffer to dump */ int len, /* length of that buffer */ int max) /* maximum amount of bytes to dump (0 = all) */{ int row, col, x, max_col; if (!max) max = len; if (max > len) max = len; max_col = max / MAX_DUMP_LINE; if ((max % MAX_DUMP_LINE) != 0) max_col++; fprintf (out, "%s [ FROM:0x%08X SIZE:%d ]\n", action, (unsigned) from, len); for (x = row = 0; row < max_col && x < max; row++) { /* print hexdump */ fprintf (out, "%04X ", x); for (col = 0; col < MAX_DUMP_LINE; col++, x++) { if (x < max) fprintf (out, "%02X ", (unsigned char) buffer[x]); else fprintf (out, " "); } /* print character representation */ x -= MAX_DUMP_LINE; fprintf (out, " "); for (col = 0; col < MAX_DUMP_LINE && x < max; col++, x++) { fprintf (out, "%c", buffer[x] >= ' ' ? buffer[x] : '.'); } fprintf (out, "\n"); } fflush (out); return 0;}/* On some platforms @code{hstrerror()} can be resolved but is not declared anywhere. That is why we do it here by hand. */#if defined (HAVE_HSTRERROR) && !defined (DECLARED_HSTRERROR)extern char * hstrerror (int);#endif/* * This is the @code{hstrerror()} wrapper function, depending on the * configuration file @file{config.h}. */char *svz_hstrerror (void){#if HAVE_HSTRERROR# if HAVE_H_ERRNO return (char *) hstrerror (h_errno);# else return (char *) hstrerror (errno);# endif#else /* not HAVE_HSTRERROR */# if HAVE_H_ERRNO return (char *) strerror (h_errno);# else return (char *) strerror (errno);# endif#endif /* not HAVE_HSTRERROR */}/* * Transform the given binary data @var{t} (UTC time) to an ASCII time text * representation without any trailing characters. */char *svz_time (long t){ static char *asc; char *p; p = asc = ctime ((time_t *) &t); while (*p) p++; while (*p < ' ') *(p--) = '\0'; return asc;}/* * Create some kind of uptime string. It tells how long the core library * has been running. */char *svz_uptime (long diff){ static char text[64]; long sec, min, hour, day, old; old = diff; sec = diff % 60; diff /= 60; min = diff % 60; diff /= 60; hour = diff % 24; diff /= 24; day = diff; if (old < 60) { sprintf (text, "%ld sec", sec); } else if (old < 60 * 60) { sprintf (text, "%ld min", min); } else if (old < 60 * 60 * 24) { sprintf (text, "%ld hours, %ld min", hour, min); } else { sprintf (text, "%ld days, %ld:%02ld", day, hour, min); } return text;}/* * Convert the given string @var{str} to lower case text representation. */char *svz_tolower (char *str){ char *p = str; while (*p) { *p = (char) (isupper ((svz_uint8_t) * p) ? tolower ((svz_uint8_t) * p) : *p); p++; } return str;}/* * This is the system dependent case insensitive string compare. It * compares the strings @var{str1} and @var{str2} and returns zero if both * strings are equal. */intsvz_strcasecmp (const char *str1, const char *str2){#if HAVE_STRCASECMP return strcasecmp (str1, str2);#elif HAVE_STRICMP return stricmp (str1, str2);#else const char *p1 = str1; const char *p2 = str2; unsigned char c1, c2; if (p1 == p2) return 0; do { c1 = isupper (*p1) ? tolower (*p1) : *p1; c2 = isupper (*p2) ? tolower (*p2) : *p2; if (c1 == '\0') break; ++p1; ++p2; } while (c1 == c2); return c1 - c2;#endif /* neither HAVE_STRCASECMP nor HAVE_STRICMP */}/* * The @code{svz_strncasecmp()} function compares the two strings @var{str1} * and @var{str2}, ignoring the case of the characters. It returns an * integer less than, equal to, or greater than zero if @var{str1} is * found, respectively, to be less than, to match, or be greater than * @var{str2}. It only compares the first @var{n} characters of @var{str1}. */intsvz_strncasecmp (const char *str1, const char *str2, unsigned int n){#if HAVE_STRNCASECMP return strncasecmp (str1, str2, n);#elif HAVE_STRNICMP return strnicmp (str1, str2, n);#else const char *p1 = str1; const char *p2 = str2; unsigned char c1, c2; if (p1 == p2) return 0; do { c1 = isupper (*p1) ? tolower (*p1) : *p1; c2 = isupper (*p2) ? tolower (*p2) : *p2; if (c1 == '\0') break; ++p1; ++p2; } while (c1 == c2 && --n > 0); return c1 - c2;#endif /* neither HAVE_STRCASECMP nor HAVE_STRICMP */}#ifdef __MINGW32__/* * This variable contains the last system or network error occurred if * it was detected and printed. Needed for the "Resource unavailable" error * condition. */int svz_errno = 0;#define MESSAGE_BUF_SIZE 256/* * There is no text representation of network (Winsock API) errors in * Win32. That is why we translate it by hand. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -