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

📄 main.c

📁 系统任务管理器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* GKrellM|  Copyright (C) 1999-2006 Bill Wilson||  Author:  Bill Wilson    billw@gkrellm.net|  Latest versions might be found at:  http://gkrellm.net||  This program is free software which I release under the GNU General Public|  License. You may redistribute and/or modify this program under the terms|  of that 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.  Version 2 is in the|  COPYRIGHT file in the top level directory of this distribution.| |  To get a copy of the GNU General Puplic License, write to the Free Software|  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*/#include "gkrellmd.h"#include "gkrellmd-private.h"#include "../src/inet.h"#ifndef HAVE_GETADDRINFOstruct addrinfo	{	int		ai_flags;		/* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */	int		ai_family;		/* PF_xxx */	int		ai_socktype;	/* SOCK_xxx */	int		ai_protocol;	/* 0 or IPPROTO_xxx for IPv4 and IPv6 */	size_t	ai_addrlen;		/* length of ai_addr */	char	*ai_canonname;	/* canonical name for hostname */	struct	sockaddr *ai_addr;	/* binary address */	struct	addrinfo *ai_next;	/* next structure in linked list */	};#endif#if !defined(IPV6_V6ONLY) && defined(IPV6_BINDV6ONLY)#define	IPV6_V6ONLY	IPV6_BINDV6ONLY#endifstruct GkrellmdConfig	_GK;GkrellmdTicks			GK;GList			*gkrellmd_client_list,				*gkrellmd_plugin_config_list;static GList	*allow_host_list;static gboolean	detach_flag;#if !defined(WIN32)struct	{	uid_t	uid;	uid_t	gid;	}	drop_privs = { 0, 0 };#endifstatic voidmake_pidfile(void)	{#if !defined(WIN32)	FILE	*f;	if (!_GK.pidfile)		return;	f = fopen(_GK.pidfile, "w");	if (f)		{		fprintf(f, "%d\n", getpid());		fclose(f);		}	else		fprintf(stderr, "gkrellmd: Can't create pidfile %s\n", _GK.pidfile);#endif	}static voidremove_pidfile(void)	{#if !defined(WIN32)	if (_GK.pidfile)		unlink(_GK.pidfile);#endif	}static voidcb_sigterm(gint sig)	{	remove_pidfile();    exit(0);	}gintgkrellmd_send_to_client(GkrellmdClient *client, gchar *buf)	{	gint	n;	if (!client->alive)		return 0;#if defined(MSG_NOSIGNAL)	n = send(client->fd, buf, strlen(buf), MSG_NOSIGNAL);#else	n = send(client->fd, buf, strlen(buf), 0);#endif	if (n < 0 && errno == EPIPE)		{		if (_GK.verbose)			printf("Write on closed pipe to host %s\n", client->hostname);		client->alive = FALSE;		}	return n;	}#if 0static gintgetline(gint fd, gchar *buf, gint len)	{	fd_set			read_fds;	struct timeval	tv;	gchar			*s;	gint			result, n;	FD_ZERO(&read_fds);	FD_SET(fd, &read_fds);	tv.tv_usec = 0;	tv.tv_sec = 15;	s = buf;	*s = '\0';	for (n = 0; n < len - 1; ++n)		{		result = select(fd + 1, &read_fds, NULL, NULL, &tv);		if (result <= 0 || read(fd, s, 1) != 1)			break;		if (*s == '\n')			{			*s = '\0';			break;			}		*++s = '\0';		}	return n;	}#endif#ifdef HAVE_GETADDRINFOstatic gbooleanis_valid_reverse(char *addr, char *host, sa_family_t family)	{	struct addrinfo	hints, *res, *r;	int		error, good;	char		addrbuf[NI_MAXHOST];	/* Reject numeric addresses */	memset(&hints, 0, sizeof(hints));	hints.ai_family = family;	hints.ai_socktype = SOCK_STREAM;	hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;	if (getaddrinfo(host, NULL, &hints, &res) == 0)		{		freeaddrinfo(res);		return 0;		}	/* Check for spoof */	memset(&hints, 0, sizeof(hints));	hints.ai_family = family;	hints.ai_socktype = SOCK_STREAM;	hints.ai_flags = AI_PASSIVE;	if (getaddrinfo(host, NULL, &hints, &res) != 0)		return 0;	good = 0;	for (r = res; good == 0 && r; r = r->ai_next)		{		error = getnameinfo(r->ai_addr, r->ai_addrlen,				    addrbuf, sizeof(addrbuf), NULL, 0,				    NI_NUMERICHOST | NI_WITHSCOPEID);		if (error == 0 && strcmp(addr, addrbuf) == 0)			{			good = 1;			break;			}		}	freeaddrinfo(res);	return good;	}#endif/* Check for CIDR match. */static gbooleancidr_match(struct sockaddr *sa, socklen_t salen, char *allowed){#ifdef HAVE_GETADDRINFO	struct addrinfo hints, *res;	struct sockaddr_storage	ss;	char		*buf;	char		*p, *ep;	guchar		*addr, *pat;	u_int32_t	mask;	int			plen, i;	gboolean	result;	buf = g_strdup(allowed);	plen = -1;	if ((p = strchr(buf, '/')) != NULL)		{		plen = strtoul(p + 1, &ep, 10);		if (errno != 0 || ep == NULL || *ep != '\0' || plen < 0)			{			g_free(buf);			return FALSE;			}		*p = '\0';		allowed = buf;		}	memset(&hints, 0, sizeof(hints));	hints.ai_family = AF_UNSPEC;	hints.ai_socktype = SOCK_STREAM;	hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;	result = getaddrinfo(allowed, NULL, &hints, &res);	g_free(buf);	if (result != 0)		return FALSE;	memcpy(&ss, res->ai_addr, res->ai_addrlen);	freeaddrinfo(res);	if (sa->sa_family != ((struct sockaddr *)&ss)->sa_family)		return FALSE;	switch (sa->sa_family)		{#if defined(INET6)		case AF_INET6:			if (plen < 0)				plen = 128;			if (plen > 128)				return FALSE;			if (((struct sockaddr_in6 *)&ss)->sin6_scope_id != 0 &&			    ((struct sockaddr_in6 *)&ss)->sin6_scope_id !=			    ((struct sockaddr_in6 *)sa)->sin6_scope_id)				return FALSE;			addr = (guchar *)&((struct sockaddr_in6 *)sa)->sin6_addr;			pat = (guchar *)&((struct sockaddr_in6 *)&ss)->sin6_addr;			i = 0;			while (plen > 0)				{				if (plen < 32)					{					mask = htonl(~(0xffffffff >> plen));					if ((*(u_int32_t *)&addr[i] & mask) !=					    (*(u_int32_t *)&pat[i] & mask))						return FALSE;					break;					}				if (*(u_int32_t *)&addr[i] !=				    *(u_int32_t *)&pat[i])					return FALSE;				i += 4;				plen -= 32;				}			break;#endif		case AF_INET:			if (plen < 0)				plen = 32;			if (plen > 32)				return FALSE;			addr = (guchar *)&((struct sockaddr_in *)sa)->sin_addr;			pat = (guchar *)&((struct sockaddr_in *)&ss)->sin_addr;			mask = htonl(~(0xffffffff >> plen));			if ((*(u_int32_t *)addr & mask) !=			    (*(u_int32_t *)pat & mask))				return FALSE;			break;		default:			return FALSE;		}	return TRUE;#else	return FALSE;#endif}static gbooleanallow_host(GkrellmdClient *client, struct sockaddr *sa, socklen_t salen)	{	GList			*list;#ifdef HAVE_GETADDRINFO	int error;	char hostbuf[NI_MAXHOST], addrbuf[NI_MAXHOST];#else	struct hostent	*hostent;#endif	gchar			buf[128];	gchar			*hostname = NULL,					*addr = NULL;	gchar			*s, *allowed;#ifdef HAVE_GETADDRINFO	error = getnameinfo(sa, salen, addrbuf, sizeof(addrbuf),			    NULL, 0, NI_NUMERICHOST | NI_WITHSCOPEID);	if (error == 0)		{		addr = addrbuf;		error = getnameinfo(sa, salen, hostbuf, sizeof(hostbuf),				    NULL, 0, NI_NAMEREQD);		if (error == 0 &&		    is_valid_reverse(addrbuf, hostbuf, sa->sa_family))			hostname = hostbuf;		}#else	hostent = gethostbyaddr((gchar *)&((struct sockaddr_in *)sa)->sin_addr,				sizeof(struct in_addr), AF_INET);	if (hostent)		hostname = hostent->h_name;	addr = inet_ntoa(((struct sockaddr_in *)sa)->sin_addr);#endif	client->hostname = g_strdup(hostname ? hostname : addr);	if (!allow_host_list)		return TRUE;	for (list = allow_host_list; list; list = list->next)		{		allowed = (gchar *) list->data;		if (   (hostname && !strcmp(hostname, allowed))			|| (addr && !strcmp(addr, allowed))			|| !strcmp("ALL", allowed)		   )			return TRUE;		if (addr && cidr_match(sa, salen, allowed))			return TRUE;		/* Check for simple IPv4 subnet match.  Worry later about ranges and		|  other hosts_access type patterns.		*/		if (   addr			&& (s = strrchr(allowed, (int) '.')) != NULL			&& *(s + 1) == '*' && *(s + 2) == '\0'			&& !strncmp(addr, allowed, (gint) (s - allowed + 1))		   )				return TRUE;		}	snprintf(buf, sizeof(buf), _("Connection not allowed from %s\n"),			hostname ? hostname : addr);	fprintf(stderr, "gkrellmd: %s", buf),	gkrellmd_send_to_client(client, "<error>\n");	gkrellmd_send_to_client(client, buf);	return FALSE;	}  /* client sends line: gkrellm x.y.z  */static GkrellmdClient *accept_client(gint fd, struct sockaddr *sa, socklen_t salen)	{	GkrellmdClient	*client;	gchar			buf[64], name[32];	gboolean		client_limit;	gint			err;	client = g_new0(GkrellmdClient, 1);	client->fd = fd;	client->alive = TRUE;	client_limit = (g_list_length(gkrellmd_client_list) >= _GK.max_clients);	if (!allow_host(client, sa, salen) || client_limit)		{		if (client_limit)			{			fprintf(stderr, _("gkrellmd: too many clients, rejecting %s\n"),					client->hostname);			gkrellmd_send_to_client(client,						"<error>\nClient limit exceeded.\n");			}		g_free(client->hostname);		g_free(client);		return NULL;		}	err = recv(fd, buf, sizeof(buf), 0);	if (err > 0)		buf[err] = '\0';	else		buf[0] = '\0';	//getline(fd, buf, sizeof(buf));	if (_GK.verbose)		printf(_("connect string from client: %s\n"), buf);	if (   sscanf(buf, "%31s %d.%d.%d", name, &client->major_version,					&client->minor_version, &client->rev_version) == 4		&& !strcmp(name, "gkrellm")	   )		{		gkrellmd_client_list = g_list_append(gkrellmd_client_list, client);		return client;		}	fprintf(stderr, _("gkrellmd: bad connect line from %s: %s\n"),				client->hostname, buf);	gkrellmd_send_to_client(client, "<error>\nBad connect string!");	g_free(client->hostname);	g_free(client);	return NULL;	}static voidremove_client(gint fd)	{	GList			*list;	GkrellmdClient	*client;	for (list = gkrellmd_client_list; list; list = list->next)		{		client = (GkrellmdClient *) list->data;		if (client->fd == fd)			{			if (_GK.verbose)				printf("Removing client %s\n", client->hostname);			close(fd);			g_free(client->hostname);			g_free(client);			gkrellmd_client_list = g_list_remove(gkrellmd_client_list, client);			break;			}		}	}static gintparse_config(gchar *config, gchar *arg)	{	if (!strcmp(config, "clear-hosts") || !strcmp(config, "c"))		{		gkrellm_free_glist_and_data(&allow_host_list);		return 0;		}	if (!strcmp(config, "detach") || !strcmp(config, "d"))		{		detach_flag = TRUE;		return 0;		}	if (!arg || !*arg)		return -1;	if (!strcmp(config, "update-hz") || !strcmp(config, "u"))		_GK.update_HZ = atoi(arg);	else if (!strcmp(config, "port") || !strcmp(config, "P"))		_GK.server_port = atoi(arg);	else if (!strcmp(config, "max-clients") || !strcmp(config, "m"))		_GK.max_clients = atoi(arg);	else if (!strcmp(config, "allow-host") || !strcmp(config, "a"))		allow_host_list = g_list_append(allow_host_list, g_strdup(arg));	else if (!strcmp(config, "plugin-enable") || !strcmp(config, "pe"))		gkrellmd_plugin_enable_list				= g_list_append(gkrellmd_plugin_enable_list, g_strdup(arg));	else if (!strcmp(config, "plugin") || !strcmp(config, "p"))		_GK.command_line_plugin = g_strdup(arg);	else if (!strcmp(config, "io-timeout"))		_GK.io_timeout = atoi(arg);	else if (!strcmp(config, "reconnect-timeout"))		_GK.reconnect_timeout = atoi(arg);	else if (!strcmp(config, "fs-interval"))		_GK.fs_interval = atoi(arg);	else if (!strcmp(config, "nfs-interval"))		_GK.nfs_interval = atoi(arg);	else if (!strcmp(config, "inet-interval"))		_GK.inet_interval = atoi(arg);	else if (!strcmp(config, "mbmon-port"))		_GK.mbmon_port = atoi(arg);	else if (!strcmp(config, "net-timer"))		_GK.net_timer = g_strdup(arg);	else if (!strcmp(config, "debug-level") || !strcmp(config, "debug"))		_GK.debug_level = (gint) strtoul(arg, NULL, 0);#if !defined(WIN32)	else if (!strcmp(config, "pidfile"))		_GK.pidfile = g_strdup(arg);	else if (!strcmp(config, "mailbox"))		gkrellmd_add_mailbox(arg);	else if (!strcmp(config, "user") || !strcmp(config, "U"))		{		struct passwd *tmp;		if ((tmp = getpwnam(arg)) != (struct passwd*) 0)			drop_privs.uid = tmp->pw_uid;		else			return -1;		}	else if (!strcmp(config, "group") || !strcmp(config, "G"))		{		struct group *tmp;		if ((tmp = getgrnam(arg)) != (struct group*) 0)			drop_privs.gid = tmp->gr_gid;		else			return -1;		}#endif	else		return -1;	return 1;	}static voidload_config(gchar *path)	{	FILE			*f;	PluginConfigRec	*cfg;	gchar			buf[128], config[32], arg[128];	gchar			*s, *plugin_config_block = NULL;	f = fopen(path, "r");	if (!f)		return;	while (fgets(buf, sizeof(buf), f))		{		if (!buf[0] || buf[0] == '#')			continue;		if (buf[0] == '[' || buf[0] == '<')			{			if (buf[1] == '/')				{				g_free(plugin_config_block);				plugin_config_block = NULL;				}			else				{				if (   (s = strchr(buf, ']')) != NULL					|| (s = strchr(buf, '>')) != NULL				   )					*s = '\0';				plugin_config_block = g_strdup(&buf[1]);				}			continue;			}		if (plugin_config_block)			{			cfg = g_new0(PluginConfigRec, 1);			cfg->name = g_strdup(plugin_config_block);			if ((s = strchr(buf, '\n')) != NULL)				*s = '\0';			cfg->line = g_strdup(buf);			gkrellmd_plugin_config_list						= g_list_append(gkrellmd_plugin_config_list, cfg);			}		else	/* main gkrellmd config line */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -