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

📄 util.c

📁 < linux网络编程工具>>配套源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
 * Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
 *	All rights reserved.
 * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
 * Copyright (c) 1988, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * By using this file, you agree to the terms and conditions set
 * forth in the LICENSE file which can be found at the top level of
 * the sendmail distribution.
 *
 */

#ifndef lint
static char id[] = "@(#)$Id: util.c,v 8.225.2.1.2.8 2000/07/03 18:28:56 geir Exp $";
#endif /* ! lint */

#include <sendmail.h>
#include <sysexits.h>


static void	readtimeout __P((time_t));

/*
**  STRIPQUOTES -- Strip quotes & quote bits from a string.
**
**	Runs through a string and strips off unquoted quote
**	characters and quote bits.  This is done in place.
**
**	Parameters:
**		s -- the string to strip.
**
**	Returns:
**		none.
**
**	Side Effects:
**		none.
*/

void
stripquotes(s)
	char *s;
{
	register char *p;
	register char *q;
	register char c;

	if (s == NULL)
		return;

	p = q = s;
	do
	{
		c = *p++;
		if (c == '\\')
			c = *p++;
		else if (c == '"')
			continue;
		*q++ = c;
	} while (c != '\0');
}
/*
**  ADDQUOTES -- Adds quotes & quote bits to a string.
**
**	Runs through a string and adds characters and quote bits.
**
**	Parameters:
**		s -- the string to modify.
**
**	Returns:
**		pointer to quoted string.
**
**	Side Effects:
**		none.
**
*/

char *
addquotes(s)
	char *s;
{
	int len = 0;
	char c;
	char *p = s, *q, *r;

	if (s == NULL)
		return NULL;

	/* Find length of quoted string */
	while ((c = *p++) != '\0')
	{
		len++;
		if (c == '\\' || c == '"')
			len++;
	}

	q = r = xalloc(len + 3);
	p = s;

	/* add leading quote */
	*q++ = '"';
	while ((c = *p++) != '\0')
	{
		/* quote \ or " */
		if (c == '\\' || c == '"')
			*q++ = '\\';
		*q++ = c;
	}
	*q++ = '"';
	*q = '\0';
	return r;
}
/*
**  RFC822_STRING -- Checks string for proper RFC822 string quoting.
**
**	Runs through a string and verifies RFC822 special characters
**	are only found inside comments, quoted strings, or backslash
**	escaped.  Also verified balanced quotes and parenthesis.
**
**	Parameters:
**		s -- the string to modify.
**
**	Returns:
**		TRUE -- if the string is RFC822 compliant.
**		FALSE -- if the string is not RFC822 compliant.
**
**	Side Effects:
**		none.
**
*/

bool
rfc822_string(s)
	char *s;
{
	bool quoted = FALSE;
	int commentlev = 0;
	char *c = s;

	if (s == NULL)
		return FALSE;

	while (*c != '\0')
	{
		/* escaped character */
		if (*c == '\\')
		{
			c++;
			if (*c == '\0')
				return FALSE;
		}
		else if (commentlev == 0 && *c == '"')
			quoted = !quoted;
		else if (!quoted)
		{
			if (*c == ')')
			{
				/* unbalanced ')' */
				if (commentlev == 0)
					return FALSE;
				else
					commentlev--;
			}
			else if (*c == '(')
				commentlev++;
			else if (commentlev == 0 &&
				 strchr(MustQuoteChars, *c) != NULL)
				return FALSE;
		}
		c++;
	}
	/* unbalanced '"' or '(' */
	if (quoted || commentlev != 0)
		return FALSE;
	else
		return TRUE;
}
/*
**  SHORTEN_RFC822_STRING -- Truncate and rebalance an RFC822 string
**
**	Arbitrarily shorten (in place) an RFC822 string and rebalance
**	comments and quotes.
**
**	Parameters:
**		string -- the string to shorten
**		length -- the maximum size, 0 if no maximum
**
**	Returns:
**		TRUE if string is changed, FALSE otherwise
**
**	Side Effects:
**		Changes string in place, possibly resulting
**		in a shorter string.
*/

