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

📄 util.c

📁 < linux网络编程工具>>配套源码
💻 C
📖 第 1 页 / 共 4 页
字号:
		*p++ = i;
		if (i == '\n')
		{
			LineNumber++;
			i = getc(f);
			if (i != EOF)
				(void) ungetc(i, f);
			if (i != ' ' && i != '\t')
				break;
		}
	}
	if (p == bp)
		return NULL;
	if (p[-1] == '\n')
		p--;
	*p = '\0';
	return bp;
}
/*
**  CURTIME -- return current time.
**
**	Parameters:
**		none.
**
**	Returns:
**		the current time.
**
**	Side Effects:
**		none.
*/

time_t
curtime()
{
	auto time_t t;

	(void) time(&t);
	return t;
}
/*
**  ATOBOOL -- convert a string representation to boolean.
**
**	Defaults to "TRUE"
**
**	Parameters:
**		s -- string to convert.  Takes "tTyY" as true,
**			others as false.
**
**	Returns:
**		A boolean representation of the string.
**
**	Side Effects:
**		none.
*/

bool
atobool(s)
	register char *s;
{
	if (s == NULL || *s == '\0' || strchr("tTyY", *s) != NULL)
		return TRUE;
	return FALSE;
}
/*
**  ATOOCT -- convert a string representation to octal.
**
**	Parameters:
**		s -- string to convert.
**
**	Returns:
**		An integer representing the string interpreted as an
**		octal number.
**
**	Side Effects:
**		none.
*/

int
atooct(s)
	register char *s;
{
	register int i = 0;

	while (*s >= '0' && *s <= '7')
		i = (i << 3) | (*s++ - '0');
	return i;
}
/*
**  BITINTERSECT -- tell if two bitmaps intersect
**
**	Parameters:
**		a, b -- the bitmaps in question
**
**	Returns:
**		TRUE if they have a non-null intersection
**		FALSE otherwise
**
**	Side Effects:
**		none.
*/

bool
bitintersect(a, b)
	BITMAP256 a;
	BITMAP256 b;
{
	int i;

	for (i = BITMAPBYTES / sizeof (int); --i >= 0; )
		if ((a[i] & b[i]) != 0)
			return TRUE;
	return FALSE;
}
/*
**  BITZEROP -- tell if a bitmap is all zero
**
**	Parameters:
**		map -- the bit map to check
**
**	Returns:
**		TRUE if map is all zero.
**		FALSE if there are any bits set in map.
**
**	Side Effects:
**		none.
*/

bool
bitzerop(map)
	BITMAP256 map;
{
	int i;

	for (i = BITMAPBYTES / sizeof (int); --i >= 0; )
		if (map[i] != 0)
			return FALSE;
	return TRUE;
}
/*
**  STRCONTAINEDIN -- tell if one string is contained in another
**
**	Parameters:
**		a -- possible substring.
**		b -- possible superstring.
**
**	Returns:
**		TRUE if a is contained in b.
**		FALSE otherwise.
*/

bool
strcontainedin(a, b)
	register char *a;
	register char *b;
{
	int la;
	int lb;
	int c;

	la = strlen(a);
	lb = strlen(b);
	c = *a;
	if (isascii(c) && isupper(c))
		c = tolower(c);
	for (; lb-- >= la; b++)
	{
		if (*b != c && isascii(*b) && isupper(*b) && tolower(*b) != c)
			continue;
		if (strncasecmp(a, b, la) == 0)
			return TRUE;
	}
	return FALSE;
}
/*
**  CHECKFD012 -- check low numbered file descriptors
**
**	File descriptors 0, 1, and 2 should be open at all times.
**	This routine verifies that, and fixes it if not true.
**
**	Parameters:
**		where -- a tag printed if the assertion failed
**
**	Returns:
**		none
*/

