コード例 #1
0
ファイル: pid.c プロジェクト: Shmuma/z
void	drop_pid_file(const char *pidfile)
{
#ifdef HAVE_FCNTL_H
	struct flock fl;

	fl.l_type   = F_UNLCK;  /* tell it to unlock the region */
	fl.l_whence = SEEK_SET; /* SEEK_SET, SEEK_CUR, SEEK_END */
	fl.l_start  = 0;        /* Offset from l_whence         */
	fl.l_len    = 0;        /* length, 0 = to EOF           */
	fl.l_pid    = zbx_get_thread_id(); /* our PID           */

#endif /* HAVE_FCNTL_H */

	/* unlock file */
#ifdef HAVE_FCNTL_H
	if(-1 != fdpid) fcntl(fdpid, F_SETLK, &fl);
#else
	if(-1 != fdpid) flock(fdpid, LOCK_UN);
#endif /* HAVE_FCNTL_H */

	/* close pid file */
	zbx_fclose(fpid);

	if(-1 == unlink(pidfile))
	{
		zabbix_log( LOG_LEVEL_DEBUG, "Cannot remove PID file [%s] [%s]", pidfile, strerror(errno));
	}
}
コード例 #2
0
ファイル: pid.c プロジェクト: Metalaria/Zabbix_
void	drop_pid_file(const char *pidfile)
{
	struct flock	fl;

	fl.l_type = F_UNLCK;
	fl.l_whence = SEEK_SET;
	fl.l_start = 0;
	fl.l_len = 0;
	fl.l_pid = zbx_get_thread_id();

	/* unlock file */
	if (-1 != fdpid)
		fcntl(fdpid, F_SETLK, &fl);

	/* close pid file */
	zbx_fclose(fpid);

	unlink(pidfile);
}
コード例 #3
0
ファイル: icmpping.c プロジェクト: baniuyao/Zabbix_PPTV
static int	process_ping(ZBX_FPING_HOST *hosts, int hosts_count, int count, int interval, int size, int timeout,
		char *error, int max_error_len)
{
	const char	*__function_name = "process_ping";

	FILE		*f;
	char		*c, *c2, params[64];
	char		filename[MAX_STRING_LEN], tmp[MAX_STRING_LEN];
	int		i;
	ZBX_FPING_HOST	*host;
	double		sec;
	int 		ret = NOTSUPPORTED;

#ifdef HAVE_IPV6
	int		family;
	char		params6[64];
	char		fping_existence = 0;
#define	FPING_EXISTS	0x1
#define	FPING6_EXISTS	0x2

#endif	/* HAVE_IPV6 */

	assert(hosts);

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() hosts_count:%d", __function_name, hosts_count);

	if (-1 == access(CONFIG_FPING_LOCATION, F_OK | X_OK))
	{
#if !defined(HAVE_IPV6)
		zbx_snprintf(error, max_error_len, "%s: %s", CONFIG_FPING_LOCATION, zbx_strerror(errno));
		return ret;
#endif
	}
	else
	{
#ifdef HAVE_IPV6
		fping_existence |= FPING_EXISTS;
#else
		if (NULL != CONFIG_SOURCE_IP)
		{
			if (FAIL == is_ip4(CONFIG_SOURCE_IP)) /* we do not have IPv4 family address in CONFIG_SOURCE_IP */
			{
				zbx_snprintf(error, max_error_len,
					"You should enable IPv6 support to use IPv6 family address for SourceIP '%s'.", CONFIG_SOURCE_IP);
				return ret;
			}
		}
#endif
	}

#ifdef HAVE_IPV6
	if (-1 == access(CONFIG_FPING6_LOCATION, F_OK | X_OK))
	{
		if (0 == (fping_existence & FPING_EXISTS))
		{
			zbx_snprintf(error, max_error_len, "At least one of '%s', '%s' must exist. Both are missing in the system.",
					CONFIG_FPING_LOCATION,
					CONFIG_FPING6_LOCATION);
			return ret;
		}
	}
	else
		fping_existence |= FPING6_EXISTS;
#endif	/* HAVE_IPV6 */

	i = zbx_snprintf(params, sizeof(params), "-q -C%d", count);
	if (0 != interval)
		i += zbx_snprintf(params + i, sizeof(params) - i, " -p%d", interval);
	if (0 != size)
		i += zbx_snprintf(params + i, sizeof(params) - i, " -b%d", size);
	if (0 != timeout)
		i += zbx_snprintf(params + i, sizeof(params) - i, " -t%d", timeout);

#ifdef HAVE_IPV6
	strscpy(params6, params);
#endif	/* HAVE_IPV6 */

	if (NULL != CONFIG_SOURCE_IP)
	{
#ifdef HAVE_IPV6
		if (0 != (fping_existence & FPING_EXISTS))
		{
			if (0 == source_ip_checked)
				get_source_ip_option(CONFIG_FPING_LOCATION, &source_ip_option, &source_ip_checked);
			if (NULL != source_ip_option)
				zbx_snprintf(params + i, sizeof(params) - i, " %s%s", source_ip_option, CONFIG_SOURCE_IP);
		}

		if (0 != (fping_existence & FPING6_EXISTS))
		{
			if (0 == source_ip6_checked)
				get_source_ip_option(CONFIG_FPING6_LOCATION, &source_ip6_option, &source_ip6_checked);
			if (NULL != source_ip6_option)
				zbx_snprintf(params6 + i, sizeof(params6) - i, " %s%s", source_ip6_option, CONFIG_SOURCE_IP);
		}
#else
		if (0 == source_ip_checked)
			get_source_ip_option(CONFIG_FPING_LOCATION, &source_ip_option, &source_ip_checked);
		if (NULL != source_ip_option)
			zbx_snprintf(params + i, sizeof(params) - i, " %s%s", source_ip_option, CONFIG_SOURCE_IP);
#endif	/* HAVE_IPV6 */
	}

	zbx_snprintf(filename, sizeof(filename), "%s/%s_%li.pinger", CONFIG_TMPDIR, progname, zbx_get_thread_id());

#ifdef HAVE_IPV6
	if (NULL != CONFIG_SOURCE_IP)
	{
		if (SUCCEED != get_address_family(CONFIG_SOURCE_IP, &family, error, max_error_len))
			return ret;

		if (family == PF_INET)
		{
			if (0 == (fping_existence & FPING_EXISTS))
			{
				zbx_snprintf(error, max_error_len, "File '%s' cannot be found in the system.",
						CONFIG_FPING_LOCATION);
				return ret;
			}

			zbx_snprintf(tmp, sizeof(tmp), "%s %s 2>&1 <%s", CONFIG_FPING_LOCATION, params, filename);
		}
		else
		{
			if (0 == (fping_existence & FPING6_EXISTS))
			{
				zbx_snprintf(error, max_error_len, "File '%s' cannot be found in the system.",
						CONFIG_FPING6_LOCATION);
				return ret;
			}

			zbx_snprintf(tmp, sizeof(tmp), "%s %s 2>&1 <%s", CONFIG_FPING6_LOCATION, params6, filename);
		}
	}
	else
	{
		i = 0;

		if (0 != (fping_existence & FPING_EXISTS))
			i += zbx_snprintf(tmp + i, sizeof(tmp) - i, "%s %s 2>&1 <%s;", CONFIG_FPING_LOCATION, params, filename);

		if (0 != (fping_existence & FPING6_EXISTS))
			i += zbx_snprintf(tmp + i, sizeof(tmp) - i, "%s %s 2>&1 <%s;", CONFIG_FPING6_LOCATION, params6, filename);
	}
#else
	zbx_snprintf(tmp, sizeof(tmp), "%s %s 2>&1 <%s", CONFIG_FPING_LOCATION, params, filename);
#endif	/* HAVE_IPV6 */

	if (NULL == (f = fopen(filename, "w")))
	{
		zbx_snprintf(error, max_error_len, "%s: %s", filename, zbx_strerror(errno));
		return ret;
	}

	zabbix_log(LOG_LEVEL_DEBUG, "%s", filename);

	for (i = 0; i < hosts_count; i++)
	{
		zabbix_log(LOG_LEVEL_DEBUG, "%s", hosts[i].addr);
		fprintf(f, "%s\n", hosts[i].addr);
	}

	fclose(f);

	zabbix_log(LOG_LEVEL_DEBUG, "%s", tmp);

	if (NULL == (f = popen(tmp, "r")))
	{
		zbx_snprintf(error, max_error_len, "%s: %s", tmp, zbx_strerror(errno));

		unlink(filename);

		return ret;
	}

	if (NULL == fgets(tmp, sizeof(tmp), f))
	{
		ret = SUCCEED; /* fping does not output anything for DNS names that fail to resolve */
	}
	else
	{
		do
		{
			zbx_rtrim(tmp, "\n");
			zabbix_log(LOG_LEVEL_DEBUG, "read line [%s]", tmp);

			host = NULL;

			if (NULL != (c = strchr(tmp, ' ')))
			{
				*c = '\0';
				for (i = 0; i < hosts_count; i++)
					if (0 == strcmp(tmp, hosts[i].addr))
					{
						host = &hosts[i];
						break;
					}
				*c = ' ';
			}

			if (NULL == host)
				continue;

			if (NULL == (c = strstr(tmp, " : ")))
				continue;

			/* when NIC bonding is used, there are also lines like */
			/* 192.168.1.2 : duplicate for [0], 96 bytes, 0.19 ms */

			if (NULL != strstr(tmp, "duplicate for"))
				continue;

			c += 3;

			do
			{
				if (NULL != (c2 = strchr(c, ' ')))
					*c2 = '\0';

				if (0 != strcmp(c, "-"))
				{
					sec = atof(c) / 1000; /* convert ms to seconds */

					if (host->rcv == 0 || host->min > sec)
						host->min = sec;
					if (host->rcv == 0 || host->max < sec)
						host->max = sec;
					host->avg = (host->avg * host->rcv + sec) / (host->rcv + 1);
					host->rcv++;
				}

				host->cnt++;

				if (NULL != c2)
					*c2++ = ' ';
			}
			while (NULL != (c = c2));

			ret = SUCCEED;
		}
		while (NULL != fgets(tmp, sizeof(tmp), f));
	}
	pclose(f);

	unlink(filename);

	if (NOTSUPPORTED == ret)
		zbx_snprintf(error, max_error_len, "fping failed: \"%s\"", tmp);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);

	return ret;
}
コード例 #4
0
ファイル: pid.c プロジェクト: Shmuma/z
int	create_pid_file(const char *pidfile)
{
	struct  stat    buf;
	int fd = 0;

#ifdef HAVE_FCNTL_H
	struct flock fl;

	fl.l_type   = F_WRLCK;  /* F_RDLCK, F_WRLCK, F_UNLCK    */
	fl.l_whence = SEEK_SET; /* SEEK_SET, SEEK_CUR, SEEK_END */
	fl.l_start  = 0;        /* Offset from l_whence         */
	fl.l_len    = 0;        /* length, 0 = to EOF           */
	fl.l_pid    = zbx_get_thread_id(); /* our PID           */

#endif /* HAVE_FCNTL_H */

	/* check if pid file already exists */
	if(stat(pidfile,&buf) == 0)
	{
#ifdef HAVE_FCNTL_H
		if( -1 == (fd = open(pidfile, O_WRONLY | O_APPEND)))
#else
		if( -1 == (fd = open(pidfile, O_APPEND)))
#endif /* HAVE_FCNTL_H */
		{
			zbx_error("Cannot open PID file [%s] [%s]", pidfile, strerror(errno));
			zabbix_log( LOG_LEVEL_CRIT, "Cannot open PID file [%s] [%s]", pidfile, strerror(errno));
			return FAIL;
		}
#ifdef HAVE_FCNTL_H
    		if(-1 == fcntl(fd, F_SETLK, &fl) && EAGAIN == errno)
#else
		if(-1 == flock(fd, LOCK_EX | LOCK_NB) && EWOULDBLOCK == errno)
#endif /* HAVE_FCNTL_H */
		{
			zbx_error("File [%s] exists and locked. Is this process already running ?", pidfile);
			zabbix_log( LOG_LEVEL_CRIT, "File [%s] exists and locked. Is this process already running ?", pidfile);
			return FAIL;
		}
		close(fd);
	}

	/* open pid file */
	if( NULL == (fpid = fopen(pidfile, "w")))
	{
		zbx_error("Cannot create PID file [%s] [%s]", pidfile, strerror(errno));
		zabbix_log( LOG_LEVEL_CRIT, "Cannot create PID file [%s] [%s]", pidfile, strerror(errno));

		return FAIL;
	}

	/* lock file */
	fdpid = fileno(fpid);
#ifdef HAVE_FCNTL_H
	if(-1 != fdpid) fcntl(fdpid, F_SETLK, &fl);
#else
	if(-1 != fdpid) flock(fdpid, LOCK_EX);
#endif /* HAVE_FCNTL_H */

	/* frite pid to file */
	fprintf(fpid, "%li", zbx_get_thread_id());
	fflush(fpid);

	return SUCCEED;
}
コード例 #5
0
ファイル: icmpping.c プロジェクト: rennhak/zabbix
static int	process_ping(ZBX_FPING_HOST *hosts, int hosts_count, char *error, int max_error_len)
{
	FILE		*f;
	char		filename[MAX_STRING_LEN], tmp[MAX_STRING_LEN],
			*c, source_ip[64];
	int		i;
	ZBX_FPING_HOST	*host;
#ifdef HAVE_IPV6
	char		*fping;
	int		family;
#endif

	assert(hosts);

	zabbix_log(LOG_LEVEL_DEBUG, "In process_ping()");

	if (NULL != CONFIG_SOURCE_IP)
		zbx_snprintf(source_ip, sizeof(source_ip), "-S%s ", CONFIG_SOURCE_IP);
	else
		*source_ip = '\0';

	if (access(CONFIG_FPING_LOCATION, F_OK|X_OK) == -1)
	{
		zbx_snprintf(error, max_error_len, "%s: [%d] %s", CONFIG_FPING_LOCATION, errno, strerror(errno));
		return NOTSUPPORTED;
	}

	zbx_snprintf(filename, sizeof(filename), "%s/zabbix_server_%li.pinger",
			CONFIG_TMPDIR,
			zbx_get_thread_id());

#ifdef HAVE_IPV6
	if (access(CONFIG_FPING6_LOCATION, F_OK|X_OK) == -1)
	{
		zbx_snprintf(error, max_error_len, "%s: [%d] %s", CONFIG_FPING6_LOCATION, errno, strerror(errno));
		return NOTSUPPORTED;
	}

	if (NULL != CONFIG_SOURCE_IP)
	{
		if (NOTSUPPORTED == get_address_family(CONFIG_SOURCE_IP, &family, error, max_error_len))
			return NOTSUPPORTED;

		if (family == PF_INET)
			fping = CONFIG_FPING_LOCATION;
		else
			fping = CONFIG_FPING6_LOCATION;

		zbx_snprintf(tmp, sizeof(tmp), "%s %s-c3 2>/dev/null <%s",
				fping,
				source_ip,
				filename);
	}
	else
		zbx_snprintf(tmp, sizeof(tmp), "%s -c3 2>/dev/null <%s;%s -c3 2>/dev/null <%s",
				CONFIG_FPING_LOCATION,
				filename,
				CONFIG_FPING6_LOCATION,
				filename);
#else /* HAVE_IPV6 */
	zbx_snprintf(tmp, sizeof(tmp), "%s %s-c3 2>/dev/null <%s",
			CONFIG_FPING_LOCATION,
			source_ip,
			filename);
#endif /* HAVE_IPV6 */

	if (NULL == (f = fopen(filename, "w"))) {
		zbx_snprintf(error, max_error_len, "%s: [%d] %s", filename, errno, strerror(errno));
		return NOTSUPPORTED;
	}

	zabbix_log(LOG_LEVEL_DEBUG, "%s", filename);

	for (i = 0; i < hosts_count; i++)
	{
		zabbix_log(LOG_LEVEL_DEBUG, "%s", hosts[i].addr);
		fprintf(f, "%s\n", hosts[i].addr);
	}

	fclose(f);

	zabbix_log(LOG_LEVEL_DEBUG, "%s", tmp);

	if (0 == (f = popen(tmp, "r"))) {
		zbx_snprintf(error, max_error_len, "%s: [%d] %s", tmp, errno, strerror(errno));

		unlink(filename);

		return NOTSUPPORTED;
	}

	while (NULL != fgets(tmp, sizeof(tmp), f)) {
		zbx_rtrim(tmp, "\n");
		zabbix_log(LOG_LEVEL_DEBUG, "Update IP [%s]",
				tmp);

		/* 12fc::21 : [0], 76 bytes, 0.39 ms (0.39 avg, 0% loss) */

		host = NULL;

		if (NULL != (c = strchr(tmp, ' '))) {
			*c = '\0';
			for (i = 0; i < hosts_count; i++)
				if (0 == strcmp(tmp, hosts[i].addr)) {
					host = &hosts[i];
					break;
				}
		}

		if (NULL != host) {
			c++;
			if (NULL != (c = strchr(c, '('))) {
				c++;
				host->alive = 1;
				host->sec = atof(c)/1000;
			}
		}
	}
	pclose(f);

	unlink(filename);

	zabbix_log(LOG_LEVEL_DEBUG, "End of process_ping()");

	return SUCCEED;
}
コード例 #6
0
static int	process_ping(ZBX_FPING_HOST *hosts, int hosts_count, int count, int interval, int size, int timeout,
		char *error, int max_error_len)
{
	const char	*__function_name = "process_ping";

	FILE		*f;
	char		*c, params[64];
	char		filename[MAX_STRING_LEN], tmp[MAX_STRING_LEN];
	size_t		offset;
	ZBX_FPING_HOST	*host;
	double		sec;
	int 		i, ret = NOTSUPPORTED, index;

#ifdef HAVE_IPV6
	int		family;
	char		params6[64];
	char		fping_existence = 0;
#define	FPING_EXISTS	0x1
#define	FPING6_EXISTS	0x2

#endif	/* HAVE_IPV6 */

	assert(hosts);

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() hosts_count:%d", __function_name, hosts_count);

	if (-1 == access(CONFIG_FPING_LOCATION, X_OK))
	{
#if !defined(HAVE_IPV6)
		zbx_snprintf(error, max_error_len, "%s: %s", CONFIG_FPING_LOCATION, zbx_strerror(errno));
		return ret;
#endif
	}
	else
	{
#ifdef HAVE_IPV6
		fping_existence |= FPING_EXISTS;
#else
		if (NULL != CONFIG_SOURCE_IP)
		{
			if (FAIL == is_ip4(CONFIG_SOURCE_IP)) /* we do not have IPv4 family address in CONFIG_SOURCE_IP */
			{
				zbx_snprintf(error, max_error_len,
					"You should enable IPv6 support to use IPv6 family address for SourceIP '%s'.", CONFIG_SOURCE_IP);
				return ret;
			}
		}
#endif
	}

#ifdef HAVE_IPV6
	if (-1 == access(CONFIG_FPING6_LOCATION, X_OK))
	{
		if (0 == (fping_existence & FPING_EXISTS))
		{
			zbx_snprintf(error, max_error_len, "At least one of '%s', '%s' must exist. Both are missing in the system.",
					CONFIG_FPING_LOCATION,
					CONFIG_FPING6_LOCATION);
			return ret;
		}
	}
	else
		fping_existence |= FPING6_EXISTS;
#endif	/* HAVE_IPV6 */

	offset = zbx_snprintf(params, sizeof(params), "-C%d", count);
	if (0 != interval)
		offset += zbx_snprintf(params + offset, sizeof(params) - offset, " -p%d", interval);
	if (0 != size)
		offset += zbx_snprintf(params + offset, sizeof(params) - offset, " -b%d", size);
	if (0 != timeout)
		offset += zbx_snprintf(params + offset, sizeof(params) - offset, " -t%d", timeout);

#ifdef HAVE_IPV6
	strscpy(params6, params);
#endif	/* HAVE_IPV6 */

	if (NULL != CONFIG_SOURCE_IP)
	{
#ifdef HAVE_IPV6
		if (0 != (fping_existence & FPING_EXISTS))
		{
			if (0 == source_ip_checked)
				get_source_ip_option(CONFIG_FPING_LOCATION, &source_ip_option, &source_ip_checked);
			if (NULL != source_ip_option)
				zbx_snprintf(params + offset, sizeof(params) - offset,
						" %s%s", source_ip_option, CONFIG_SOURCE_IP);
		}

		if (0 != (fping_existence & FPING6_EXISTS))
		{
			if (0 == source_ip6_checked)
				get_source_ip_option(CONFIG_FPING6_LOCATION, &source_ip6_option, &source_ip6_checked);
			if (NULL != source_ip6_option)
				zbx_snprintf(params6 + offset, sizeof(params6) - offset,
						" %s%s", source_ip6_option, CONFIG_SOURCE_IP);
		}
#else
		if (0 == source_ip_checked)
			get_source_ip_option(CONFIG_FPING_LOCATION, &source_ip_option, &source_ip_checked);
		if (NULL != source_ip_option)
			zbx_snprintf(params + offset, sizeof(params) - offset,
					" %s%s", source_ip_option, CONFIG_SOURCE_IP);
#endif	/* HAVE_IPV6 */
	}

	zbx_snprintf(filename, sizeof(filename), "%s/%s_%li.pinger", CONFIG_TMPDIR, progname, zbx_get_thread_id());

#ifdef HAVE_IPV6
	if (NULL != CONFIG_SOURCE_IP)
	{
		if (SUCCEED != get_address_family(CONFIG_SOURCE_IP, &family, error, max_error_len))
			return ret;

		if (family == PF_INET)
		{
			if (0 == (fping_existence & FPING_EXISTS))
			{
				zbx_snprintf(error, max_error_len, "File '%s' cannot be found in the system.",
						CONFIG_FPING_LOCATION);
				return ret;
			}

			zbx_snprintf(tmp, sizeof(tmp), "%s %s 2>&1 <%s", CONFIG_FPING_LOCATION, params, filename);
		}
		else
		{
			if (0 == (fping_existence & FPING6_EXISTS))
			{
				zbx_snprintf(error, max_error_len, "File '%s' cannot be found in the system.",
						CONFIG_FPING6_LOCATION);
				return ret;
			}

			zbx_snprintf(tmp, sizeof(tmp), "%s %s 2>&1 <%s", CONFIG_FPING6_LOCATION, params6, filename);
		}
	}
	else
	{
		offset = 0;

		if (0 != (fping_existence & FPING_EXISTS))
			offset += zbx_snprintf(tmp + offset, sizeof(tmp) - offset,
					"%s %s 2>&1 <%s;", CONFIG_FPING_LOCATION, params, filename);

		if (0 != (fping_existence & FPING6_EXISTS))
			zbx_snprintf(tmp + offset, sizeof(tmp) - offset,
					"%s %s 2>&1 <%s;", CONFIG_FPING6_LOCATION, params6, filename);
	}
#else
	zbx_snprintf(tmp, sizeof(tmp), "%s %s 2>&1 <%s", CONFIG_FPING_LOCATION, params, filename);
#endif	/* HAVE_IPV6 */

	if (NULL == (f = fopen(filename, "w")))
	{
		zbx_snprintf(error, max_error_len, "%s: %s", filename, zbx_strerror(errno));
		return ret;
	}

	zabbix_log(LOG_LEVEL_DEBUG, "%s", filename);

	for (i = 0; i < hosts_count; i++)
	{
		zabbix_log(LOG_LEVEL_DEBUG, "    %s", hosts[i].addr);
		fprintf(f, "%s\n", hosts[i].addr);
	}

	fclose(f);

	zabbix_log(LOG_LEVEL_DEBUG, "%s", tmp);

	if (NULL == (f = popen(tmp, "r")))
	{
		zbx_snprintf(error, max_error_len, "%s: %s", tmp, zbx_strerror(errno));

		unlink(filename);

		return ret;
	}

	if (NULL == fgets(tmp, sizeof(tmp), f))
	{
		ret = SUCCEED; /* fping does not output anything for DNS names that fail to resolve */
	}
	else
	{
		for (i = 0; i < hosts_count; i++)
		{
			hosts[i].status = zbx_malloc(NULL, count);
			memset(hosts[i].status, 0, count);
		}

		do
		{
			zbx_rtrim(tmp, "\n");
			zabbix_log(LOG_LEVEL_DEBUG, "read line [%s]", tmp);

			host = NULL;

			if (NULL != (c = strchr(tmp, ' ')))
			{
				*c = '\0';
				for (i = 0; i < hosts_count; i++)
					if (0 == strcmp(tmp, hosts[i].addr))
					{
						host = &hosts[i];
						break;
					}
				*c = ' ';
			}

			if (NULL == host)
				continue;

			if (NULL == (c = strstr(tmp, " : ")))
				continue;

			/* when NIC bonding is used, there are also lines like */
			/* 192.168.1.2 : duplicate for [0], 96 bytes, 0.19 ms */

			if (NULL != strstr(tmp, "duplicate for"))
				continue;

			c += 3;

			/* The were two issues with processing only the fping's final status line:  */
			/*   1) pinging broadcast addresses could have resulted in responses from   */
			/*      different hosts, which were counted as the target host responses;   */
			/*   2) there is a bug in fping (v3.8 at least) where pinging broadcast     */
			/*      address will result in no individual responses, but the final       */
			/*      status line might contain a bogus value.                            */
			/* Because of the above issues we must monitor the individual responses     */
			/* and mark the valid ones.                                                 */
			if ('[' == *c)
			{
				/* Fping appends response source address in format '[<- 10.3.0.10]' */
				/* if it does not match the target address. Ignore such responses.  */
				if (NULL != strstr(c + 1, "[<-"))
					continue;

				/* get the index of individual ping response */
				index = atoi(c + 1);

				if (0 > index || index >= count)
					continue;

				host->status[index] = 1;

				continue;
			}

			/* process status line for a host */
			index = 0;
			do
			{
				if (1 == host->status[index])
				{
					sec = atof(c) / 1000; /* convert ms to seconds */

					if (0 == host->rcv || host->min > sec)
						host->min = sec;
					if (0 == host->rcv || host->max < sec)
						host->max = sec;
					host->avg = (host->avg * host->rcv + sec) / (host->rcv + 1);
					host->rcv++;
				}
			}
			while (++index < count && NULL != (c = strchr(c + 1, ' ')));

			host->cnt = count;

			ret = SUCCEED;
		}
		while (NULL != fgets(tmp, sizeof(tmp), f));

		for (i = 0; i < hosts_count; i++)
			zbx_free(hosts[i].status);
	}
	pclose(f);

	unlink(filename);

	if (NOTSUPPORTED == ret)
		zbx_snprintf(error, max_error_len, "fping failed: \"%s\"", tmp);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);

	return ret;
}