Beispiel #1
0
/*
 *	Convert endianess
 */
void do_endianconvert (void) 
{
	char			*p = data;
	union jffs2_node_union 	*node, newnode;
	int			fd, len;
	jint32_t		mode;
	uint32_t		crc;
	
	fd = open (cnvfile, O_WRONLY | O_CREAT, 0644);
	if (fd < 0) {
		fprintf (stderr, "Cannot open / create file: %s\n", cnvfile);
		return;
	}	

	while ( p < (data + imglen)) {
		node = (union jffs2_node_union*) p;

		/* Skip empty space */
		if (je16_to_cpu (node->u.magic) == 0xFFFF && je16_to_cpu (node->u.nodetype) == 0xFFFF) {
			write (fd, p, 4);
			p += 4;
			continue;
		}
		
		if (je16_to_cpu (node->u.magic) != JFFS2_MAGIC_BITMASK)	{
			printf ("Wrong bitmask  at  0x%08x, 0x%04x\n", p - data, je16_to_cpu (node->u.magic));
			newnode.u.magic = cnv_e16 (node->u.magic);			
			newnode.u.nodetype = cnv_e16 (node->u.nodetype);
			write (fd, &newnode, 4);
			p += 4;
			continue;
		}

		crc = crc32 (0, node, sizeof (struct jffs2_unknown_node) - 4);
		if (crc != je32_to_cpu (node->u.hdr_crc)) {
			printf ("Wrong hdr_crc  at  0x%08x, 0x%08x instead of 0x%08x\n", p - data, je32_to_cpu (node->u.hdr_crc), crc);
		}

		switch(je16_to_cpu(node->u.nodetype)) {

		case JFFS2_NODETYPE_INODE:

			newnode.i.magic = cnv_e16 (node->i.magic);			
			newnode.i.nodetype = cnv_e16 (node->i.nodetype);
			newnode.i.totlen = cnv_e32 (node->i.totlen);
			newnode.i.hdr_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_unknown_node) - 4));
			newnode.i.ino = cnv_e32 (node->i.ino);
			newnode.i.version = cnv_e32 (node->i.version);
			mode.v32 = node->i.mode.m;
			mode = cnv_e32 (mode);
			newnode.i.mode.m = mode.v32;
			newnode.i.uid = cnv_e16 (node->i.uid);
			newnode.i.gid = cnv_e16 (node->i.gid);
			newnode.i.isize = cnv_e32 (node->i.isize);
			newnode.i.atime = cnv_e32 (node->i.atime);
			newnode.i.mtime = cnv_e32 (node->i.mtime);
			newnode.i.ctime = cnv_e32 (node->i.ctime);
			newnode.i.offset = cnv_e32 (node->i.offset);
			newnode.i.csize = cnv_e32 (node->i.csize);
			newnode.i.dsize = cnv_e32 (node->i.dsize);
			newnode.i.compr = node->i.compr;
			newnode.i.usercompr = node->i.usercompr;
			newnode.i.flags = cnv_e16 (node->i.flags);
			if (recalccrc) {
				len = je32_to_cpu(node->i.csize);
				newnode.i.data_crc = cpu_to_e32 ( crc32(0, p + sizeof (struct jffs2_raw_inode), len));
			} else
				newnode.i.data_crc = cnv_e32 (node->i.data_crc);
			
			newnode.i.node_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_raw_inode) - 8));
			
			write (fd, &newnode, sizeof (struct jffs2_raw_inode));
			write (fd, p + sizeof (struct jffs2_raw_inode), PAD (je32_to_cpu (node->i.totlen) -  sizeof (struct jffs2_raw_inode)));

			p += PAD(je32_to_cpu (node->i.totlen));						
			break;
				
		case JFFS2_NODETYPE_DIRENT:
			newnode.d.magic = cnv_e16 (node->d.magic);
			newnode.d.nodetype = cnv_e16 (node->d.nodetype);
			newnode.d.totlen = cnv_e32 (node->d.totlen);
			newnode.d.hdr_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_unknown_node) - 4));
			newnode.d.pino = cnv_e32 (node->d.pino);
			newnode.d.version = cnv_e32 (node->d.version);
			newnode.d.ino = cnv_e32 (node->d.ino);
			newnode.d.mctime = cnv_e32 (node->d.mctime);
			newnode.d.nsize = node->d.nsize;
			newnode.d.type = node->d.type;
			newnode.d.unused[0] = node->d.unused[0];
			newnode.d.unused[1] = node->d.unused[1];
			newnode.d.node_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_raw_dirent) - 8));
			if (recalccrc)
				newnode.d.name_crc = cpu_to_e32 ( crc32(0, p + sizeof (struct jffs2_raw_dirent), node->d.nsize));
			else
				newnode.d.name_crc = cnv_e32 (node->d.name_crc);

			write (fd, &newnode, sizeof (struct jffs2_raw_dirent));
			write (fd, p + sizeof (struct jffs2_raw_dirent), PAD (je32_to_cpu (node->d.totlen) -  sizeof (struct jffs2_raw_dirent)));
			p += PAD(je32_to_cpu (node->d.totlen));						
			break;
	
		case JFFS2_NODETYPE_CLEANMARKER:
		case JFFS2_NODETYPE_PADDING:
			newnode.u.magic = cnv_e16 (node->u.magic);
			newnode.u.nodetype = cnv_e16 (node->u.nodetype);
			newnode.u.totlen = cnv_e32 (node->u.totlen);
			newnode.u.hdr_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_unknown_node) - 4));
			
			write (fd, &newnode, sizeof (struct jffs2_unknown_node));
			len = PAD(je32_to_cpu (node->u.totlen) - sizeof (struct jffs2_unknown_node));
			if (len > 0) 
				write (fd, p + sizeof (struct jffs2_unknown_node), len);
				
			p += PAD(je32_to_cpu (node->u.totlen));						
			break;

		case JFFS2_NODETYPE_SUMMARY : {
			struct jffs2_sum_marker *sm_ptr;
			int i,sum_len;
			int counter = 0;

			newnode.s.magic = cnv_e16 (node->s.magic);
			newnode.s.nodetype = cnv_e16 (node->s.nodetype);
			newnode.s.totlen = cnv_e32 (node->s.totlen);
			newnode.s.hdr_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_unknown_node) - 4));
			newnode.s.sum_num = cnv_e32 (node->s.sum_num);
			newnode.s.cln_mkr = cnv_e32 (node->s.cln_mkr);
			newnode.s.padded = cnv_e32 (node->s.padded);

			newnode.s.node_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_raw_summary) - 8));

			// summary header
			p += sizeof (struct jffs2_raw_summary);

			// summary data
			sum_len = je32_to_cpu (node->s.totlen) - sizeof (struct jffs2_raw_summary) - sizeof (struct jffs2_sum_marker);

			for (i=0; i<je32_to_cpu (node->s.sum_num); i++) {
				union jffs2_sum_flash *fl_ptr;

				fl_ptr = (union jffs2_sum_flash *) p;

				switch (je16_to_cpu (fl_ptr->u.nodetype)) {
					case JFFS2_NODETYPE_INODE:

						fl_ptr->i.nodetype = cnv_e16 (fl_ptr->i.nodetype);
						fl_ptr->i.inode = cnv_e32 (fl_ptr->i.inode);
						fl_ptr->i.version = cnv_e32 (fl_ptr->i.version);
						fl_ptr->i.offset = cnv_e32 (fl_ptr->i.offset);
						fl_ptr->i.totlen = cnv_e32 (fl_ptr->i.totlen);
						p += sizeof (struct jffs2_sum_inode_flash);
						counter += sizeof (struct jffs2_sum_inode_flash);
						break;

					case JFFS2_NODETYPE_DIRENT:
						fl_ptr->d.nodetype = cnv_e16 (fl_ptr->d.nodetype);
						fl_ptr->d.totlen = cnv_e32 (fl_ptr->d.totlen);
						fl_ptr->d.offset = cnv_e32 (fl_ptr->d.offset);
						fl_ptr->d.pino = cnv_e32 (fl_ptr->d.pino);
						fl_ptr->d.version = cnv_e32 (fl_ptr->d.version);
						fl_ptr->d.ino = cnv_e32 (fl_ptr->d.ino);
						p += sizeof (struct jffs2_sum_dirent_flash) + fl_ptr->d.nsize;
						counter += sizeof (struct jffs2_sum_dirent_flash) + fl_ptr->d.nsize;
						break;

					default :
						printf("Unknown node in summary information!!! nodetype(%x)\n", je16_to_cpu (fl_ptr->u.nodetype));
						exit(EXIT_FAILURE);
						break;
				}

			}

			//pad
			p += sum_len - counter;

			// summary marker
			sm_ptr = (struct jffs2_sum_marker *) p;
			sm_ptr->offset = cnv_e32 (sm_ptr->offset);
			sm_ptr->magic = cnv_e32 (sm_ptr->magic);
			p += sizeof (struct jffs2_sum_marker);

			// generate new crc on sum data
			newnode.s.sum_crc = cpu_to_e32 ( crc32(0, ((char *) node) + sizeof (struct jffs2_raw_summary), 
				je32_to_cpu (node->s.totlen) - sizeof (struct jffs2_raw_summary)));

			// write out new node header
			write(fd, &newnode, sizeof (struct jffs2_raw_summary));
			// write out new summary data
			write(fd, &node->s.sum, sum_len + sizeof (struct jffs2_sum_marker));

			break;
		}

		case 0xffff:
			write (fd, p, 4);
			p += 4;
			break;
			
		default:	
			printf ("Unknown node type: 0x%04x at 0x%08x, totlen 0x%08x\n", je16_to_cpu (node->u.nodetype), p - data, je32_to_cpu (node->u.totlen));
			p += PAD(je32_to_cpu (node->u.totlen));
				
		}
	}

	close (fd);

}
/*
 *	Convert endianess
 */
