Home | History | Annotate | Download | only in UNIX
      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 
     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 }
     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 
    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 
    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