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

📄 genromfs.c

📁 wizfwtools: tools for developing firmware images for Beyonwiz embedded devices (www.beyonwiz.com)
💻 C
📖 第 1 页 / 共 2 页
字号:
}/* Node manipulating functions */void freenode(struct filenode *n){	/* Rare, not yet */}void setnode(struct filenode *n, dev_t dev, ino_t ino, mode_t um){	n->ondev = dev;	n->onino = ino;	n->modes = um;}struct filenode *newnode(const char *base, const char *name, int curroffset){	struct filenode *node;	int len;	char *str;	node = malloc(sizeof (*node));	if (!node) {		fprintf(stderr,"out of memory\n");		exit(1);	}	len = strlen(name);	str = malloc(len+1);	if (!str) {		fprintf(stderr,"out of memory\n");		exit(1);	}	strcpy(str, name);	node->name = str;	if (!curroffset) {		len = 1;		name = ".";	}	if (strlen(base))		len++;	str = malloc(strlen(base)+len+1);	if (!str) {		fprintf(stderr,"out of memory\n");		exit(1);	}	if (strlen(base)) {		sprintf(str, "%s/%s", base, name);	} else {		strcpy(str, name);	}	node->realname = str;	node->next = node->prev = NULL;	node->parent = NULL;	initlist(&node->dirlist, node);	node->ondev = -1;	node->onino = -1;	node->modes = -1;	node->size = 0;	node->devnode = 0;	node->orig_link = NULL;	node->offset = curroffset;	node->pad = 0;	return node;}struct filenode *findnode(struct filenode *node, dev_t dev, ino_t ino){	struct filenode *found, *p;	/* scan the whole tree */	if (node->ondev == dev && node->onino == ino)		return node;	p = node->dirlist.head;	while (p->next) {		found = findnode(p, dev, ino);		if (found)			return found;		p = p->next;	}	return NULL;}#define ALIGNUP16(x) (((x)+15)&~15)int spaceneeded(struct filenode *node){	return 16 + ALIGNUP16(strlen(node->name)+1) + ALIGNUP16(node->size);}int alignnode(struct filenode *node, int curroffset, int extraspace){	int align = findalign(node), d;				d = ((curroffset + extraspace) & (align - 1));	if (d) {		align -= d;		curroffset += align;		node->offset += align;		node->pad = align;	}	return curroffset;}int processdir(int level, const char *base, const char *dirname, struct stat *sb,	struct filenode *dir, struct filenode *root, int curroffset){	DIR *dirfd;	struct dirent *dp;	struct filenode *n, *link;	struct excludes *pe;	if (level <= 1) {		/* Ok, to make sure . and .. are handled correctly		 * we add them first.  Note also that we alloc them		 * first to get to know the real name		 */		link = newnode(base, ".", curroffset);		if (!lstat(link->realname, sb)) {			setnode(link, sb->st_dev, sb->st_ino, sb->st_mode);			append(&dir->dirlist, link);			/* special case for root node - '..'s in subdirs should link to			 *   '.' of root node, not root node itself.			 */			dir->dirlist.owner = link;			curroffset = alignnode(link, curroffset, 0) + spaceneeded(link);			n = newnode(base, "..", curroffset);			if (!lstat(n->realname, sb)) {				setnode(n, sb->st_dev, sb->st_ino, sb->st_mode);				append(&dir->dirlist, n);				n->orig_link = link;				curroffset = alignnode(n, curroffset, 0) + spaceneeded(n);			}		}	}	dirfd = opendir(dir->realname);	if (dirfd == NULL) {		perror(dir->realname);		exit(1);	}	while(dirfd && (dp = readdir(dirfd))) {		/* don't process main . and .. twice */		if (level <= 1 &&		    (strcmp(dp->d_name, ".") == 0		     || strcmp(dp->d_name, "..") == 0))			continue;		n = newnode(base, dp->d_name, curroffset);		/* Process exclude list. */		for (pe = excludelist; pe; pe = pe->next) {			if (!nodematch(pe->pattern, n)) { freenode(n); break; }		}		if (pe) continue;		if (lstat(n->realname, sb)) {			fprintf(stderr, "ignoring '%s' (lstat failed)\n", n->realname);			freenode(n); continue;		}		/* strip 000_ from files/directories except '.' and '..' */		if (case_insensitive_mode &&		    (strcmp(dp->d_name, ".") != 0		     && strcmp(dp->d_name, "..") != 0))		{			if(n->name[3] == 'x') // "001x_filename" If marked as executable then force exe permission.				sb->st_mode |= S_IXUSR;			n->name += 5;		}				/* Handle special names */		if ( n->name[0] == '@' ) {			if (S_ISLNK(sb->st_mode)) {				/* this is a link to follow at build time */				n->name = n->name + 1; /* strip off the leading @ */				memset(bigbuf, 0, sizeof(bigbuf));				readlink(n->realname, bigbuf, sizeof(bigbuf));				n->realname = strdup(bigbuf);				if (lstat(n->realname, sb)) {					fprintf(stderr, "ignoring '%s' (lstat failed)\n",						n->realname);					freenode(n); continue;				}			} else if (S_ISREG(sb->st_mode) && sb->st_size == 0) {				/*				 *        special file @name,[bcp..],major,minor				 */				char      devname[32];				char      type;				int       major;				int       minor;										if (sscanf(n->name, "@%[a-zA-Z0-9_+-],%c,%d,%d",					   devname, &type, &major, &minor) == 4 ) {					strcpy(n->name, devname);					sb->st_rdev = makedev(major, minor);					sb->st_mode &= ~S_IFMT;					switch (type) {					case 'c':					case 'u':						sb->st_mode |= S_IFCHR;						break;					case 'b':						sb->st_mode |= S_IFBLK;						break;					case 'p':						sb->st_mode |= S_IFIFO;						break;					default:						fprintf(stderr, "Invalid special device type '%c' "							"for file %s\n", type, n->realname);						freenode(n);						continue;					}				}			}		}		setnode(n, sb->st_dev, sb->st_ino, sb->st_mode);		/* Skip unreadable files/dirs */		if (!S_ISLNK(n->modes) && access(n->realname, R_OK)) {			fprintf(stderr, "ignoring '%s' (access failed)\n", n->realname);			freenode(n); continue;		}		/* Look up old links */		if ( strcmp(n->name, ".") == 0 ) {			append(&dir->dirlist, n);			link = n->parent;		} else if (strcmp(n->name, "..") == 0) {			append(&dir->dirlist, n);			link = n->parent->parent;		} else {			link = findnode(root, n->ondev, n->onino);			append(&dir->dirlist, n);		}		if (link) {			n->orig_link = link;			curroffset = alignnode(n, curroffset, 0) + spaceneeded(n);			continue;		}		if (S_ISREG(sb->st_mode)) {			curroffset = alignnode(n, curroffset, spaceneeded(n));			n->size = sb->st_size;		} else			curroffset = alignnode(n, curroffset, 0);		if (S_ISLNK(sb->st_mode)) {			n->size = sb->st_size;		}		curroffset += spaceneeded(n);		if (S_ISCHR(sb->st_mode) || S_ISBLK(sb->st_mode)) {			n->devnode = sb->st_rdev;		}		if (S_ISDIR(sb->st_mode)) {			if (!strcmp(n->name, "..")) {				curroffset = processdir(level+1, dir->realname, dp->d_name,							sb, dir, root, curroffset);			} else {				curroffset = processdir(level+1, n->realname, dp->d_name,							sb, n, root, curroffset);			}		}	}	if (dirfd) closedir(dirfd);	return curroffset;}void showhelp(const char *argv0){	printf("genromfs \n");	printf("Usage: %s [OPTIONS] -f IMAGE\n",argv0);	printf("Create a romfs filesystem image from a directory\n");	printf("\n");	printf("  -f IMAGE               Output the image into this file\n");	printf("  -d DIRECTORY           Use this directory as source\n");	printf("  -v                     (Too) verbose operation\n");	printf("  -V VOLUME              Use the specified volume name\n");	printf("  -a ALIGN               Align regular file data to ALIGN bytes\n");	printf("  -A ALIGN,PATTERN       Align all objects matching pattern to at least ALIGN bytes\n");	printf("  -x PATTERN             Exclude all objects matching pattern\n");	printf("  -i                     Case insensitive mode. Strip nnn_ from filenames in the image\n");		printf("  -h                     Show this help\n");	printf("\n");	printf("Report bugs to chexum@shadow.banki.hu\n");}int main(int argc, char *argv[]){	int c;	char *dir = ".";	char *outf = NULL;	char *volname = NULL;	int verbose=0;	char buf[256];	struct filenode *root;	struct stat sb;	int lastoff;	int i;	char *p;	struct aligns *pa, *pa2;	struct excludes *pe, *pe2;	FILE *f;#ifdef WIN32	case_insensitive_mode = 1; // We hardcode this for the Windows platform.#endif	while ((c = getopt(argc, argv, "V:vd:f:ha:A:x:i")) != EOF) {		switch(c) {		case 'i':			case_insensitive_mode = 1;			break;		case 'd':			dir = optarg;			break;		case 'f':			outf = optarg;			break;		case 'V':			volname = optarg;			break;		case 'v':			verbose = 1;			break;		case 'h':			showhelp(argv[0]);			exit(0);		case 'a':			align = strtoul(optarg, NULL, 0);			if (align < 16 || (align & (align - 1))) {				fprintf(stderr, "Align has to be at least 16 bytes and a power of two\n");				exit(1);			}			break;		case 'A':			i = strtoul(optarg, &p, 0);			if (i < 16 || (i & (i - 1))) {				fprintf(stderr, "Align has to be at least 16 bytes and a power of two\n");				exit(1);			}			if (*p != ',' || !p[1]) {				fprintf(stderr, "-A takes N,PATTERN format of argument, where N is a number\n");				exit(1);			}			/* strlen(p+1) + 1 eq strlen(p) */			pa = (struct aligns *)malloc(sizeof(*pa) + strlen(p));			pa->align = i;			pa->next = NULL;			strcpy(pa->pattern, p + 1);			if (!alignlist)				alignlist = pa;			else {				for (pa2 = alignlist; pa2->next; pa2 = pa2->next)					;				pa2->next = pa;			}			break;		case 'x':			pe = (struct excludes *)malloc(sizeof(*pe) + strlen(optarg) + 1);			pe->next = NULL;			strcpy(pe->pattern, optarg);			if (!excludelist)				excludelist = pe;			else {				for (pe2 = excludelist; pe2->next; pe2 = pe2->next)					;				pe2->next = pe;			}			break;		default:			exit(1);		}	}	if (!volname) {		sprintf(buf, "rom %08lx", time(NULL));		volname = buf;	}	if (!outf) {		fprintf(stderr, "%s: you must specify the destination file\n", argv[0]);		fprintf(stderr, "Try `%s -h' for more information\n",argv[0]);		exit(1);	}	if (strcmp(outf, "-") == 0) {		f = fdopen(1,"wb");	} else		f = fopen(outf, "wb");	if (!f) {		perror(outf);		exit(1);	}		realbase = strlen(dir);	root = newnode(dir, volname, 0);	root->parent = root;	lastoff = processdir (1, dir, dir, &sb, root, root, spaceneeded(root));	if (verbose)		shownode(0, root, stderr);	dumpall(root, lastoff, f);	exit(0);}

⌨️ 快捷键说明

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