/* This function constructs a root inode with no name and no data. The inode is then written to the filesystem image. */ int make_root_dir(FILE *fs, int first_ino, const char *root_dir_path, int depth) { struct jffs_file f; struct stat st; __u16 chksum; if (stat(root_dir_path, &st) < 0) { perror("stat"); exit(1); } f.inode.magic = JFFS_MAGIC; f.inode.ino = first_ino; f.inode.pino = 0; f.inode.version = 1; f.inode.mode = st.st_mode; f.inode.uid = 0; /* root */ f.inode.gid = 0; /* root */ f.inode.atime = st.st_atime; f.inode.mtime = st.st_mtime; f.inode.ctime = st.st_ctime; f.inode.offset = 0; f.inode.dsize = 0; f.inode.rsize = 0; f.inode.nsize = 0; /*f.inode.nlink = st.st_nlink;*/ f.inode.nlink = 1; f.inode.spare = 0; f.inode.rename = 0; f.inode.deleted = 0; f.inode.accurate = 0; f.inode.dchksum = 0; f.inode.nchksum = 0; f.inode.chksum = 0; f.name = 0; f.data = 0; jffs_swap_inode(&f.inode); chksum = jffs_checksum(&f.inode, sizeof(struct jffs_raw_inode)); jffs_swap_inode(&f.inode); f.inode.chksum = chksum; f.inode.accurate = 0xff; write_file(&f, fs, st); if (verbose >= 1) { jffs_print_trace(root_dir_path, depth); } if (verbose >= 2) { jffs_print_raw_inode(&f.inode); } return first_ino; }
/* This function constructs a root inode with no name and no data. The inode is then written to the filesystem image. */ int make_root_dir(FILE *fs, int first_ino, const char *root_dir_path, int depth) { struct jffs_file f; struct stat st; if (stat(root_dir_path, &st) < 0) { perror("stat"); exit(1); } write_val32(&f.inode.magic, JFFS_MAGIC); write_val32(&f.inode.ino, first_ino); write_val32(&f.inode.pino, 0); write_val32(&f.inode.version, 1); write_val32(&f.inode.mode, st.st_mode); write_val16(&f.inode.uid, 0); /* root */ write_val16(&f.inode.gid, 0); /* root */ write_val32(&f.inode.atime, st.st_atime); write_val32(&f.inode.mtime, st.st_mtime); write_val32(&f.inode.ctime, st.st_ctime); write_val32(&f.inode.offset, 0); write_val32(&f.inode.dsize, 0); write_val32(&f.inode.rsize,0); f.inode.nsize = 0; /*f.inode.nlink = st.st_nlink;*/ f.inode.nlink = 1; f.inode.spare = 0; f.inode.rename = 0; f.inode.deleted = 0; f.inode.accurate = 0; write_val32(&f.inode.dchksum, 0); write_val16(&f.inode.nchksum, 0); write_val16(&f.inode.chksum, 0); f.name = 0; f.data = 0; write_val16(&f.inode.chksum, jffs_checksum(&f.inode, sizeof(struct jffs_raw_inode))); f.inode.accurate = 0xff; write_file(&f, fs, st); if (verbose >= 1) { jffs_print_trace(root_dir_path, depth); } if (verbose >= 2) { jffs_print_raw_inode(&f.inode); } return first_ino; }
/* This is the routine that constructs the filesystem image. */ int mkfs(FILE *fs, const char *path, int ino, int parent, int depth) { struct dirent *dir_entry; DIR *dir; struct stat st; struct jffs_file f; int name_len; int pos = 0; int new_ino = ino; char *filename; int path_len = strlen(path); if (verbose >= 2) { fprintf(stderr, "***mkfs(): path: \"%s\"\r\n", path); } if (!(dir = opendir(path))) { perror("opendir"); fprintf(stderr, "mkfs(): opendir() failed! (%s)\n", path); exit(1); } while ((dir_entry = readdir(dir))) { if (verbose >= 2) { fprintf(stderr, "mkfs(): name: %s\n", dir_entry->d_name); } name_len = strlen(dir_entry->d_name); if (((name_len == 1) && (dir_entry->d_name[0] == '.')) || ((name_len == 2) && (dir_entry->d_name[0] == '.') && (dir_entry->d_name[1] == '.'))) { continue; } if (!(filename = (char *)alloca(path_len + name_len + 1))) { fprintf(stderr, "mkfs(): Allocation failed!\n"); exit(0); } strcpy(filename, path); strcat(filename, dir_entry->d_name); if (verbose >= 2) { fprintf(stderr, "mkfs(): filename: %s\n", filename); } if (lstat(filename, &st) < 0) { perror("lstat"); exit(1); } if (verbose >= 2) { fprintf(stderr, "mkfs(): filename: \"%s\", ino: %d, parent: %d\n", filename, new_ino, parent); } if (S_ISREG(st.st_mode) && st.st_size == 0) { char devname[32]; char type; int major; int minor; if (sscanf(dir_entry->d_name, "@%31[-a-zA-Z0-9_+],%c,%d,%d", devname, &type, &major, &minor) == 4) { strcpy(dir_entry->d_name, devname); st.st_rdev = makedev(major, minor); st.st_mode &= ~S_IFMT; switch (type) { case 'c': case 'u': st.st_mode |= S_IFCHR; break; case 'b': st.st_mode |= S_IFBLK; break; case 'p': st.st_mode |= S_IFIFO; break; default: fprintf(stderr, "mkfs(): invalid special device type '%c' for file %s\n", type, filename); exit(1); } } } if (squash) { st.st_uid = 0; st.st_gid = 0; } write_val32(&f.inode.magic, JFFS_MAGIC); write_val32(&f.inode.ino, new_ino); write_val32(&f.inode.pino, parent); write_val32(&f.inode.version, 1); write_val32(&f.inode.mode, st.st_mode); write_val16(&f.inode.uid, st.st_uid); write_val16(&f.inode.gid, st.st_gid); write_val32(&f.inode.atime, st.st_atime); write_val32(&f.inode.mtime, st.st_mtime); write_val32(&f.inode.ctime, st.st_ctime); write_val32(&f.inode.dsize, 0); write_val32(&f.inode.rsize, 0); f.inode.nsize = name_len; /*f.inode.nlink = st.st_nlink;*/ f.inode.nlink = 1; f.inode.spare = 0; f.inode.rename = 0; f.inode.deleted = 0; f.inode.accurate = 0; write_val32(&f.inode.dchksum, 0); write_val16(&f.inode.nchksum, 0); write_val16(&f.inode.chksum, 0); if (dir_entry->d_name) { f.name = strdup(dir_entry->d_name); } else { f.name = 0; } repeat: write_val32(&f.inode.offset, pos); f.data = 0; f.inode.accurate = 0; if (S_ISREG(st.st_mode) && st.st_size) { if (st.st_size - pos < MAX_CHUNK_SIZE) { write_val32(&f.inode.dsize, st.st_size - pos); } else { write_val32(&f.inode.dsize, MAX_CHUNK_SIZE); } read_data(&f, path, pos); pos += read_val32(&f.inode.dsize); } else if (S_ISLNK(st.st_mode)) { int linklen; unsigned char *linkdata = (unsigned char *)malloc(1000); if (!linkdata) { fprintf(stderr, "mkfs(): malloc() failed! (linkdata)\n"); exit(1); } if ((linklen = readlink(filename, linkdata, 1000)) < 0) { free(linkdata); fprintf(stderr, "mkfs(): readlink() failed! f.name = \"%s\"\n", f.name); exit(1); } write_val32(&f.inode.dsize, linklen); f.data = linkdata; f.data[linklen] = '\0'; } else if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode)) { write_val32(&f.inode.dsize, sizeof(st.st_rdev) / 4); } write_val16(&f.inode.chksum, 0); if (!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode)) { write_val32(&f.inode.dchksum, jffs_checksum((void *)f.data, read_val32(&f.inode.dsize))); } else { write_val32(&f.inode.dchksum, jffs_checksum((void *)&st.st_rdev, sizeof(st.st_rdev) / 4)); } write_val16(&f.inode.nchksum, jffs_checksum((void *)f.name, f.inode.nsize)); write_val16(&f.inode.chksum, jffs_checksum((void *)&f.inode, sizeof(struct jffs_raw_inode))); f.inode.accurate = 0xff; write_file(&f, fs, st); if (S_ISREG(st.st_mode) && st.st_size) { if (pos < st.st_size) { write_val32(&f.inode.version, read_val32(&f.inode.version) + 1); goto repeat; } } new_ino++; pos = 0; if (verbose >= 1) { jffs_print_trace(f.name, depth); } if (verbose >= 2) { jffs_print_raw_inode(&f.inode); } if (S_ISDIR(st.st_mode)) { char *new_path; if (!(new_path = (char *)alloca(strlen(path) + name_len + 1 + 1))) { fprintf(stderr, "mkfs(): alloca() failed! (new_path)\n"); exit(1); } strcpy(new_path, path); strncat(new_path, f.name, f.inode.nsize); strcat(new_path, "/"); if (verbose >= 2) { fprintf(stderr, "mkfs(): new_path: \"%s\"\n", new_path); } new_ino = mkfs(fs, new_path, new_ino, new_ino - 1, depth + 1); } if (f.name) { free(f.name); } if (f.data) { free(f.data); } } closedir(dir); return new_ino; }
/* This is the routine that constructs the filesystem image. */ int mkfs(FILE *fs, const char *path, int ino, int parent, int depth) { struct dirent *dir_entry; DIR *dir; struct stat st; struct jffs_file f; int name_len; int pos = 0; int new_ino = ino; char *filename; int path_len = strlen(path); __u16 chksum; if (verbose >= 2) { fprintf(stderr, "***mkfs(): path: \"%s\"\r\n", path); } if (!(dir = opendir(path))) { perror("opendir"); fprintf(stderr, "mkfs(): opendir() failed! (%s)\n", path); exit(1); } while ((dir_entry = readdir(dir))) { if (verbose >= 2) { fprintf(stderr, "mkfs(): name: %s\n", dir_entry->d_name); } name_len = strlen(dir_entry->d_name); if (((name_len == 1) && (dir_entry->d_name[0] == '.')) || ((name_len == 2) && (dir_entry->d_name[0] == '.') && (dir_entry->d_name[1] == '.'))) { continue; } if (!(filename = (char *)alloca(path_len + name_len + 1))) { fprintf(stderr, "mkfs(): Allocation failed!\n"); exit(0); } strcpy(filename, path); strcat(filename, dir_entry->d_name); if (verbose >= 2) { fprintf(stderr, "mkfs(): filename: %s\n", filename); } if (lstat(filename, &st) < 0) { perror("lstat"); exit(1); } if (verbose >= 2) { fprintf(stderr, "mkfs(): filename: \"%s\", ino: %d, parent: %d\n", filename, new_ino, parent); } f.inode.magic = JFFS_MAGIC; f.inode.ino = new_ino; f.inode.pino = parent; f.inode.version = 1; f.inode.mode = st.st_mode; f.inode.uid = st.st_uid; f.inode.gid = st.st_gid; f.inode.atime = st.st_atime; f.inode.mtime = st.st_mtime; f.inode.ctime = st.st_ctime; f.inode.dsize = 0; f.inode.rsize = 0; f.inode.nsize = name_len; /*f.inode.nlink = st.st_nlink;*/ f.inode.nlink = 1; f.inode.spare = 0; f.inode.rename = 0; f.inode.deleted = 0; f.inode.accurate = 0; f.inode.dchksum = 0; f.inode.nchksum = 0; f.inode.chksum = 0; if (dir_entry->d_name) { f.name = strdup(dir_entry->d_name); } else { f.name = 0; } repeat: f.inode.offset = pos; f.data = 0; f.inode.accurate = 0; if (S_ISREG(st.st_mode) && st.st_size) { if (st.st_size - pos < MAX_CHUNK_SIZE) { f.inode.dsize = st.st_size - pos; } else { f.inode.dsize = MAX_CHUNK_SIZE; } read_data(&f, path, pos); pos += f.inode.dsize; } else if (S_ISLNK(st.st_mode)) { int linklen; unsigned char *linkdata = (unsigned char *)malloc(1000); if (!linkdata) { fprintf(stderr, "mkfs(): malloc() failed! (linkdata)\n"); exit(1); } if ((linklen = readlink(filename, linkdata, 1000)) < 0) { free(linkdata); fprintf(stderr, "mkfs(): readlink() failed! f.name = \"%s\"\n", f.name); exit(1); } f.inode.dsize = linklen; f.data = linkdata; f.data[linklen] = '\0'; } else if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode)) { f.inode.dsize = sizeof(st.st_rdev) / 4; } f.inode.chksum = 0; if (!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode)) { f.inode.dchksum = jffs_checksum((void *)f.data, f.inode.dsize); } else { f.inode.dchksum = jffs_checksum((void *)&st.st_rdev, sizeof(st.st_rdev) / 4); } f.inode.nchksum = jffs_checksum((void *)f.name, f.inode.nsize); jffs_swap_inode(&f.inode); chksum = jffs_checksum((void *)&f.inode, sizeof(struct jffs_raw_inode)); jffs_swap_inode(&f.inode); f.inode.chksum = chksum; f.inode.accurate = 0xff; write_file(&f, fs, st); if (S_ISREG(st.st_mode) && st.st_size) { if (pos < st.st_size) { f.inode.version++; goto repeat; } } new_ino++; pos = 0; if (verbose >= 1) { jffs_print_trace(f.name, depth); } if (verbose >= 2) { jffs_print_raw_inode(&f.inode); } if (S_ISDIR(st.st_mode)) { char *new_path; if (!(new_path = (char *)alloca(strlen(path) + name_len + 1 + 1))) { fprintf(stderr, "mkfs(): alloca() failed! (new_path)\n"); exit(1); } strcpy(new_path, path); strncat(new_path, f.name, f.inode.nsize); strcat(new_path, "/"); if (verbose >= 2) { fprintf(stderr, "mkfs(): new_path: \"%s\"\n", new_path); } new_ino = mkfs(fs, new_path, new_ino, new_ino - 1, depth + 1); } if (f.name) { free(f.name); } if (f.data) { free(f.data); } } closedir(dir); return new_ino; }