1/*---------------------------------------------------------------------------* 2 * PANSIFileSystemUNIXImpl.c * 3 * * 4 * Copyright 2007, 2008 Nuance Communciations, Inc. * 5 * * 6 * Licensed under the Apache License, Version 2.0 (the 'License'); * 7 * you may not use this file except in compliance with the License. * 8 * * 9 * You may obtain a copy of the License at * 10 * http://www.apache.org/licenses/LICENSE-2.0 * 11 * * 12 * Unless required by applicable law or agreed to in writing, software * 13 * distributed under the License is distributed on an 'AS IS' BASIS, * 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 * See the License for the specific language governing permissions and * 16 * limitations under the License. * 17 * * 18 *---------------------------------------------------------------------------*/ 19 20#include <sys/types.h> 21#include <sys/stat.h> 22 23#include "errno.h" 24#include "PFileSystemImpl.h" 25#include "PANSIFileSystem.h" 26#include "PANSIFileSystemImpl.h" 27#include "phashtable.h" 28#include "LCHAR.h" 29#include "plog.h" 30 31ESR_ReturnCode PANSIFileSystemGetVirtualPathImpl(PFileSystem* self, LCHAR* path, size_t* len) 32{ 33 PANSIFileSystemImpl* impl = (PANSIFileSystemImpl*) self; 34 PHashTableEntry* entry; 35 LCHAR driveLetter = 0; 36 LCHAR* key; 37 LCHAR* value; 38 LCHAR* bestKey = NULL; 39 LCHAR* bestValue = NULL; 40 ESR_BOOL isAbsolute; 41 ESR_ReturnCode rc; 42 43 CHKLOG(rc, lstrtrim(path)); 44 CHKLOG(rc, PFileSystemCanonicalSlashes(path)); 45 CHKLOG(rc, PFileSystemIsAbsolutePath(path, &isAbsolute)); 46 if (isAbsolute && path[0] != L('/')) 47 { 48 /* Skip drive letters in absolute paths */ 49 driveLetter = path[0]; 50 LSTRCPY(path, path + 2); 51 } 52 CHKLOG(rc, PHashTableEntryGetFirst(impl->directoryMap, &entry)); 53 while (entry!=NULL) 54 { 55 CHKLOG(rc, PHashTableEntryGetKeyValue(entry, (void **)&key, (void **)&value)); 56 if (LSTRSTR(path, value)==path) 57 { 58 /* File-system handles file path */ 59 60 if (bestValue==NULL || LSTRLEN(value) > LSTRLEN(bestValue)) 61 { 62 /* Found a better match -- the new key is a subdirectory of the previous bestKey */ 63 bestKey = key; 64 bestValue = value; 65 } 66 } 67 CHKLOG(rc, PHashTableEntryAdvance(&entry)); 68 } 69 if (bestKey == NULL) 70 { 71 rc = ESR_INVALID_STATE; 72 PLogError(L("PANSIFileSystem does not handle the specified path: %s"), path); 73 goto CLEANUP; 74 } 75 76 /* Delete the real-path */ 77 LSTRCPY(path, path + LSTRLEN(bestValue)); 78 /* Insert the virtual-path */ 79 CHKLOG(rc, lstrinsert(bestKey, path, 0, len)); 80 81 /* Bring back the drive letter */ 82 if (driveLetter!=0) 83 { 84 CHKLOG(rc, lstrinsert(L("X:/"), path, LSTRLEN(bestKey), len)); 85 path[LSTRLEN(bestKey)] = driveLetter; 86 } 87 return ESR_SUCCESS; 88 CLEANUP: 89 return rc; 90} 91ESR_ReturnCode PANSIFileSystemMkdirImpl(PFileSystem* self, const LCHAR* path) 92{ 93 LCHAR realPath[P_PATH_MAX]; 94 size_t len; 95 ESR_ReturnCode rc; 96 97 passert(path!=NULL); 98 LSTRCPY(realPath, path); 99 len = P_PATH_MAX; 100 CHKLOG(rc, PANSIFileSystemGetRealPathImpl(self, realPath, &len)); 101 102 if (mkdir(realPath, S_IRWXU|S_IRWXG|S_IRWXO ) != 0) 103 { 104 switch (errno) 105 { 106 case EEXIST: 107 return ESR_IDENTIFIER_COLLISION; 108 case ENOENT: 109 return ESR_NO_MATCH_ERROR; 110 default: 111 PLogError(L("ESR_INVALID_STATE")); 112 return ESR_INVALID_STATE; 113 } 114 } 115 return ESR_SUCCESS; 116CLEANUP: 117 return rc; 118} 119 120ESR_ReturnCode PANSIFileSystemGetcwdImpl(PFileSystem* self, LCHAR* path, size_t* len) 121{ 122 ESR_ReturnCode rc; 123 124 if (path==NULL) 125 { 126 rc = ESR_INVALID_ARGUMENT; 127 PLogError(ESR_rc2str(rc)); 128 goto CLEANUP; 129 } 130 if (getcwd(path, *len) == NULL) 131 { 132 switch (errno) 133 { 134 case ERANGE: 135 *len = P_PATH_MAX; 136 return ESR_BUFFER_OVERFLOW; 137 case ENOMEM: 138 default: 139 PLogError(L("ESR_INVALID_STATE")); 140 return ESR_INVALID_STATE; 141 } 142 } 143 144 CHKLOG(rc, PANSIFileSystemGetVirtualPathImpl(self, path, len)); 145 return ESR_SUCCESS; 146CLEANUP: 147 return rc; 148} 149 150ESR_ReturnCode PANSIFileSystemChdirImpl(PFileSystem* self, const LCHAR* path) 151{ 152 LCHAR realPath[P_PATH_MAX]; 153 size_t len; 154 ESR_ReturnCode rc; 155 156 passert(path!=NULL); 157 LSTRCPY(realPath, path); 158 len = P_PATH_MAX; 159 CHKLOG(rc, PANSIFileSystemGetRealPathImpl(self, realPath, &len)); 160 161 if ((*path != '\0') && (chdir(realPath) != 0)) 162 return ESR_NO_MATCH_ERROR; 163 return ESR_SUCCESS; 164CLEANUP: 165 return rc; 166} 167