• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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