/*
 * @(#)iws.c 1.1.0
 *
 * Copyright (c) 1998-1999 Servertec. All Rights Reserved.
 *
 * This software is the confidential and proprietary information of
 * Servertec ("Confidential Information").  You shall not disclose
 * such Confidential Information and shall use it only in accordance
 * with the terms of the license agreement you entered into with
 * Servertec.
 *
 * SERVERTEC MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY
 * OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 * PURPOSE, OR NON-INFRINGEMENT. SERVERTEC SHALL NOT BE LIABLE FOR ANY
 * DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
 *
 * THIS NOTICE MUST NOT BE ALTERED NOR REMOVED.
 *
 * CopyrightVersion 1.0
 */

#define PACKAGE "stec.iws."
#define CLASS "iws"

#include "parse_params.h"

#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <process.h>
#endif

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <signal.h>

#define KB 1024
#define BUF_SIZE (((8 * KB) + 1) * sizeof(char))

#ifdef _WIN32
#define RESTART 0x7fff
#else
// this is a kludge for Linux which mangles the return code
// the real value that stec.iws.iws returns is 0x7fff
#define RESTART 65280
#endif

#define JAVA "java"
#define SPACE " "
#define PATHSIZE 256
#define MSVM "jview"

void error(char *msg)
{
    fprintf(stderr, "%s\n", msg);
    exit(-1);
}

char *envfilenm = NULL;

void _wrapup(void)
{
	if(envfilenm != NULL)
	{
		remove(envfilenm);
		envfilenm = NULL;
	}
}

void wrapup(int i)
{
	_wrapup();
}

int main( int argc, char *argv[], char *envp[] )
{
	char *java_exe;
	char *classpath;
    char buf[BUF_SIZE];
	char **envarg;
	int rc;
	FILE *envFH;
	int count;

	int length;
	char *p;

#ifdef _WIN32
    char **args, **ap;
	char *param;

	int usingMSVM;
	int lMSVM;
	int i;
#else
	char command[BUF_SIZE];
#endif

	signal(SIGINT, wrapup);
	signal(SIGTERM, wrapup);
	signal(SIGABRT, wrapup);
#ifdef _WIN32
	signal(SIGBREAK, wrapup);
#else
	signal(SIGHUP, wrapup);
	signal(SIGQUIT, wrapup);
#endif

	atexit(_wrapup);

	// setup java
	java_exe = (char *)getenv("JAVA_EXE");
    if(java_exe == 0)
	{
		error("JAVA_EXE is not defined.");
	}

	count = count_args(java_exe);
	if(count == 0)
	{
		error("JAVA_EXE is empty.");
	}
	
#ifdef _WIN32
	param = extract_arg(java_exe, 0);

	strip_quotes(param);

	// which java vm, microsoft/javasoft
	usingMSVM = FALSE;
	p = param;
	lMSVM = strlen(MSVM);
	length = strlen(param) - lMSVM + 1;
	for(i = 0; i < length; i++)
	{
		if(strnicmp(p, MSVM, lMSVM) == 0)
		{
			usingMSVM = TRUE;
			break;
		}

		p++;
	}

	// add 4 for parameters: -classpath <classpath> <package>.<class> 0x00
    ap = args = (char **)malloc((argc + count + 4) * sizeof(char *));
    
	*ap++ = param;

	for(i = 1; i < count; i++)
	{
		param = extract_arg(java_exe, i);
		strip_quotes(param);
		
		*ap++ = param;
	}

	// setup args

	// setup classpath
	classpath = (char *)getenv("CLASSPATH");
    if (classpath == 0)
		error("CLASSPATH is not defined.");

	if(!usingMSVM)
	{
		sprintf(buf, "-classpath %s", classpath);
	    *ap++ = strdup(buf);
	}
#else
	// setup java executable
	strcpy(command, java_exe);

	// setup args
    strcat(command, SPACE);

	// setup classpath
	classpath = (char *)getenv("CLASSPATH");
    if (classpath == 0)
		error("CLASSPATH is not defined.");

    sprintf(buf, "-classpath %s", classpath);
	strcat(command, buf);
#endif

	// setup env file
	envfilenm = (char *)tempnam(NULL, "~" CLASS);
	if(envfilenm == NULL)
		error("Unable to create a temp filename.");

	envFH = fopen(envfilenm, "wb");

	// setup environmental variables
	
	envarg = envp;
	while(*envarg)
	{
		fprintf(envFH, "%s\n", *envarg++);
	}

	fflush(envFH);
	fclose(envFH);

#ifdef _WIN32
	if(usingMSVM)
		sprintf(buf, "/D:env=%s", envfilenm);
	else
		sprintf(buf, "-Denv=%s", envfilenm);

	*ap++ = strdup(buf);

	// setup CLASS executable
    *ap++ = strdup(PACKAGE CLASS);

	// setup user arguements
    while(--argc > 0)
	{
		*ap++ = strdup(*++argv);
	}

    *ap = NULL;
#else
	sprintf(buf, "-Denv=%s", envfilenm);
    strcat(command, SPACE);
	strcat(command, buf);

	// setup CLASS executable
    strcat(command, SPACE);
	strcat(command, PACKAGE CLASS);

	// setup user arguements
    while (--argc > 0)
	{
	   	strcat(command, SPACE);
		strcat(command, *++argv);
	}
#endif

	do
	{
#ifdef _WIN32
		rc = spawnv(P_WAIT, args[0], args);
#else
		rc = system(command);
#endif
	}
	while(rc == RESTART);

	return rc;
}
