1 /*
2 Copyright (C) 2005-2006 Remon Sijrier
3
4 This file is part of Traverso
5
6 Traverso is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19
20 $Id: FileHelpers.cpp,v 1.10 2007/11/05 15:49:30 r_sijrier Exp $
21 */
22
23 #include "FileHelpers.h"
24
25 #include <sys/stat.h>
26 #include "Config.h"
27 #include <QDir>
28 #include <Utils.h>
29 #include <QObject>
30 #include <QFile>
31 #include <unistd.h>
32
33 #include "Debugger.h"
34
35 // delete file/dir pName after prepending $HOME/traversoprojects/ to it
36 //
37 // if it is a directory, calls itself recursively on any file/dir in the directory
38 // before removing the directory
remove_recursively(const QString & pName)39 int FileHelper::remove_recursively(const QString& pName)
40 {
41 QString name = config().get_property("Project", "directory", "/directory/unknown").toString();
42 name += "/" + pName;
43
44 QFileInfo fileInfo(name);
45
46 if (!fileInfo.exists()) {
47 PERROR("File does not exist! %s", QS_C(name));
48 return -1;
49 }
50
51 if (!fileInfo.isWritable()) {
52 PERROR("failed to remove %s: you don't have write access to it\n", name.toLatin1().data());
53 return -1;
54 }
55
56 if(fileInfo.isFile()) {
57 QFile file(name);
58 if (!file.remove()) {
59 PERROR("failed to remove file %s\n", name.toLatin1().data());
60 return -1;
61 }
62 return 1;
63 } else if(fileInfo.isDir()) {
64 QDir dir(name);
65 QFileInfoList list = dir.entryInfoList();
66 QFileInfo fi;
67
68 for (int i = 0; i < list.size(); ++i) {
69 fi = list.at(i);
70 if ((fi.fileName() != ".") && (fi.fileName() != "..")) {
71 QString nextFileName = pName + "/" + fi.fileName();
72 if (remove_recursively(nextFileName) < 0) {
73 PERROR("failed to remove directory %s\n", nextFileName.toLatin1().data());
74 return -1;
75 }
76 }
77 }
78
79 if (!dir.rmdir(name)) {
80 PERROR("failed to remove directory %s\n", name.toLatin1().data());
81 return -1;
82 }
83
84 return 1;
85 }
86
87 return 1;
88 }
89
90
copy_recursively(const QString & pNameFrom,const QString & pNameTo)91 int FileHelper::copy_recursively(const QString& pNameFrom, const QString& pNameTo)
92 {
93 #if defined (Q_WS_X11) || defined (Q_WS_MAC)
94 QString nameFrom = config().get_property("Project", "directory", "/directory/unknown").toString();
95 QString nameTo(nameFrom);
96
97 nameFrom += pNameFrom;
98 nameTo += pNameTo;
99
100 QFileInfo fileFromInfo(nameFrom);
101 QFileInfo fileToInfo(nameTo);
102
103 if (!fileFromInfo.exists()) {
104 PERROR("File or directory %s doesn't exist\n", pNameFrom.toLatin1().data());
105 return -1;
106 }
107 if (fileToInfo.exists()) {
108 PERROR("File or directory %s already exists", pNameTo.toLatin1().data());
109 return -1;
110 }
111
112 if(fileFromInfo.isFile()) {
113 QFile fileFrom(nameFrom);
114 if (!fileFrom.open(QIODevice::ReadOnly)) {
115 PERROR("failed to open file %s for reading\n", nameFrom.toLatin1().data());
116 return -1;
117 }
118
119 QFile fileTo(nameTo);
120 if (!fileTo.open(QIODevice::WriteOnly)) {
121 fileFrom.close();
122 PERROR("failed to open file for writting%s\n", nameFrom.toLatin1().data());
123 return -1;
124 }
125
126 // the real copy part should perhaps be implemented using QDataStream
127 // but .handle() will still be needed to get the optimal block-size
128 //
129 //! \todo does not keep file mode yet
130 int bufferSize = 4096;
131 int fileDescFrom = fileFrom.handle();
132 int fileDescTo = fileTo.handle();
133
134 #if defined(DHAVE_SYS_STAT_H)
135 struct stat fileStat;
136 if (fstat(fileDescFrom, &fileStat) == 0) {
137 bufferSize = (int)fileStat.st_blksize;
138 }
139 #endif
140
141 void *buffer = malloc(sizeof(char) * bufferSize);
142 // QMemArray<char> buffer(bufferSize);
143
144 for (;;) {
145 int nRead = read(fileDescFrom, buffer, bufferSize);
146 if (nRead < 0) {
147 fileFrom.close();
148 fileTo.close();
149 PERROR("Error while reading file %s\n", nameFrom.toLatin1().data());
150 return -1;
151 }
152 if (nRead == 0)
153 break;
154 if (write(fileDescTo, buffer, nRead) < 0) {
155 fileFrom.close();
156 fileTo.close();
157 PERROR("Error while writing file %s\n", nameTo.toLatin1().data());
158 return -1;
159 }
160 }
161 free(buffer);
162
163 fileFrom.close();
164 fileTo.close();
165
166 return 0;
167 } else if(fileFromInfo.isDir()) {
168 QDir dirFrom(nameFrom);
169 QDir dirTo(nameTo);
170 if (!dirTo.mkdir(nameTo)) {
171 PERROR("failed to create directory %s\n", nameTo.toLatin1().data());
172 return -1;
173 }
174
175 QFileInfoList list = dirFrom.entryInfoList();
176 QFileInfo fi;
177 QString fileName;
178 for (int i = 0; i < list.size(); ++i) {
179 fileName = fi.fileName();
180 if ((fileName != ".") && (fileName != "..")) {
181 copy_recursively(pNameFrom + "/" + fileName, pNameTo + "/" + fileName);
182 }
183 }
184 return 0;
185 }
186
187 #endif
188
189 return -1;
190 }
191
fileerror_to_string(int error)192 QString FileHelper::fileerror_to_string(int error)
193 {
194 switch(error) {
195 case QFile::NoError: return QObject::tr("No error occurred"); break;
196 case QFile::ReadError: return QObject::tr("An error occurred when reading from the file."); break;
197 case QFile::WriteError: return QObject::tr("An error occurred when writing to the file."); break;
198 case QFile::FatalError: return QObject::tr("A fatal error occurred."); break;
199 case QFile::OpenError: return QObject::tr("The file could not be opened."); break;
200 case QFile::ResourceError: return QObject::tr("Resourc error"); break;
201 case QFile::AbortError: return QObject::tr("The operation was aborted."); break;
202 case QFile::TimeOutError: return QObject::tr("A timeout occurred."); break;
203 case QFile::UnspecifiedError: return QObject::tr("An unspecified error occurred."); break;
204 case QFile::RemoveError: return QObject::tr("The file could not be removed."); break;
205 case QFile::RenameError: return QObject::tr("The file could not be renamed."); break;
206 case QFile::PositionError: return QObject::tr("The position in the file could not be changed."); break;
207 case QFile::ResizeError: return QObject::tr("The file could not be resized."); break;
208 case QFile::PermissionsError: return QObject::tr("The file could not be accessed."); break;
209 case QFile::CopyError: return QObject::tr("The file could not be copied."); break;
210 default: return QObject::tr("Unknown error");
211 }
212 }
213