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

📄 dump.c

📁 这是一个SIGMA方案的PMP播放器的UCLINUX程序,可播放DVD,VCD,CD MP3...有很好的参考价值.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Support code for the hexdump and od applets, * based on code from util-linux v 2.11l * * Copyright (c) 1989 *	The Regents of the University of California.  All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Original copyright notice is retained at the end of this file. */#include <stdlib.h>#include <string.h>#include <ctype.h>		/* for isdigit() */#include "dump.h"#include "libbb.h"enum _vflag vflag = FIRST;FS *fshead;				/* head of format strings */extern FS *fshead;				/* head of format strings */extern int blocksize;static FU *endfu;static char **_argv;static off_t savaddress;		/* saved address/offset in stream */static off_t eaddress;			/* end address */static off_t address;			/* address/offset in stream */off_t skip;                      /* bytes to skip */off_t saveaddress;int exitval;				/* final exit value */int blocksize;				/* data block size */int length = -1;			/* max bytes to read */int size(FS *fs){	register FU *fu;	register int bcnt, cursize;	register char *fmt;	int prec;	/* figure out the data block size needed for each format unit */	for (cursize = 0, fu = fs->nextfu; fu; fu = fu->nextfu) {		if (fu->bcnt) {			cursize += fu->bcnt * fu->reps;			continue;		}		for (bcnt = prec = 0, fmt = fu->fmt; *fmt; ++fmt) {			if (*fmt != '%')				continue;			/*			 * skip any special chars -- save precision in			 * case it's a %s format.			 */			while (index(".#-+ 0123456789" + 1, *++fmt));			if (*fmt == '.' && isdigit(*++fmt)) {				prec = atoi(fmt);				while (isdigit(*++fmt));			}			switch(*fmt) {			case 'c':				bcnt += 1;				break;			case 'd': case 'i': case 'o': case 'u':			case 'x': case 'X':				bcnt += 4;				break;			case 'e': case 'E': case 'f': case 'g': case 'G':				bcnt += 8;				break;			case 's':				bcnt += prec;				break;			case '_':				switch(*++fmt) {				case 'c': case 'p': case 'u':					bcnt += 1;					break;				}			}		}		cursize += bcnt * fu->reps;	}	return(cursize);}void rewrite(FS *fs){	enum { NOTOKAY, USEBCNT, USEPREC } sokay;	register PR *pr, **nextpr = NULL;	register FU *fu;	register char *p1, *p2;	char savech, *fmtp;	int nconv, prec = 0;	for (fu = fs->nextfu; fu; fu = fu->nextfu) {		/*		 * break each format unit into print units; each		 * conversion character gets its own.		 */		for (nconv = 0, fmtp = fu->fmt; *fmtp; nextpr = &pr->nextpr) {			/* NOSTRICT */			pr = (PR *)xmalloc(sizeof(PR));			if (!fu->nextpr)				fu->nextpr = pr;			else				*nextpr = pr;			/* skip preceding text and up to the next % sign */			for (p1 = fmtp; *p1 && *p1 != '%'; ++p1);			/* only text in the string */			if (!*p1) {				pr->fmt = fmtp;				pr->flags = F_TEXT;				break;			}			/*			 * get precision for %s -- if have a byte count, don't			 * need it.			 */			if (fu->bcnt) {				sokay = USEBCNT;				/* skip to conversion character */				for (++p1; index(".#-+ 0123456789", *p1); ++p1);			} else {				/* skip any special chars, field width */				while (index(".#-+ 0123456789" + 1, *++p1));				if (*p1 == '.' && isdigit(*++p1)) {					sokay = USEPREC;					prec = atoi(p1);					while (isdigit(*++p1));				}				else					sokay = NOTOKAY;			}			p2 = p1 + 1;		/* set end pointer */			/*			 * figure out the byte count for each conversion;			 * rewrite the format as necessary, set up blank-			 * padding for end of data.			 */			switch(*p1) {			case 'c':				pr->flags = F_CHAR;				switch(fu->bcnt) {				case 0: case 1:					pr->bcnt = 1;					break;				default:					p1[1] = '\0';					error_msg_and_die("bad byte count for conversion character %s.", p1);				}				break;			case 'd': case 'i':				pr->flags = F_INT;				goto sw1;			case 'l':				++p2;				switch(p1[1]) {				case 'd': case 'i':					++p1;					pr->flags = F_INT;					goto sw1;				case 'o': case 'u': case 'x': case 'X':					++p1;					pr->flags = F_UINT;					goto sw1;				default:					p1[2] = '\0';					error_msg_and_die("hexdump: bad conversion character %%%s.\n", p1);				}				/* NOTREACHED */			case 'o': case 'u': case 'x': case 'X':				pr->flags = F_UINT;sw1:				switch(fu->bcnt) {				case 0: case 4:					pr->bcnt = 4;					break;				case 1:					pr->bcnt = 1;					break;				case 2:					pr->bcnt = 2;					break;				default:					p1[1] = '\0';					error_msg_and_die("bad byte count for conversion character %s.", p1);				}				break;			case 'e': case 'E': case 'f': case 'g': case 'G':				pr->flags = F_DBL;				switch(fu->bcnt) {				case 0: case 8:					pr->bcnt = 8;					break;				case 4:					pr->bcnt = 4;					break;				default:					p1[1] = '\0';					error_msg_and_die("bad byte count for conversion character %s.", p1);				}				break;			case 's':				pr->flags = F_STR;				switch(sokay) {				case NOTOKAY:					error_msg_and_die("%%s requires a precision or a byte count.");				case USEBCNT:					pr->bcnt = fu->bcnt;					break;				case USEPREC:					pr->bcnt = prec;					break;				}				break;			case '_':				++p2;				switch(p1[1]) {				case 'A':					endfu = fu;					fu->flags |= F_IGNORE;					/* FALLTHROUGH */				case 'a':					pr->flags = F_ADDRESS;					++p2;					switch(p1[2]) {					case 'd': case 'o': case'x':						*p1 = p1[2];						break;					default:						p1[3] = '\0';						error_msg_and_die("hexdump: bad conversion character %%%s.\n", p1);					}					break;				case 'c':					pr->flags = F_C;					/* *p1 = 'c';	set in conv_c */					goto sw2;				case 'p':					pr->flags = F_P;					*p1 = 'c';					goto sw2;				case 'u':					pr->flags = F_U;					/* *p1 = 'c';	set in conv_u */sw2:					switch(fu->bcnt) {					case 0: case 1:						pr->bcnt = 1;						break;					default:						p1[2] = '\0';						error_msg_and_die("bad byte count for conversion character %s.", p1);					}					break;				default:					p1[2] = '\0';					error_msg_and_die("hexdump: bad conversion character %%%s.\n", p1);				}				break;			default:				p1[1] = '\0';				error_msg_and_die("hexdump: bad conversion character %%%s.\n", p1);			}			/*			 * copy to PR format string, set conversion character			 * pointer, update original.			 */			savech = *p2;			p1[1] = '\0';			if (!(pr->fmt = strdup(fmtp)))				perror_msg_and_die("hexdump");			*p2 = savech;			pr->cchar = pr->fmt + (p1 - fmtp);			fmtp = p2;			/* only one conversion character if byte count */			if (!(pr->flags&F_ADDRESS) && fu->bcnt && nconv++) {				error_msg_and_die("hexdump: byte count with multiple conversion characters.\n");			}		}		/*		 * if format unit byte count not specified, figure it out		 * so can adjust rep count later.		 */		if (!fu->bcnt)			for (pr = fu->nextpr; pr; pr = pr->nextpr)				fu->bcnt += pr->bcnt;	}	/*	 * if the format string interprets any data at all, and it's	 * not the same as the blocksize, and its last format unit	 * interprets any data at all, and has no iteration count,	 * repeat it as necessary.	 *	 * if, rep count is greater than 1, no trailing whitespace	 * gets output from the last iteration of the format unit.	 */	for (fu = fs->nextfu;; fu = fu->nextfu) {		if (!fu->nextfu && fs->bcnt < blocksize &&		    !(fu->flags&F_SETREP) && fu->bcnt)			fu->reps += (blocksize - fs->bcnt) / fu->bcnt;		if (fu->reps > 1) {			for (pr = fu->nextpr;; pr = pr->nextpr)				if (!pr->nextpr)					break;			for (p1 = pr->fmt, p2 = NULL; *p1; ++p1)				p2 = isspace(*p1) ? p1 : NULL;			if (p2)				pr->nospace = p2;		}		if (!fu->nextfu)			break;	}}static void doskip(char *fname, int statok){	struct stat sbuf;	if (statok) {		if (fstat(fileno(stdin), &sbuf)) {			perror_msg_and_die("hexdump: %s", fname);		}		if ( ( ! (S_ISCHR(sbuf.st_mode) || 			  S_ISBLK(sbuf.st_mode) || 			  S_ISFIFO(sbuf.st_mode)) ) &&		     skip >= sbuf.st_size) {		  /* If size valid and skip >= size */			skip -= sbuf.st_size;			address += sbuf.st_size;			return;		}	}	if (fseek(stdin, skip, SEEK_SET)) {		perror_msg_and_die("hexdump: %s", fname);	}	savaddress = address += skip;	skip = 0;}int next(char **argv){	static int done;	int statok;	if (argv) {		_argv = argv;		return(1);	}	for (;;) {		if (*_argv) {			if (!(freopen(*_argv, "r", stdin))) {				perror_msg("%s", *_argv);				exitval = 1;				++_argv;				continue;			}			statok = done = 1;		} else {			if (done++)				return(0);			statok = 0;		}		if (skip)			doskip(statok ? *_argv : "stdin", statok);		if (*_argv)			++_argv;		if (!skip)			return(1);	}	/* NOTREACHED */}static u_char *get(void){	static int ateof = 1;	static u_char *curp, *savp;	register int n;	int need, nread;	u_char *tmpp;	if (!curp) {		curp = (u_char *)xmalloc(blocksize);		savp = (u_char *)xmalloc(blocksize);	} else {		tmpp = curp;		curp = savp;		savp = tmpp;		address = savaddress += blocksize;	}	for (need = blocksize, nread = 0;;) {		/*		 * if read the right number of bytes, or at EOF for one file,		 * and no other files are available, zero-pad the rest of the		 * block and set the end flag.		 */		if (!length || (ateof && !next((char **)NULL))) {			if (need == blocksize) {				return((u_char *)NULL);			}			if (vflag != ALL && !bcmp(curp, savp, nread)) {				if (vflag != DUP) {					printf("*\n");				}				return((u_char *)NULL);			}			bzero((char *)curp + nread, need);			eaddress = address + nread;			return(curp);		}		n = fread((char *)curp + nread, sizeof(u_char),

⌨️ 快捷键说明

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