/*---------------------------------------------------------------------------* * PANSIFileSystemUNIXImpl.c * * * * Copyright 2007, 2008 Nuance Communciations, Inc. * * * * Licensed under the Apache License, Version 2.0 (the 'License'); * * you may not use this file except in compliance with the License. * * * * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an 'AS IS' BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * * * *---------------------------------------------------------------------------*/ #include <sys/types.h> #include <sys/stat.h> #include "errno.h" #include "PFileSystemImpl.h" #include "PANSIFileSystem.h" #include "PANSIFileSystemImpl.h" #include "phashtable.h" #include "LCHAR.h" #include "plog.h" ESR_ReturnCode PANSIFileSystemGetVirtualPathImpl(PFileSystem* self, LCHAR* path, size_t* len) { PANSIFileSystemImpl* impl = (PANSIFileSystemImpl*) self; PHashTableEntry* entry; LCHAR driveLetter = 0; LCHAR* key; LCHAR* value; LCHAR* bestKey = NULL; LCHAR* bestValue = NULL; ESR_BOOL isAbsolute; ESR_ReturnCode rc; CHKLOG(rc, lstrtrim(path)); CHKLOG(rc, PFileSystemCanonicalSlashes(path)); CHKLOG(rc, PFileSystemIsAbsolutePath(path, &isAbsolute)); if (isAbsolute && path[0] != L('/')) { /* Skip drive letters in absolute paths */ driveLetter = path[0]; LSTRCPY(path, path + 2); } CHKLOG(rc, PHashTableEntryGetFirst(impl->directoryMap, &entry)); while (entry!=NULL) { CHKLOG(rc, PHashTableEntryGetKeyValue(entry, (void **)&key, (void **)&value)); if (LSTRSTR(path, value)==path) { /* File-system handles file path */ if (bestValue==NULL || LSTRLEN(value) > LSTRLEN(bestValue)) { /* Found a better match -- the new key is a subdirectory of the previous bestKey */ bestKey = key; bestValue = value; } } CHKLOG(rc, PHashTableEntryAdvance(&entry)); } if (bestKey == NULL) { rc = ESR_INVALID_STATE; PLogError(L("PANSIFileSystem does not handle the specified path: %s"), path); goto CLEANUP; } /* Delete the real-path */ LSTRCPY(path, path + LSTRLEN(bestValue)); /* Insert the virtual-path */ CHKLOG(rc, lstrinsert(bestKey, path, 0, len)); /* Bring back the drive letter */ if (driveLetter!=0) { CHKLOG(rc, lstrinsert(L("X:/"), path, LSTRLEN(bestKey), len)); path[LSTRLEN(bestKey)] = driveLetter; } return ESR_SUCCESS; CLEANUP: return rc; } ESR_ReturnCode PANSIFileSystemMkdirImpl(PFileSystem* self, const LCHAR* path) { LCHAR realPath[P_PATH_MAX]; size_t len; ESR_ReturnCode rc; passert(path!=NULL); LSTRCPY(realPath, path); len = P_PATH_MAX; CHKLOG(rc, PANSIFileSystemGetRealPathImpl(self, realPath, &len)); if (mkdir(realPath, S_IRWXU|S_IRWXG|S_IRWXO ) != 0) { switch (errno) { case EEXIST: return ESR_IDENTIFIER_COLLISION; case ENOENT: return ESR_NO_MATCH_ERROR; default: PLogError(L("ESR_INVALID_STATE")); return ESR_INVALID_STATE; } } return ESR_SUCCESS; CLEANUP: return rc; } ESR_ReturnCode PANSIFileSystemGetcwdImpl(PFileSystem* self, LCHAR* path, size_t* len) { ESR_ReturnCode rc; if (path==NULL) { rc = ESR_INVALID_ARGUMENT; PLogError(ESR_rc2str(rc)); goto CLEANUP; } if (getcwd(path, *len) == NULL) { switch (errno) { case ERANGE: *len = P_PATH_MAX; return ESR_BUFFER_OVERFLOW; case ENOMEM: default: PLogError(L("ESR_INVALID_STATE")); return ESR_INVALID_STATE; } } CHKLOG(rc, PANSIFileSystemGetVirtualPathImpl(self, path, len)); return ESR_SUCCESS; CLEANUP: return rc; } ESR_ReturnCode PANSIFileSystemChdirImpl(PFileSystem* self, const LCHAR* path) { LCHAR realPath[P_PATH_MAX]; size_t len; ESR_ReturnCode rc; passert(path!=NULL); LSTRCPY(realPath, path); len = P_PATH_MAX; CHKLOG(rc, PANSIFileSystemGetRealPathImpl(self, realPath, &len)); if ((*path != '\0') && (chdir(realPath) != 0)) return ESR_NO_MATCH_ERROR; return ESR_SUCCESS; CLEANUP: return rc; }