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; }
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); }