static void _eject(struct stat *s, char *out, int olen, char *data, unsigned datasize)
{
    // Nothing is special about this value, just picked something in the
    // approximate range that was being used already, and avoiding small
    // values which may be special.
    static unsigned next_inode = 300000;

    while(total_size & 3) {
        total_size++;
        putchar(0);
    }

    fix_stat(out, s);
//    fprintf(stderr, "_eject %s: mode=0%o\n", out, s->st_mode);

    printf("%06x%08x%08x%08x%08x%08x%08x"
           "%08x%08x%08x%08x%08x%08x%08x%s%c",
           0x070701,
           next_inode++,  //  s.st_ino,
           s->st_mode,
           0, // s.st_uid,
           0, // s.st_gid,
           1, // s.st_nlink,
           0, // s.st_mtime,
           datasize,
           0, // volmajor
           0, // volminor
           0, // devmajor
           0, // devminor,
           olen + 1,
           0,
           out,
           0
           );

    total_size += 6 + 8*13 + olen + 1;

    if(strlen(out) != (unsigned int)olen) die("ACK!");

    while(total_size & 3) {
        total_size++;
        putchar(0);
    }

    if(datasize) {
        fwrite(data, datasize, 1, stdout);
        total_size += datasize;
    }
}
Example #2
0
int mkyaffs2image(char* target_directory, char* filename, int fixstats, mkyaffs2image_callback callback, int gzip)
{
	struct stat stats;
	memset(obj_list, 0, sizeof(objItem) * MAX_OBJECTS);
	n_obj = 0;
	obj_id = YAFFS_NOBJECT_BUCKETS + 1;

	if (stat(target_directory,&stats) < 0)
		return -1;
	
	outFile = -1;
	outgzFile = Z_NULL;

	outFile = open(filename, O_CREAT | O_TRUNC | O_WRONLY, S_IREAD | S_IWRITE);
	
	if(outFile < 0) {
		fprintf(stderr,"Could not open output file %s\n",filename);
		return -1;
	}

	if(gzip) outgzFile = gzdopen(outFile, "wb");

	if (fixstats) {
		int len = strlen(target_directory);

		if((len >= 4) && (!strcmp(target_directory + len - 4, "data"))) {
			source_path_len = len - 4;
		} else if((len >= 6) && (!strcmp(target_directory + len - 6, "system"))) {
			source_path_len = len - 6;
		} else {            
			fprintf(stderr,"Fixstats (-f) option requested but filesystem is not data or android!\n");
			return -1;
		}
		fix_stat(target_directory, &stats);
	}

	//printf("Processing directory %s into image file %s\n",argv[1],argv[2]);
	error =  write_object_header(1, YAFFS_OBJECT_TYPE_DIRECTORY, &stats, 1,"", -1, NULL);
	if(error)
		error = process_directory(YAFFS_OBJECTID_ROOT,target_directory,fixstats,callback);
	
	if(outgzFile == Z_NULL) close(outFile);
	else gzclose(outgzFile);
	
	return error < 0 ? error : 0;
}
int main(int argc, char *argv[])
{
	int fixstats = 0;
	struct stat stats;
	int opt;
	char *image;
	char *dir;
	char *secontext = NULL;

	while ((opt = getopt(argc, argv, "fc:s:")) != -1) {
		switch (opt) {
		case 'f':
			fixstats = 1;
			break;
		case 'c':
			chunkSize = (unsigned)strtoul(optarg, NULL, 0);
			break;
		case 's':
			spareSize = (unsigned)strtoul(optarg, NULL, 0);
			break;
		default:
			usage();
			exit(1);
		}
	}

	if (!chunkSize || !spareSize) {
		usage();
		exit(1);
	}

	if ((argc - optind < 2) || (argc - optind > 4)) {
		usage();
		exit(1);
	}

	dir = argv[optind];
	seprefixlen = strlen(dir);
	image = argv[optind + 1];

	if (optind + 2 < argc) {
		if (!strncmp(argv[optind + 2], "convert", strlen("convert")))
			convert_endian = 1;
		else {
			struct selinux_opt seopts[] = {
				{ SELABEL_OPT_PATH, argv[optind + 2] }
			};
			sehnd = selabel_open(SELABEL_CTX_FILE, seopts, 1);
			if (!sehnd) {
				perror(argv[optind + 2]);
				usage();
				exit(1);
			}
			if (optind + 3 >= argc) {
				usage();
				exit(1);
			}
			mntpoint = argv[optind + 3];
			if (optind + 4 < argc) {
				if (!strncmp(argv[optind + 4], "convert", strlen("convert")))
					convert_endian = 1;
			}
		}
	}

	if(stat(dir,&stats) < 0)
	{
		fprintf(stderr,"Could not stat %s\n",dir);
		exit(1);
	}
	
	if(!S_ISDIR(stats.st_mode))
	{
		fprintf(stderr," %s is not a directory\n",dir);
		exit(1);
	}
	
	outFile = open(image,O_CREAT | O_TRUNC | O_WRONLY, S_IREAD | S_IWRITE);
	
	
	if(outFile < 0)
	{
		fprintf(stderr,"Could not open output file %s\n",image);
		exit(1);
	}

    if (fixstats) {
        int len = strlen(dir);
        
        if((len >= 4) && (!strcmp(dir + len - 4, "data"))) {
            source_path_len = len - 4;
        } else if((len >= 6) && (!strcmp(dir + len - 6, "system"))) {
            source_path_len = len - 6;
        } else {            
            fprintf(stderr,"Fixstats (-f) option requested but filesystem is not data or android!\n");
            exit(1);
        }
        fix_stat(dir, &stats);
    }
    
	//printf("Processing directory %s into image file %s\n",dir,image);
    if (sehnd) {

        char *sepath = NULL;
        if (mntpoint[0] == '/')
	    sepath = strdup(mntpoint);
        else if (asprintf(&sepath, "/%s", mntpoint) < 0)
            sepath = NULL;

        if (!sepath) {
	    perror("malloc");
	    exit(1);
	}

	if (selabel_lookup(sehnd, &secontext, sepath, stats.st_mode) < 0) {
	    perror("selabel_lookup");
	    free(sepath);
	    exit(1);
	}

	free(sepath);
    }

    error =  write_object_header(1, YAFFS_OBJECT_TYPE_DIRECTORY, &stats, 1,"", -1, NULL, secontext);
	if(error)
	error = process_directory(YAFFS_OBJECTID_ROOT,dir,fixstats);
	
	close(outFile);
	
	if(error < 0)
	{
		perror("operation incomplete");
		exit(1);
	}
	else
	{
        /*
		printf("Operation complete.\n"
		       "%d objects in %d directories\n"
		       "%d NAND pages\n",nObjects, nDirectories, nPages);
        */
	}
	
	close(outFile);
	
	exit(0);
}	
static int process_directory(int parent, const char *path, int fixstats)
{

	DIR *dir;
	struct dirent *entry;
	char *secontext = NULL;

	nDirectories++;
	
	dir = opendir(path);
	
	if(dir)
	{
		while((entry = readdir(dir)) != NULL)
		{
		
			/* Ignore . and .. */
			if(strcmp(entry->d_name,".") &&
			   strcmp(entry->d_name,".."))
 			{
 				char full_name[500];
				char *suffix, dest_name[500];
				int ret;
				struct stat stats;
				int equivalentObj;
				int newObj;
				
				sprintf(full_name,"%s/%s",path,entry->d_name);
				
				lstat(full_name,&stats);

				if (sehnd) {
					suffix = full_name + seprefixlen;
					ret = snprintf(dest_name,
						       sizeof dest_name,
						       "%s%s", mntpoint,
						       suffix);
					if (ret < 0 ||
					    (size_t) ret >= sizeof dest_name) {
						fprintf(stderr,
							"snprintf failed on %s%s\n",
							mntpoint, suffix);
						exit(1);
					}

					char *sepath = NULL;
					if (dest_name[0] == '/')
					        sepath = strdup(dest_name);
					else if (asprintf(&sepath, "/%s", dest_name) < 0)
                                                sepath = NULL;

					if (!sepath) {
					        perror("malloc");
					        exit(1);
					}

					if (selabel_lookup(sehnd, &secontext,
							   sepath,
							   stats.st_mode) < 0) {
					        perror("selabel_lookup");
					        free(sepath);
					        exit(1);
					}
					free(sepath);
				}

				if(S_ISLNK(stats.st_mode) ||
				    S_ISREG(stats.st_mode) ||
				    S_ISDIR(stats.st_mode) ||
				    S_ISFIFO(stats.st_mode) ||
				    S_ISBLK(stats.st_mode) ||
				    S_ISCHR(stats.st_mode) ||
				    S_ISSOCK(stats.st_mode))
				{
				
					newObj = obj_id++;
					nObjects++;

                    if (fixstats) {
                        fix_stat(full_name, &stats);
                    }

					//printf("Object %d, %s is a ",newObj,full_name);
					
					/* We're going to create an object for it */
					if((equivalentObj = find_obj_in_list(stats.st_dev, stats.st_ino)) > 0)
					{
					 	/* we need to make a hard link */
					 	//printf("hard link to object %d\n",equivalentObj);
						error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_HARDLINK, &stats, parent, entry->d_name, equivalentObj, NULL, secontext);
					}
					else 
					{
						
						add_obj_to_list(stats.st_dev,stats.st_ino,newObj);
						
						if(S_ISLNK(stats.st_mode))
						{
					
							char symname[500];
						
							memset(symname,0, sizeof(symname));
					
							readlink(full_name,symname,sizeof(symname) -1);
						
							//printf("symlink to \"%s\"\n",symname);
							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SYMLINK, &stats, parent, entry->d_name, -1, symname, secontext);

						}
						else if(S_ISREG(stats.st_mode))
						{
							//printf("file, ");
							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_FILE, &stats, parent, entry->d_name, -1, NULL, secontext);

							if(error >= 0)
							{
								int h;
								__u8 bytes[chunkSize];
								int nBytes;
								int chunk = 0;
								
								h = open(full_name,O_RDONLY);
								if(h >= 0)
								{
									memset(bytes,0xff,sizeof(bytes));
									while((nBytes = read(h,bytes,sizeof(bytes))) > 0)
									{
										chunk++;
										write_chunk(bytes,newObj,chunk,nBytes);
										memset(bytes,0xff,sizeof(bytes));
									}
									if(nBytes < 0) 
									   error = nBytes;
									   
									//printf("%d data chunks written\n",chunk);
								}
								else
								{
									perror("Error opening file");
								}
								close(h);
								
							}							
														
						}
						else if(S_ISSOCK(stats.st_mode))
						{
							//printf("socket\n");
							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL, secontext);
						}
						else if(S_ISFIFO(stats.st_mode))
						{
							//printf("fifo\n");
							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL, secontext);
						}
						else if(S_ISCHR(stats.st_mode))
						{
							//printf("character device\n");
							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL, secontext);
						}
						else if(S_ISBLK(stats.st_mode))
						{
							//printf("block device\n");
							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL, secontext);
						}
						else if(S_ISDIR(stats.st_mode))
						{
							//printf("directory\n");
							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_DIRECTORY, &stats, parent, entry->d_name, -1, NULL, secontext);