bool
shorten_rfc822_string(string, length)
	char *string;
	size_t length;
{
	bool backslash = FALSE;
	bool modified = FALSE;
	bool quoted = FALSE;
	size_t slen;
	int parencount = 0;
	char *ptr = string;

	/*
	**  If have to rebalance an already short enough string,
	**  need to do it within allocated space.
	*/
	slen = strlen(string);
	if (length == 0 || slen < length)
		length = slen;

	while (*ptr != '\0')
	{
		if (backslash)
		{
			backslash = FALSE;
			goto increment;
		}

		if (*ptr == '\\')
			backslash = TRUE;
		else if (*ptr == '(')
		{
			if (!quoted)
				parencount++;
		}
		else if (*ptr == ')')
		{
			if (--parencount < 0)
				parencount = 0;
		}

		/* Inside a comment, quotes don't matter */
		if (parencount <= 0 && *ptr == '"')
			quoted = !quoted;

increment:
		/* Check for sufficient space for next character */
		if (length - (ptr - string) <= (size_t) ((backslash ? 1 : 0) +
						parencount +
						(quoted ? 1 : 0)))
		{
			/* Not enough, backtrack */
			if (*ptr == '\\')
				backslash = FALSE;
			else if (*ptr == '(' && !quoted)
				parencount--;
			else if (*ptr == '"' && parencount == 0)
				quoted = FALSE;
			break;
		}
		ptr++;
	}

	/* Rebalance */
	while (parencount-- > 0)
	{
		if (*ptr != ')')
		{
			modified = TRUE;
			*ptr = ')';
		}
		ptr++;
	}
	if (quoted)
	{
		if (*ptr != '"')
		{
			modified = TRUE;
			*ptr = '"';
		}
		ptr++;
	}
	if (*ptr != '\0')
	{
		modified = TRUE;
		*ptr = '\0';
	}
	return modified;
}
/*
**  FIND_CHARACTER -- find an unquoted character in an RFC822 string
**
**	Find an unquoted, non-commented character in an RFC822
**	string and return a pointer to its location in the
**	string.
**
**	Parameters:
**		string -- the string to search
**		character -- the character to find
**
**	Returns:
**		pointer to the character, or
**		a pointer to the end of the line if character is not found
*/

char *
find_character(string, character)
	char *string;
	int character;
{
	bool backslash = FALSE;
	bool quoted = FALSE;
	int parencount = 0;

	while (string != NULL && *string != '\0')
	{
		if (backslash)
		{
			backslash = FALSE;
			if (!quoted && character == '\\' && *string == '\\')
				break;
			string++;
			continue;
		}
		switch (*string)
		{
		  case '\\':
			backslash = TRUE;
			break;

		  case '(':
			if (!quoted)
				parencount++;
			break;

		  case ')':
			if (--parencount < 0)
				parencount = 0;
			break;
		}

		/* Inside a comment, nothing matters */
		if (parencount > 0)
		{
			string++;
			continue;
		}

		if (*string == '"')
			quoted = !quoted;
		else if (*string == character && !quoted)
			break;
		string++;
	}

	/* Return pointer to the character */
	return string;
}
/*
**  XALLOC -- Allocate memory and bitch wildly on failure.
**
**	THIS IS A CLUDGE.  This should be made to give a proper
**	error -- but after all, what can we do?
**
**	Parameters:
**		sz -- size of area to allocate.
**
**	Returns:
**		pointer to data region.
**
**	Side Effects:
**		Memory is allocated.
*/

char *
xalloc(sz)
	register int sz;
{
	register char *p;

	/* some systems can't handle size zero mallocs */
	if (sz <= 0)
		sz = 1;

	p = malloc((unsigned) sz);
	if (p == NULL)
	{
		syserr("!Out of memory!!");
		/* exit(EX_UNAVAILABLE); */
	}
	return p;
}
/*
**  COPYPLIST -- copy list of pointers.
**
**	This routine is the equivalent of newstr for lists of
**	pointers.
**
**	Parameters:
**		list -- list of pointers to copy.
**			Must be NULL terminated.
**		copycont -- if TRUE, copy the contents of the vector
**			(which must be a string) also.
**
**	Returns:
**		a copy of 'list'.
**
**	Side Effects:
**		none.
*/

char **
copyplist(list, copycont)
	char **list;
	bool copycont;
{
	register char **vp;
	register char **newvp;

	for (vp = list; *vp != NULL; vp++)
		continue;

	vp++;

	newvp = (char **) xalloc((int) (vp - list) * sizeof *vp);
	memmove((char *) newvp, (char *) list, (int) (vp - list) * sizeof *vp);

	if (copycont)
	{
		for (vp = newvp; *vp != NULL; vp++)
			*vp = newstr(*vp);
	}

	return newvp;
}
/*
**  COPYQUEUE -- copy address queue.
**
**	This routine is the equivalent of newstr for address queues
**	addresses marked as QS_IS_DEAD() aren't copied
**
**	Parameters:
**		addr -- list of address structures to copy.
**
**	Returns:
**		a copy of 'addr'.
**
**	Side Effects:
**		none.
*/

