This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch master
in repository efm2.

View the commit online.

commit 575fbfa026df5575e0d68132c3f92450c49c7bdf
Author: Carsten Haitzler (Rasterman) <ras...@rasterman.com>
AuthorDate: Mon Apr 29 19:14:25 2024 +0100

    move fs working code into fs.c and make it also do rm and cp
---
 src/backends/default/{mv.c => fs.c} | 379 +++++++++++++-----------------
 src/backends/default/fs.h           |  10 +
 src/backends/default/meson.build    |   1 +
 src/backends/default/mv.c           | 447 +-----------------------------------
 4 files changed, 175 insertions(+), 662 deletions(-)

diff --git a/src/backends/default/mv.c b/src/backends/default/fs.c
similarity index 57%
copy from src/backends/default/mv.c
copy to src/backends/default/fs.c
index 740357e..593fef3 100644
--- a/src/backends/default/mv.c
+++ b/src/backends/default/fs.c
@@ -1,16 +1,10 @@
 // for copy_file_range()
-#include <asm-generic/errno-base.h>
 #define _GNU_SOURCE
 #define _FILE_OFFSET_BITS 64
 
 #include <Eina.h>
-#include <Ecore.h>
 #include <Ecore_File.h>
-#include <Efreet.h>
-#include <Efreet_Mime.h>
-#include <Eet.h>
 
-#include <asm-generic/errno.h>
 #include <errno.h>
 #include <sys/types.h>
 #include <pwd.h>
@@ -18,10 +12,8 @@
 #include <unistd.h>
 #include <fcntl.h>
 
-#include "meta.h"
 #include "status.h"
-
-static const char *config_dir = NULL;
+#include "fs.h"
 
 // generic error handler. special case handling all errnos for everything is
 // pretty insane - so handle non-errors in switches and otherwise pass to
@@ -107,7 +99,7 @@ _error_handle(const char *src, const char *dst, int errno_in)
 // not be 100% right as the fs can change while the scan happens and after
 // so any move that devolves into a cp + rm isn't going to be atomic and
 // handle a changing fs while it works anyway
-static Eina_Bool
+Eina_Bool
 fs_scan(const char *src)
 {
   Eina_Bool      res = EINA_TRUE;
@@ -150,14 +142,14 @@ fs_scan(const char *src)
       // or a char or block device etc.
       status_count(1, ecore_file_file_get(src));
       // in addition each byte in the file count as a progress item too
-      if (st.st_size > 0)
-        status_count(st.st_size, ecore_file_file_get(src));
+      if (st.st_size > 0) status_count(st.st_size, ecore_file_file_get(src));
     }
   return res;
 }
 
-static Eina_Bool
-fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err)
+Eina_Bool
+fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err, Eina_Bool cp,
+         Eina_Bool rm)
 { // cp_rm /path/to/src/filename /path/to/dst/filename
   // XXX: ecore_file_mv() ? <- look at it
   // XXX: utime()/utimes() -> utimensat()
@@ -196,7 +188,7 @@ fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err)
   //   fs_chmod(src_meta, dst_meta)
   //   fs_chown(src_meta, dst_meta)
   //   fs_rm(src_meta)
-  Eina_Bool res = EINA_TRUE;
+  Eina_Bool      res = EINA_TRUE;
   Eina_Iterator *it;
   const char    *s;
   struct stat    st;
@@ -225,16 +217,19 @@ fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err)
   old_umask = umask(0);
   if (S_ISDIR(st.st_mode))
     { // it's a dir - scan this recursively
-      if (mkdir(dst, st.st_mode) != 0)
+      if (cp)
         {
-          switch (errno)
+          if (mkdir(dst, st.st_mode) != 0)
             {
-            case EEXIST: // ignore - mv would mv over this anyway
-              break;
-            default: // WAT
-              _error_handle(NULL, dst, errno);
-              res = EINA_FALSE;
-              goto err;
+              switch (errno)
+                {
+                case EEXIST: // ignore - mv would mv over this anyway
+                  break;
+                default: // WAT
+                  _error_handle(NULL, dst, errno);
+                  res = EINA_FALSE;
+                  goto err;
+                }
             }
         }
       it = eina_file_ls(src);
@@ -243,7 +238,7 @@ fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err)
           EINA_ITERATOR_FOREACH(it, s)
           {
             Eina_Strbuf *buf = eina_strbuf_new();
-            const char *fs = ecore_file_file_get(s);
+            const char  *fs  = ecore_file_file_get(s);
 
             if (buf)
               {
@@ -252,7 +247,8 @@ fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err)
                     eina_strbuf_append(buf, dst);
                     eina_strbuf_append(buf, "/");
                     eina_strbuf_append(buf, fs);
-                    if (!fs_cp_rm(s, eina_strbuf_string_get(buf), report_err))
+                    if (!fs_cp_rm(s, eina_strbuf_string_get(buf), report_err,
+                                  cp, rm))
                       res = EINA_FALSE;
                   }
                 eina_strbuf_free(buf);