// NCB modified 10/9/2001				process_directory(1,full_name);
							process_directory(newObj,full_name,fixstats);
						}
					}
				}
				else
				{
					//printf(" we don't handle this type\n");
				}
			}
		}
		closedir(dir);
	}
	
	return 0;

}
Example #5
0
static int process_directory(int parent, const char *path, int fixstats, mkyaffs2image_callback callback)
{

	DIR *dir;
	struct dirent *entry;

	//nDirectories++;
	
	dir = opendir(path);
	
	if(dir)
	{
		while((entry = readdir(dir)) != NULL)
		{
		
			/* Ignore . and .. */
			if(strcmp(entry->d_name,".") &&
			   strcmp(entry->d_name,".."))
 			{
 				char full_name[PATH_MAX];
				struct stat stats;
				int equivalentObj;
				int newObj;
				
				sprintf(full_name,"%s/%s",path,entry->d_name);
				
				lstat(full_name,&stats);
				
				if(S_ISLNK(stats.st_mode) ||
				    S_ISREG(stats.st_mode) ||
				    S_ISDIR(stats.st_mode) ||
				    S_ISFIFO(stats.st_mode) ||
				    S_ISBLK(stats.st_mode) ||
				    S_ISCHR(stats.st_mode) ||
				    S_ISSOCK(stats.st_mode))
				{
				
					newObj = obj_id++;
					if (callback != NULL)
                        callback(full_name);
					//nObjects++;

                    if (fixstats) {
                        fix_stat(full_name, &stats);
                    }

					//printf("Object %d, %s is a ",newObj,full_name);
					
					/* We're going to create an object for it */
					if((equivalentObj = find_obj_in_list(stats.st_dev, stats.st_ino)) > 0)
					{
					 	/* we need to make a hard link */
					 	//printf("hard link to object %d\n",equivalentObj);
						error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_HARDLINK, &stats, parent, entry->d_name, equivalentObj, NULL);
					}
					else 
					{
						
						add_obj_to_list(stats.st_dev,stats.st_ino,newObj);
						
						if(S_ISLNK(stats.st_mode))
						{
					
							char symname[PATH_MAX];
						
							memset(symname,0, sizeof(symname));
					
							readlink(full_name,symname,sizeof(symname) -1);
						
							//printf("symlink to \"%s\"\n",symname);
							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SYMLINK, &stats, parent, entry->d_name, -1, symname);

						}
						else if(S_ISREG(stats.st_mode))
						{
							//printf("file, ");
							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_FILE, &stats, parent, entry->d_name, -1, NULL);

							if(error >= 0)
							{
								int h;
								__u8 bytes[chunkSize];
								int nBytes;
								int chunk = 0;
								
								h = open(full_name,O_RDONLY);
								if(h >= 0)
								{
									memset(bytes,0xff,sizeof(bytes));
									while((nBytes = read(h,bytes,sizeof(bytes))) > 0)
									{
										chunk++;
										write_chunk(bytes,newObj,chunk,nBytes);
										memset(bytes,0xff,sizeof(bytes));
									}
									if(nBytes < 0) 
									   error = nBytes;
									   
									//printf("%d data chunks written\n",chunk);
								}
								else
								{
									perror("Error opening file");
								}
								close(h);
								
							}							
														
						}
						else if(S_ISSOCK(stats.st_mode))
						{
							//printf("socket\n");
							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL);
						}
						else if(S_ISFIFO(stats.st_mode))
						{
							//printf("fifo\n");
							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL);
						}
						else if(S_ISCHR(stats.st_mode))
						{
							//printf("character device\n");
							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL);
						}
						else if(S_ISBLK(stats.st_mode))
						{
							//printf("block device\n");
							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL);
						}
						else if(S_ISDIR(stats.st_mode))
						{
							//printf("directory\n");
							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_DIRECTORY, &stats, parent, entry->d_name, -1, NULL);