void do_endianconvert (void) 
{
	char			*p = data;
	union jffs2_node_union 	*node, newnode;
	int			fd, len;
	jint32_t		mode;
	uint32_t		crc;
	
	fd = open (cnvfile, O_WRONLY | O_CREAT, 0644);
	if (fd < 0) {
		fprintf (stderr, "Cannot open / create file: %s\n", cnvfile);
		return;
	}	

	while ( p < (data + imglen)) {
		node = (union jffs2_node_union*) p;

		/* Skip empty space */
		if (de16_to_cpu (node->u.magic) == 0xFFFF && de16_to_cpu (node->u.nodetype) == 0xFFFF) {
			write (fd, p, 4);
			p += 4;
			continue;
		}
		
		if (de16_to_cpu (node->u.magic) != JFFS2_MAGIC_BITMASK)	{
			printf ("Wrong bitmask  at  0x%08x, 0x%04x\n", p - data, de16_to_cpu (node->u.magic));
			newnode.u.magic = cnv_e16 (node->u.magic);			
			newnode.u.nodetype = cnv_e16 (node->u.nodetype);
			write (fd, &newnode, 4);
			p += 4;
			continue;
		}

		crc = crc32 (0, node, sizeof (struct jffs2_unknown_node) - 4);
		if (crc != de32_to_cpu (node->u.hdr_crc)) {
			printf ("Wrong hdr_crc  at  0x%08x, 0x%08x instead of 0x%08x\n", p - data, de32_to_cpu (node->u.hdr_crc), crc);
		}

		switch(de16_to_cpu(node->u.nodetype)) {

		case JFFS2_NODETYPE_INODE:

			newnode.i.magic = cnv_e16 (node->i.magic);			
			newnode.i.nodetype = cnv_e16 (node->i.nodetype);
			newnode.i.totlen = cnv_e32 (node->i.totlen);
			newnode.i.hdr_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_unknown_node) - 4));
			newnode.i.ino = cnv_e32 (node->i.ino);
			newnode.i.version = cnv_e32 (node->i.version);
			mode.v32 = node->i.mode.m;
			mode = cnv_e32 (mode);
			newnode.i.mode.m = mode.v32;
			newnode.i.uid = cnv_e16 (node->i.uid);
			newnode.i.gid = cnv_e16 (node->i.gid);
			newnode.i.isize = cnv_e32 (node->i.isize);
			newnode.i.atime = cnv_e32 (node->i.atime);
			newnode.i.mtime = cnv_e32 (node->i.mtime);
			newnode.i.ctime = cnv_e32 (node->i.ctime);
			newnode.i.offset = cnv_e32 (node->i.offset);
			newnode.i.csize = cnv_e32 (node->i.csize);
			newnode.i.dsize = cnv_e32 (node->i.dsize);
			newnode.i.compr = node->i.compr;
			newnode.i.usercompr = node->i.usercompr;
			newnode.i.flags = cnv_e16 (node->i.flags);
			if (recalccrc) {
				len = de32_to_cpu(node->i.csize);
				newnode.i.data_crc = cpu_to_e32 ( crc32(0, p + sizeof (struct jffs2_raw_inode), len));
			} else
				newnode.i.data_crc = cnv_e32 (node->i.data_crc);
			
			newnode.i.node_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_raw_inode) - 8));
			
			write (fd, &newnode, sizeof (struct jffs2_raw_inode));
			write (fd, p + sizeof (struct jffs2_raw_inode), PAD (de32_to_cpu (node->i.totlen) -  sizeof (struct jffs2_raw_inode)));

			p += PAD(de32_to_cpu (node->i.totlen));						
			break;
				
		case JFFS2_NODETYPE_DIRENT:
			newnode.d.magic = cnv_e16 (node->d.magic);
			newnode.d.nodetype = cnv_e16 (node->d.nodetype);
			newnode.d.totlen = cnv_e32 (node->d.totlen);
			newnode.d.hdr_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_unknown_node) - 4));
			newnode.d.pino = cnv_e32 (node->d.pino);
			newnode.d.version = cnv_e32 (node->d.version);
			newnode.d.ino = cnv_e32 (node->d.ino);
			newnode.d.mctime = cnv_e32 (node->d.mctime);
			newnode.d.nsize = node->d.nsize;
			newnode.d.type = node->d.type;
			newnode.d.unused[0] = node->d.unused[0];
			newnode.d.unused[1] = node->d.unused[1];
			newnode.d.node_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_raw_dirent) - 8));
			if (recalccrc)
				newnode.d.name_crc = cpu_to_e32 ( crc32(0, p + sizeof (struct jffs2_raw_dirent), node->d.nsize));
			else
				newnode.d.name_crc = cnv_e32 (node->d.name_crc);

			write (fd, &newnode, sizeof (struct jffs2_raw_dirent));
			write (fd, p + sizeof (struct jffs2_raw_dirent), PAD (de32_to_cpu (node->d.totlen) -  sizeof (struct jffs2_raw_dirent)));
			p += PAD(de32_to_cpu (node->d.totlen));						
			break;
	
		case JFFS2_NODETYPE_CLEANMARKER:
		case JFFS2_NODETYPE_PADDING:
			newnode.u.magic = cnv_e16 (node->u.magic);
			newnode.u.nodetype = cnv_e16 (node->u.nodetype);
			newnode.u.totlen = cnv_e32 (node->u.totlen);
			newnode.u.hdr_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_unknown_node) - 4));
			
			write (fd, &newnode, sizeof (struct jffs2_unknown_node));
			len = PAD(de32_to_cpu (node->u.totlen) - sizeof (struct jffs2_unknown_node));
			if (len > 0) 
				write (fd, p + sizeof (struct jffs2_unknown_node), len);
				
			p += PAD(de32_to_cpu (node->u.totlen));						
			break;
	
		case 0xffff:
			write (fd, p, 4);
			p += 4;
			break;
			
		default:	
			printf ("Unknown node type: 0x%04x at 0x%08x, totlen 0x%08x\n", de16_to_cpu (node->u.nodetype), p - data, de32_to_cpu (node->u.totlen));
			p += PAD(de32_to_cpu (node->u.totlen));
				
		}
	}

	close (fd);

}