dos2unix: do not destroy symlinks and mode of the file being converted.
authorDenis Vlasenko <vda.linux@googlemail.com>
Sat, 14 Jun 2008 04:28:41 +0000 (04:28 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Sat, 14 Jun 2008 04:28:41 +0000 (04:28 -0000)
coreutils/dos2unix.c
libbb/xreadlink.c

index 2db7e11a17f7fb9eb375b0a4268d50e01d610f48..311dc13808c5da9e3f4d0466745127e5367e9986 100644 (file)
@@ -24,24 +24,27 @@ static void convert(char *fn, int conv_type)
 {
        FILE *in, *out;
        int i;
-       char *name_buf = name_buf; /* for compiler */
+       char *temp_fn = temp_fn; /* for compiler */
+       char *resolved_fn = resolved_fn;
 
        in = stdin;
        out = stdout;
        if (fn != NULL) {
-               in = xfopen(fn, "r");
-               /*
-                  The file is then created with mode read/write and
-                  permissions 0666 for glibc 2.0.6 and earlier or
-                  0600 for glibc 2.0.7 and later.
-                */
-               name_buf = xasprintf("%sXXXXXX", fn);
-               i = mkstemp(name_buf);
+               struct stat st;
+
+               resolved_fn = xmalloc_follow_symlinks(fn);
+               if (resolved_fn == NULL)
+                       bb_simple_perror_msg_and_die(fn);
+               in = xfopen(resolved_fn, "r");
+               fstat(fileno(in), &st);
+
+               temp_fn = xasprintf("%sXXXXXX", resolved_fn);
+               i = mkstemp(temp_fn);
                if (i == -1
-                || fchmod(i, 0600) == -1
+                || fchmod(i, st.st_mode) == -1
                 || !(out = fdopen(i, "w+"))
                ) {
-                       bb_perror_nomsg_and_die();
+                       bb_simple_perror_msg_and_die(temp_fn);
                }
        }
 
@@ -56,12 +59,12 @@ static void convert(char *fn, int conv_type)
 
        if (fn != NULL) {
                if (fclose(in) < 0 || fclose(out) < 0) {
-                       unlink(name_buf);
+                       unlink(temp_fn);
                        bb_perror_nomsg_and_die();
                }
-// TODO: destroys symlinks. See how passwd handles this
-               xrename(name_buf, fn);
-               free(name_buf);
+               xrename(temp_fn, resolved_fn);
+               free(temp_fn);
+               free(resolved_fn);
        }
 }
 
index 706a3d9fff98f5ac5ecc31f6108551646ae4e2cb..0b961b6f90765895f927bd85ea8bf11667727006 100644 (file)
@@ -54,7 +54,6 @@ char *xmalloc_follow_symlinks(const char *path)
        goto jump_in;
 
        while (1) {
-
                linkpath = xmalloc_readlink(buf);
                if (!linkpath) {
                        /* not a symlink, or doesn't exist */