/* Copyright (C) 2003-2015 LiveCode Ltd. This file is part of LiveCode. LiveCode is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License v3 as published by the Free Software Foundation. LiveCode is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with LiveCode. If not see . */ #include #include #include #include #if !defined(TARGET_SUBPLATFORM_ANDROID) && !defined(TARGET_SUBPLATFORM_IPHONE) #include #endif #include #include #include using std::nothrow; #define PATH_MAX 4096 #define stricmp strcasecmp typedef int int4; char *string_from_utf16(const unsigned short *p_string, int p_length) { char *t_result; t_result = (char *)malloc(p_length); for(int i = 0; i < p_length; ++i) t_result[i] = p_string[i]; return t_result; } // Turn an ISO8859-1 encoded string as UTF-8. char *string_to_utf8(const char *p_string) { char *t_utf8_string; t_utf8_string = (char *)malloc(strlen(p_string) * 2 + 1); int i, j; for(i = 0, j = 0; p_string[i] != '\0'; ++i) { unsigned int v; v = ((unsigned char *)p_string)[i]; if (v < 128) t_utf8_string[j++] = v; else { // SN-2015-03-11: [[ Bug 14413 ]] Do the expected shift t_utf8_string[j++] = (0xC0 | (v >> 6)); t_utf8_string[j++] = (0x80 | (v & 63)); } } t_utf8_string[j] = '\0'; return t_utf8_string; } // LINUX implimentation of externals. char *os_path_to_native(const char *p_path) { return (strdup(p_path)); } char *os_path_to_native_utf8(const char *p_path) { return string_to_utf8(p_path); } char *os_path_from_native(const char *p_native_path) { return (strdup(p_native_path)); } char *strclone(const char *one) { char *two = NULL; if (one != NULL) { two = new (nothrow) char[strlen(one) + 1]; strcpy(two, one); } return two; } char *get_current_directory() { char *dptr = new (nothrow) char[PATH_MAX + 2]; getcwd(dptr, PATH_MAX); return dptr; } char *os_path_resolve(const char *p_native_path) { if (p_native_path == NULL) return get_current_directory(); char *tildepath; #if !defined(TARGET_SUBPLATFORM_ANDROID) && !defined(TARGET_SUBPLATFORM_IPHONE) if (p_native_path[0] == '~') { char *tpath = strclone(p_native_path); char *tptr = strchr(tpath, '/'); if (tptr == NULL) { tpath[0] = '\0'; tptr = tpath; } else *tptr++ = '\0'; struct passwd *pw; if (*(tpath + 1) == '\0') pw = getpwuid(getuid()); else pw = getpwnam(tpath + 1); if (pw == NULL) return NULL; tildepath = new (nothrow) char[strlen(pw->pw_dir) + strlen(tptr) + 2]; strcpy(tildepath, pw->pw_dir); if (*tptr) { strcat(tildepath, "/"); strcat(tildepath, tptr); } delete tpath; } else #endif tildepath = strclone(p_native_path); struct stat buf; if (lstat(tildepath, &buf) != 0 || !S_ISLNK(buf.st_mode)) return tildepath; int4 size; char *newname = new (nothrow) char[PATH_MAX + 2]; if ((size = readlink(tildepath, newname, PATH_MAX)) < 0) { delete tildepath; delete newname; return NULL; } delete tildepath; newname[size] = '\0'; if (newname[0] != '/') { char *fullpath = new (nothrow) char[strlen(p_native_path) + strlen(newname) + 2]; strcpy(fullpath, p_native_path); char *sptr = strrchr(fullpath, '/'); if (sptr == NULL) sptr = fullpath; else sptr++; strcpy(sptr, newname); delete newname; newname = os_path_resolve(fullpath); delete fullpath; } return newname; }