📄 util.c
字号:
/* X-Chat * Copyright (C) 1998 Peter Zelezny. * * This program 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 of the License, or * (at your option) any later version. * * This program 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 program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */#include <stdio.h>#include <unistd.h>#include <string.h>#include <stdlib.h>#include <sys/types.h>#ifdef WIN32#include <sys/timeb.h>#include <winsock.h>#include <process.h>#else#include <sys/time.h>#include <fcntl.h>#include <dirent.h>#include <sys/utsname.h>#endif#include <errno.h>#include "xchat.h"#include <ctype.h>#include "util.h"#include "../../config.h"#ifdef USING_FREEBSD#include <sys/sysctl.h>#endif#ifdef SOCKS#include <socks.h>#endif#ifndef HAVE_SNPRINTF#define snprintf g_snprintf#endif#ifdef USE_DEBUG#undef free#undef malloc#undef realloc#undef strdupint current_mem_usage;struct mem_block{ char *file; void *buf; int size; int line; int total; struct mem_block *next;};struct mem_block *mroot = NULL;void *xchat_malloc (int size, char *file, int line){ void *ret; struct mem_block *new; current_mem_usage += size; ret = malloc (size); if (!ret) { printf ("Out of memory! (%d)\n", current_mem_usage); exit (255); } new = malloc (sizeof (struct mem_block)); new->buf = ret; new->size = size; new->next = mroot; new->line = line; new->file = strdup (file); mroot = new; printf ("%s:%d Malloc'ed %d bytes, now \033[35m%d\033[m\n", file, line, size, current_mem_usage); return ret;}void *xchat_realloc (char *old, int len, char *file, int line){ char *ret; ret = xchat_malloc (len, file, line); if (ret) { strcpy (ret, old); xchat_free (old, file, line); } return ret;}void *xchat_strdup (char *str, char *file, int line){ void *ret; struct mem_block *new; int size; size = strlen (str) + 1; current_mem_usage += size; ret = malloc (size); if (!ret) { printf ("Out of memory! (%d)\n", current_mem_usage); exit (255); } strcpy (ret, str); new = malloc (sizeof (struct mem_block)); new->buf = ret; new->size = size; new->next = mroot; new->line = line; new->file = strdup (file); mroot = new; printf ("%s:%d strdup (\"%-.40s\") size: %d, total: \033[35m%d\033[m\n", file, line, str, size, current_mem_usage); return ret;}voidxchat_mem_list (void){ struct mem_block *cur, *p; GSList *totals = 0; GSList *list; cur = mroot; while (cur) { list = totals; while (list) { p = list->data; if (p->line == cur->line && strcmp (p->file, cur->file) == 0) { p->total += p->size; break; } list = list->next; } if (!list) { cur->total = cur->size; totals = g_slist_prepend (totals, cur); } cur = cur->next; } fprintf (stderr, "file line size num total\n"); list = totals; while (list) { cur = list->data; fprintf (stderr, "%-15.15s %6d %6d %6d %6d\n", cur->file, cur->line, cur->size, cur->total/cur->size, cur->total); list = list->next; }}voidxchat_free (void *buf, char *file, int line){ struct mem_block *cur, *last; last = NULL; cur = mroot; while (cur) { if (buf == cur->buf) break; last = cur; cur = cur->next; } if (cur == NULL) { printf ("%s:%d \033[31mTried to free unknown block %lx!\033[m\n", file, line, (unsigned long) buf); /* abort(); */ free (buf); return; } current_mem_usage -= cur->size; printf ("%s:%d Free'ed %d bytes, usage now \033[35m%d\033[m\n", file, line, cur->size, current_mem_usage); if (last) last->next = cur->next; else mroot = cur->next; free (cur->file); free (cur);}#define malloc(n) xchat_malloc(n, __FILE__, __LINE__)#define realloc(n, m) xchat_realloc(n, m, __FILE__, __LINE__)#define free(n) xchat_free(n, __FILE__, __LINE__)#define strdup(n) xchat_strdup(n, __FILE__, __LINE__)#endif /* MEMORY_DEBUG */char *file_part (char *file){ char *filepart = file; if (!file) return ""; while (1) { switch (*file) { case 0: return (filepart); case '/':#ifdef WIN32 case '\\':#endif filepart = file + 1; break; } file++; }}voidpath_part (char *file, char *path){ char *filepart = file_part (file); *filepart = 0; strcpy (path, file);}char * /* like strstr(), but nocase */nocasestrstr (char *s, char *wanted){ register const size_t len = strlen (wanted); if (len == 0) return (char *)s; while (tolower(*s) != tolower(*wanted) || strncasecmp (s, wanted, len)) if (*s++ == '\0') return (char *)NULL; return (char *)s;}char *errorstring (int err){ static char tbuf[16]; switch (err) { case -1: return ""; case 0: return _("Remote host closed socket");#ifndef WIN32 case ECONNREFUSED: return _("Connection refused"); case ENETUNREACH: case EHOSTUNREACH: return _("No route to host"); case ETIMEDOUT: return _("Connection timed out"); case EADDRNOTAVAIL: return _("Cannot assign that address"); case ECONNRESET:#else case WSAECONNREFUSED: return _("Connection refused"); case WSAENETUNREACH: case WSAEHOSTUNREACH: return _("No route to host"); case WSAETIMEDOUT: return _("Connection timed out"); case WSAEADDRNOTAVAIL: return _("Cannot assign that address"); case WSAECONNRESET:#endif return _("Connection reset by peer"); } sprintf (tbuf, "%d", err); return tbuf;}intwaitline (int sok, char *buf, int bufsize){ int i = 0; while (1) { if (read (sok, &buf[i], 1) < 1) return -1; if (buf[i] == '\n' || bufsize == i + 1) { buf[i] = 0; return i; } i++; }}/* checks for "~" in a file and expands */char *expand_homedir (char *file){#ifndef WIN32 char *ret; if (*file == '~') { ret = malloc (strlen (file) + strlen (g_get_home_dir ()) + 1); sprintf (ret, "%s%s", g_get_home_dir (), file + 1); return ret; }#endif return strdup (file);}unsigned char *strip_color (unsigned char *text){ int nc = 0; int i = 0; int col = 0; int len = strlen (text); unsigned char *new_str = malloc (len + 2); while (len > 0) { if ((col && isdigit (*text) && nc < 2) || (col && *text == ',' && isdigit (*(text+1)) && nc < 3)) { nc++; if (*text == ',') nc = 0; } else { col = 0; switch (*text) { case '\003': /*ATTR_COLOR: */ col = 1; nc = 0; break; case '\007': /*ATTR_BEEP: */ case '\017': /*ATTR_RESET: */ case '\026': /*ATTR_REVERSE: */ case '\002': /*ATTR_BOLD: */ case '\037': /*ATTR_UNDERLINE: */ break; default: new_str[i] = *text; i++; } } text++; len--; } new_str[i] = 0; return new_str;}#if defined (USING_LINUX) || defined (USING_FREEBSD)static voidget_cpu_info (int *mhz, int *cpus){#ifdef USING_LINUX char buf[256]; int fh; *mhz = 0; *cpus = 0; fh = open ("/proc/cpuinfo", O_RDONLY); /* linux 2.2+ only */ if (fh == -1) { *cpus = 1; return; } while (1) { if (waitline (fh, buf, sizeof buf) < 0) break; if (!strncmp (buf, "cycle frequency [Hz]\t:", 22)) /* alpha */ { *mhz = atoi (buf + 23) / 1048576; } else if (!strncmp (buf, "cpu MHz\t\t:", 10)) /* i386 */ { *mhz = atof (buf + 11) + 0.5; } else if (!strncmp (buf, "clock\t\t:", 8)) /* PPC */ { *mhz = atoi (buf + 9); } else if (!strncmp (buf, "processor\t", 10)) { (*cpus)++; } } close (fh); if (!*cpus) *cpus = 1;#endif#ifdef USING_FREEBSD int mib[2], ncpu; u_long freq; size_t len; *mhz = 0; *cpus = 0; mib[0] = CTL_HW; mib[1] = HW_NCPU; len = sizeof(ncpu); sysctl(mib, 2, &ncpu, &len, NULL, 0); len = sizeof(freq); sysctlbyname("machdep.tsc_freq", &freq, &len, NULL, 0); *cpus = ncpu; *mhz = (freq / 1000000);#endif}#endif#ifdef WIN32static intget_mhz (void){ HKEY hKey; int result, data, dataSize; if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Hardware\\Description\\System\\" "CentralProcessor\\0", 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) { dataSize = sizeof (data); result = RegQueryValueEx (hKey, "~MHz", 0, 0, (LPBYTE)&data, &dataSize); RegCloseKey (hKey); if (result == ERROR_SUCCESS) return data; } return 0; /* fails on Win9x */}char *get_cpu_str (void){ static char verbuf[64]; OSVERSIONINFO osvi; SYSTEM_INFO si; int mhz; osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); GetVersionEx (&osvi); GetSystemInfo (&si); mhz = get_mhz (); if (mhz) sprintf (verbuf, "Windoze %ld.%ld [i%1d86/%dMHz]", osvi.dwMajorVersion, osvi.dwMinorVersion, si.wProcessorLevel, mhz); else sprintf (verbuf, "Windoze %ld.%ld [i%1d86]", osvi.dwMajorVersion, osvi.dwMinorVersion, si.wProcessorLevel); return verbuf;}#elsechar *get_cpu_str (void){#if defined (USING_LINUX) || defined (USING_FREEBSD) int mhz, cpus;#endif struct utsname un; static char *buf = NULL; if (buf) return buf; buf = malloc (128); uname (&un);#if defined (USING_LINUX) || defined (USING_FREEBSD) get_cpu_info (&mhz, &cpus); if (mhz) snprintf (buf, 128, (cpus == 1) ? "%s %s [%s/%dMHz]" : "%s %s [%s/%dMHz/SMP]", un.sysname, un.release, un.machine, mhz); else#endif snprintf (buf, 128, "%s %s [%s]", un.sysname, un.release, un.machine); return buf;}#endifintbuf_get_line (char *ibuf, char **buf, int *position, int len){ int pos = *position, spos = pos; if (pos == len) return 0; while (ibuf[pos++] != '\n') { if (pos == len) return 0; } pos--; ibuf[pos] = 0; *buf = &ibuf[spos]; pos++; *position = pos; return 1;}int match(const char *mask, const char *string){ register const char *m = mask, *s = string; register char ch; const char *bm, *bs; /* Will be reg anyway on a decent CPU/compiler */ /* Process the "head" of the mask, if any */ while ((ch = *m++) && (ch != '*')) switch (ch) { case '\\': if (*m == '?' || *m == '*') ch = *m++; default: if (tolower(*s) != tolower(ch)) return 0; case '?': if (!*s++) return 0; }; if (!ch) return !(*s); /* We got a star: quickly find if/where we match the next char */got_star: bm = m; /* Next try rollback here */ while ((ch = *m++)) switch (ch) { case '?': if (!*s++) return 0; case '*': bm = m; continue; /* while */ case '\\': if (*m == '?' || *m == '*') ch = *m++; default: goto break_while; /* C is structured ? */ };break_while: if (!ch) return 1; /* mask ends with '*', we got it */ ch = tolower(ch); while (tolower(*s++) != ch) if (!*s) return 0; bs = s; /* Next try start from here */ /* Check the rest of the "chunk" */ while ((ch = *m++))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -