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

📄 util.c

📁 < linux网络编程工具>>配套源码
💻 C
📖 第 1 页 / 共 4 页
字号:
		if (!isascii(c))
		{
			if (c == MATCHREPL)
			{
				printf("%s$", TermEscape.te_rv_on);
				shiftout = TRUE;
				if (*s == '\0')
					continue;
				c = *s++ & 0377;
				goto printchar;
			}
			if (c == MACROEXPAND || c == MACRODEXPAND)
			{
				printf("%s$", TermEscape.te_rv_on);
				if (c == MACRODEXPAND)
					(void) putchar('&');
				shiftout = TRUE;
				if (*s == '\0')
					continue;
				if (strchr("=~&?", *s) != NULL)
					(void) putchar(*s++);
				if (bitset(0200, *s))
					printf("{%s}", macname(*s++ & 0377));
				else
					printf("%c", *s++);
				continue;
			}
			for (mp = MetaMacros; mp->metaname != '\0'; mp++)
			{
				if ((mp->metaval & 0377) == c)
				{
					printf("%s$%c",
						TermEscape.te_rv_on,
						mp->metaname);
					shiftout = TRUE;
					break;
				}
			}
			if (c == MATCHCLASS || c == MATCHNCLASS)
			{
				if (bitset(0200, *s))
					printf("{%s}", macname(*s++ & 0377));
				else if (*s != '\0')
					printf("%c", *s++);
			}
			if (mp->metaname != '\0')
				continue;

			/* unrecognized meta character */
			printf("%sM-", TermEscape.te_rv_on);
			shiftout = TRUE;
			c &= 0177;
		}
  printchar:
		if (isprint(c))
		{
			(void) putchar(c);
			continue;
		}

		/* wasn't a meta-macro -- find another way to print it */
		switch (c)
		{
		  case '\n':
			c = 'n';
			break;

		  case '\r':
			c = 'r';
			break;

		  case '\t':
			c = 't';
			break;
		}
		if (!shiftout)
		{
			printf("%s", TermEscape.te_rv_on);
			shiftout = TRUE;
		}
		if (isprint(c))
		{
			(void) putchar('\\');
			(void) putchar(c);
		}
		else
		{
			(void) putchar('^');
			(void) putchar(c ^ 0100);
		}
	}
	if (shiftout)
		printf("%s", TermEscape.te_rv_off);
	(void) fflush(stdout);
}
/*
**  MAKELOWER -- Translate a line into lower case
**
**	Parameters:
**		p -- the string to translate.  If NULL, return is
**			immediate.
**
**	Returns:
**		none.
**
**	Side Effects:
**		String pointed to by p is translated to lower case.
*/

void
makelower(p)
	register char *p;
{
	register char c;

	if (p == NULL)
		return;
	for (; (c = *p) != '\0'; p++)
		if (isascii(c) && isupper(c))
			*p = tolower(c);
}
/*
**  BUILDFNAME -- build full name from gecos style entry.
**
**	This routine interprets the strange entry that would appear
**	in the GECOS field of the password file.
**
**	Parameters:
**		p -- name to build.
**		user -- the login name of this user (for &).
**		buf -- place to put the result.
**		buflen -- length of buf.
**
**	Returns:
**		none.
**
**	Side Effects:
**		none.
*/

