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

📄 cramfs.patch

📁 sm86xx rootfs来源包括补丁( GPL )的
💻 PATCH
📖 第 1 页 / 共 3 页
字号:
+	unsigned long mode, unsigned long rdev, struct entry *root, loff_t *fslen_ub)+{+	char *name, *path, *full;+	struct entry *curr, *parent, *entry, *prev;+	+	full = xstrdup(full_path);+	path = xstrdup(dirname(full));+	name = full_path + strlen(path) + 1;+	free(full);+	if (strcmp(path, "/") == 0) {+		parent = root;+		name = full_path + 1;+	} else {+		if (!(parent = find_filesystem_entry(root, path+1, S_IFDIR)))+			error_msg_and_die("%s/%s: could not find parent\n", path, name);+	}+	if ((entry = find_filesystem_entry(parent, name, (mode & S_IFMT)))) {+		/* its there, just modify permissions */+		entry->mode = mode;+		entry->uid = uid;+		entry->gid = gid;+	} else { /* make a new entry */+	+		/* code partially replicated from parse_directory() */+		size_t namelen;+		if (S_ISREG(mode)) {+			error_msg_and_die("%s: regular file from device_table file must exist on disk!", full_path);+		}++		namelen = strlen(name);+		if (namelen > MAX_INPUT_NAMELEN) {+			error_msg_and_die(+				"Very long (%u bytes) filename `%s' found.\n"+				" Please increase MAX_INPUT_NAMELEN in mkcramfs.c and recompile.  Exiting.\n",+				namelen, name);+		}+		entry = xcalloc(1, sizeof(struct entry));+		entry->name = xstrdup(name);+		/* truncate multi-byte UTF-8 filenames on character boundary */+		if (namelen > CRAMFS_MAXPATHLEN) {+			namelen = CRAMFS_MAXPATHLEN;+			warn_namelen = 1;+			/* the first lost byte must not be a trail byte */+			while ((entry->name[namelen] & 0xc0) == 0x80) {+				namelen--;+				/* are we reasonably certain it was UTF-8 ? */+				if (entry->name[namelen] < 0x80 || !namelen) {+					error_msg_and_die("cannot truncate filenames not encoded in UTF-8");+				}+			}+			entry->name[namelen] = '\0';+		}+		entry->mode = mode;+		entry->uid = uid;+		entry->gid = gid;+		entry->size = 0;+		if (S_ISBLK(mode) || S_ISCHR(mode)) {+			entry->size = rdev;+			if (entry->size & -(1<<CRAMFS_SIZE_WIDTH))+				warn_dev = 1;+		}+		+		/* ok, now we have to backup and correct the size of all the entries above us */+		*fslen_ub += sizeof(struct cramfs_inode) + ((namelen + 3) & ~3);+		parent->size += sizeof(struct cramfs_inode) + ((namelen + 3) & ~3);++		/* alright, time to link us in */+		curr = parent->child;+		prev = NULL;+		while (curr && strcmp(name, curr->name) > 0) {+			prev = curr;+			curr = curr->next;+		}+		if (!prev) parent->child = entry;+		else prev->next = entry;+		entry->next = curr;+		entry->child = NULL;+	}+	if (entry->uid >= 1 << CRAMFS_UID_WIDTH)+		warn_uid = 1;+	if (entry->gid >= 1 << CRAMFS_GID_WIDTH) {+		/* TODO: We ought to replace with a default+		   gid instead of truncating; otherwise there+		   are security problems.  Maybe mode should+		   be &= ~070.  Same goes for uid once Linux+		   supports >16-bit uids. */+		warn_gid = 1;+	}+	free(path);+}++/* the GNU C library has a wonderful scanf("%as", string) which will+ allocate the string with the right size, good to avoid buffer overruns. + the following macros use it if available or use a hacky workaround...+ */++#ifdef __GNUC__+#define SCANF_PREFIX "a"+#define SCANF_STRING(s) (&s)+#define GETCWD_SIZE 0+#else+#define SCANF_PREFIX "511"+#define SCANF_STRING(s) (s = xmalloc(512))+#define GETCWD_SIZE -1+inline int snprintf(char *str, size_t n, const char *fmt, ...)+{+	int ret;+	va_list ap;++	va_start(ap, fmt);+	ret = vsprintf(str, fmt, ap);+	va_end(ap);+	return ret;+}+#endif++/*  device table entries take the form of:+    <path>	<type> <mode>	<uid>	<gid>	<major>	<minor>	<start>	<inc>	<count>+    /dev/mem     c    640       0       0         1       1       0     0         -++    type can be one of: +	f	A regular file+	d	Directory+	c	Character special device file+	b	Block special device file+	p	Fifo (named pipe)++    I don't bother with symlinks (permissions are irrelevant), hard+    links (special cases of regular files), or sockets (why bother).++    Regular files must exist in the target root directory.  If a char,+    block, fifo, or directory does not exist, it will be created.+*/++static int interpret_table_entry(char *line, struct entry *root, loff_t *fslen_ub)+{+	char type, *name = NULL;+	unsigned long mode = 0755, uid = 0, gid = 0, major = 0, minor = 0;+	unsigned long start = 0, increment = 1, count = 0;++	if (sscanf (line, "%" SCANF_PREFIX "s %c %lo %lu %lu %lu %lu %lu %lu %lu",+		 SCANF_STRING(name), &type, &mode, &uid, &gid, &major, &minor,+		 &start, &increment, &count) < 0) +	{+		return 1;+	}++	if (!strcmp(name, "/")) {+		error_msg_and_die("Device table entries require absolute paths");+	}++	switch (type) {+	case 'd':+		mode |= S_IFDIR;+		modify_entry(name, uid, gid, mode, 0, root, fslen_ub);+		break;+	case 'f':+		mode |= S_IFREG;+		modify_entry(name, uid, gid, mode, 0, root, fslen_ub);+		break;+	case 'p':+		mode |= S_IFIFO;+		modify_entry(name, uid, gid, mode, 0, root, fslen_ub);+		break;+	case 'c':+	case 'b':+		mode |= (type == 'c') ? S_IFCHR : S_IFBLK;+		if (count > 0) {+			char *buf;+			unsigned long i;+			dev_t rdev;++			for (i = start; i < count; i++) {+				asprintf(&buf, "%s%lu", name, i);+				rdev = makedev(major, minor + (i * increment - start));+				modify_entry(buf, uid, gid, mode, rdev, root, fslen_ub);+				free(buf);+			}+		} else {+			dev_t rdev = makedev(major, minor);+			modify_entry(name, uid, gid, mode, rdev, root, fslen_ub);+		}+		break;+	default:+		error_msg_and_die("Unsupported file type");+	}+	free(name);+	return 0;+}++static int parse_device_table(FILE *file, struct entry *root, loff_t *fslen_ub)+{+	char *line;+	int status = 0;+	size_t length = 0;++	/* Turn off squash, since we must ensure that values+	 * entered via the device table are not squashed */+	opt_squash = 0;++	/* Looks ok so far.  The general plan now is to read in one+	 * line at a time, check for leading comment delimiters ('#'),+	 * then try and parse the line as a device table.  If we fail+	 * to parse things, try and help the poor fool to fix their+	 * device table with a useful error msg... */+	line = NULL;+	while (getline(&line, &length, file) != -1) {+		/* First trim off any whitespace */+		int len = strlen(line);++		/* trim trailing whitespace */+		while (len > 0 && isspace(line[len - 1]))+			line[--len] = '\0';+		/* trim leading whitespace */+		memmove(line, &line[strspn(line, " \n\r\t\v")], len);++		/* How long are we after trimming? */+		len = strlen(line);++		/* If this is NOT a comment line, try to interpret it */+		if (len && *line != '#') {+			if (interpret_table_entry(line, root, fslen_ub))+				status = 1;+		}++		free(line);+		line = NULL;+	}+	free(line);+	fclose(file);++	return status;+}++void traverse(struct entry *entry, int depth)+{+	struct entry *curr = entry;+	int i;++	while (curr) {+		for (i = 0; i < depth; i++) putchar(' ');+		printf("%s: size=%d mode=%d same=%p\n",+			(curr->name)? (char*)curr->name : "/", +			curr->size, curr->mode, curr->same);+		if (curr->child) traverse(curr->child, depth + 4);+		curr = curr->next;+	}+}++static void free_filesystem_entry(struct entry *dir)+{+	struct entry *e = dir, *last;++	if (S_ISDIR(dir->mode)) {+		e = dir->child;+	}+	while (e) {+		if (e->name)+			free(e->name);+		if (e->path)+			free(e->path);+		if (e->uncompressed)+			free(e->uncompressed);+		last = e;+		if (e->child) {+			free_filesystem_entry(e);+		}+		e = e->next;+		free(last);+	}+}+++/*+ * Usage:+ *+ *      mkcramfs directory-name outfile+ *+ * where "directory-name" is simply the root of the directory+ * tree that we want to generate a compressed filesystem out+ * of.+ */ int main(int argc, char **argv) { 	struct stat st;		/* used twice... */@@ -692,6 +1138,7 @@ 	u32 crc; 	int c;			/* for getopt */ 	char *ep;		/* for strtoul */+	FILE *devtable = NULL;  	total_blocks = 0; @@ -699,7 +1146,7 @@ 		progname = argv[0];  	/* command line options */-	while ((c = getopt(argc, argv, "hEe:i:n:psvz")) != EOF) {+	while ((c = getopt(argc, argv, "hEe:i:n:psvzD:q")) != EOF) { 		switch (c) { 		case 'h': 			usage(MKFS_OK);@@ -715,7 +1162,7 @@ 		case 'i': 			opt_image = optarg; 			if (lstat(opt_image, &st) < 0) {-				die(MKFS_ERROR, 1, "lstat failed: %s", opt_image);+				error_msg_and_die("lstat failed: %s", opt_image); 			} 			image_length = st.st_size; /* may be padded later */ 			fslen_ub += (image_length + 3); /* 3 is for padding */@@ -736,6 +1183,16 @@ 		case 'z': 			opt_holes = 1; 			break;+		case 'q':+			opt_squash = 1;+			break;+		case 'D':+			devtable = xfopen(optarg, "r");+			if (fstat(fileno(devtable), &st) < 0)+				perror_msg_and_die(optarg);+			if (st.st_size < 10)+				error_msg_and_die("%s: not a proper device table file\n", optarg);+			break; 		} 	} @@ -745,25 +1202,23 @@ 	outfile = argv[optind + 1];  	if (stat(dirname, &st) < 0) {-		die(MKFS_USAGE, 1, "stat failed: %s", dirname);-	}-	fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0666);-	if (fd < 0) {-		die(MKFS_USAGE, 1, "open failed: %s", outfile);+		error_msg_and_die("stat failed: %s", dirname); 	}+	fd = xopen(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0666); -	root_entry = calloc(1, sizeof(struct entry));-	if (!root_entry) {-		die(MKFS_ERROR, 1, "calloc failed");-	}+	root_entry = xcalloc(1, sizeof(struct entry)); 	root_entry->mode = st.st_mode; 	root_entry->uid = st.st_uid; 	root_entry->gid = st.st_gid;  	root_entry->size = parse_directory(root_entry, dirname, &root_entry->child, &fslen_ub); +	if (devtable) {+		parse_device_table(devtable, root_entry, &fslen_ub);+	}+ 	/* always allocate a multiple of blksize bytes because that's-	   what we're going to write later on */+           what we're going to write later on */ 	fslen_ub = ((fslen_ub - 1) | (blksize - 1)) + 1;  	if (fslen_ub > MAXFSLEN) {@@ -790,7 +1245,7 @@ 	rom_image = mmap(NULL, fslen_ub?fslen_ub:1, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);  	if (rom_image == MAP_FAILED) {-		die(MKFS_ERROR, 1, "mmap failed");+		error_msg_and_die("mmap failed"); 	}  	/* Skip the first opt_pad bytes for boot loader code */@@ -807,6 +1262,7 @@ 	}  	offset = write_directory_structure(root_entry->child, rom_image, offset);+	if (opt_verbose) 	printf("Directory data: %d bytes\n", offset);  	offset = write_data(root_entry, rom_image, offset);@@ -814,30 +1270,38 @@ 	/* We always write a multiple of blksize bytes, so that 	   losetup works. */ 	offset = ((offset - 1) | (blksize - 1)) + 1;+	if (opt_verbose) 	printf("Everything: %d kilobytes\n", offset >> 10);  	/* Write the superblock now that we can fill in all of the fields. */ 	write_superblock(root_entry, rom_image+opt_pad, offset);+	if (opt_verbose) 	printf("Super block: %d bytes\n", sizeof(struct cramfs_super));  	/* Put the checksum in. */ 	crc = crc32(0L, Z_NULL, 0); 	crc = crc32(crc, (rom_image+opt_pad), (offset-opt_pad)); 	((struct cramfs_super *) (rom_image+opt_pad))->fsid.crc = crc;+	if (opt_verbose) 	printf("CRC: %x\n", crc);  	/* Check to make sure we allocated enough space. */ 	if (fslen_ub < offset) {-		die(MKFS_ERROR, 0, "not enough space allocated for ROM image (%Ld allocated, %d used)", fslen_ub, offset);+		error_msg_and_die("not enough space allocated for ROM "+			"image (%Ld allocated, %d used)", fslen_ub, offset); 	}  	written = write(fd, rom_image, offset); 	if (written < 0) {-		die(MKFS_ERROR, 1, "write failed");+		error_msg_and_die("write failed"); 	} 	if (offset != written) {-		die(MKFS_ERROR, 0, "ROM image write failed (wrote %d of %d bytes)", written, offset);+		error_msg_and_die("ROM image write failed (wrote %d of %d bytes)", written, offset); 	}+	+	/* Free up memory */+	free_filesystem_entry(root_entry);+	free(root_entry);  	/* (These warnings used to come at the start, but they scroll off the 	   screen too quickly.) */

⌨️ 快捷键说明

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