X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fmake_ext4fs.git;a=blobdiff_plain;f=make_ext4fs.c;h=edfa25cd623586b1f313e5b311cdbfd98aad2bed;hp=62a3f1acd9b9041be7a2b7fb842ca780a35b230c;hb=828ec043d24e6963d6fd3957262ff5382e262adc;hpb=fb5c011b4912fb14cfa87a06a5542c06aecc9278 diff --git a/make_ext4fs.c b/make_ext4fs.c index 62a3f1a..edfa25c 100644 --- a/make_ext4fs.c +++ b/make_ext4fs.c @@ -14,7 +14,6 @@ * limitations under the License. */ -#include "make_ext4fs.h" #include "ext4_utils.h" #include "allocate.h" #include "contents.h" @@ -35,43 +34,9 @@ #include #include -#ifdef USE_MINGW - -#include - -/* These match the Linux definitions of these flags. - L_xx is defined to avoid conflicting with the win32 versions. -*/ -#define L_S_IRUSR 00400 -#define L_S_IWUSR 00200 -#define L_S_IXUSR 00100 -#define S_IRWXU (L_S_IRUSR | L_S_IWUSR | L_S_IXUSR) -#define S_IRGRP 00040 -#define S_IWGRP 00020 -#define S_IXGRP 00010 -#define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP) -#define S_IROTH 00004 -#define S_IWOTH 00002 -#define S_IXOTH 00001 -#define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH) -#define S_ISUID 0004000 -#define S_ISGID 0002000 -#define S_ISVTX 0001000 - -#else - -#include -#include -#include - -#define O_BINARY 0 - -#endif - /* TODO: Not implemented: Allocating blocks in the same block group as the file inode Hash or binary tree directories - Special files: sockets, devices, fifos */ static int filter_dot(const struct dirent *d) @@ -79,8 +44,7 @@ static int filter_dot(const struct dirent *d) return (strcmp(d->d_name, "..") && strcmp(d->d_name, ".")); } -static u32 build_default_directory_structure(const char *dir_path, - struct selabel_handle *sehnd) +static u32 build_default_directory_structure(const char *dir_path) { u32 inode; u32 root_inode; @@ -98,26 +62,9 @@ static u32 build_default_directory_structure(const char *dir_path, inode_set_permissions(inode, dentries.mode, dentries.uid, dentries.gid, dentries.mtime); -#ifndef USE_MINGW - if (sehnd) { - char *path = NULL; - char *secontext = NULL; - - asprintf(&path, "%slost+found", dir_path); - if (selabel_lookup(sehnd, &secontext, path, S_IFDIR) < 0) { - error("cannot lookup security context for %s", path); - } else { - inode_set_selinux(inode, secontext); - freecon(secontext); - } - free(path); - } -#endif - return root_inode; } -#ifndef USE_MINGW /* Read a local directory and create the same tree in the generated filesystem. Calls itself recursively with each directory in the given directory. full_path is an absolute or relative path, with a trailing slash, to the @@ -127,7 +74,7 @@ static u32 build_default_directory_structure(const char *dir_path, if the image were mounted at the specified mount point */ static u32 build_directory_structure(const char *full_path, const char *dir_path, u32 dir_inode, fs_config_func_t fs_config_func, - struct selabel_handle *sehnd, int verbose, time_t fixed_time) + int verbose, time_t fixed_time) { int entries = 0; struct dentry *dentries; @@ -198,30 +145,17 @@ static u32 build_directory_structure(const char *full_path, const char *dir_path } uint64_t capabilities; if (fs_config_func != NULL) { -#ifdef ANDROID unsigned int mode = 0; unsigned int uid = 0; unsigned int gid = 0; int dir = S_ISDIR(stat.st_mode); - fs_config_func(dentries[i].path, dir, &uid, &gid, &mode, &capabilities); - dentries[i].mode = mode; - dentries[i].uid = uid; - dentries[i].gid = gid; - dentries[i].capabilities = capabilities; -#else - error("can't set android permissions - built without android support"); -#endif - } -#ifndef USE_MINGW - if (sehnd) { - if (selabel_lookup(sehnd, &dentries[i].secon, dentries[i].path, stat.st_mode) < 0) { - error("cannot lookup security context for %s", dentries[i].path); + if (fs_config_func(dentries[i].path, dir, &uid, &gid, &mode, &capabilities)) { + dentries[i].mode = mode; + dentries[i].uid = uid; + dentries[i].gid = gid; + dentries[i].capabilities = capabilities; } - - if (dentries[i].secon && verbose) - printf("Labeling %s as %s\n", dentries[i].path, dentries[i].secon); } -#endif if (S_ISREG(stat.st_mode)) { dentries[i].file_type = EXT4_FT_REG_FILE; @@ -263,10 +197,6 @@ static u32 build_directory_structure(const char *full_path, const char *dir_path dentries[0].file_type = EXT4_FT_DIR; dentries[0].uid = 0; dentries[0].gid = 0; - if (sehnd) { - if (selabel_lookup(sehnd, &dentries[0].secon, dentries[0].path, dentries[0].mode) < 0) - error("cannot lookup security context for %s", dentries[0].path); - } entries++; dirs++; } @@ -288,11 +218,16 @@ static u32 build_directory_structure(const char *full_path, const char *dir_path if (ret < 0) critical_error_errno("asprintf"); entry_inode = build_directory_structure(subdir_full_path, - subdir_dir_path, inode, fs_config_func, sehnd, verbose, fixed_time); + subdir_dir_path, inode, fs_config_func, verbose, fixed_time); free(subdir_full_path); free(subdir_dir_path); } else if (dentries[i].file_type == EXT4_FT_SYMLINK) { entry_inode = make_link(dentries[i].link); + } else if (dentries[i].file_type == EXT4_FT_CHRDEV || + dentries[i].file_type == EXT4_FT_BLKDEV || + dentries[i].file_type == EXT4_FT_SOCK || + dentries[i].file_type == EXT4_FT_FIFO) { + entry_inode = make_special(dentries[i].full_path); } else { error("unknown file type on %s", dentries[i].path); entry_inode = 0; @@ -305,16 +240,6 @@ static u32 build_directory_structure(const char *full_path, const char *dir_path if (ret) error("failed to set permissions on %s\n", dentries[i].path); - /* - * It's important to call inode_set_selinux() before - * inode_set_capabilities(). Extended attributes need to - * be stored sorted order, and we guarantee this by making - * the calls in the proper order. - * Please see xattr_assert_sane() in contents.c - */ - ret = inode_set_selinux(entry_inode, dentries[i].secon); - if (ret) - error("failed to set SELinux context on %s\n", dentries[i].path); ret = inode_set_capabilities(entry_inode, dentries[i].capabilities); if (ret) error("failed to set capability on %s\n", dentries[i].path); @@ -323,13 +248,11 @@ static u32 build_directory_structure(const char *full_path, const char *dir_path free(dentries[i].full_path); free(dentries[i].link); free((void *)dentries[i].filename); - free(dentries[i].secon); } free(dentries); return inode; } -#endif static u32 compute_block_size() { @@ -388,48 +311,6 @@ static u32 compute_bg_desc_reserve_blocks() return bg_desc_reserve_blocks; } -void reset_ext4fs_info() { - // Reset all the global data structures used by make_ext4fs so it - // can be called again. - memset(&info, 0, sizeof(info)); - memset(&aux_info, 0, sizeof(aux_info)); - - if (ext4_sparse_file) { - sparse_file_destroy(ext4_sparse_file); - ext4_sparse_file = NULL; - } -} - -int make_ext4fs_sparse_fd(int fd, long long len, - const char *mountpoint, struct selabel_handle *sehnd) -{ - reset_ext4fs_info(); - info.len = len; - - return make_ext4fs_internal(fd, NULL, mountpoint, NULL, 0, 1, 0, 0, sehnd, 0, -1, NULL); -} - -int make_ext4fs(const char *filename, long long len, - const char *mountpoint, struct selabel_handle *sehnd) -{ - int fd; - int status; - - reset_ext4fs_info(); - info.len = len; - - fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644); - if (fd < 0) { - error_errno("open"); - return EXIT_FAILURE; - } - - status = make_ext4fs_internal(fd, NULL, mountpoint, NULL, 0, 0, 0, 1, sehnd, 0, -1, NULL); - close(fd); - - return status; -} - /* return a newly-malloc'd string that is a copy of str. The new string is guaranteed to have a trailing slash. If absolute is true, the new string is also guaranteed to have a leading slash. @@ -491,28 +372,24 @@ static char *canonicalize_rel_slashes(const char *str) } int make_ext4fs_internal(int fd, const char *_directory, - const char *_mountpoint, fs_config_func_t fs_config_func, int gzip, + fs_config_func_t fs_config_func, int gzip, int sparse, int crc, int wipe, - struct selabel_handle *sehnd, int verbose, time_t fixed_time, + int verbose, time_t fixed_time, FILE* block_list_file) { u32 root_inode_num; u16 root_mode; - char *mountpoint; char *directory = NULL; if (setjmp(setjmp_env)) return EXIT_FAILURE; /* Handle a call to longjmp() */ - if (_mountpoint == NULL) { - mountpoint = strdup(""); - } else { - mountpoint = canonicalize_abs_slashes(_mountpoint); + if (_directory == NULL) { + fprintf(stderr, "Need a source directory\n"); + return EXIT_FAILURE; } - if (_directory) { - directory = canonicalize_rel_slashes(_directory); - } + directory = canonicalize_rel_slashes(_directory); if (info.len <= 0) info.len = get_file_size(fd); @@ -579,6 +456,7 @@ int make_ext4fs_internal(int fd, const char *_directory, printf(" Blocks: %"PRIu64"\n", aux_info.len_blocks); printf(" Block groups: %d\n", aux_info.groups); + printf(" Reserved blocks: %"PRIu64"\n", (aux_info.len_blocks / 100) * info.reserve_pcnt); printf(" Reserved block group size: %d\n", info.bg_desc_reserve_blocks); ext4_sparse_file = sparse_file_new(info.block_size, info.len); @@ -596,49 +474,22 @@ int make_ext4fs_internal(int fd, const char *_directory, if (info.feat_compat & EXT4_FEATURE_COMPAT_RESIZE_INODE) ext4_create_resize_inode(); -#ifdef USE_MINGW - // Windows needs only 'create an empty fs image' functionality - assert(!directory); - root_inode_num = build_default_directory_structure(mountpoint, sehnd); -#else - if (directory) - root_inode_num = build_directory_structure(directory, mountpoint, 0, - fs_config_func, sehnd, verbose, fixed_time); - else - root_inode_num = build_default_directory_structure(mountpoint, sehnd); -#endif + root_inode_num = build_directory_structure(directory, "", 0, + fs_config_func, verbose, fixed_time); root_mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; inode_set_permissions(root_inode_num, root_mode, 0, 0, 0); -#ifndef USE_MINGW - if (sehnd) { - char *secontext = NULL; - - if (selabel_lookup(sehnd, &secontext, mountpoint, S_IFDIR) < 0) { - error("cannot lookup security context for %s", mountpoint); - } - if (secontext) { - if (verbose) { - printf("Labeling %s as %s\n", mountpoint, secontext); - } - inode_set_selinux(root_inode_num, secontext); - } - freecon(secontext); - } -#endif - ext4_update_free(); ext4_queue_sb(); if (block_list_file) { - size_t dirlen = directory ? strlen(directory) : 0; + size_t dirlen = strlen(directory); struct block_allocation* p = get_saved_allocation_chain(); while (p) { - if (directory && strncmp(p->filename, directory, dirlen) == 0) { - // substitute mountpoint for the leading directory in the filename, in the output file - fprintf(block_list_file, "%s%s", mountpoint, p->filename + dirlen); + if (strncmp(p->filename, directory, dirlen) == 0) { + fprintf(block_list_file, "%s", p->filename + dirlen); } else { fprintf(block_list_file, "%s", p->filename); } @@ -664,7 +515,6 @@ int make_ext4fs_internal(int fd, const char *_directory, sparse_file_destroy(ext4_sparse_file); ext4_sparse_file = NULL; - free(mountpoint); free(directory); return 0;