void
checkfd012(where)
	char *where;
{
#if XDEBUG
	register int i;

	for (i = 0; i < 3; i++)
		fill_fd(i, where);
#endif /* XDEBUG */
}
/*
**  CHECKFDOPEN -- make sure file descriptor is open -- for extended debugging
**
**	Parameters:
**		fd -- file descriptor to check.
**		where -- tag to print on failure.
**
**	Returns:
**		none.
*/

void
checkfdopen(fd, where)
	int fd;
	char *where;
{
#if XDEBUG
	struct stat st;

	if (fstat(fd, &st) < 0 && errno == EBADF)
	{
		syserr("checkfdopen(%d): %s not open as expected!", fd, where);
		printopenfds(TRUE);
	}
#endif /* XDEBUG */
}
/*
**  CHECKFDS -- check for new or missing file descriptors
**
**	Parameters:
**		where -- tag for printing.  If null, take a base line.
**
**	Returns:
**		none
**
**	Side Effects:
**		If where is set, shows changes since the last call.
*/

void
checkfds(where)
	char *where;
{
	int maxfd;
	register int fd;
	bool printhdr = TRUE;
	int save_errno = errno;
	static BITMAP256 baseline;
	extern int DtableSize;

	if (DtableSize > 256)
		maxfd = 256;
	else
		maxfd = DtableSize;
	if (where == NULL)
		clrbitmap(baseline);

	for (fd = 0; fd < maxfd; fd++)
	{
		struct stat stbuf;

		if (fstat(fd, &stbuf) < 0 && errno != EOPNOTSUPP)
		{
			if (!bitnset(fd, baseline))
				continue;
			clrbitn(fd, baseline);
		}
		else if (!bitnset(fd, baseline))
			setbitn(fd, baseline);
		else
			continue;

		/* file state has changed */
		if (where == NULL)
			continue;
		if (printhdr)
		{
			sm_syslog(LOG_DEBUG, CurEnv->e_id,
				  "%s: changed fds:",
				  where);
			printhdr = FALSE;
		}
		dumpfd(fd, TRUE, TRUE);
	}
	errno = save_errno;
}
/*
**  PRINTOPENFDS -- print the open file descriptors (for debugging)
**
**	Parameters:
**		logit -- if set, send output to syslog; otherwise
**			print for debugging.
**
**	Returns:
**		none.
*/

#if NETINET || NETINET6
# include <arpa/inet.h>
#endif /* NETINET || NETINET6 */

void
printopenfds(logit)
	bool logit;
{
	register int fd;
	extern int DtableSize;

	for (fd = 0; fd < DtableSize; fd++)
		dumpfd(fd, FALSE, logit);
}
/*
**  DUMPFD -- dump a file descriptor
**
**	Parameters:
**		fd -- the file descriptor to dump.
**		printclosed -- if set, print a notification even if
**			it is closed; otherwise print nothing.
**		logit -- if set, send output to syslog instead of stdout.
*/

