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
PANSIFileSystemGetVirtualPathImpl(PFileSystem * self,LCHAR * path,size_t * len)31 ESR_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 }
PANSIFileSystemMkdirImpl(PFileSystem * self,const LCHAR * path)91 ESR_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;
116 CLEANUP:
117 return rc;
118 }
119
PANSIFileSystemGetcwdImpl(PFileSystem * self,LCHAR * path,size_t * len)120 ESR_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;
146 CLEANUP:
147 return rc;
148 }
149
PANSIFileSystemChdirImpl(PFileSystem * self,const LCHAR * path)150 ESR_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;
164 CLEANUP:
165 return rc;
166 }
167