1 /* nmcopyopdir.cc
2 * This file belongs to Worker, a file manager for UN*X/X11.
3 * Copyright (C) 2001-2014 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 #include "nmcopyopdir.hh"
23 #include "copyopwin.hh"
24 #include "deleteop.h"
25 #include "simplelist.hh"
26 #include "verzeichnis.hh"
27 #include "fileentry.hh"
28 #include "copyorder.hh"
29 #include "deleteorder.hh"
30
NM_CopyOp_Dir(const FileEntry * fe)31 NM_CopyOp_Dir::NM_CopyOp_Dir(const FileEntry *fe)
32 {
33 int erg;
34
35 fileentry=fe;
36 subdirs=new List();
37 verz=new Verzeichnis();
38 files=dirs=error_counter=0;
39 bytes = 0;
40 ok=false;
41 user_abort = false;
42
43 erg = verz->readDir( fe->fullname );
44 if ( erg == 0 ) ok = true;
45 else if ( erg > 0 ) user_abort = true;
46 }
47
~NM_CopyOp_Dir()48 NM_CopyOp_Dir::~NM_CopyOp_Dir()
49 {
50 int id=subdirs->initEnum();
51 NM_CopyOp_Dir *cod=(NM_CopyOp_Dir*)subdirs->getFirstElement(id);
52 while(cod!=NULL) {
53 delete cod;
54 cod=(NM_CopyOp_Dir*)subdirs->getNextElement(id);
55 }
56 subdirs->closeEnum( id );
57 delete subdirs;
58 delete verz;
59 }
60
61 int
createSubDirs(std::shared_ptr<struct copyorder> co,unsigned long * gf,unsigned long * gd)62 NM_CopyOp_Dir::createSubDirs( std::shared_ptr< struct copyorder > co,unsigned long *gf,unsigned long *gd)
63 {
64 NM_CopyOp_Dir *cod1;
65 bool enter;
66 bool cancel=false;
67
68 /*TODO: vielleicht sollte der Fehler weitergereicht werden, aber cancel=true soll nicht entstehen
69 daher erstmal 0 zurueckgeben */
70 if(ok==false) return 0;
71
72 if ( verz->dirOpened() == false ) return 0;
73
74 /*TODO:Vorerst zu langsam, kann aber an MemSystem liegen, daher nochmal ohne
75 das pruefen
76 if(co->cowin!=NULL) {
77 co->cowin->setmessage(verz->getDir(),1);
78 if ( co->cowin->redraw() != 0 ) cancel = true;
79 }*/
80
81 for ( Verzeichnis::verz_it fe_it1 = verz->begin();
82 fe_it1 != verz->end() && cancel == false;
83 fe_it1++ ) {
84 FileEntry *fe = *fe_it1;
85 if(strcmp(fe->name,"..")!=0) {
86 enter=false;
87 if(fe->isDir()==true) {
88 // fe is a dir, check if it is a link and take it only when follow_symlinks==true
89 // entry is a dir so it cannot be a corrupt link so no need to check
90 if(fe->isLink==false) enter=true;
91 else if(co->follow_symlinks==true) enter=true;
92 }
93 if(enter==true) {
94 // fe is a dir so creating corresponding entry
95 cod1=new NM_CopyOp_Dir(fe);
96 if ( cod1->user_abort == false ) {
97 // recursive call
98 if(cod1->createSubDirs(co,gf,gd)!=0) cancel=true;
99 } else cancel = true;
100 // add the values from this subdir to this dir
101 files+=cod1->files;
102 dirs+=cod1->dirs;
103 bytes+=cod1->bytes;
104
105 // add this subdir to the list
106 subdirs->addElement(cod1);
107
108 // this is a dir so inc the counter
109 dirs++;
110 (*gd)++;
111
112 if(co->cowin!=NULL) {
113 co->cowin->set_files_to_copy(*gf);
114 co->cowin->set_dirs_to_copy(*gd);
115 if ( co->cowin->redraw() & 1 ) cancel = true;
116 }
117 } else {
118 // is not dir (mostly a file but can also be links ...)
119 files++;
120 (*gf)++;
121 if ( ( fe->isLink == true ) &&
122 ( co->follow_symlinks == true ) &&
123 ( fe->isCorrupt == false ) ) {
124 bytes += fe->dsize();
125 } else {
126 bytes += fe->size();
127 }
128 }
129 }
130 }
131 return (cancel==true)?1:0;
132 }
133
134 int
createSubDirs(struct deleteorder * delorder,unsigned long * gf,unsigned long * gd)135 NM_CopyOp_Dir::createSubDirs(struct deleteorder *delorder,unsigned long *gf,unsigned long *gd)
136 {
137 NM_CopyOp_Dir *cod1;
138 bool enter;
139 bool cancel=false;
140
141 if(ok==false) return 0;
142
143 if ( verz->dirOpened() == false ) return 0;
144
145 for ( Verzeichnis::verz_it fe_it1 = verz->begin();
146 fe_it1 != verz->end() && cancel == false;
147 fe_it1++ ) {
148 FileEntry *fe = *fe_it1;
149 if(strcmp(fe->name,"..")!=0) {
150 enter=false;
151 if(fe->isDir()==true) {
152 // fe is a dir, check if it is a link and take it only when follow_symlinks==true
153 if(fe->isLink==false) enter=true;
154 }
155 if(enter==true) {
156 // fe is a dir so creating corresponding entry
157 cod1=new NM_CopyOp_Dir(fe);
158 if ( cod1->user_abort == false ) {
159 // recursive call
160 if(cod1->createSubDirs(delorder,gf,gd)!=0) cancel=true;
161 } else cancel = true;
162 // add the values from this subdir to this dir
163 files+=cod1->files;
164 dirs+=cod1->dirs;
165 bytes+=cod1->bytes;
166
167 // add this subdir to the list
168 subdirs->addElement(cod1);
169
170 // this is a dir so inc the counter
171 dirs++;
172 (*gd)++;
173
174 if(delorder->dowin!=NULL) {
175 delorder->dowin->set_files_to_delete(*gf);
176 delorder->dowin->set_dirs_to_delete(*gd);
177 if(delorder->dowin->redraw()!=0) cancel=true;
178 }
179 } else {
180 // is not dir (mostly a file but can also be links ...)
181 files++;
182 (*gf)++;
183 // when deleting only size of file, not the dest matters
184 bytes += fe->size();
185 }
186 }
187 }
188 return (cancel==true)?1:0;
189 }
190
191 int
createSubDirs()192 NM_CopyOp_Dir::createSubDirs()
193 {
194 NM_CopyOp_Dir *cod1;
195 bool enter;
196
197 if(ok==false) return 0;
198
199 if ( verz->dirOpened() == false ) return 0;
200
201 for ( Verzeichnis::verz_it fe_it1 = verz->begin();
202 fe_it1 != verz->end();
203 fe_it1++ ) {
204 FileEntry *fe = *fe_it1;
205 if(strcmp(fe->name,"..")!=0) {
206 enter=false;
207 if(fe->isDir()==true) {
208 // fe is a dir, check if it is a link and take it only when follow_symlinks==true
209 if(fe->isLink==false) enter=true;
210 }
211 if(enter==true) {
212 // fe is a dir so creating corresponding entry
213 cod1=new NM_CopyOp_Dir(fe);
214 // recursive call
215 cod1->createSubDirs();
216
217 // add this subdir to the list
218 subdirs->addElement(cod1);
219 }
220 }
221 }
222 return 0;
223 }
224