#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
}
/* 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;
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;
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)
size = llistxattr(filename, NULL, 0);
if (size == -1) {
+ if (errno == ENOTSUP)
+ return 0;
retval = errno;
com_err(__func__, retval, _("while listing attributes of \"%s\""),
filename);
retval = retval ? retval : close_retval;
}
return retval;
- return 0;
}
#else /* HAVE_LLISTXATTR */
static errcode_t set_inode_xattr(ext2_filsys fs EXT2FS_ATTR((unused)),
struct ext2_inode inode;
unsigned long devmajor, devminor, mode;
int filetype;
+ time_t now;
switch(st_mode & S_IFMT) {
case S_IFCHR:
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);
errcode_t retval;
struct ext2_inode inode;
char *cp;
+ time_t now;
fd = ext2fs_open_file(src, O_RDONLY, 0);
if (fd < 0) {
if (retval) {
com_err(dest, retval, _("while looking up \"%s\""),
dest);
- return retval;
+ goto out;
}
dest = cp+1;
} else
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)
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) {
size_t new_list_size = temp_list_size + 32;
struct dirent **new_list = (struct dirent**)realloc(
temp_list, new_list_size * sizeof(struct dirent*));
- if (new_list == NULL) {
- goto out;
- }
+ if (new_list == NULL)
+ goto out_err;
temp_list_size = new_list_size;
temp_list = new_list;
}
// add the copy of dirent to the list
temp_list[num_dent] = (struct dirent*)malloc((dent->d_reclen + 3) & ~3);
+ if (!temp_list[num_dent])
+ goto out_err;
memcpy(temp_list[num_dent], dent, dent->d_reclen);
num_dent++;
}
+ closedir(dir);
if (compar != NULL) {
qsort(temp_list, num_dent, sizeof(struct dirent*),
(int (*)(const void*, const void*))compar);
}
-
- // release the temp list
*name_list = temp_list;
- temp_list = NULL;
+ return num_dent;
-out:
- if (temp_list != NULL) {
- while (num_dent > 0) {
- free(temp_list[--num_dent]);
- }
- free(temp_list);
- num_dent = -1;
- }
+out_err:
closedir(dir);
- return num_dent;
+ while (num_dent > 0)
+ free(temp_list[--num_dent]);
+ free(temp_list);
+ return -1;
}
static int alphasort(const struct dirent **a, const struct dirent **b) {
const char *name;
struct dirent **dent;
struct stat st;
- char *ln_target = NULL;
unsigned int save_inode;
ext2_ino_t ino;
errcode_t retval = 0;
- int read_cnt;
int hdlink;
size_t cur_dir_path_len;
int i, num_dents;
goto out;
}
break;
- case S_IFLNK:
+ case S_IFLNK: {
+ char *ln_target;
+ int read_cnt;
+
ln_target = malloc(st.st_size + 1);
if (ln_target == NULL) {
com_err(__func__, retval,
goto out;
}
break;
-#endif
+ }
+#endif /* !_WIN32 */
case S_IFREG:
retval = do_write_internal(fs, parent_ino, name, name,
root);
}
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;
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:
}
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);
}