void
buildfname(gecos, user, buf, buflen)
	register char *gecos;
	char *user;
	char *buf;
	int buflen;
{
	register char *p;
	register char *bp = buf;

	if (*gecos == '*')
		gecos++;

	/* copy gecos, interpolating & to be full name */
	for (p = gecos; *p != '\0' && *p != ',' && *p != ';' && *p != '%'; p++)
	{
		if (bp >= &buf[buflen - 1])
		{
			/* buffer overflow -- just use login name */
			snprintf(buf, buflen, "%s", user);
			return;
		}
		if (*p == '&')
		{
			/* interpolate full name */
			snprintf(bp, buflen - (bp - buf), "%s", user);
			*bp = toupper(*bp);
			bp += strlen(bp);
		}
		else
			*bp++ = *p;
	}
	*bp = '\0';
}
/*
**  FIXCRLF -- fix <CR><LF> in line.
**
**	Looks for the <CR><LF> combination and turns it into the
**	UNIX canonical <NL> character.  It only takes one line,
**	i.e., it is assumed that the first <NL> found is the end
**	of the line.
**
**	Parameters:
**		line -- the line to fix.
**		stripnl -- if true, strip the newline also.
**
**	Returns:
**		none.
**
**	Side Effects:
**		line is changed in place.
*/

void
fixcrlf(line, stripnl)
	char *line;
	bool stripnl;
{
	register char *p;

	p = strchr(line, '\n');
	if (p == NULL)
		return;
	if (p > line && p[-1] == '\r')
		p--;
	if (!stripnl)
		*p++ = '\n';
	*p = '\0';
}
/*
**  PUTLINE -- put a line like fputs obeying SMTP conventions
**
**	This routine always guarantees outputing a newline (or CRLF,
**	as appropriate) at the end of the string.
**
**	Parameters:
**		l -- line to put.
**		mci -- the mailer connection information.
**
**	Returns:
**		none
**
**	Side Effects:
**		output of l to fp.
*/

void
putline(l, mci)
	register char *l;
	register MCI *mci;
{
	putxline(l, strlen(l), mci, PXLF_MAPFROM);
}
/*
**  PUTXLINE -- putline with flags bits.
**
**	This routine always guarantees outputing a newline (or CRLF,
**	as appropriate) at the end of the string.
**
**	Parameters:
**		l -- line to put.
**		len -- the length of the line.
**		mci -- the mailer connection information.
**		pxflags -- flag bits:
**		    PXLF_MAPFROM -- map From_ to >From_.
**		    PXLF_STRIP8BIT -- strip 8th bit.
**		    PXLF_HEADER -- map bare newline in header to newline space.
**
**	Returns:
**		none
**
**	Side Effects:
**		output of l to fp.
*/

void
putxline(l, len, mci, pxflags)
	register char *l;
	size_t len;
	register MCI *mci;
	int pxflags;
{
	bool dead = FALSE;
	register char *p, *end;
	int slop = 0;

	/* strip out 0200 bits -- these can look like TELNET protocol */
	if (bitset(MCIF_7BIT, mci->mci_flags) ||
	    bitset(PXLF_STRIP8BIT, pxflags))
	{
		register char svchar;

		for (p = l; (svchar = *p) != '\0'; ++p)
			if (bitset(0200, svchar))
				*p = svchar &~ 0200;
	}

	end = l + len;
	do
	{
		/* find the end of the line */
		p = memchr(l, '\n', end - l);
		if (p == NULL)
			p = end;

		if (TrafficLogFile != NULL)
			fprintf(TrafficLogFile, "%05d >>> ", (int) getpid());

		/* check for line overflow */
		while (mci->mci_mailer->m_linelimit > 0 &&
		       (p - l + slop) > mci->mci_mailer->m_linelimit)
		{
			char *l_base = l;
			register char *q = &l[mci->mci_mailer->m_linelimit - slop - 1];

			if (l[0] == '.' && slop == 0 &&
			    bitnset(M_XDOT, mci->mci_mailer->m_flags))
			{
				if (putc('.', mci->mci_out) == EOF)
					dead = TRUE;
				if (TrafficLogFile != NULL)
					(void) putc('.', TrafficLogFile);
			}
			else if (l[0] == 'F' && slop == 0 &&
				 bitset(PXLF_MAPFROM, pxflags) &&
				 strncmp(l, "From ", 5) == 0 &&
				 bitnset(M_ESCFROM, mci->mci_mailer->m_flags))
			{
				if (putc('>', mci->mci_out) == EOF)
					dead = TRUE;
				if (TrafficLogFile != NULL)
					(void) putc('>', TrafficLogFile);
			}
			if (dead)
				break;

			while (l < q)
			{
				if (putc((unsigned char) *l++, mci->mci_out) ==
				    EOF)
				{
					dead = TRUE;
					break;
				}

				/* record progress for DATA timeout */
				DataProgress = TRUE;
			}
			if (dead)
				break;

			if (putc('!', mci->mci_out) == EOF ||
			    fputs(mci->mci_mailer->m_eol,
				  mci->mci_out) == EOF ||
			    putc(' ', mci->mci_out) == EOF)
			{
				dead = TRUE;
				break;
			}

			/* record progress for DATA timeout */
			DataProgress = TRUE;

			if (TrafficLogFile != NULL)
			{
				for (l = l_base; l < q; l++)
					(void) putc((unsigned char)*l,
						    TrafficLogFile);
				fprintf(TrafficLogFile, "!\n%05d >>>  ",
					(int) getpid());
			}
			slop = 1;
		}

		if (dead)
			break;

		/* output last part */
		if (l[0] == '.' && slop == 0 &&
		    bitnset(M_XDOT, mci->mci_mailer->m_flags))
		{
			if (putc('.', mci->mci_out) == EOF)
				break;
			if (TrafficLogFile != NULL)
				(void) putc('.', TrafficLogFile);
		}
		else if (l[0] == 'F' && slop == 0 &&
			 bitset(PXLF_MAPFROM, pxflags) &&
			 strncmp(l, "From ", 5) == 0 &&
			 bitnset(M_ESCFROM, mci->mci_mailer->m_flags))
		{
			if (putc('>', mci->mci_out) == EOF)
				break;
			if (TrafficLogFile != NULL)
				(void) putc('>', TrafficLogFile);
		}
		for ( ; l < p; ++l)
		{
			if (TrafficLogFile != NULL)
				(void) putc((unsigned char)*l, TrafficLogFile);
			if (putc((unsigned char) *l, mci->mci_out) == EOF)
			{
				dead = TRUE;
				break;
			}

			/* record progress for DATA timeout */
			DataProgress = TRUE;
		}
		if (dead)
			break;

		if (TrafficLogFile != NULL)
			(void) putc('\n', TrafficLogFile);
		if (fputs(mci->mci_mailer->m_eol, mci->mci_out) == EOF)
			break;
		if (l < end && *l == '\n')
		{
			if (*++l != ' ' && *l != '\t' && *l != '\0' &&
			    bitset(PXLF_HEADER, pxflags))
			{
				if (putc(' ', mci->mci_out) == EOF)
					break;
				if (TrafficLogFile != NULL)
					(void) putc(' ', TrafficLogFile);
			}
		}

		/* record progress for DATA timeout */
		DataProgress = TRUE;
	} while (l < end);
}
/*
**  XUNLINK -- unlink a file, doing logging as appropriate.
**
**	Parameters:
**		f -- name of file to unlink.
**
**	Returns:
**		none.
**
**	Side Effects:
**		f is unlinked.
*/

void
xunlink(f)
	char *f;
{
	register int i;

	if (LogLevel > 98)
		sm_syslog(LOG_DEBUG, CurEnv->e_id,
			  "unlink %s",
			  f);

	i = unlink(f);
	if (i < 0 && LogLevel > 97)
		sm_syslog(LOG_DEBUG, CurEnv->e_id,
			  "%s: unlink-fail %d",
			  f, errno);
}
/*
**  SFGETS -- "safe" fgets -- times out and ignores random interrupts.
**
**	Parameters:
**		buf -- place to put the input line.
**		siz -- size of buf.
**		fp -- file to read from.
**		timeout -- the timeout before error occurs.
**		during -- what we are trying to read (for error messages).
**
**	Returns:
**		NULL on error (including timeout).  This will also leave
**			buf containing a null string.
**		buf otherwise.
**
**	Side Effects:
**		none.
*/


