/* SCCSID: addins/ibm/install_addin/install_addin.c, dss_cdsa_addins, addins_rel2, dss_980303 1.4 3/5/98 14:12:06 */
/*
 * (C) COPYRIGHT International Business Machines Corp. 1997
 * All Rights Reserved
 * Licensed Materials - Property of IBM
 *
 */
//-----------------------------------------------------------------------
//
//	File Name:		install_addin.c
//
//	Description:	Generic install program
//
//	Version:		1.0
//
//	Comments:		This program implements the common part needed to install
//					any CDSA-compliant addin.  Each addin developer can create
//					an executable that will install the addin by using this
//					file as the main program and using an addin-specific
//					file to define certain well-defined symbols like the
//					info structure.
//
//					This approach results in reusable code for the generic
//					install to the extent possible.
//
//	Change Flags:
//
//		SHM000	06/24/97	Original generic install program
//
//-----------------------------------------------------------------------

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include "cssm.h"
#include "install_addin.h"

#define	MAX_PATH_LEN	512

static void 
Usage(char **argv)
{
	printf("%s <addin filename> <addin directory> 'install'|'uninstall'\n", argv[0]);
	printf("  Installs the named addin.\n");
	printf("  If no arguments are given, you will be prompted\n");
}

static CSSM_RETURN 
ProcessArgs(int argc, char **argv, char *NameString, char *FileString, char *DirString, char *ActionString)
{
	CSSM_RETURN rc;
	CSSM_BOOL				Prompt = FALSE;

	rc = CSSM_OK;

	// Process arguments

	if (argc == 4)
	{
		strcpy(FileString,		argv[1]);
		strcpy(DirString,		argv[2]);
		strcpy(ActionString,	argv[3]);
	}
	else if (argc == 1)
	{
		Prompt = TRUE;
	}
	else
	{
		Usage(argv);
		rc = CSSM_FAIL;
	}

	// Prompt if necessary

	if (Prompt == TRUE) {
		printf("addin directory?\n");
        fflush(stdin); 
		gets(DirString);

		printf("addin filename? \n");
        fflush(stdin); 
		gets(FileString);

		printf("action? [install|uninstall]\n");
        fflush(stdin); 
		gets(ActionString);
	}

	// Note: currently we will not prompt for name to minimize user input
	// and equate it to the string given for the filename
	strcpy(NameString, FileString);

	return rc;
}

static void 
MyFree (void *MemPtr, void *AllocRef)
{	
	free (MemPtr);
}

static void *
MyMalloc (unsigned int Size, void *AllocRef)
{	
	return malloc (Size);
}

static void *
MyRealloc (void *MemPtr, unsigned int Size, void *AllocRef)
{	
	return realloc (MemPtr, Size);
};

static void *
MyCalloc (unsigned int Num, unsigned int Size, void *AllocRef)
{	
	return calloc (Num, Size);
}

static CSSM_RETURN 
InitializeCSSM(void)
{
	CSSM_RETURN				rc = CSSM_OK;
	CSSM_API_MEMORY_FUNCS   MemoryFuncs;
	CSSM_VERSION			CSSMVersion = { CSSM_MAJOR, CSSM_MINOR };
    CSSM_ERROR_PTR          CSSMError;  

	// Initialize CSSM

    MemoryFuncs.malloc_func 	= MyMalloc;
    MemoryFuncs.free_func 		= MyFree;
    MemoryFuncs.realloc_func 	= MyRealloc;
    MemoryFuncs.calloc_func 	= MyCalloc;

    rc = CSSM_Init(&CSSMVersion, &MemoryFuncs, NULL);

    if (rc != CSSM_OK)
    {
		CSSMError = CSSM_GetError();
		printf("CSSM_Init failed\n");
		rc = CSSMError->error;
    }

	return rc;
}


static CSSM_RETURN 
GetModuleInfoAndGUID(CSSM_MODULE_INFO **ModuleInfo, CSSM_GUID **ModuleGUID)
{
	CSSM_RETURN	rc = CSSM_OK;

	// Get module info; this function must be implemented by the addin provider

	rc = GetModuleInfo(ModuleInfo);
	
	if (rc != CSSM_OK)
	{
		printf("GetModuleInfo failed\n");
	}

	// Get module GUID; this function must be implemented by the addin provider

	if (rc == CSSM_OK)
	{
		rc = GetModuleGUID(ModuleGUID);
	}
	
	if (rc != CSSM_OK)
	{
		printf("GetModuleGUID failed\n");
	}

	return rc;
}

int main(int argc, char **argv)
{
	CSSM_RETURN				rc = CSSM_OK;
	char					NameString[MAX_PATH_LEN];
	char 					FileString[MAX_PATH_LEN];
	char 					DirString[MAX_PATH_LEN];
	char					ActionString[MAX_PATH_LEN];
	CSSM_MODULE_INFO		*ModuleInfo;
	CSSM_GUID				*ModuleGUID;

	// Process arguments

	rc = ProcessArgs(argc, argv, NameString, FileString, 
					 DirString, ActionString);

	if (rc == CSSM_OK)
	{
		rc = GetModuleInfoAndGUID(&ModuleInfo, &ModuleGUID);
	}

	if (rc == CSSM_OK)
	{
		rc = InitializeCSSM();
	}

	// Perform appropriate install/uninstall action

	if (rc == CSSM_OK)
	{
		if (strcmp(ActionString, "install") == 0)
		{
			rc = CSSM_ModuleInstall (NameString, FileString, DirString,
									 ModuleGUID, ModuleInfo, 
									 NULL, NULL);
		}
		else if (strcmp(ActionString, "uninstall") == 0)
		{
			// TBD: put in ModuleUninstall code
			rc = CSSM_ModuleUninstall (ModuleGUID);
		}
	}

	if (rc != CSSM_OK)
	{
		printf("Exiting with rc = %d\n", rc);
	}

	return rc;
}
