[hackers] [sbase] cp: improvements || Hiltjo Posthuma

From: <git_AT_suckless.org>
Date: Mon, 21 Jul 2014 17:44:32 +0200

commit 323c45edb7a553e473730dbbcf238a5ad9a8fbb5
Author: Hiltjo Posthuma <hiltjo_AT_codemadness.org>
Date: Mon Jul 21 16:27:20 2014 +0000

    cp: improvements
    
    - improve copying block, char devices, fifo and sockets with -a.
    - improve exit status code.

diff --git a/cp.c b/cp.c
index 62f4593..0a11bfe 100644
--- a/cp.c
+++ b/cp.c
_AT_@ -49,5 +49,5 @@ main(int argc, char *argv[])
         if(argc > 2 && !(stat(argv[argc-1], &st) == 0 && S_ISDIR(st.st_mode)))
                 eprintf("%s: not a directory
", argv[argc-1]);
         enmasse(argc, argv, cp);
- return EXIT_SUCCESS;
+ return cp_status;
 }
diff --git a/fs.h b/fs.h
index cb66856..2ac9574 100644
--- a/fs.h
+++ b/fs.h
_AT_@ -7,6 +7,7 @@ extern bool cp_fflag;
 extern bool cp_pflag;
 extern bool cp_rflag;
 extern bool cp_vflag;
+extern int cp_status;
 
 extern bool rm_fflag;
 extern bool rm_rflag;
diff --git a/util/cp.c b/util/cp.c
index c50a81c..eace1e7 100644
--- a/util/cp.c
+++ b/util/cp.c
_AT_@ -1,14 +1,15 @@
 /* See LICENSE file for copyright and license details. */
 #include <dirent.h>
 #include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <unistd.h>
 #include <sys/stat.h>
 #include <sys/types.h>
-#include <limits.h>
+#include <unistd.h>
 #include <utime.h>
 
 #include "../fs.h"
_AT_@ -21,6 +22,7 @@ bool cp_fflag = false;
 bool cp_pflag = false;
 bool cp_rflag = false;
 bool cp_vflag = false;
+int cp_status = EXIT_SUCCESS;
 
 int
 cp(const char *s1, const char *s2)
_AT_@ -35,27 +37,26 @@ cp(const char *s1, const char *s2)
         DIR *dp;
         int r;
 
+ if(cp_vflag)
+ printf("'%s' -> '%s'
", s1, s2);
+
         if(cp_dflag == true)
                 r = lstat(s1, &st);
         else
                 r = stat(s1, &st);
 
- if(cp_vflag)
- printf("'%s' -> '%s'
", s1, s2);
-
         if(r == 0) {
                 if(cp_dflag == true && S_ISLNK(st.st_mode)) {
- if(cp_fflag == true)
- remove(s2);
- if(readlink(s1, buf, sizeof(buf) - 1) >= 0)
- symlink(buf, s2);
-
- /* preserve owner ? */
- if(cp_aflag == true || cp_pflag == true) {
- if(lchown(s2, st.st_uid, st.st_gid) == -1)
- weprintf("cp: can't preserve ownership of '%s':", s2);
+ if(readlink(s1, buf, sizeof(buf) - 1) >= 0) {
+ if(cp_fflag == true);
+ unlink(s2);
+ if(symlink(buf, s2) != 0) {
+ weprintf("%s: can't create '%s'
", argv0, s2);
+ cp_status = EXIT_FAILURE;
+ return 0;
+ }
                         }
- return 0;
+ goto preserve;
                 }
                 if(S_ISDIR(st.st_mode)) {
                         if (!cp_rflag)
_AT_@ -70,8 +71,7 @@ cp(const char *s1, const char *s2)
                         apathmax(&ns1, &size1);
                         apathmax(&ns2, &size2);
                         while((d = readdir(dp))) {
- if(strcmp(d->d_name, ".")
- && strcmp(d->d_name, "..")) {
+ if(strcmp(d->d_name, ".") && strcmp(d->d_name, "..")) {
                                         r = snprintf(ns1, size1, "%s/%s", s1, d->d_name);
                                         if(r >= size1 || r < 0) {
                                                 eprintf("%s/%s: filename too long
",
_AT_@ -85,26 +85,38 @@ cp(const char *s1, const char *s2)
                                         fnck(ns1, ns2, cp);
                                 }
                         }
-
                         closedir(dp);
                         free(ns1);
                         free(ns2);
                         goto preserve;
                 }
         }
+
+ if(cp_aflag == true) {
+ if(S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode) ||
+ S_ISSOCK(st.st_mode) || S_ISFIFO(st.st_mode)) {
+ unlink(s2);
+ if(mknod(s2, st.st_mode, st.st_rdev) < 0) {
+ weprintf("%s: can't create '%s':", argv0, s2);
+ cp_status = EXIT_FAILURE;
+ return 0;
+ }
+ goto preserve;
+ }
+ }
+
         if(!(f1 = fopen(s1, "r")))
                 eprintf("fopen %s:", s1);
 
         if(!(f2 = fopen(s2, "w"))) {
                 if (cp_fflag == true) {
                         unlink(s2);
- if (!(f2 = fopen(s2, "w")))
+ if(!(f2 = fopen(s2, "w")))
                                 eprintf("fopen %s:", s2);
                 } else {
                         eprintf("fopen %s:", s2);
                 }
         }
-
         concat(f1, s1, f2, s2);
         fchmod(fileno(f2), st.st_mode);
         fclose(f2);
_AT_@ -112,15 +124,21 @@ cp(const char *s1, const char *s2)
 
 preserve:
         if(cp_aflag == true || cp_pflag == true) {
- /* timestamp */
- ut.actime = st.st_atime;
- ut.modtime = st.st_mtime;
- utime(s2, &ut);
-
+ if(!(S_ISLNK(st.st_mode))) {
+ /* timestamp */
+ ut.actime = st.st_atime;
+ ut.modtime = st.st_mtime;
+ utime(s2, &ut);
+ }
                 /* preserve owner ? */
- if(chown(s2, st.st_uid, st.st_gid) == -1)
+ if(S_ISLNK(st.st_mode))
+ r = lchown(s2, st.st_uid, st.st_gid);
+ else
+ r = chown(s2, st.st_uid, st.st_gid);
+ if(r == -1) {
                         weprintf("cp: can't preserve ownership of '%s':", s2);
+ cp_status = EXIT_FAILURE;
+ }
         }
-
         return 0;
 }
Received on Mon Jul 21 2014 - 17:44:32 CEST

This archive was generated by hypermail 2.3.0 : Mon Jul 21 2014 - 17:48:23 CEST