// NCB modified 10/9/2001				process_directory(1,full_name);
							process_directory(newObj,full_name,fixstats,callback);
						}
					}
				}
				else
				{
					//printf(" we don't handle this type\n");
				}
			}
		}

		closedir(dir);
	}
	
	return 0;

}
int main(int argc, char *argv[])
{
	int fixstats = 0;
	struct stat stats;
	int opt;
	char *image;
	char *dir;

	while ((opt = getopt(argc, argv, "fc:s:")) != -1) {
		switch (opt) {
		case 'f':
			fixstats = 1;
			break;
		case 'c':
			chunkSize = (unsigned)strtoul(optarg, NULL, 0);
			break;
		case 's':
			spareSize = (unsigned)strtoul(optarg, NULL, 0);
			break;
		default:
			usage();
			exit(1);
		}
	}

	if (!chunkSize || !spareSize) {
		usage();
		exit(1);
	}

	if ((argc - optind < 2) || (argc - optind > 3)) {
		usage();
		exit(1);
	}

	dir = argv[optind];
	image = argv[optind + 1];

	if (optind + 2 < argc) {
		if (!strncmp(argv[optind + 2], "convert", strlen("convert")))
			convert_endian = 1;
		else {
			usage();
			exit(1);
		}
	}

	if(stat(dir,&stats) < 0)
	{
		fprintf(stderr,"Could not stat %s\n",dir);
		exit(1);
	}
	
	if(!S_ISDIR(stats.st_mode))
	{
		fprintf(stderr," %s is not a directory\n",dir);
		exit(1);
	}
	
	outFile = open(image,O_CREAT | O_TRUNC | O_WRONLY, S_IREAD | S_IWRITE);
	
	
	if(outFile < 0)
	{
		fprintf(stderr,"Could not open output file %s\n",image);
		exit(1);
	}

    if (fixstats) {
        int len = strlen(dir);
        
        if((len >= 4) && (!strcmp(dir + len - 4, "data"))) {
            source_path_len = len - 4;
        } else if((len >= 6) && (!strcmp(dir + len - 6, "system"))) {
            source_path_len = len - 6;
        } else if((len >= 8) && (!strcmp(dir + len - 8, "custpack"))) {
            source_path_len = len - 8;
        } else if((len >= 7) && (!strcmp(dir + len - 7, "persist"))) {
            source_path_len = len - 7;
        } else {
            fprintf(stderr,"Fixstats (-f) option requested but filesystem is not data, persist or android ( custpack or system )!\n");
            exit(1);
        }
        fix_stat(dir, &stats);
    }
    
	//printf("Processing directory %s into image file %s\n",dir,image);
	error =  write_object_header(1, YAFFS_OBJECT_TYPE_DIRECTORY, &stats, 1,"", -1, NULL);
	if(error)
	error = process_directory(YAFFS_OBJECTID_ROOT,dir,fixstats);
	
	close(outFile);
	
	if(error < 0)
	{
		perror("operation incomplete");
		exit(1);
	}
	else
	{
        /*
		printf("Operation complete.\n"
		       "%d objects in %d directories\n"
		       "%d NAND pages\n",nObjects, nDirectories, nPages);
        */
	}
	
	close(outFile);
	
	exit(0);
}