Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

285 lines (236 sloc) 7.136 kb
/*
* %CopyrightBegin%
*
* Copyright Ericsson AB 2003-2009. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* %CopyrightEnd%
*/
#pragma comment(linker,"/manifestdependency:\"type='win32' "\
"name='Microsoft.Windows.Common-Controls' "\
"version='6.0.0.0' processorArchitecture='*' "\
"publicKeyToken='6595b64144ccf1df' language='*'\"")
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include "init_file.h"
typedef int ErlexecFunction(int, char **, HANDLE, int);
#define INI_FILENAME "erl.ini"
#define INI_SECTION "erlang"
#define ERLEXEC_BASENAME "erlexec.dll"
static void get_parameters(void);
static void error(char* format, ...);
static char *erlexec_name;
static char *erlexec_dir;
#ifdef WIN32_WERL
#define WERL 1
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
int argc = __argc;
char **argv = __argv;
#else
#define WERL 0
int main(int argc, char **argv)
{
#endif
HANDLE erlexec_handle; /* Instance */
ErlexecFunction *win_erlexec;
char *path = malloc(100);
char *npath;
int pathlen;
get_parameters();
if ((pathlen = GetEnvironmentVariable("PATH",path,100)) == 0) {
error("No PATH variable (!)");
} else if (pathlen > 100) {
path = realloc(path,pathlen);
GetEnvironmentVariable("PATH",path,pathlen);
}
npath = malloc(strlen(path) + strlen(erlexec_dir) + 2);
sprintf(npath,"%s;%s",erlexec_dir,path);
SetEnvironmentVariable("PATH",npath);
if ((erlexec_handle = LoadLibrary(erlexec_name)) == NULL) {
error("Could not load module %s.",erlexec_name);
}
if ((win_erlexec = (ErlexecFunction *)
GetProcAddress(erlexec_handle,"win_erlexec")) == NULL) {
error("Could not find entry point \"win_erlexec\" in %s.", erlexec_name);
}
return (*win_erlexec)(argc,argv,erlexec_handle,WERL);
}
static char *replace_filename(char *path, char *new_base)
{
int plen = strlen(path);
char *res = malloc((plen+strlen(new_base)+1)*sizeof(char));
char *p;
strcpy(res,path);
for (p = res+plen-1 ;p >= res && *p != '\\'; --p)
;
*(p+1) ='\0';
strcat(res,new_base);
return res;
}
static char *do_lookup_in_section(InitSection *inis, char *name,
char *section, char *filename)
{
char *p = lookup_init_entry(inis, name);
if (p == NULL) {
error("Could not find key %s in section %s of file %s",
name,section,filename);
}
return _strdup(p);
}
static void copy_latest_vsn(char *latest_vsn, char *next_vsn)
{
/* Copy */
char *lp;
char *np;
/* Find vsn */
for (lp = next_vsn+strlen(next_vsn)-1 ;lp >= next_vsn && *lp != '\\'; --lp)
;
/* lp =+ length("erts-"); */
for (np = next_vsn+strlen(next_vsn)-1 ;np >= next_vsn && *np != '\\'; --np)
;
/* np =+ length("erts-"); */
for (; lp && np; ++lp, ++np) {
if (*lp == *np) {
continue;
}
if (*np == '.' || *np == '\0' || *np <= *lp) {
/* */
return;
}
if (*lp == '.' || *lp == '\0') {
strcpy(latest_vsn, next_vsn);
return;
}
}
return;
}
static char *find_erlexec_dir2(char *install_dir)
{
/* List install dir and look for latest erts-vsn */
HANDLE dir_handle; /* Handle to directory. */
char wildcard[MAX_PATH]; /* Wildcard to search for. */
WIN32_FIND_DATA find_data; /* Data found by FindFirstFile() or FindNext(). */
char latest_vsn[MAX_PATH];
/* Setup wildcard */
int length = strlen(install_dir);
char *p;
if (length+3 >= MAX_PATH) {
error("Cannot find erlexec.exe");
}
strcpy(wildcard, install_dir);
p = wildcard+length-1;
if (*p != '/' && *p != '\\')
*++p = '\\';
strcpy(++p, "erts*");
/* Find first dir */
dir_handle = FindFirstFile(wildcard, &find_data);
if (dir_handle == INVALID_HANDLE_VALUE) {
/* No erts-vsn found*/
return NULL;
}
strcpy(latest_vsn, find_data.cFileName);
/* Find the rest */
while((strncmp("erts", latest_vsn, 4) /= 0) &&
FindNextFile(dir_handle, &find_data)) {
copy_latest_vsn(latest_vsn, find_data.cFileName);
}
FindClose(dir_handle);
p = malloc((strlen(install_dir)+1+strlen(latest_vsn)+4+1)*sizeof(char));
strcpy(p,install_dir);
strcat(p,"\\");
strcat(p,latest_vsn);
strcat(p,"\\bin");
return p;
}
static char *find_erlexec_dir(char *erlpath)
{
/* Assume that the path to erl is absolute and
* that it is not a symbolic link*/
char *dir =_strdup(erlpath);
char *p;
char *p2;
/* Chop of base name*/
for (p = dir+strlen(dir)-1 ;p >= dir && *p != '\\'; --p)
;
*p ='\0';
p--;
/* Check if dir path is like ...\install_dir\erts-vsn\bin */
for (;p >= dir && *p != '\\'; --p)
;
p--;
for (p2 = p;p2 >= dir && *p2 != '\\'; --p2)
;
p2++;
if (strncmp(p2, "erts-", strlen("erts-")) == 0) {
p = _strdup(dir);
free(dir);
return p;
}
/* Assume that dir path is like ...\install_dir\bin */
*++p ='\0'; /* chop off bin dir */
p = find_erlexec_dir2(dir);
free(dir);
if (p == NULL) {
error("Cannot find erlexec.exe");
} else {
return p;
}
}
static void get_parameters(void)
{
char buffer[MAX_PATH];
char *ini_filename;
HANDLE module = GetModuleHandle(NULL);
InitFile *inif;
InitSection *inis;
char *bindir;
if (module = NULL) {
error("Cannot GetModuleHandle()");
}
if (GetModuleFileName(module,buffer,MAX_PATH) == 0) {
error("Could not GetModuleFileName");
}
ini_filename = replace_filename(buffer,INI_FILENAME);
if ((inif = load_init_file(ini_filename)) == NULL) {
erlexec_dir = find_erlexec_dir(ini_filename);
SetEnvironmentVariable("ERLEXEC_DIR", erlexec_dir);
} else {
if ((inis = lookup_init_section(inif,INI_SECTION)) == NULL) {
error("Could not find section %s in init file %s",
INI_SECTION, ini_filename);
}
erlexec_dir = do_lookup_in_section(inis, "Bindir", INI_SECTION, ini_filename);
free_init_file(inif);
}
erlexec_name = malloc(strlen(erlexec_dir) + strlen(ERLEXEC_BASENAME) + 2);
strcpy(erlexec_name,erlexec_dir);
strcat(erlexec_name, "\\" ERLEXEC_BASENAME);
free(ini_filename);
}
static void error(char* format, ...)
{
char sbuf[2048];
va_list ap;
va_start(ap, format);
vsprintf(sbuf, format, ap);
va_end(ap);
#ifndef WIN32_WERL
fprintf(stderr, "%s\n", sbuf);
#else
MessageBox(NULL, sbuf, "Werl", MB_OK|MB_ICONERROR);
#endif
exit(1);
}
Jump to Line
Something went wrong with that request. Please try again.