diff options
author | Andrew Niefer | 2006-12-05 21:56:56 +0000 |
---|---|---|
committer | Andrew Niefer | 2006-12-05 21:56:56 +0000 |
commit | df79a8d6117a5778bf28b6f468b0f42c0b026dc8 (patch) | |
tree | 7e45edf17164e808735cb059de0992a28014133c /bundles/org.eclipse.equinox.executable/library/eclipseCommon.c | |
parent | 234f2e8893c4de279f7ebc545b01e249d05335f3 (diff) | |
download | rt.equinox.framework-df79a8d6117a5778bf28b6f468b0f42c0b026dc8.tar.gz rt.equinox.framework-df79a8d6117a5778bf28b6f468b0f42c0b026dc8.tar.xz rt.equinox.framework-df79a8d6117a5778bf28b6f468b0f42c0b026dc8.zip |
Moving launcher code from equinox-incubator/org.eclipse.equinox.launcher
(formely from platform-launcher)
Diffstat (limited to 'bundles/org.eclipse.equinox.executable/library/eclipseCommon.c')
-rw-r--r-- | bundles/org.eclipse.equinox.executable/library/eclipseCommon.c | 277 |
1 files changed, 277 insertions, 0 deletions
diff --git a/bundles/org.eclipse.equinox.executable/library/eclipseCommon.c b/bundles/org.eclipse.equinox.executable/library/eclipseCommon.c new file mode 100644 index 000000000..cde658660 --- /dev/null +++ b/bundles/org.eclipse.equinox.executable/library/eclipseCommon.c @@ -0,0 +1,277 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Andrew Niefer + *******************************************************************************/ + +#include "eclipseCommon.h" +#include "eclipseUnicode.h" + +#ifdef _WIN32 +#include <direct.h> +#include <windows.h> +#else +#include <unistd.h> +#include <strings.h> +#include <dirent.h> +#endif +#include <stdlib.h> +#include <sys/stat.h> + +/* Global Variables */ +_TCHAR* officialName = NULL; + +/* Local Variables */ +#ifndef _WIN32 +static _TCHAR* filterPrefix = NULL; /* prefix for the find files filter */ +static int prefixLength = 0; +#endif + + +/** + * Convert a wide string to a narrow one + * Caller must free the null terminated string returned. + */ +char *toNarrow(_TCHAR* src) +{ +#ifdef UNICODE + int byteCount = WideCharToMultiByte (CP_ACP, 0, (wchar_t *)src, -1, NULL, 0, NULL, NULL); + char *dest = malloc(byteCount+1); + dest[byteCount] = 0; + WideCharToMultiByte (CP_UTF8, 0, (wchar_t *)src, -1, dest, byteCount, NULL, NULL); + return dest; +#else + return _tcsdup(src); +#endif +} + + + /* + * Find the absolute pathname to where a command resides. + * + * The string returned by the function must be freed. + */ +#define EXTRA 20 +_TCHAR* findCommand( _TCHAR* command ) +{ + _TCHAR* cmdPath; + int length; + _TCHAR* ch; + _TCHAR* dir; + _TCHAR* path; + struct _stat stats; + + /* If the command was an abolute pathname, use it as is. */ + if (command[0] == dirSeparator || + (_tcslen( command ) > 2 && command[1] == _T_ECLIPSE(':'))) + { + length = _tcslen( command ); + cmdPath = malloc( (length + EXTRA) * sizeof(_TCHAR) ); /* add extra space for a possible ".exe" extension */ + _tcscpy( cmdPath, command ); + } + + else + { + /* If the command string contains a path separator */ + if (_tcschr( command, dirSeparator ) != NULL) + { + /* It must be relative to the current directory. */ + length = MAX_PATH_LENGTH + EXTRA + _tcslen( command ); + cmdPath = malloc( length * sizeof (_TCHAR)); + _tgetcwd( cmdPath, length ); + if (cmdPath[ _tcslen( cmdPath ) - 1 ] != dirSeparator) + { + length = _tcslen( cmdPath ); + cmdPath[ length ] = dirSeparator; + cmdPath[ length+1 ] = _T_ECLIPSE('\0'); + } + _tcscat( cmdPath, command ); + } + + /* else the command must be in the PATH somewhere */ + else + { + /* Get the directory PATH where executables reside. */ + path = _tgetenv( _T_ECLIPSE("PATH") ); + if (!path) + { + return NULL; + } + else + { + length = _tcslen( path ) + _tcslen( command ) + MAX_PATH_LENGTH; + cmdPath = malloc( length * sizeof(_TCHAR)); + + /* Foreach directory in the PATH */ + dir = path; + while (dir != NULL && *dir != _T_ECLIPSE('\0')) + { + ch = _tcschr( dir, pathSeparator ); + if (ch == NULL) + { + _tcscpy( cmdPath, dir ); + } + else + { + length = ch - dir; + _tcsncpy( cmdPath, dir, length ); + cmdPath[ length ] = _T_ECLIPSE('\0'); + ch++; + } + dir = ch; /* advance for the next iteration */ + +#ifdef _WIN32 + /* Remove quotes */ + if (_tcschr( cmdPath, _T_ECLIPSE('"') ) != NULL) + { + int i = 0, j = 0, c; + length = _tcslen( cmdPath ); + while (i < length) { + c = cmdPath[ i++ ]; + if (c == _T_ECLIPSE('"')) continue; + cmdPath[ j++ ] = c; + } + cmdPath[ j ] = _T_ECLIPSE('\0'); + } +#endif + /* Determine if the executable resides in this directory. */ + if (cmdPath[0] == _T_ECLIPSE('.') && + (_tcslen(cmdPath) == 1 || (_tcslen(cmdPath) == 2 && cmdPath[1] == dirSeparator))) + { + _tgetcwd( cmdPath, MAX_PATH_LENGTH ); + } + if (cmdPath[ _tcslen( cmdPath ) - 1 ] != dirSeparator) + { + length = _tcslen( cmdPath ); + cmdPath[ length ] = dirSeparator; + cmdPath[ length+1 ] = _T_ECLIPSE('\0'); + } + _tcscat( cmdPath, command ); + + /* If the file is not a directory and can be executed */ + if (_tstat( cmdPath, &stats ) == 0 && (stats.st_mode & S_IFREG) != 0) + { + /* Stop searching */ + dir = NULL; + } + } + } + } + } + +#ifdef _WIN32 + /* If the command does not exist */ + if (_tstat( cmdPath, &stats ) != 0 || (stats.st_mode & S_IFREG) == 0) + { + /* If the command does not end with .exe, append it an try again. */ + length = _tcslen( cmdPath ); + if (length > 4 && _tcsicmp( &cmdPath[ length - 4 ], _T_ECLIPSE(".exe") ) != 0) + _tcscat( cmdPath, _T_ECLIPSE(".exe") ); + } +#endif + + /* Verify the resulting command actually exists. */ + if (_tstat( cmdPath, &stats ) != 0 || (stats.st_mode & S_IFREG) == 0) + { + free( cmdPath ); + cmdPath = NULL; + } + +#if !defined(_WIN32) && !defined(MACOSX) + /* resolve symlinks */ + ch = cmdPath; + cmdPath = canonicalize_file_name(cmdPath); + free(ch); +#endif + + /* Return the absolute command pathname. */ + return cmdPath; +} + +#ifndef _WIN32 +#ifdef MACOSX +static int filter(struct dirent *dir) { +#else +static int filter(const struct dirent *dir) { +#endif + if(_tcslen(dir->d_name) <= prefixLength) + return 0; + return (_tcsncmp(dir->d_name, filterPrefix, prefixLength) == 0 && + dir->d_name[prefixLength] == _T_ECLIPSE('_')); +} +#endif + /* + * Looks for files of the form /path/prefix_version.<extension> and returns the full path to + * the file with the largest version number + */ +_TCHAR* findFile( _TCHAR* path, _TCHAR* prefix) +{ + struct _stat stats; + int pathLength; + _TCHAR* candidate = NULL; + _TCHAR* result = NULL; + +#ifdef _WIN32 + _TCHAR* fileName = NULL; + WIN32_FIND_DATA data; + HANDLE handle; +#else + struct dirent **files; + int count; +#endif + + /* does path exist? */ + if( _tstat(path, &stats) != 0 ) + return NULL; + + pathLength = _tcslen(path); + +#ifdef _WIN32 + fileName = malloc( (_tcslen(path) + 1 + _tcslen(prefix) + 3) * sizeof(_TCHAR)); + fileName = _tcscpy(fileName, path); + fileName[pathLength] = dirSeparator; + fileName[pathLength + 1] = 0; + _tcscat(fileName, prefix); + _tcscat(fileName, _T_ECLIPSE("_*")); + prefix = fileName; + + handle = FindFirstFile(prefix, &data); + if(handle != INVALID_HANDLE_VALUE) { + candidate = _tcsdup(data.cFileName); + while(FindNextFile(handle, &data) != 0) { + fileName = data.cFileName; + /* compare, take the highest version */ + if( _tcscmp(candidate, fileName) < 0) { + free(candidate); + candidate = _tcsdup(fileName); + } + } + FindClose(handle); + } +#else + filterPrefix = prefix; + prefixLength = _tcslen(prefix); + /* TODO should write out own comparator to better handle OSGi versions */ + count = scandir(path, &files, &filter, alphasort); + if(count > 0) { + candidate = _tcsdup(files[count - 1]->d_name); + } +#endif + + if(candidate != NULL) { + result = malloc((pathLength + 1 + _tcslen(candidate) + 1) * sizeof(_TCHAR)); + _tcscpy(result, path); + result[pathLength] = dirSeparator; + result[pathLength + 1] = 0; + _tcscat(result, candidate); + free(candidate); + return result; + } + return NULL; +} |