|
@@ -6,6 +6,7 @@
|
|
#include <linux/delay.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/string.h>
|
|
#include <linux/string.h>
|
|
#include <linux/syscalls.h>
|
|
#include <linux/syscalls.h>
|
|
|
|
+#include <linux/utime.h>
|
|
|
|
|
|
static __initdata char *message;
|
|
static __initdata char *message;
|
|
static void __init error(char *x)
|
|
static void __init error(char *x)
|
|
@@ -72,6 +73,49 @@ static void __init free_hash(void)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static long __init do_utime(char __user *filename, time_t mtime)
|
|
|
|
+{
|
|
|
|
+ struct timespec t[2];
|
|
|
|
+
|
|
|
|
+ t[0].tv_sec = mtime;
|
|
|
|
+ t[0].tv_nsec = 0;
|
|
|
|
+ t[1].tv_sec = mtime;
|
|
|
|
+ t[1].tv_nsec = 0;
|
|
|
|
+
|
|
|
|
+ return do_utimes(AT_FDCWD, filename, t, AT_SYMLINK_NOFOLLOW);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static __initdata LIST_HEAD(dir_list);
|
|
|
|
+struct dir_entry {
|
|
|
|
+ struct list_head list;
|
|
|
|
+ char *name;
|
|
|
|
+ time_t mtime;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static void __init dir_add(const char *name, time_t mtime)
|
|
|
|
+{
|
|
|
|
+ struct dir_entry *de = kmalloc(sizeof(struct dir_entry), GFP_KERNEL);
|
|
|
|
+ if (!de)
|
|
|
|
+ panic("can't allocate dir_entry buffer");
|
|
|
|
+ INIT_LIST_HEAD(&de->list);
|
|
|
|
+ de->name = kstrdup(name, GFP_KERNEL);
|
|
|
|
+ de->mtime = mtime;
|
|
|
|
+ list_add(&de->list, &dir_list);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void __init dir_utime(void)
|
|
|
|
+{
|
|
|
|
+ struct dir_entry *de, *tmp;
|
|
|
|
+ list_for_each_entry_safe(de, tmp, &dir_list, list) {
|
|
|
|
+ list_del(&de->list);
|
|
|
|
+ do_utime(de->name, de->mtime);
|
|
|
|
+ kfree(de->name);
|
|
|
|
+ kfree(de);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static __initdata time_t mtime;
|
|
|
|
+
|
|
/* cpio header parsing */
|
|
/* cpio header parsing */
|
|
|
|
|
|
static __initdata unsigned long ino, major, minor, nlink;
|
|
static __initdata unsigned long ino, major, minor, nlink;
|
|
@@ -97,6 +141,7 @@ static void __init parse_header(char *s)
|
|
uid = parsed[2];
|
|
uid = parsed[2];
|
|
gid = parsed[3];
|
|
gid = parsed[3];
|
|
nlink = parsed[4];
|
|
nlink = parsed[4];
|
|
|
|
+ mtime = parsed[5];
|
|
body_len = parsed[6];
|
|
body_len = parsed[6];
|
|
major = parsed[7];
|
|
major = parsed[7];
|
|
minor = parsed[8];
|
|
minor = parsed[8];
|
|
@@ -130,6 +175,7 @@ static inline void __init eat(unsigned n)
|
|
count -= n;
|
|
count -= n;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static __initdata char *vcollected;
|
|
static __initdata char *collected;
|
|
static __initdata char *collected;
|
|
static __initdata int remains;
|
|
static __initdata int remains;
|
|
static __initdata char *collect;
|
|
static __initdata char *collect;
|
|
@@ -271,6 +317,7 @@ static int __init do_name(void)
|
|
if (wfd >= 0) {
|
|
if (wfd >= 0) {
|
|
sys_fchown(wfd, uid, gid);
|
|
sys_fchown(wfd, uid, gid);
|
|
sys_fchmod(wfd, mode);
|
|
sys_fchmod(wfd, mode);
|
|
|
|
+ vcollected = kstrdup(collected, GFP_KERNEL);
|
|
state = CopyFile;
|
|
state = CopyFile;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -278,12 +325,14 @@ static int __init do_name(void)
|
|
sys_mkdir(collected, mode);
|
|
sys_mkdir(collected, mode);
|
|
sys_chown(collected, uid, gid);
|
|
sys_chown(collected, uid, gid);
|
|
sys_chmod(collected, mode);
|
|
sys_chmod(collected, mode);
|
|
|
|
+ dir_add(collected, mtime);
|
|
} else if (S_ISBLK(mode) || S_ISCHR(mode) ||
|
|
} else if (S_ISBLK(mode) || S_ISCHR(mode) ||
|
|
S_ISFIFO(mode) || S_ISSOCK(mode)) {
|
|
S_ISFIFO(mode) || S_ISSOCK(mode)) {
|
|
if (maybe_link() == 0) {
|
|
if (maybe_link() == 0) {
|
|
sys_mknod(collected, mode, rdev);
|
|
sys_mknod(collected, mode, rdev);
|
|
sys_chown(collected, uid, gid);
|
|
sys_chown(collected, uid, gid);
|
|
sys_chmod(collected, mode);
|
|
sys_chmod(collected, mode);
|
|
|
|
+ do_utime(collected, mtime);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
return 0;
|
|
@@ -294,6 +343,8 @@ static int __init do_copy(void)
|
|
if (count >= body_len) {
|
|
if (count >= body_len) {
|
|
sys_write(wfd, victim, body_len);
|
|
sys_write(wfd, victim, body_len);
|
|
sys_close(wfd);
|
|
sys_close(wfd);
|
|
|
|
+ do_utime(vcollected, mtime);
|
|
|
|
+ kfree(vcollected);
|
|
eat(body_len);
|
|
eat(body_len);
|
|
state = SkipIt;
|
|
state = SkipIt;
|
|
return 0;
|
|
return 0;
|
|
@@ -311,6 +362,7 @@ static int __init do_symlink(void)
|
|
clean_path(collected, 0);
|
|
clean_path(collected, 0);
|
|
sys_symlink(collected + N_ALIGN(name_len), collected);
|
|
sys_symlink(collected + N_ALIGN(name_len), collected);
|
|
sys_lchown(collected, uid, gid);
|
|
sys_lchown(collected, uid, gid);
|
|
|
|
+ do_utime(collected, mtime);
|
|
state = SkipIt;
|
|
state = SkipIt;
|
|
next_state = Reset;
|
|
next_state = Reset;
|
|
return 0;
|
|
return 0;
|
|
@@ -466,6 +518,7 @@ static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
|
|
buf += inptr;
|
|
buf += inptr;
|
|
len -= inptr;
|
|
len -= inptr;
|
|
}
|
|
}
|
|
|
|
+ dir_utime();
|
|
kfree(window);
|
|
kfree(window);
|
|
kfree(name_buf);
|
|
kfree(name_buf);
|
|
kfree(symlink_buf);
|
|
kfree(symlink_buf);
|