static jmp_buf	CtxReadTimeout;

char *
sfgets(buf, siz, fp, timeout, during)
	char *buf;
	int siz;
	FILE *fp;
	time_t timeout;
	char *during;
{
	register EVENT *ev = NULL;
	register char *p;
	int save_errno;

	if (fp == NULL)
	{
		buf[0] = '\0';
		return NULL;
	}

	/* set the timeout */
	if (timeout != 0)
	{
		if (setjmp(CtxReadTimeout) != 0)
		{
			if (LogLevel > 1)
				sm_syslog(LOG_NOTICE, CurEnv->e_id,
					  "timeout waiting for input from %.100s during %s",
					  CurHostName ? CurHostName : "local",
					  during);
			buf[0] = '\0';
#if XDEBUG
			checkfd012(during);
#endif /* XDEBUG */
			if (TrafficLogFile != NULL)
				fprintf(TrafficLogFile, "%05d <<< [TIMEOUT]\n",
					(int) getpid());
			errno = 0;
			return NULL;
		}
		ev = setevent(timeout, readtimeout, 0);
	}

	/* try to read */
	p = NULL;
	errno = 0;
	while (!feof(fp) && !ferror(fp))
	{
		errno = 0;
		p = fgets(buf, siz, fp);
		if (p != NULL || errno != EINTR)
			break;
		clearerr(fp);
	}
	save_errno = errno;

	/* clear the event if it has not sprung */
	clrevent(ev);

	/* clean up the books and exit */
	LineNumber++;
	if (p == NULL)
	{
		buf[0] = '\0';
		if (TrafficLogFile != NULL)
			fprintf(TrafficLogFile, "%05d <<< [EOF]\n", (int) getpid());
		errno = save_errno;
		return NULL;
	}
	if (TrafficLogFile != NULL)
		fprintf(TrafficLogFile, "%05d <<< %s", (int) getpid(), buf);
	if (SevenBitInput)
	{
		for (p = buf; *p != '\0'; p++)
			*p &= ~0200;
	}
	else if (!HasEightBits)
	{
		for (p = buf; *p != '\0'; p++)
		{
			if (bitset(0200, *p))
			{
				HasEightBits = TRUE;
				break;
			}
		}
	}
	return buf;
}

/* ARGSUSED */
static void
readtimeout(timeout)
	time_t timeout;
{
	longjmp(CtxReadTimeout, 1);
}
/*
**  FGETFOLDED -- like fgets, but know about folded lines.
**
**	Parameters:
**		buf -- place to put result.
**		n -- bytes available.
**		f -- file to read from.
**
**	Returns:
**		input line(s) on success, NULL on error or EOF.
**		This will normally be buf -- unless the line is too
**			long, when it will be xalloc()ed.
**
**	Side Effects:
**		buf gets lines from f, with continuation lines (lines
**		with leading white space) appended.  CRLF's are mapped
**		into single newlines.  Any trailing NL is stripped.
*/

char *
fgetfolded(buf, n, f)
	char *buf;
	register int n;
	FILE *f;
{
	register char *p = buf;
	char *bp = buf;
	register int i;

	n--;
	while ((i = getc(f)) != EOF)
	{
		if (i == '\r')
		{
			i = getc(f);
			if (i != '\n')
			{
				if (i != EOF)
					(void) ungetc(i, f);
				i = '\r';
			}
		}
		if (--n <= 0)
		{
			/* allocate new space */
			char *nbp;
			int nn;

			nn = (p - bp);
			if (nn < MEMCHUNKSIZE)
				nn *= 2;
			else
				nn += MEMCHUNKSIZE;
			nbp = xalloc(nn);
			memmove(nbp, bp, p - bp);
			p = &nbp[p - bp];
			if (bp != buf)
				free(bp);
			bp = nbp;
			n = nn - (p - bp);
		}

⌨️ 快捷键说明

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