⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 util.c

📁 The major functionality added in this release includes: - Rootless mode in X11 - Widget Templt
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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 + -