CATSFC/sdk-modifications/libsrc/fs/fatdir_ex.c

183 lines
3.8 KiB
C
Executable file

#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/dir.h>
#include "fatdir.h"
#include "fatdir_ex.h"
#include "cache.h"
#include "file_allocation_table.h"
#include "partition.h"
#include "directory.h"
#include "bit_ops.h"
#include "filetime.h"
#include "unicode/unicode.h"
int dirnextl (DIR_ITER *dirState, char *filename, char *longFilename, struct stat *filestat)
{
DIR_STATE_STRUCT* state = (DIR_STATE_STRUCT*) (dirState->dirStruct);
// Make sure we are still using this entry
if (!state->inUse) {
errno = EBADF;
return -1;
}
// Make sure there is another file to report on
if (! state->validEntry) {
errno = ENOENT;
return -1;
}
// Get the filename
strncpy (filename, state->currentEntry.d_name, MAX_FILENAME_LENGTH);
// Get long filename
_FAT_unicode_unicode_to_local( state->currentEntry.unicodeFilename, (u8 *)longFilename );
// Get the stats, if requested
if (filestat != NULL) {
_FAT_directory_entryStat (state->partition, &(state->currentEntry), filestat);
}
// Look for the next entry for use next time
state->validEntry =
_FAT_directory_getNextEntry (state->partition, &(state->currentEntry));
return 0;
}
int renamex( const char *oldName, const char *newName )
{
PARTITION* partition = NULL;
DIR_ENTRY oldDirEntry;
DIR_ENTRY newDirEntry;
const char *pathEnd;
u32 dirCluster;
// Get the partition this directory is on
partition = _FAT_partition_getPartitionFromPath (oldName);
if (partition == NULL) {
errno = ENODEV;
return -1;
}
// Make sure the same partition is used for the old and new names
if (partition != _FAT_partition_getPartitionFromPath (newName)) {
errno = EXDEV;
return -1;
}
// Make sure we aren't trying to write to a read-only disc
if (partition->readOnly) {
errno = EROFS;
return -1;
}
// Move the path pointer to the start of the actual path
if (strchr (oldName, ':') != NULL) {
oldName = strchr (oldName, ':') + 1;
}
if (strchr (oldName, ':') != NULL) {
errno = EINVAL;
return -1;
}
if (strchr (newName, ':') != NULL) {
newName = strchr (newName, ':') + 1;
}
if (strchr (newName, ':') != NULL) {
errno = EINVAL;
return -1;
}
// Search for the file on the disc
if (!_FAT_directory_entryFromPath (partition, &oldDirEntry, oldName, NULL)) {
errno = ENOENT;
return -1;
}
// Make sure there is no existing file / directory with the new name
if (_FAT_directory_entryFromPath (partition, &newDirEntry, newName, NULL)) {
errno = EEXIST;
return -1;
}
// Create the new file entry
// Get the directory it has to go in
pathEnd = strrchr (newName, DIR_SEPARATOR);
if (pathEnd == NULL) {
// No path was specified
dirCluster = partition->cwdCluster;
pathEnd = newName;
} else {
// Path was specified -- get the right dirCluster
// Recycling newDirEntry, since it needs to be recreated anyway
if (!_FAT_directory_entryFromPath (partition, &newDirEntry, newName, pathEnd) ||
!_FAT_directory_isDirectory(&newDirEntry)) {
errno = ENOTDIR;
return -1;
}
dirCluster = _FAT_directory_entryGetCluster (newDirEntry.entryData);
// Move the pathEnd past the last DIR_SEPARATOR
pathEnd += 1;
}
// Copy the entry data
memcpy (&newDirEntry, &oldDirEntry, sizeof(DIR_ENTRY));
// Set the new name
strncpy (newDirEntry.d_name, pathEnd, MAX_FILENAME_LENGTH - 1);
// Write the new entry
if (!_FAT_directory_addEntry (partition, &newDirEntry, dirCluster)) {
errno = ENOSPC;
return -1;
}
// Remove the old entry
if (!_FAT_directory_removeEntry (partition, &oldDirEntry)) {
errno = EIO;
return -1;
}
// Flush any sectors in the disc cache
if (!_FAT_cache_flush (partition->cache)) {
errno = EIO;
return -1;
}
return 0;
}