14a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*---------------------------------------------------------------------------*
24a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  PANSIFileSystemUNIXImpl.c  *
34a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
44a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  Copyright 2007, 2008 Nuance Communciations, Inc.                               *
54a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
64a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  Licensed under the Apache License, Version 2.0 (the 'License');          *
74a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  you may not use this file except in compliance with the License.         *
84a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
94a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  You may obtain a copy of the License at                                  *
104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0                           *
114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software      *
134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  distributed under the License is distributed on an 'AS IS' BASIS,        *
144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  See the License for the specific language governing permissions and      *
164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  limitations under the License.                                           *
174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *---------------------------------------------------------------------------*/
194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <sys/types.h>
214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <sys/stat.h>
224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "errno.h"
244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "PFileSystemImpl.h"
254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "PANSIFileSystem.h"
264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "PANSIFileSystemImpl.h"
274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "phashtable.h"
284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "LCHAR.h"
294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "plog.h"
304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode PANSIFileSystemGetVirtualPathImpl(PFileSystem* self, LCHAR* path, size_t* len)
324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  PANSIFileSystemImpl* impl = (PANSIFileSystemImpl*) self;
344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  PHashTableEntry* entry;
354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  LCHAR driveLetter = 0;
364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  LCHAR* key;
374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  LCHAR* value;
384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  LCHAR* bestKey = NULL;
394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  LCHAR* bestValue = NULL;
404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ESR_BOOL isAbsolute;
414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ESR_ReturnCode rc;
424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  CHKLOG(rc, lstrtrim(path));
444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  CHKLOG(rc, PFileSystemCanonicalSlashes(path));
454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  CHKLOG(rc, PFileSystemIsAbsolutePath(path, &isAbsolute));
464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (isAbsolute && path[0] != L('/'))
474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /* Skip drive letters in absolute paths */
494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    driveLetter = path[0];
504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    LSTRCPY(path, path + 2);
514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  CHKLOG(rc, PHashTableEntryGetFirst(impl->directoryMap, &entry));
534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  while (entry!=NULL)
544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    CHKLOG(rc, PHashTableEntryGetKeyValue(entry, (void **)&key, (void **)&value));
564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (LSTRSTR(path, value)==path)
574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      /* File-system handles file path */
594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (bestValue==NULL || LSTRLEN(value) > LSTRLEN(bestValue))
614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        /* Found a better match -- the new key is a subdirectory of the previous bestKey */
634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        bestKey = key;
644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        bestValue = value;
654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    CHKLOG(rc, PHashTableEntryAdvance(&entry));
684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (bestKey == NULL)
704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    rc = ESR_INVALID_STATE;
724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    PLogError(L("PANSIFileSystem does not handle the specified path: %s"), path);
734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    goto CLEANUP;
744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* Delete the real-path */
774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  LSTRCPY(path, path + LSTRLEN(bestValue));
784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* Insert the virtual-path */
794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  CHKLOG(rc, lstrinsert(bestKey, path, 0, len));
804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* Bring back the drive letter */
824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (driveLetter!=0)
834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    CHKLOG(rc, lstrinsert(L("X:/"), path, LSTRLEN(bestKey), len));
854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    path[LSTRLEN(bestKey)] = driveLetter;
864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return ESR_SUCCESS;
884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project CLEANUP:
894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return rc;
904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode PANSIFileSystemMkdirImpl(PFileSystem* self, const LCHAR* path)
924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  LCHAR realPath[P_PATH_MAX];
944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  size_t len;
954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ESR_ReturnCode rc;
964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  passert(path!=NULL);
984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  LSTRCPY(realPath, path);
994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  len = P_PATH_MAX;
1004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  CHKLOG(rc, PANSIFileSystemGetRealPathImpl(self, realPath, &len));
1014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (mkdir(realPath, S_IRWXU|S_IRWXG|S_IRWXO ) != 0)
1034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
1044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      switch (errno)
1054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
1064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       case EEXIST:
1074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         return ESR_IDENTIFIER_COLLISION;
1084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       case ENOENT:
1094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         return ESR_NO_MATCH_ERROR;
1104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       default:
1114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         PLogError(L("ESR_INVALID_STATE"));
1124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         return ESR_INVALID_STATE;
1134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
1144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return ESR_SUCCESS;
1164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectCLEANUP:
1174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return rc;
1184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
1194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode PANSIFileSystemGetcwdImpl(PFileSystem* self, LCHAR* path, size_t* len)
1214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
1224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	ESR_ReturnCode rc;
1234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	if (path==NULL)
1254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	{
1264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		rc = ESR_INVALID_ARGUMENT;
1274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		PLogError(ESR_rc2str(rc));
1284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		goto CLEANUP;
1294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	}
1304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (getcwd(path, *len) == NULL)
1314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
1324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      switch (errno)
1334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
1344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       case ERANGE:
1354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         *len = P_PATH_MAX;
1364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         return ESR_BUFFER_OVERFLOW;
1374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       case ENOMEM:
1384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       default:
1394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         PLogError(L("ESR_INVALID_STATE"));
1404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         return ESR_INVALID_STATE;
1414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
1424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	CHKLOG(rc, PANSIFileSystemGetVirtualPathImpl(self, path, len));
1454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	return ESR_SUCCESS;
1464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectCLEANUP:
1474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	return rc;
1484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
1494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode PANSIFileSystemChdirImpl(PFileSystem* self, const LCHAR* path)
1514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
1524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	LCHAR realPath[P_PATH_MAX];
1534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	size_t len;
1544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	ESR_ReturnCode rc;
1554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	passert(path!=NULL);
1574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	LSTRCPY(realPath, path);
1584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	len = P_PATH_MAX;
1594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	CHKLOG(rc, PANSIFileSystemGetRealPathImpl(self, realPath, &len));
1604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	if ((*path != '\0') && (chdir(realPath) != 0))
1624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		return ESR_NO_MATCH_ERROR;
1634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	return ESR_SUCCESS;
1644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectCLEANUP:
1654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	return rc;
1664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
167