diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-06-14 04:28:41 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-06-14 04:28:41 +0000 |
commit | a1767a1f5d744804958b2ef0516cbd5d33292c0c (patch) | |
tree | 9f8d284587e8270cf6be2b1f7f5033f1f21c884d /coreutils/dos2unix.c | |
parent | 21765fa063830923d13426ec6989c16da9210e49 (diff) | |
download | busybox-w32-a1767a1f5d744804958b2ef0516cbd5d33292c0c.tar.gz busybox-w32-a1767a1f5d744804958b2ef0516cbd5d33292c0c.tar.bz2 busybox-w32-a1767a1f5d744804958b2ef0516cbd5d33292c0c.zip |
dos2unix: do not destroy symlinks and mode of the file being converted.
Diffstat (limited to 'coreutils/dos2unix.c')
-rw-r--r-- | coreutils/dos2unix.c | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/coreutils/dos2unix.c b/coreutils/dos2unix.c index 2db7e11a1..311dc1380 100644 --- a/coreutils/dos2unix.c +++ b/coreutils/dos2unix.c | |||
@@ -24,24 +24,27 @@ static void convert(char *fn, int conv_type) | |||
24 | { | 24 | { |
25 | FILE *in, *out; | 25 | FILE *in, *out; |
26 | int i; | 26 | int i; |
27 | char *name_buf = name_buf; /* for compiler */ | 27 | char *temp_fn = temp_fn; /* for compiler */ |
28 | char *resolved_fn = resolved_fn; | ||
28 | 29 | ||
29 | in = stdin; | 30 | in = stdin; |
30 | out = stdout; | 31 | out = stdout; |
31 | if (fn != NULL) { | 32 | if (fn != NULL) { |
32 | in = xfopen(fn, "r"); | 33 | struct stat st; |
33 | /* | 34 | |
34 | The file is then created with mode read/write and | 35 | resolved_fn = xmalloc_follow_symlinks(fn); |
35 | permissions 0666 for glibc 2.0.6 and earlier or | 36 | if (resolved_fn == NULL) |
36 | 0600 for glibc 2.0.7 and later. | 37 | bb_simple_perror_msg_and_die(fn); |
37 | */ | 38 | in = xfopen(resolved_fn, "r"); |
38 | name_buf = xasprintf("%sXXXXXX", fn); | 39 | fstat(fileno(in), &st); |
39 | i = mkstemp(name_buf); | 40 | |
41 | temp_fn = xasprintf("%sXXXXXX", resolved_fn); | ||
42 | i = mkstemp(temp_fn); | ||
40 | if (i == -1 | 43 | if (i == -1 |
41 | || fchmod(i, 0600) == -1 | 44 | || fchmod(i, st.st_mode) == -1 |
42 | || !(out = fdopen(i, "w+")) | 45 | || !(out = fdopen(i, "w+")) |
43 | ) { | 46 | ) { |
44 | bb_perror_nomsg_and_die(); | 47 | bb_simple_perror_msg_and_die(temp_fn); |
45 | } | 48 | } |
46 | } | 49 | } |
47 | 50 | ||
@@ -56,12 +59,12 @@ static void convert(char *fn, int conv_type) | |||
56 | 59 | ||
57 | if (fn != NULL) { | 60 | if (fn != NULL) { |
58 | if (fclose(in) < 0 || fclose(out) < 0) { | 61 | if (fclose(in) < 0 || fclose(out) < 0) { |
59 | unlink(name_buf); | 62 | unlink(temp_fn); |
60 | bb_perror_nomsg_and_die(); | 63 | bb_perror_nomsg_and_die(); |
61 | } | 64 | } |
62 | // TODO: destroys symlinks. See how passwd handles this | 65 | xrename(temp_fn, resolved_fn); |
63 | xrename(name_buf, fn); | 66 | free(temp_fn); |
64 | free(name_buf); | 67 | free(resolved_fn); |
65 | } | 68 | } |
66 | } | 69 | } |
67 | 70 | ||