ADDRESS *
copyqueue(addr)
	ADDRESS *addr;
{
	register ADDRESS *newaddr;
	ADDRESS *ret;
	register ADDRESS **tail = &ret;

	while (addr != NULL)
	{
		if (!QS_IS_DEAD(addr->q_state))
		{
			newaddr = (ADDRESS *) xalloc(sizeof *newaddr);
			STRUCTCOPY(*addr, *newaddr);
			*tail = newaddr;
			tail = &newaddr->q_next;
		}
		addr = addr->q_next;
	}
	*tail = NULL;

	return ret;
}
/*
**  LOG_SENDMAIL_PID -- record sendmail pid and command line.
**
**	Parameters:
**		e -- the current envelope.
**
**	Returns:
**		none.
**
**	Side Effects:
**		writes pidfile.
*/

void
log_sendmail_pid(e)
	ENVELOPE *e;
{
	long sff;
	FILE *pidf;
	char pidpath[MAXPATHLEN + 1];

	/* write the pid to the log file for posterity */
	sff = SFF_NOLINK|SFF_ROOTOK|SFF_REGONLY|SFF_CREAT;
	if (TrustedUid != 0 && RealUid == TrustedUid)
		sff |= SFF_OPENASROOT;
	expand(PidFile, pidpath, sizeof pidpath, e);
	pidf = safefopen(pidpath, O_WRONLY|O_TRUNC, 0644, sff);
	if (pidf == NULL)
	{
		sm_syslog(LOG_ERR, NOQID, "unable to write %s", pidpath);
	}
	else
	{
		extern char *CommandLineArgs;

		/* write the process id on line 1 */
		fprintf(pidf, "%ld\n", (long) getpid());

		/* line 2 contains all command line flags */
		fprintf(pidf, "%s\n", CommandLineArgs);

		/* flush and close */
		(void) fclose(pidf);
	}
}
/*
**  SET_DELIVERY_MODE -- set and record the delivery mode
**
**	Parameters:
**		mode -- delivery mode
**		e -- the current envelope.
**
**	Returns:
**		none.
**
**	Side Effects:
**		sets $&{deliveryMode} macro
*/

void
set_delivery_mode(mode, e)
	int mode;
	ENVELOPE *e;
{
	char buf[2];

	e->e_sendmode = (char)mode;
	buf[0] = (char)mode;
	buf[1] = '\0';
	define(macid("{deliveryMode}", NULL), newstr(buf), e);
}
/*
**  PRINTAV -- print argument vector.
**
**	Parameters:
**		av -- argument vector.
**
**	Returns:
**		none.
**
**	Side Effects:
**		prints av.
*/

void
printav(av)
	register char **av;
{
	while (*av != NULL)
	{
		if (tTd(0, 44))
			dprintf("\n\t%08lx=", (u_long) *av);
		else
			(void) putchar(' ');
		xputs(*av++);
	}
	(void) putchar('\n');
}
/*
**  LOWER -- turn letter into lower case.
**
**	Parameters:
**		c -- character to turn into lower case.
**
**	Returns:
**		c, in lower case.
**
**	Side Effects:
**		none.
*/

char
lower(c)
	register int c;
{
	return ((isascii(c) && isupper(c)) ? tolower(c) : c);
}
/*
**  XPUTS -- put string doing control escapes.
**
**	Parameters:
**		s -- string to put.
**
**	Returns:
**		none.
**
**	Side Effects:
**		output to stdout
*/

void
xputs(s)
	register const char *s;
{
	register int c;
	register struct metamac *mp;
	bool shiftout = FALSE;
	extern struct metamac MetaMacros[];

	if (s == NULL)
	{
		printf("%s<null>%s", TermEscape.te_rv_on, TermEscape.te_rv_off);
		return;
	}
	while ((c = (*s++ & 0377)) != '\0')
	{
		if (shiftout)
		{
			printf("%s", TermEscape.te_rv_off);
			shiftout = FALSE;
		}

⌨️ 快捷键说明

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