1 /* copycore.hh
2  * This file belongs to Worker, a file manager for UN*X/X11.
3  * Copyright (C) 2013-2017 Ralf Hoffmann.
4  * You can contact me at: ralf@boomerangsworld.de
5  *   or http://www.boomerangsworld.de/worker
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21 
22 #ifndef COPYCORE_HH
23 #define COPYCORE_HH
24 
25 #include "wdefines.h"
26 #include <list>
27 #include <functional>
28 #include <string>
29 #include "fileentry.hh"
30 #include <thread>
31 #include <atomic>
32 #include <mutex>
33 #include <condition_variable>
34 #include "nwc_os_makedirs.hh"
35 
36 class CopyOpWin;
37 struct copyorder;
38 class FileEntry;
39 class NM_CopyOp_Dir;
40 
41 class CopyCore
42 {
43 public:
44     CopyCore( std::shared_ptr< struct copyorder > co );
45     ~CopyCore();
46 
47     int deleteCopiedButNotMoved( std::function< void( const std::pair< std::string, bool > & ) > processed_callback );
48 
49     void setCancel( bool nv );
50     bool getCancel() const;
51 
52     void registerFEToCopy( const FileEntry &fe,
53                            int row,
54                            const std::vector< NWC::OS::deep_dir_info > &file_base_segments );
55 
56     int buildCopyDatabase();
57 
58     int executeCopy();
59 
60     typedef enum { NM_COPY_OK,
61                    NM_COPY_SKIP,
62                    NM_COPY_CANCEL,
63                    NM_COPY_NEED_DELETE } nm_copy_t;
64 
65     void setPreCopyCallback( std::function< void( loff_t size, int row, bool is_dir ) > cb );
66     void setPostCopyCallback( std::function< void( const std::string &source_fullname, int row,
67                                                    nm_copy_t res,
68                                                    bool is_dir, unsigned long dir_error_counter,
69                                                    const std::string &target_fullname ) > cb );
70 
71     loff_t getBytesToCopy() const;
72 
73     std::shared_ptr< struct copyorder > getCopyOrder();
74 
75     bool finished();
76 
77     void join();
78 
79     void setAskToCancel();
80 
81     bool timed_wait_for_finished();
82 private:
83     typedef enum { REG_COPY_OK, REG_COPY_SKIP, REG_COPY_CANCEL, REG_COPY_ERROR } reg_copy_erg_t;
84 
85     typedef enum { NM_NEWNAME_OK,
86                    NM_NEWNAME_SKIP,
87                    NM_NEWNAME_CANCEL,
88                    NM_NEWNAME_OVERWRITE,
89                    NM_NEWNAME_USE } nm_newname_t;
90 
91     nm_newname_t getNewName4File( const FileEntry *oldfe, const char *dest,
92                                   char **newname_return, bool acceptrename );
93     nm_newname_t getNewName4Dir( const FileEntry *oldfe, const char *dest,
94                                  char **newname_return, bool acceptrename );
95     nm_copy_t copydir( const FileEntry *fe,
96                        NM_CopyOp_Dir *cod,
97                        bool acceptrename,
98                        const char *destdir,
99                        std::string *effective_target_fullname);
100     nm_copy_t copyfile( const FileEntry *fe,
101                         bool acceptrename,
102                         const char *destdir,
103                         std::string *effective_target_fullname );
104 
105     reg_copy_erg_t copyfile_reg( const char *sourcename,
106                                  const char *destname,
107                                  const char *destdirname,
108                                  const char *destbasename,
109                                  mode_t create_mode,
110                                  CopyOpWin *cowin,
111                                  loff_t bytesToCopy );
112 
113     int tryApplyOwnerPerm( const char *filename,
114                            const uid_t wanted_user,
115                            const gid_t wanted_group,
116                            const mode_t wanted_mode );
117 
118     void pushForPostDelete( const FileEntry *fe );
119 
120     int executeCopyThread();
121 
122     void checkAskToCancel();
123 
124     void setFinished();
125 
126 #define BUFSIZE 128*1024
127     void *buf;
128 
129     std::shared_ptr< struct copyorder > m_copyorder;
130 
131     std::atomic< bool > m_cancel;
132 
133     std::list< std::pair< std::string, bool > > m_copy_deletefe_list;
134 
135     class copy_base_entry {
136     public:
137         copy_base_entry( const FileEntry &tfe, int row,
138                          const std::vector< NWC::OS::deep_dir_info > &file_base_segments );
139         ~copy_base_entry();
entry() const140         const FileEntry &entry() const
141         {
142             return m_fe;
143         }
144 
get_file_base_segments()145         std::vector< NWC::OS::deep_dir_info > &get_file_base_segments()
146         {
147             return m_file_base_segments;
148         }
149 
150         int m_row;  // corresponding row or -1
151         NM_CopyOp_Dir *m_cod; // when fe is dir, this will be the corresponding structure
152     private:
153         FileEntry m_fe;  // element to copy
154         std::vector< NWC::OS::deep_dir_info > m_file_base_segments;
155     };
156 
157     int prepare_destination_dir( copy_base_entry &cbe,
158                                  std::string &destdir,
159                                  bool post_run );
160 
161     std::list< copy_base_entry > m_copy_list;
162 
163     std::function< void( loff_t size, int row, bool is_dir ) > m_pre_cb;
164     std::function< void( const std::string &source_fullname, int row,
165                          nm_copy_t res,
166                          bool is_dir, unsigned long dir_error_counter,
167                          const std::string &target_fullname ) > m_post_cb;
168 
169     loff_t m_bytes_to_copy;
170 
171     std::mutex m_finished_mutex;
172     std::condition_variable m_finished_cond;
173     std::atomic< bool> m_finished;
174 
175     std::atomic< bool> m_ask_to_cancel;
176 
177     std::thread m_copy_thread;
178 };
179 
180 #endif
181