summaryrefslogtreecommitdiffstats
path: root/misc/create_inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'misc/create_inode.c')
-rw-r--r--misc/create_inode.c73
1 files changed, 51 insertions, 22 deletions
diff --git a/misc/create_inode.c b/misc/create_inode.c
index a3a34cd..4e292a2 100644
--- a/misc/create_inode.c
+++ b/misc/create_inode.c
@@ -9,7 +9,6 @@
* %End-Header%
*/
-#define _FILE_OFFSET_BITS 64
#define _LARGEFILE64_SOURCE 1
#define _GNU_SOURCE 1
@@ -39,6 +38,8 @@
#include "create_inode.h"
#include "support/nls-enable.h"
+#include "create_inode_libarchive.h"
+
/* 64KiB is the minimum blksize to best minimize system call overhead. */
#define COPY_FILE_BUFLEN 65536
@@ -69,7 +70,7 @@ static int ext2_file_type(unsigned int mode)
}
/* Link an inode number to a directory */
-static errcode_t add_link(ext2_filsys fs, ext2_ino_t parent_ino,
+errcode_t add_link(ext2_filsys fs, ext2_ino_t parent_ino,
ext2_ino_t ino, const char *name)
{
struct ext2_inode inode;
@@ -107,9 +108,16 @@ static errcode_t add_link(ext2_filsys fs, ext2_ino_t parent_ino,
return retval;
}
+static time_t clamped_time(ext2_filsys fs, time_t t)
+{
+ if ((fs->flags2 & EXT2_FLAG2_USE_FAKE_TIME) && t > fs->now)
+ return fs->now;
+ return t;
+}
+
/* Set the uid, gid, mode and time for the inode */
-static errcode_t set_inode_extra(ext2_filsys fs, ext2_ino_t ino,
- struct stat *st)
+errcode_t set_inode_extra(ext2_filsys fs, ext2_ino_t ino,
+ const struct stat *st)
{
errcode_t retval;
struct ext2_inode inode;
@@ -125,9 +133,9 @@ static errcode_t set_inode_extra(ext2_filsys fs, ext2_ino_t ino,
inode.i_gid = st->st_gid;
ext2fs_set_i_gid_high(inode, st->st_gid >> 16);
inode.i_mode = (LINUX_S_IFMT & inode.i_mode) | (~S_IFMT & st->st_mode);
- inode.i_atime = st->st_atime;
- inode.i_mtime = st->st_mtime;
- inode.i_ctime = st->st_ctime;
+ ext2fs_inode_xtime_set(&inode, i_atime, clamped_time(fs, st->st_atime));
+ ext2fs_inode_xtime_set(&inode, i_ctime, clamped_time(fs, st->st_ctime));
+ ext2fs_inode_xtime_set(&inode, i_mtime, clamped_time(fs, st->st_mtime));
retval = ext2fs_write_inode(fs, ino, &inode);
if (retval)
@@ -256,6 +264,7 @@ errcode_t do_mknod_internal(ext2_filsys fs, ext2_ino_t cwd, const char *name,
struct ext2_inode inode;
unsigned long devmajor, devminor, mode;
int filetype;
+ time_t now;
switch(st_mode & S_IFMT) {
case S_IFCHR:
@@ -309,8 +318,10 @@ errcode_t do_mknod_internal(ext2_filsys fs, ext2_ino_t cwd, const char *name,
ext2fs_inode_alloc_stats2(fs, ino, +1, 0);
memset(&inode, 0, sizeof(inode));
inode.i_mode = mode;
- inode.i_atime = inode.i_ctime = inode.i_mtime =
- fs->now ? fs->now : time(0);
+ now = fs->now ? fs->now : time(0);
+ ext2fs_inode_xtime_set(&inode, i_atime, now);
+ ext2fs_inode_xtime_set(&inode, i_ctime, now);
+ ext2fs_inode_xtime_set(&inode, i_mtime, now);
if (filetype != S_IFIFO) {
devmajor = major(st_rdev);
@@ -631,6 +642,7 @@ errcode_t do_write_internal(ext2_filsys fs, ext2_ino_t cwd, const char *src,
errcode_t retval;
struct ext2_inode inode;
char *cp;
+ time_t now;
fd = ext2fs_open_file(src, O_RDONLY, 0);
if (fd < 0) {
@@ -684,8 +696,10 @@ errcode_t do_write_internal(ext2_filsys fs, ext2_ino_t cwd, const char *src,
ext2fs_inode_alloc_stats2(fs, newfile, +1, 0);
memset(&inode, 0, sizeof(inode));
inode.i_mode = (statbuf.st_mode & ~S_IFMT) | LINUX_S_IFREG;
- inode.i_atime = inode.i_ctime = inode.i_mtime =
- fs->now ? fs->now : time(0);
+ now = fs->now ? fs->now : time(0);
+ ext2fs_inode_xtime_set(&inode, i_atime, now);
+ ext2fs_inode_xtime_set(&inode, i_ctime, now);
+ ext2fs_inode_xtime_set(&inode, i_mtime, now);
inode.i_links_count = 1;
retval = ext2fs_inode_size_set(fs, &inode, statbuf.st_size);
if (retval)
@@ -720,12 +734,6 @@ out:
return retval;
}
-struct file_info {
- char *path;
- size_t path_len;
- size_t path_max_len;
-};
-
static errcode_t path_append(struct file_info *target, const char *file)
{
if (strlen(file) + target->path_len + 1 > target->path_max_len) {
@@ -1044,7 +1052,7 @@ out:
}
errcode_t populate_fs2(ext2_filsys fs, ext2_ino_t parent_ino,
- const char *source_dir, ext2_ino_t root,
+ const char *source, ext2_ino_t root,
struct fs_ops_callbacks *fs_callbacks)
{
struct file_info file_info;
@@ -1069,14 +1077,35 @@ errcode_t populate_fs2(ext2_filsys fs, ext2_ino_t parent_ino,
file_info.path_max_len = 255;
file_info.path = calloc(file_info.path_max_len, 1);
- retval = set_inode_xattr(fs, root, source_dir);
+ /* interpret input as tarball either if it's "-" (stdin) or if it's
+ * a regular file (or a symlink pointing to a regular file)
+ */
+ if (strcmp(source, "-") == 0) {
+ retval = __populate_fs_from_tar(fs, parent_ino, NULL, root, &hdlinks,
+ &file_info, fs_callbacks);
+ goto out;
+ }
+
+ struct stat st;
+ if (stat(source, &st)) {
+ retval = errno;
+ com_err(__func__, retval, _("while calling stat"));
+ return retval;
+ }
+ if (S_ISREG(st.st_mode)) {
+ retval = __populate_fs_from_tar(fs, parent_ino, source, root, &hdlinks,
+ &file_info, fs_callbacks);
+ goto out;
+ }
+
+ retval = set_inode_xattr(fs, root, source);
if (retval) {
com_err(__func__, retval,
_("while copying xattrs on root directory"));
goto out;
}
- retval = __populate_fs(fs, parent_ino, source_dir, root, &hdlinks,
+ retval = __populate_fs(fs, parent_ino, source, root, &hdlinks,
&file_info, fs_callbacks);
out:
@@ -1086,7 +1115,7 @@ out:
}
errcode_t populate_fs(ext2_filsys fs, ext2_ino_t parent_ino,
- const char *source_dir, ext2_ino_t root)
+ const char *source, ext2_ino_t root)
{
- return populate_fs2(fs, parent_ino, source_dir, root, NULL);
+ return populate_fs2(fs, parent_ino, source, root, NULL);
}