| 333 | } |
| 334 | |
| 335 | int copyFile(const char *src_path, const char *dst_path, FileProcessParam *param) { |
| 336 | // The source and destination paths are identical |
| 337 | if (strcasecmp(src_path, dst_path) == 0) { |
| 338 | return VITASHELL_ERROR_SRC_AND_DST_IDENTICAL; |
| 339 | } |
| 340 | |
| 341 | // The destination is a subfolder of the source folder |
| 342 | int len = strlen(src_path); |
| 343 | if (strncasecmp(src_path, dst_path, len) == 0 && (dst_path[len] == '/' || dst_path[len - 1] == '/')) { |
| 344 | return VITASHELL_ERROR_DST_IS_SUBFOLDER_OF_SRC; |
| 345 | } |
| 346 | |
| 347 | SceUID fdsrc = sceIoOpen(src_path, SCE_O_RDONLY, 0); |
| 348 | if (fdsrc < 0) |
| 349 | return fdsrc; |
| 350 | |
| 351 | SceUID fddst = sceIoOpen(dst_path, SCE_O_WRONLY | SCE_O_CREAT | SCE_O_TRUNC, 0777); |
| 352 | if (fddst < 0) { |
| 353 | sceIoClose(fdsrc); |
| 354 | return fddst; |
| 355 | } |
| 356 | |
| 357 | void *buf = memalign(4096, TRANSFER_SIZE); |
| 358 | |
| 359 | while (1) { |
| 360 | int read = sceIoRead(fdsrc, buf, TRANSFER_SIZE); |
| 361 | |
| 362 | if (read < 0) { |
| 363 | free(buf); |
| 364 | |
| 365 | sceIoClose(fddst); |
| 366 | sceIoClose(fdsrc); |
| 367 | |
| 368 | sceIoRemove(dst_path); |
| 369 | |
| 370 | return read; |
| 371 | } |
| 372 | |
| 373 | if (read == 0) |
| 374 | break; |
| 375 | |
| 376 | int written = sceIoWrite(fddst, buf, read); |
| 377 | |
| 378 | if (written < 0) { |
| 379 | free(buf); |
| 380 | |
| 381 | sceIoClose(fddst); |
| 382 | sceIoClose(fdsrc); |
| 383 | |
| 384 | sceIoRemove(dst_path); |
| 385 | |
| 386 | return written; |
| 387 | } |
| 388 | |
| 389 | if (param) { |
| 390 | if (param->value) |
| 391 | (*param->value) += read; |
| 392 | |