| 238 | } |
| 239 | |
| 240 | bool cFileUtil::Copy(const TSTRING& src_path, const TSTRING& dest_path) |
| 241 | { |
| 242 | enum |
| 243 | { |
| 244 | BUF_SIZE = 4096 |
| 245 | }; |
| 246 | int8 buf[BUF_SIZE]; |
| 247 | int nBytesRead; |
| 248 | |
| 249 | cFile srcFile, destFile; |
| 250 | |
| 251 | srcFile.Open(src_path.c_str()); |
| 252 | // Create destination file. We'll fix the permissions later. |
| 253 | destFile.Open(dest_path.c_str(), cFile::OPEN_WRITE | cFile::OPEN_CREATE); |
| 254 | |
| 255 | for (int i = srcFile.GetSize(); i > 0;) |
| 256 | { |
| 257 | nBytesRead = srcFile.Read(buf, BUF_SIZE); |
| 258 | destFile.Write(buf, nBytesRead); |
| 259 | i -= nBytesRead; |
| 260 | } |
| 261 | |
| 262 | struct stat srcStat; |
| 263 | stat(src_path.c_str(), &srcStat); |
| 264 | |
| 265 | // restore permissions and ownership |
| 266 | // don't worry if it fails. it's not mission-critical. |
| 267 | chmod(dest_path.c_str(), srcStat.st_mode); |
| 268 | chown(dest_path.c_str(), srcStat.st_uid, srcStat.st_gid); |
| 269 | |
| 270 | srcFile.Close(); |
| 271 | destFile.Close(); |
| 272 | |
| 273 | return true; |
| 274 | } |