void
dumpfd(fd, printclosed, logit)
	int fd;
	bool printclosed;
	bool logit;
{
	register char *p;
	char *hp;
#ifdef S_IFSOCK
	SOCKADDR sa;
#endif /* S_IFSOCK */
	auto SOCKADDR_LEN_T slen;
	int i;
#if STAT64 > 0
	struct stat64 st;
#else /* STAT64 > 0 */
	struct stat st;
#endif /* STAT64 > 0 */
	char buf[200];

	p = buf;
	snprintf(p, SPACELEFT(buf, p), "%3d: ", fd);
	p += strlen(p);

	if (
#if STAT64 > 0
	    fstat64(fd, &st)
#else /* STAT64 > 0 */
	    fstat(fd, &st)
#endif /* STAT64 > 0 */
	    < 0)
	{
		if (errno != EBADF)
		{
			snprintf(p, SPACELEFT(buf, p), "CANNOT STAT (%s)",
				errstring(errno));
			goto printit;
		}
		else if (printclosed)
		{
			snprintf(p, SPACELEFT(buf, p), "CLOSED");
			goto printit;
		}
		return;
	}

	i = fcntl(fd, F_GETFL, NULL);
	if (i != -1)
	{
		snprintf(p, SPACELEFT(buf, p), "fl=0x%x, ", i);
		p += strlen(p);
	}

	snprintf(p, SPACELEFT(buf, p), "mode=%o: ", (int) st.st_mode);
	p += strlen(p);
	switch (st.st_mode & S_IFMT)
	{
#ifdef S_IFSOCK
	  case S_IFSOCK:
		snprintf(p, SPACELEFT(buf, p), "SOCK ");
		p += strlen(p);
		memset(&sa, '\0', sizeof sa);
		slen = sizeof sa;
		if (getsockname(fd, &sa.sa, &slen) < 0)
			snprintf(p, SPACELEFT(buf, p), "(%s)",
				 errstring(errno));
		else
		{
			hp = hostnamebyanyaddr(&sa);
			if (hp == NULL)
			{
				/* EMPTY */
				/* do nothing */
			}
# if NETINET
			else if (sa.sa.sa_family == AF_INET)
				snprintf(p, SPACELEFT(buf, p), "%s/%d",
					 hp, ntohs(sa.sin.sin_port));
# endif /* NETINET */
# if NETINET6
			else if (sa.sa.sa_family == AF_INET6)
				snprintf(p, SPACELEFT(buf, p), "%s/%d",
					 hp, ntohs(sa.sin6.sin6_port));
# endif /* NETINET6 */
			else
				snprintf(p, SPACELEFT(buf, p), "%s", hp);
		}
		p += strlen(p);
		snprintf(p, SPACELEFT(buf, p), "->");
		p += strlen(p);
		slen = sizeof sa;
		if (getpeername(fd, &sa.sa, &slen) < 0)
			snprintf(p, SPACELEFT(buf, p), "(%s)", errstring(errno));
		else
		{
			hp = hostnamebyanyaddr(&sa);
			if (hp == NULL)
			{
				/* EMPTY */
				/* do nothing */
			}
# if NETINET
			else if (sa.sa.sa_family == AF_INET)
				snprintf(p, SPACELEFT(buf, p), "%s/%d",
					 hp, ntohs(sa.sin.sin_port));
# endif /* NETINET */
# if NETINET6
			else if (sa.sa.sa_family == AF_INET6)
				snprintf(p, SPACELEFT(buf, p), "%s/%d",
					 hp, ntohs(sa.sin6.sin6_port));
# endif /* NETINET6 */
			else
				snprintf(p, SPACELEFT(buf, p), "%s", hp);
		}
		break;
#endif /* S_IFSOCK */

	  case S_IFCHR:
		snprintf(p, SPACELEFT(buf, p), "CHR: ");
		p += strlen(p);
		goto defprint;

	  case S_IFBLK:
		snprintf(p, SPACELEFT(buf, p), "BLK: ");
		p += strlen(p);
		goto defprint;

#if defined(S_IFIFO) && (!defined(S_IFSOCK) || S_IFIFO != S_IFSOCK)
	  case S_IFIFO:
		snprintf(p, SPACELEFT(buf, p), "FIFO: ");
		p += strlen(p);
		goto defprint;
#endif /* defined(S_IFIFO) && (!defined(S_IFSOCK) || S_IFIFO != S_IFSOCK) */

#ifdef S_IFDIR
	  case S_IFDIR:
		snprintf(p, SPACELEFT(buf, p), "DIR: ");
		p += strlen(p);
		goto defprint;
#endif /* S_IFDIR */

#ifdef S_IFLNK
	  case S_IFLNK:
		snprintf(p, SPACELEFT(buf, p), "LNK: ");
		p += strlen(p);
		goto defprint;
#endif /* S_IFLNK */

	  default:
defprint:
		/*CONSTCOND*/
		if (sizeof st.st_ino > sizeof (long))
			snprintf(p, SPACELEFT(buf, p),
				 "dev=%d/%d, ino=%s, nlink=%d, u/gid=%d/%d, ",
				 major(st.st_dev), minor(st.st_dev),
				 quad_to_string(st.st_ino),
				 (int) st.st_nlink, (int) st.st_uid,
				 (int) st.st_gid);
		else
			snprintf(p, SPACELEFT(buf, p),
				 "dev=%d/%d, ino=%lu, nlink=%d, u/gid=%d/%d, ",
				 major(st.st_dev), minor(st.st_dev),
				 (unsigned long) st.st_ino,
				 (int) st.st_nlink, (int) st.st_uid,
				 (int) st.st_gid);
		/*CONSTCOND*/
		if (sizeof st.st_size > sizeof (long))
			snprintf(p, SPACELEFT(buf, p), "size=%s",
				 quad_to_string(st.st_size));
		else
			snprintf(p, SPACELEFT(buf, p), "size=%lu",
				 (unsigned long) st.st_size);
		break;
	}

printit:
	if (logit)
		sm_syslog(LOG_DEBUG, CurEnv ? CurEnv->e_id : NULL,
			  "%.800s", buf);
	else
		printf("%s\n", buf);
}
/*
**  SHORTEN_HOSTNAME -- strip local domain information off of hostname.
**
**	Parameters:
**		host -- the host to shorten (stripped in place).
**
**	Returns:
**		none.
*/

