| 473 | } |
| 474 | |
| 475 | int Rename(FsNode* olddir, char* oldpath, FsNode* newdir, char* newpath){ |
| 476 | assert(olddir && newdir); |
| 477 | |
| 478 | if((olddir->flags & FS_NODE_TYPE) != FS_NODE_DIRECTORY){ |
| 479 | return -ENOTDIR; |
| 480 | } |
| 481 | |
| 482 | if((newdir->flags & FS_NODE_TYPE) != FS_NODE_DIRECTORY){ |
| 483 | return -ENOTDIR; |
| 484 | } |
| 485 | |
| 486 | FsNode* oldnode = ResolvePath(oldpath, olddir); |
| 487 | |
| 488 | if(!oldnode){ |
| 489 | return -ENOENT; |
| 490 | } |
| 491 | |
| 492 | if((oldnode->flags & FS_NODE_TYPE) == FS_NODE_DIRECTORY){ |
| 493 | Log::Warning("Filesystem: Rename: We do not support using rename on directories yet!"); |
| 494 | return -ENOSYS; |
| 495 | } |
| 496 | |
| 497 | FsNode* newpathParent = ResolveParent(newpath, newdir); |
| 498 | |
| 499 | if(!newpathParent){ |
| 500 | return -ENOENT; |
| 501 | } else if((newpathParent->flags & FS_NODE_TYPE) != FS_NODE_DIRECTORY){ |
| 502 | return -ENOTDIR; // Parent of newpath is not a directory |
| 503 | } |
| 504 | |
| 505 | FsNode* newnode = ResolvePath(newpath, newdir); |
| 506 | |
| 507 | if(newnode){ |
| 508 | if((newnode->flags & FS_NODE_TYPE) == FS_NODE_DIRECTORY){ |
| 509 | return -EISDIR; // If it exists newpath must not be a directory |
| 510 | } |
| 511 | } |
| 512 | |
| 513 | DirectoryEntry oldpathDirent; |
| 514 | strncpy(oldpathDirent.name, fs::BaseName(oldpath), NAME_MAX); |
| 515 | |
| 516 | DirectoryEntry newpathDirent; |
| 517 | strncpy(newpathDirent.name, fs::BaseName(newpath), NAME_MAX); |
| 518 | |
| 519 | if((oldnode->flags & FS_NODE_TYPE) != FS_NODE_SYMLINK && oldnode->volumeID == newpathParent->volumeID){ // Easy shit we can just link and unlink |
| 520 | FsNode* oldpathParent = fs::ResolveParent(oldpath, olddir); |
| 521 | assert(oldpathParent); // If this is null something went horribly wrong |
| 522 | |
| 523 | if(newnode){ |
| 524 | if(auto e = newpathParent->Unlink(&newpathDirent)){ |
| 525 | return e; // Unlink error |
| 526 | } |
| 527 | } |
| 528 | |
| 529 | if(auto e = newpathParent->Link(oldnode, &newpathDirent)){ |
| 530 | return e; // Link error |
| 531 | } |
| 532 |
no test coverage detected