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

📄 nstoa.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
字号:
/*	@(#)nstoa.c 1.1 92/07/30 SMI 	*//*	Copyright (c) 1984 AT&T	*//*	  All Rights Reserved  	*//*	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T	*//*	The copyright notice above does not evidence any   	*//*	actual or intended publication of such source code.	*/#ident	"@(#)nlsadmin:nstoa.c	1.4"/*	stoa - convert string to address	If a string begins in \o or \O, the following address is octal	"  "   "       "    " \x or \X, the following address is hex	Otherwise, a string is considered text. Text may be quoted	with double quotes and the C-like escapes \n, \b, \t, \v, \r, and \nnn	(nnn = octal char) are recognized.	A \ followed by a newline causes the newline	to vanish. A \ followed by any other char causes any "magic" of	any other char to disappear.	Other escape sequences recognized are:		\!cmd args [ \! || EOL ]	which is replaced by the raw output of the execution of cmd.	This may only be used in a string.		\$cmd args [ \$ || EOL ]	which is replaced by the output of the execution of cmd and	is then reprocessed.	A  NULL is returned on any error(s).*/#include <stdio.h>#include <memory.h>#include <ctype.h>#include "nsaddr.h"#ifndef S4#include <malloc.h>#endif#define	toupper(c)	(islower(c) ? _toupper(c) : (c))#define	todigit(c)	((int)((c) - '0'))	/* char to digit */#define	toxdigit(c)	((isdigit(c))?todigit(c):(toupper(c)-(int)'A'+10))#define	isodigit(c)	(isdigit(c) && ((c) != '9') && ((c) != '8'))#define	itoac(i)	(((i) > 9) ? ((char)((i)-10) + 'A'):((char)(i) + '0'))	#define	MASK(n)		((1 << (n)) - 1)#define	MAXRLEVEL	10	/* maximum recursion level */#define	SBUFSIZE	128#define	TRUE	1;#define	FALSE	0;char	scanbuf[SBUFSIZE];int	sbp = 0;int	rec = 0;	/* Recursion level */char	sbuf[SBUFSIZE];#ifdef S4extern char *malloc();#endifextern void free();struct netbuf *stoa(str, addr)			/* Return 0 for success, -1 for error */char	*str;struct netbuf	*addr;{	char	*xfer(), *prescan();	int	myadr;		/* was netbuf struct allocated here ? */	int	quote;		/* quoted string ? */	myadr = FALSE;	if (!str)		return NULL;	while (*str && isspace(*str))	/* leading whites are OK */		++str;	str = prescan(str);		/* Do all \$ ... \$ */	if (!str || !*str) return NULL;		/* Nothing to convert */	if (!addr) {		if ((addr = (struct netbuf *)malloc(sizeof(struct netbuf))) == NULL)			return NULL;		myadr = TRUE;		addr->buf = NULL;		addr->maxlen = 0;		addr->len = 0;	}	/* Now process the address */	quote = 0;	if (*str == '\\') {		++str;		switch (*str) {		case 'X':	/* hex */		case 'x':			addr->len = dobase(++str, sbuf, HEX);			break;		case 'o':	/* octal */		case 'O':			addr->len = dobase(++str, sbuf, OCT);			break;		case '\0':	/* No address given!, length is 0 */			addr->len = dostring(str, sbuf, 0);			break;		default:	/* \ is handled by dostring */			addr->len = dostring(--str, sbuf, quote);			break;		}	}	else {		if (*str == '"') {	/* quoted string */			quote = 1;			++str;		}		addr->len = dostring(str, sbuf, quote);	}	if (addr->len == 0) {	/* Error in conversion */		if (myadr)			free(addr);		return NULL;	}	if ((addr->buf = xfer(addr->buf, sbuf, addr->len, addr->maxlen)) == NULL)		return NULL;	else		return addr;}/*	dostring:	Copy string at s to buf translating		escaped characters and shell escapes.	return length of string.*/intdostring(s, buf, quote)		/* read in a raw address */char	*s, *buf;int	quote;{	char	*xcmd();	int	oc, ch, len = 0;	int	l = 0;	char	*rout;	while (*s) {		if (len >= SBUFSIZE) {			fprintf(stderr, "dostring: string too long\n");			break;		}		else if (*s == '\\')			switch(*++s) {			case '!':	/* raw shell escape */				if (rout = xcmd(s+1, '!', &s, &l)) {					if (len + l < SBUFSIZE)						memcpy(buf+len, rout, l);					len += l;					free(rout);				}				break;			case '\n':	/* ignore newline */				++s;				break;			case 'b':	/* backspace */				buf[len++] = '\b'; s++;				break;			case 'n':	/* newline */				buf[len++] = '\n'; s++;				break;			case 'r':	/* return */				buf[len++] = '\r'; s++;				break;			case 't':	/* horiz. tab */				buf[len++] = '\t'; s++;				break;			case 'v':	/* vert. tab */				buf[len++] = '\v'; s++;			case '0':			case '1':			case '2':			case '3':				for(oc=ch=0; (*s >= '0' && *s <= '7') && oc++ < 3; ++s) 					ch = (ch << 3) | (*s - '0');				buf[len++] = ch;				break;			case 0:		/* end of string -- terminate */				break;			default:	/* take the character blindly */				buf[len++] = *s++;				break;			}		else if ((quote && (*s == '"')) || (!quote && isspace(*s)))			break;		else			buf[len++] = *s++;	}	return (len >= SBUFSIZE) ? 0 : len;}/*	dobase :	converts a hex or octal ASCII string		to a binary address. Only HEX or OCT may be used		for type.	return length of binary string (in bytes), 0 if error.	The binary result is placed at buf.*/intdobase(s, buf, type)	/* read in an address */char	*s, *buf;	/* source ASCII, result binary string */int	type;{	void	memcp();	int	bp = SBUFSIZE - 1;	int	shift = 0;	char	*end;	for (end = s; *end && ((type == OCT) ? isodigit(*end) :		isxdigit(*end)); ++end) ;	/* any non-white, non-digits cause address to be rejected,	   other fields are ignored */	if ((*s == 0) || (end == s) || (!isspace(*end) && *end)) {		fprintf(stderr, "dobase: Illegal trailer on address string\n");		buf[0] = '\0';		return 0;	}	--end;	buf[bp] = '\0';	while (bp > 0 && end >= s) {		buf[bp] |= toxdigit(*end) << shift;		if (type == OCT) {			if (shift > 5) {				buf[--bp] = (todigit(*end) >> (8 - shift))					& MASK(shift-5);			}			if ((shift = (shift + 3) % 8) == 0)				buf[--bp] = 0;		}		else	/* hex */			if ((shift = (shift) ? 0 : 4) == 0)				buf[--bp] = 0;;		--end;	}	if (bp == 0) {		fprintf(stderr, "stoa: dobase: number to long\n");		return 0;	}	/* need to catch end case to avoid extra 0's in front	*/	if (!shift)		bp++;	memcp(buf, &buf[bp], (SBUFSIZE - bp));	return (SBUFSIZE - bp);}#ifdef NOTUSED/*	atos(str, addr, type)	convert address to ASCII form with address in hex, octal,	or character form.	return pointer to buffer (NULL on failure).*/char *atos(str, addr, type)char	*str;struct netbuf	*addr;int	type;{	char	*xfer();	int	mystr = 0;	/* was str allocated here ? */	unsigned	x_atos(), o_atos();	void	memcp();	char	*base;	if (addr == NULL)		return NULL;	if (str == NULL)		if ((str = malloc(SBUFSIZE)) == NULL)			return NULL;		else			mystr = 1;	switch (type) {	case OCT:		/* first add \o 	*/		sbuf[0] = '\\';		sbuf[1] = 'o';		return xfer(str, sbuf, o_atos(sbuf+2, addr->buf, addr->len) + 2,			mystr ? SBUFSIZE : 0);	case HEX:		/* first add \x 	*/		sbuf[0] = '\\';		sbuf[1] = 'x';		return xfer(str, sbuf, x_atos(sbuf+2, addr->buf, addr->len) + 2,			mystr ? SBUFSIZE : 0);	case RAW:		base = xfer(str, addr->buf,			 addr->len + 1, mystr ? SBUFSIZE : 0);		if (base)			base[addr->len] = '\0';	/* terminate */		return base;	default:		return NULL;	}}/*	x_atos, o_atos	return the number of bytes occupied by string + NULL *//*	x_atos :	convert an address string a, length s		to hex ASCII in s*/unsignedx_atos(s, a, l)char	*s, *a;unsigned	l;{	char	*b;	b = s;	while (l--) {		*s++ = itoac(((*a >> 4) & MASK (4)));		*s++ = itoac((*a & MASK(4)));		++a;	}	*s = '\0';	return (s - b + 1);}/*	o_atos :	convert an address a, length l		to octal ASCII in s*/unsignedo_atos(s, a, l)char	*s, *a;unsigned	l;{	int	i, shift;	char	*b;	b = s;	if (l == 0) {		*s = '\0';		return 0;	}	/* take care of partial bits and set shift factor for next 3 */	i = l % 3;	*s++ = itoac((*a>>(i+5)) & MASK(3-i));	shift = 2 + i;	while (l)		if (shift <= 5) {			*s++ = itoac((*a >> shift) & MASK(3));			if (shift == 0) {				++a;				--l;			}			shift += (shift < 3) ? 5 : -3;		}		else {			i = (*a & MASK(shift-5)) << (8-shift);			i |= (*++a >> shift) & MASK(8-shift);			*s++ = itoac(i);			shift -= 3;			--l;		}	*s++ = '\0';	return (s - b + 1);}#endif /* NOTUSED */voidmemcp(d, s, n)	/* safe memcpy for overlapping regions */char	*d, *s;int	n;{	while (n--)		*d++ = *s++;}/* transfer block to a given destination or allocate one of the    right size     if max = 0 : ignore max*/char *xfer(dest, src, len, max)char	*dest, *src;unsigned	len, max;{	if (max && dest && max < len) {		/* No room */		fprintf(stderr, "xfer: destination not long enough\n");		return NULL;	}	if (!dest)		if ((dest = malloc(len)) == NULL) {			fprintf(stderr, "xfer: malloc failed\n");			return NULL;		}	memcpy(dest, src, (int)len);	return dest;}/*	prescan:	scan through string s, expanding all \$...\$		as shell escapes.	Return pointer to string of expanded text.*/char *prescan(s)char	*s;{	int	scan();	rec = sbp = 0;	if (!s || !*s || !scan(s))		return NULL;	scanbuf[sbp] = '\0';	return scanbuf;}/*	scan:	scan through string s, expanding all \$...\$.	(Part II of prescan)	Return 0 if anything failed, else 1.*/scan(s)char	*s;{	char	*xcmd();	char	*cmd;	int	len;	int	esc = 0;		/* Keep lookout for \\$ */	while (*s) {		if (!esc && (*s == '\\' && *(s+1) == '$')) {			if (rec++ == MAXRLEVEL) {				fprintf(stderr, "scan: Recursion \level past %d on shell escape\n", rec);				return 0;			}			if ((cmd = xcmd(s+2, '$', &s, &len)) != NULL) {				cmd[len] = '\0'; 				if (*cmd != '\0')					scan(cmd);				free(cmd);			}			else				return 0;		}		else if (sbp == SBUFSIZE) {			fprintf(stderr, "Overflow on shell esc expansion\n");			return 0;		}		else if (sbp < SBUFSIZE)			esc = ((scanbuf[sbp++] = *s++) == '\\');	}	return 1;}/*	xcmd :	extract command line for shell escape and execute it		return pointer to output of command*/char *xcmd(s, ec, ps, len)char	*s;		/* input string */char	ec;		/* escape char ( $ or ! ) */char	**ps;		/* address of input string pointer */int	*len;		/* Number of bytes of output from command */{	FILE	*popen();	int	pclose(), fread();	FILE	*pfp;		/* pipe for process */	char	*cmd;		/* command buffer */	char	*cmdp;		/* pointer along cmd */	char	*ocmd;		/* output of command buffer */	int	esc = 0;	/* escaped escape shell */	*len = 0;	if ((cmd = cmdp = malloc(SBUFSIZE)) == NULL) {		fprintf(stderr, "xcmd: malloc failed\n");		return NULL;	}	if ((ocmd = malloc(SBUFSIZE)) == NULL) {		fprintf(stderr, "xcmd: malloc failed\n");		free(cmd);		return NULL;	}	while (*s) {		if (!esc && *s == '\\' && *(s+1) == ec) {			s += 2;			break;		}		else			esc = (*cmdp++ = *s++) == '\\';	}	*cmdp = '\0';	*ps = s;	if ((pfp = popen(cmd, "r")) == NULL)		fprintf(stderr, "xcmd: popen failed\n");	while (fread(&ocmd[*len], 1, 1, pfp))		if ((*len += 1) >= SBUFSIZE) {			fprintf(stderr, "xcmd: command output too long\n");			break;		}	pclose(pfp);	free(cmd);	return ocmd;}

⌨️ 快捷键说明

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