void
shorten_hostname(host)
	char host[];
{
	register char *p;
	char *mydom;
	int i;
	bool canon = FALSE;

	/* strip off final dot */
	p = &host[strlen(host) - 1];
	if (*p == '.')
	{
		*p = '\0';
		canon = TRUE;
	}

	/* see if there is any domain at all -- if not, we are done */
	p = strchr(host, '.');
	if (p == NULL)
		return;

	/* yes, we have a domain -- see if it looks like us */
	mydom = macvalue('m', CurEnv);
	if (mydom == NULL)
		mydom = "";
	i = strlen(++p);
	if ((canon ? strcasecmp(p, mydom) : strncasecmp(p, mydom, i)) == 0 &&
	    (mydom[i] == '.' || mydom[i] == '\0'))
		*--p = '\0';
}
/*
**  PROG_OPEN -- open a program for reading
**
**	Parameters:
**		argv -- the argument list.
**		pfd -- pointer to a place to store the file descriptor.
**		e -- the current envelope.
**
**	Returns:
**		pid of the process -- -1 if it failed.
*/

int
prog_open(argv, pfd, e)
	char **argv;
	int *pfd;
	ENVELOPE *e;
{
	int pid;
	int i;
	int save_errno;
	int fdv[2];
	char *p, *q;
	char buf[MAXLINE + 1];
	extern int DtableSize;

	if (pipe(fdv) < 0)
	{
		syserr("%s: cannot create pipe for stdout", argv[0]);
		return -1;
	}
	pid = fork();
	if (pid < 0)
	{
		syserr("%s: cannot fork", argv[0]);
		(void) close(fdv[0]);
		(void) close(fdv[1]);
		return -1;
	}
	if (pid > 0)
	{
		/* parent */
		(void) close(fdv[1]);
		*pfd = fdv[0];
		return pid;
	}

	/* child -- close stdin */
	(void) close(0);

	/* stdout goes back to parent */
	(void) close(fdv[0]);
	if (dup2(fdv[1], 1) < 0)
	{
		syserr("%s: cannot dup2 for stdout", argv[0]);
		_exit(EX_OSERR);
	}
	(void) close(fdv[1]);

	/* stderr goes to transcript if available */
	if (e->e_xfp != NULL)
	{
		int xfd;

		xfd = fileno(e->e_xfp);
		if (xfd >= 0 && dup2(xfd, 2) < 0)
		{
			syserr("%s: cannot dup2 for stderr", argv[0]);
			_exit(EX_OSERR);
		}
	}

	/* this process has no right to the queue file */
	if (e->e_lockfp != NULL)
		(void) close(fileno(e->e_lockfp));

	/* chroot to the program mailer directory, if defined */
	if (ProgMailer != NULL && ProgMailer->m_rootdir != NULL)
	{

⌨️ 快捷键说明

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