@@ -261,149 +257,194 @@ fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err)
           }
           eina_iterator_free(it);
         }
-      if (res) rmdir(src);
+      if ((rm) && (res))
+        {
+          if (rmdir(src) != 0)
+            {
+              switch (errno)
+                {
+                case ENOENT: // ignore missing
+                  break;
+                default:
+                  _error_handle(src, NULL, errno);
+                  res = EINA_FALSE;
+                  goto err;
+                }
+            }
+        }
     }
   else if (S_ISLNK(st.st_mode))
     {
-      char link[PATH_MAX];
-      ssize_t lnsz;
+      if (cp)
+        {
+          char    link[PATH_MAX];
+          ssize_t lnsz;
 
-      lnsz = readlink(src, link, sizeof(link));
-      if ((lnsz > 0) && (lnsz < (ssize_t)sizeof(link)))
-        {
-          if (symlink(link, dst) < 0)
-            { // XXX: soft error? e.g. mv on FAT fs?
-              status_pos(1, "Move - Error creating symlink");
-            }
-        }
-      else if (lnsz < 0)
-        { // XXX: handle read link err
-          switch (errno)
+          lnsz = readlink(src, link, sizeof(link));
+          if ((lnsz > 0) && (lnsz < (ssize_t)sizeof(link)))
             {
-            case ENOENT: // ignore this error - file removed during scan ?
-              status_pos(1, "Move - File vanished");
-              break;
-            default:
-              _error_handle(src, dst, errno);
-              return EINA_FALSE;
+              if (symlink(link, dst) < 0)
+                { // XXX: soft error? e.g. mv on FAT fs?
+                  status_pos(1, "Move - Error creating symlink");
+                }
+            }
+          else if (lnsz < 0)
+            { // XXX: handle read link err
+              switch (errno)
+                {
+                case ENOENT: // ignore this error - file removed during scan ?
+                  status_pos(1, "Move - File vanished");
+                  break;
+                default:
+                  _error_handle(src, dst, errno);
+                  return EINA_FALSE;
+                }
+            }
+          else // 0 sized symlink ... WAT?
+            {  // XXX: handle this
             }
-        }
-      else // 0 sized symlink ... WAT?
-        {
         }
     }
   else if (S_ISFIFO(st.st_mode))
     {
-      if (mkfifo(dst, st.st_mode) < 0)
-        { // XXX: soft error? ignore?
+      if (cp)
+        {
+          if (mkfifo(dst, st.st_mode) < 0)
+            { // XXX: soft error? ignore?
+            }
         }
     }
   else if (S_ISSOCK(st.st_mode))
     {
-      // we can't just make sockets - so ignore but have this here to document
+      if (cp)
+        {
+          // we can't just make sockets - so ignore but document here
+        }
     }
   else if ((S_ISCHR(st.st_mode)) || (S_ISBLK(st.st_mode)))
     {
-      if (mknod(dst, st.st_mode, st.st_dev) < 0)
-        { // XXX: soft error? ignore?
+      if (cp)
+        {
+          if (mknod(dst, st.st_mode, st.st_dev) < 0)
+            { // XXX: soft error? ignore?
+            }
         }
     }
   else
     {
-      int fd_in, fd_ou;
-      void *old_copy_buf = NULL;
-
-      fd_in = open(src, O_RDONLY);
-      fd_ou = open(dst, O_WRONLY | O_CREAT, st.st_mode);
-      if ((fd_in >= 0) && (fd_ou >= 0))
+      if (cp)
         {
-          ssize_t    size = 1 * 1024 * 1024; // 1mb default
-          ssize_t    ret, ret2;
-          off_t      off_in = 0, off_ou = 0;
-          Eina_Bool  old_copy = EINA_FALSE;
+          int   fd_in, fd_ou;
+          void *old_copy_buf = NULL;
 
-          for (;;)
+          fd_in = open(src, O_RDONLY);
+          fd_ou = open(dst, O_WRONLY | O_CREAT, st.st_mode);
+          if ((fd_in >= 0) && (fd_ou >= 0))
             {
-              if (old_copy)
+              ssize_t   size = 1 * 1024 * 1024; // 1mb default
+              ssize_t   ret, ret2;
+              off_t     off_in = 0, off_ou = 0;
+              Eina_Bool old_copy = EINA_FALSE;
+
+              for (;;)
                 {
-                  if (!old_copy_buf)
+                  if (old_copy)
                     {
-                      size = 256 * 1024; // drop to 256k buffer
-                      old_copy_buf = malloc(size);
                       if (!old_copy_buf)
                         {
-                          res = EINA_FALSE;
-                          goto err_copy;
+                          size         = 256 * 1024; // drop to 256k buffer
+                          old_copy_buf = malloc(size);
+                          if (!old_copy_buf)
+                            {
+                              res = EINA_FALSE;
+                              goto err_copy;
+                            }
                         }
-                    }
 again_read:
-                  ret = read(fd_in, old_copy_buf, size);
-                  if (ret < 0)
-                    {
-                      switch (errno)
-                        {
-                        case EAGAIN:
-                        case EINTR:
-                          goto again_read;
-                        default:
-                          _error_handle(src, NULL, errno);
-                          res = EINA_FALSE;
-                          goto err_copy;
-                        }
-                    }
-                  else
-                    {
-                      off_in += ret;
-again_write:
-                      ret2 = write(fd_ou, old_copy_buf, ret);
-                      if (ret2 < 0)
+                      ret = read(fd_in, old_copy_buf, size);
+                      if (ret < 0)
                         {
                           switch (errno)
                             {
                             case EAGAIN:
                             case EINTR:
-                              goto again_write;
+                              goto again_read;
                             default:
-                              _error_handle(NULL, dst, errno);
+                              _error_handle(src, NULL, errno);
                               res = EINA_FALSE;
                               goto err_copy;
                             }
                         }
-                      else if (ret2 == ret)
+                      else
                         {
-                          off_ou += ret;
-                          if (ret < size) break; // end of file
+                          off_in += ret;
+again_write:
+                          ret2 = write(fd_ou, old_copy_buf, ret);
+                          if (ret2 < 0)
+                            {
+                              switch (errno)
+                                {
+                                case EAGAIN:
+                                case EINTR:
+                                  goto again_write;
+                                default:
+                                  _error_handle(NULL, dst, errno);
+                                  res = EINA_FALSE;
+                                  goto err_copy;
+                                }
+                            }
+                          else if (ret2 == ret)
+                            {
+                              off_ou += ret;
+                              if (ret < size) break; // end of file
+                            }
                         }
                     }
-                }
-              else
-                {
-                  ret = copy_file_range(fd_in, &off_in, fd_ou, &off_ou, size, 0);
-                  if (ret < 0)
+                  else
                     {
-                     switch (errno)
-                       {
-                        case EOPNOTSUPP:
-                        case EXDEV:
-                          old_copy = EINA_TRUE;
-                          break;
-                        case EBADF:
-                        default: // WAT
-                          _error_handle(src, dst, errno);
-                          res = EINA_FALSE;
-                          goto err_copy;
-                       }
+                      ret = copy_file_range(fd_in, &off_in, fd_ou, &off_ou,
+                                            size, 0);
+                      if (ret < 0)
+                        {
+                          switch (errno)
+                            {
+                            case EOPNOTSUPP:
+                            case EXDEV:
+                              old_copy = EINA_TRUE;
+                              break;
+                            case EBADF:
+                            default: // WAT
+                              _error_handle(src, dst, errno);
+                              res = EINA_FALSE;
+                              goto err_copy;
+                            }
+                        }
+                      else if (ret < size) break; // end of file
                     }
-                  else if (ret < size) break; // end of file
+                }
+            }
+err_copy:
+          if (old_copy_buf) free(old_copy_buf);
+          if (fd_in >= 0) close(fd_in);
+          if (fd_ou >= 0) close(fd_ou);
+        }
+      if ((rm) && (res))
+        {
+          if (unlink(src) != 0)
+            {
+              switch (errno)
+                {
+                case ENOENT: // ignore missing
+                  break;
+                default:
+                  _error_handle(src, NULL, errno);
+                  res = EINA_FALSE;
+                  goto err_unlink;
                 }
             }
         }
-err_copy:
-      if (old_copy_buf) free(old_copy_buf);
-      if (fd_in >= 0) close(fd_in);
-      if (fd_ou >= 0) close(fd_ou);
-      if (res) unlink(src);
     }
+err_unlink:
   chown(dst, st.st_uid, st.st_gid);
 #ifdef STAT_NSEC
 #ifdef st_mtime
@@ -435,11 +476,11 @@ err:
   return res;
 }
 
-static Eina_Bool
+Eina_Bool
 fs_mv(const char *src, const char *dst, Eina_Bool report_err)
 { // mv /path/to/src/filename /path/to/dst/filename
   Eina_Bool res = EINA_TRUE;
-  int ret;
+  int       ret;
 
   status_op("mv");
   status_count(1, src);
@@ -450,7 +491,7 @@ fs_mv(const char *src, const char *dst, Eina_Bool report_err)
       switch (errno)
         {
         case EXDEV: // revert to cp + rm
-          return fs_cp_rm(src, dst, report_err);
+          return fs_cp_rm(src, dst, report_err, EINA_TRUE, EINA_TRUE);
           break;
         default:
           if (report_err) _error_handle(src, dst, errno);
@@ -461,97 +502,3 @@ fs_mv(const char *src, const char *dst, Eina_Bool report_err)
   status_pos(1, src);
   return res;
 }
-
-int
-main(int argc, char **argv)
-{ // mv [src] [dst]
-  const char *src, *dst, *fname, *home_dir;
-  Eina_Strbuf *buf = NULL;
-
-  if (argc < 3) return -1;
-  src = ""
-  dst = argv[2];
-  eina_init();
-  eet_init();
-  ecore_init();
-  efreet_init();
-
-  fprintf(stderr, "MV: [%s] -> [%s]\n", src, dst);
-  fflush(stderr);
-
-  config_dir = getenv("E_HOME_DIR");
-  home_dir   = getenv("HOME");
-  if (!home_dir) return 77; // no $HOME? definitely an error!
-  if (!config_dir)
-    {
-      char sbuf[PATH_MAX];
-
-      snprintf(sbuf, sizeof(sbuf), "%s/.e/e", home_dir);
-      config_dir = eina_stringshare_add(sbuf);
-    }
-  meta_init(config_dir);
-
-  // src = ""
-  // dst = DDIR/
-  //
-  // mv          SDIR/SFILE DDIR/SFILE
-  // if errno == EXDEV
-  //   cp        SDIR/SFILE DDIR/SFILE
-  //   rm        SDIR/SFILE
-  // else if errno == 0
-  //   if exists SDIR/.efm/SFILE.efm
-  //     mkdir   DDIR/.efm
-  //     mv      SDIR/.efm/SFILE.efm DDIR/.efm/SFILE.efm
-
-  fname = ecore_file_file_get(src);
-  if (!fname) goto err;
-  buf = eina_strbuf_new();
-  if (!buf) goto err;
-  eina_strbuf_append(buf, dst);
-  eina_strbuf_append(buf, "/");
-  eina_strbuf_append(buf, fname);
-  status_begin();
-  if (fs_mv(src, eina_strbuf_string_get(buf), EINA_TRUE))
-    {
-      Eina_Bool src_can_write, dst_can_write;
-      const char *dstfile;
-      char *src_meta, *dst_meta;
-
-      dstfile = eina_strbuf_string_get(buf);
-      
-      src_can_write = meta_path_can_write(src);
-      dst_can_write = meta_path_can_write(eina_strbuf_string_get(buf));
-
-      if (src_can_write) src_meta = meta_path_find(src, "meta.efm");
-      else src_meta = meta_path_user_find(src, "meta.efm");
-      if (dst_can_write) dst_meta = meta_path_find(dstfile, "meta.efm");
-      else dst_meta = meta_path_user_find(dstfile, "meta.efm");
-      if ((src_meta) && (dst_meta) && (meta_path_prepare(dstfile)))
-        fs_mv(src_meta, dst_meta, EINA_FALSE);
-      free(src_meta);
-      free(dst_meta);
-      if (src_can_write) src_meta = meta_path_find(src, "thumb.efm");
-      else src_meta = meta_path_user_find(src, "thumb.efm");
-      if (dst_can_write) dst_meta = meta_path_find(dstfile, "thumb.efm");
-      else dst_meta = meta_path_user_find(dstfile, "thumb.efm");
-      if ((src_meta) && (dst_meta) && (meta_path_prepare(dstfile)))
-        fs_mv(src_meta, dst_meta, EINA_FALSE);
-      free(src_meta);
-      free(dst_meta);
-    }
-  else
-    {
-      status_end();
-    }
-err:
-  if (buf) eina_strbuf_free(buf);
-  status_end();
-
-  meta_shutdown();
-
-  efreet_shutdown();
-  ecore_shutdown();
-  eet_shutdown();
-  eina_shutdown();
-  return 0;
-}
\ No newline at end of file
diff --git a/src/backends/default/fs.h b/src/backends/default/fs.h
new file mode 100644
index 0000000..cb50630
--- /dev/null
+++ b/src/backends/default/fs.h
@@ -0,0 +1,10 @@
+#ifndef FS_H
+#define FS_H
+#include <Eina.h>
+
+Eina_Bool fs_scan(const char *src);
+Eina_Bool fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err,
+                   Eina_Bool cp, Eina_Bool rm);
+Eina_Bool fs_mv(const char *src, const char *dst, Eina_Bool report_err);
+
+#endif
\ No newline at end of file
diff --git a/src/backends/default/meson.build b/src/backends/default/meson.build
index 4aba107..c464309 100644
--- a/src/backends/default/meson.build
+++ b/src/backends/default/meson.build
@@ -36,6 +36,7 @@ executable('thumb', [
   install_dir: dir)
 executable('mv', [
     '../../shared/sha.c',
+    'fs.c',
     'mv.c',
     'meta.c',
     'status.c'
diff --git a/src/backends/default/mv.c b/src/backends/default/mv.c
index 740357e..08004a3 100644
--- a/src/backends/default/mv.c
+++ b/src/backends/default/mv.c
@@ -1,8 +1,3 @@
-// for copy_file_range()
-#include <asm-generic/errno-base.h>
-#define _GNU_SOURCE
-#define _FILE_OFFSET_BITS 64
-
 #include <Eina.h>
 #include <Ecore.h>
 #include <Ecore_File.h>
@@ -10,8 +5,6 @@
 #include <Efreet_Mime.h>
 #include <Eet.h>
 
-#include <asm-generic/errno.h>
-#include <errno.h>
 #include <sys/types.h>
 #include <pwd.h>
 #include <grp.h>
@@ -20,448 +13,10 @@
 
 #include "meta.h"
 #include "status.h"
+#include "fs.h"
 
 static const char *config_dir = NULL;
 
-// generic error handler. special case handling all errnos for everything is
-// pretty insane - so handle non-errors in switches and otherwise pass to
-// this tio handle the reast in a generic way.
-static void
-_error_handle(const char *src, const char *dst, int errno_in)
-{
-  switch (errno_in)
-    {
-    case EACCES:
-      status_error(src, dst, "Move - Access denied");
-      return;
-    case EFAULT:
-      status_error(src, dst, "Move - Memory Fault");
-      return;
-    case ELOOP:
-      status_error(src, dst, "Move - Too many symlinks");
-      return;
-    case ENAMETOOLONG:
-      status_error(src, dst, "Move - Name too long");
-      return;
-    case ENOMEM:
-      status_error(src, dst, "Move - Out of memory");
-      return;
-    case ENOTDIR:
-      status_error(src, dst, "Move - Path component is not a directory");
-      return;
-    case EOVERFLOW:
-      status_error(src, dst, "Move - Overflow");
-      return;
-    case EDQUOT:
-      status_error(src, dst, "Move - Over quota");
-      return;
-    case EINVAL:
-      status_error(src, dst, "Move - Inmvalid value");
-      return;
-    case EMLINK:
-      status_error(src, dst, "Move - Too many source links");
-      return;
-    case ENOENT:
-      status_error(src, dst, "Move - File does not exist");
-      return;
-    case ENOSPC:
-      status_error(src, dst, "Move - Disk full");
-      return;
-    case EPERM:
-      status_error(src, dst, "Move - Permission denied");
-      return;
-    case EROFS:
-      status_error(src, dst, "Move - Read only filesystem");
-      return;
-    case EBADF:
-      status_error(src, dst, "Move - Bad file descriptor");
-      return;
-    case EIO:
-      status_error(src, dst, "Move - I/O error");
-      return;
-    case EISDIR:
-      status_error(src, dst, "Move - Destination is dir");
-      return;
-    case EFBIG:
-      status_error(src, dst, "Move - File too big");
-      return;
-    case ETXTBSY:
-      status_error(src, dst, "Move - Text file busy");
-      return;
-    case EBUSY:
-      status_error(src, dst, "Move - File busy");
-      return;
-    case ENOTEMPTY:
-      status_error(src, dst, "Move - Destination not empty");
-      return;
-    case EEXIST:
-      status_error(src, dst, "Move - File exists");
-      return;
-    default: // WAT? we should not get here - we handled everything...
-      status_error(src, dst, "Move - Unknown error");
-      break;
-    }
-}
-
-// this scans a tree to build a potential operation progress count. it may
-// not be 100% right as the fs can change while the scan happens and after
-// so any move that devolves into a cp + rm isn't going to be atomic and
-// handle a changing fs while it works anyway
-static Eina_Bool
-fs_scan(const char *src)
-{
-  Eina_Bool      res = EINA_TRUE;
-  Eina_Iterator *it;
-  const char    *s;
-  struct stat    st;
-
-  if (strlen(src) < 1) return EINA_FALSE;
-
-  if (lstat(src, &st) != 0)
-    {
-      switch (errno)
-        {
-        case ENOENT: // ignore this error - file removed during scan ?
-          return EINA_TRUE;
-        default:
-          _error_handle(src, NULL, errno);
-          return EINA_FALSE;
-        }
-    }
-  if (S_ISDIR(st.st_mode))
-    { // it's a dir - scan this recursively
-      it = eina_file_ls(src);
-      if (it)
-        {
-          EINA_ITERATOR_FOREACH(it, s)
-          {
-            if (res)
-              {
-                if (!fs_scan(s)) res = EINA_FALSE;
-              }
-            eina_stringshare_del(s);
-          }
-          eina_iterator_free(it);
-        }
-    }
-  else
-    {
-      // the file itself count as 1 progress item - useful if it's a symlink
-      // or a char or block device etc.
-      status_count(1, ecore_file_file_get(src));
-      // in addition each byte in the file count as a progress item too
-      if (st.st_size > 0)
-        status_count(st.st_size, ecore_file_file_get(src));
-    }
-  return res;
-}
-
-static Eina_Bool
-fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err)
-{ // cp_rm /path/to/src/filename /path/to/dst/filename
-  // XXX: ecore_file_mv() ? <- look at it
-  // XXX: utime()/utimes() -> utimensat()
-  //
-  // if src is dir
-  //   fs_mkdir(dst)
-  //   for all files in src
-  //     fs_cp_rm(src/file, dst/file, report_err)
-  //     fs_utimes(src, dst)
-  //     fs_chmod(src, dst)
-  //     fs_chown(src, dst)
-  //   fs_utimes(src, dst)
-  //   fs_chmod(src, dst)
-  //   fs_chown(src, dst)
-  //   fs_rmdir(src)
-  // else
-  //   if (src is file)
-  //     fs_cp(src, dst, report_err)
-  //     fs_cp_xattr(src, dst)
-  //   else if (src is symlink)
-  //     fs_ln(src, dst)
-  //   else if (src is fifo)
-  //     fs_mkfifo(dst)
-  //   else if (src is socket)
-  //     fs_touch(dst)
-  //   else if (src is chrdev)
-  //     fs_chrdevdup(src, dst)
-  //   else if (src is blkdev)
-  //     fs_blkdevdup(src, dst)
-  //   fs_utimes(src, dst)
-  //   fs_chmod(src, dst)
-  //   fs_chown(src, dst)
-  //   fs_rm(src)
-  //   fs_cp(src_meta, dst_meta)
-  //   fs_utimes(src_meta, dst_meta)
-  //   fs_chmod(src_meta, dst_meta)
-  //   fs_chown(src_meta, dst_meta)
-  //   fs_rm(src_meta)
-  Eina_Bool res = EINA_TRUE;
-  Eina_Iterator *it;
-  const char    *s;
-  struct stat    st;
-  mode_t         old_umask;
-  struct timeval times[2];
-
-  if (strlen(src) < 1) return EINA_FALSE;
-
-  // first count how much work needs doing
-  if (!fs_scan(src)) return EINA_FALSE;
-
-  fprintf(stderr, "cp_rm [%s] -> [%s]\n", src, dst);
-  fflush(stderr);
-  if (lstat(src, &st) != 0)
-    {
-      switch (errno)
-        {
-        case ENOENT: // ignore this error - file removed during scan ?
-          status_pos(1, "Move - File vanished");
-          break;
-        default:
-          _error_handle(src, dst, errno);
-          return EINA_FALSE;
-        }
-    }
-  old_umask = umask(0);
-  if (S_ISDIR(st.st_mode))
-    { // it's a dir - scan this recursively
-      if (mkdir(dst, st.st_mode) != 0)
-        {
-          switch (errno)
-            {
-            case EEXIST: // ignore - mv would mv over this anyway
-              break;
-            default: // WAT
-              _error_handle(NULL, dst, errno);
-              res = EINA_FALSE;
-              goto err;
-            }
-        }
-      it = eina_file_ls(src);
-      if (it)
-        {
-          EINA_ITERATOR_FOREACH(it, s)
-          {
-            Eina_Strbuf *buf = eina_strbuf_new();
-            const char *fs = ecore_file_file_get(s);
-
-            if (buf)
-              {
-                if ((res) && (fs))
-                  {
-                    eina_strbuf_append(buf, dst);
-                    eina_strbuf_append(buf, "/");
-                    eina_strbuf_append(buf, fs);
-                    if (!fs_cp_rm(s, eina_strbuf_string_get(buf), report_err))
-                      res = EINA_FALSE;
-                  }
-                eina_strbuf_free(buf);
-              }
-            eina_stringshare_del(s);
-          }
-          eina_iterator_free(it);
-        }
-      if (res) rmdir(src);
-    }
-  else if (S_ISLNK(st.st_mode))
-    {
-      char link[PATH_MAX];
-      ssize_t lnsz;
-
-      lnsz = readlink(src, link, sizeof(link));
-      if ((lnsz > 0) && (lnsz < (ssize_t)sizeof(link)))
-        {
-          if (symlink(link, dst) < 0)
-            { // XXX: soft error? e.g. mv on FAT fs?
-              status_pos(1, "Move - Error creating symlink");
-            }
-        }
-      else if (lnsz < 0)
-        { // XXX: handle read link err
-          switch (errno)
-            {
-            case ENOENT: // ignore this error - file removed during scan ?
-              status_pos(1, "Move - File vanished");
-              break;
-            default:
-              _error_handle(src, dst, errno);
-              return EINA_FALSE;
-            }
-        }
-      else // 0 sized symlink ... WAT?
-        {
-        }
-    }
-  else if (S_ISFIFO(st.st_mode))
-    {
-      if (mkfifo(dst, st.st_mode) < 0)
-        { // XXX: soft error? ignore?
-        }
-    }
-  else if (S_ISSOCK(st.st_mode))
-    {
-      // we can't just make sockets - so ignore but have this here to document
-    }
-  else if ((S_ISCHR(st.st_mode)) || (S_ISBLK(st.st_mode)))
-    {
-      if (mknod(dst, st.st_mode, st.st_dev) < 0)
-        { // XXX: soft error? ignore?
-        }
-    }
-  else
-    {
-      int fd_in, fd_ou;
-      void *old_copy_buf = NULL;
-
-      fd_in = open(src, O_RDONLY);
-      fd_ou = open(dst, O_WRONLY | O_CREAT, st.st_mode);
-      if ((fd_in >= 0) && (fd_ou >= 0))
-        {
-          ssize_t    size = 1 * 1024 * 1024; // 1mb default
-          ssize_t    ret, ret2;
-          off_t      off_in = 0, off_ou = 0;
-          Eina_Bool  old_copy = EINA_FALSE;
-
-          for (;;)
-            {
-              if (old_copy)
-                {
-                  if (!old_copy_buf)
-                    {
-                      size = 256 * 1024; // drop to 256k buffer
-                      old_copy_buf = malloc(size);
-                      if (!old_copy_buf)
-                        {
-                          res = EINA_FALSE;
-                          goto err_copy;
-                        }
-                    }
-again_read:
-                  ret = read(fd_in, old_copy_buf, size);
-                  if (ret < 0)
-                    {
-                      switch (errno)
-                        {
-                        case EAGAIN:
-                        case EINTR:
-                          goto again_read;
-                        default:
-                          _error_handle(src, NULL, errno);
-                          res = EINA_FALSE;
-                          goto err_copy;
-                        }
-                    }
-                  else
-                    {
-                      off_in += ret;
-again_write:
-                      ret2 = write(fd_ou, old_copy_buf, ret);
-                      if (ret2 < 0)
-                        {
-                          switch (errno)
-                            {
-                            case EAGAIN:
-                            case EINTR:
-                              goto again_write;
-                            default:
-                              _error_handle(NULL, dst, errno);
-                              res = EINA_FALSE;
-                              goto err_copy;
-                            }
-                        }
-                      else if (ret2 == ret)
-                        {
-                          off_ou += ret;
-                          if (ret < size) break; // end of file
-                        }
-                    }
-                }
-              else
-                {
-                  ret = copy_file_range(fd_in, &off_in, fd_ou, &off_ou, size, 0);
-                  if (ret < 0)
-                    {
-                     switch (errno)
-                       {
-                        case EOPNOTSUPP:
-                        case EXDEV:
-                          old_copy = EINA_TRUE;
-                          break;
-                        case EBADF:
-                        default: // WAT
-                          _error_handle(src, dst, errno);
-                          res = EINA_FALSE;
-                          goto err_copy;
-                       }
-                    }
-                  else if (ret < size) break; // end of file
-                }
-            }
-        }
-err_copy:
-      if (old_copy_buf) free(old_copy_buf);
-      if (fd_in >= 0) close(fd_in);
-      if (fd_ou >= 0) close(fd_ou);
-      if (res) unlink(src);
-    }
-  chown(dst, st.st_uid, st.st_gid);
-#ifdef STAT_NSEC
-#ifdef st_mtime
-#define STAT_NSEC_ATIME(st) (unsigned long long)((st)->st_atim.tv_nsec)
-#define STAT_NSEC_MTIME(st) (unsigned long long)((st)->st_mtim.tv_nsec)
-#define STAT_NSEC_CTIME(st) (unsigned long long)((st)->st_ctim.tv_nsec)
-#else
-#define STAT_NSEC_ATIME(st) (unsigned long long)((st)->st_atimensec)
-#define STAT_NSEC_MTIME(st) (unsigned long long)((st)->st_mtimensec)
-#define STAT_NSEC_CTIME(st) (unsigned long long)((st)->st_ctimensec)
-#endif
-#else
-#define STAT_NSEC_ATIME(st) (unsigned long long)(0)
-#define STAT_NSEC_MTIME(st) (unsigned long long)(0)
-#define STAT_NSEC_CTIME(st) (unsigned long long)(0)
-#endif
-  times[0].tv_sec  = st.st_atime;
-  times[0].tv_usec = STAT_NSEC_ATIME(st) * 1000;
-  times[1].tv_sec  = st.st_mtime;
-  times[1].tv_usec = STAT_NSEC_MTIME(st) * 1000;
-  utimes(dst, times);
-err:
-  umask(old_umask);
-  if (!res)
-    {
-      fprintf(stderr, "MV: ERROR!!!!!!!!!!!!!!!!!!!!!!!!!\n");
-      fflush(stderr);
-    }
-  return res;
-}
-
-static Eina_Bool
-fs_mv(const char *src, const char *dst, Eina_Bool report_err)
-{ // mv /path/to/src/filename /path/to/dst/filename
-  Eina_Bool res = EINA_TRUE;
-  int ret;
-
-  status_op("mv");
-  status_count(1, src);
-  ret = rename(src, dst);
-  if (ret == 0) return res;
-  else
-    {
-      switch (errno)
-        {
-        case EXDEV: // revert to cp + rm
-          return fs_cp_rm(src, dst, report_err);
-          break;
-        default:
-          if (report_err) _error_handle(src, dst, errno);
-          res = EINA_FALSE;
-          break;
-        }
-    }
-  status_pos(1, src);
-  return res;
-}
-
 int
 main(int argc, char **argv)
 { // mv [src] [dst]

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to