/* ***** BEGIN LICENSE BLOCK *****
 * Source last modified: $Id: postinst.cpp,v 1.3.4.3 2004/07/09 01:49:20 hubbe Exp $
 * 
 * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
 * 
 * The contents of this file, and the files included with this file,
 * are subject to the current version of the RealNetworks Public
 * Source License (the "RPSL") available at
 * http://www.helixcommunity.org/content/rpsl unless you have licensed
 * the file under the current version of the RealNetworks Community
 * Source License (the "RCSL") available at
 * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
 * will apply. You may also obtain the license terms directly from
 * RealNetworks.  You may not use this file except in compliance with
 * the RPSL or, if you have a valid RCSL with RealNetworks applicable
 * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
 * the rights, obligations and limitations governing use of the
 * contents of the file.
 * 
 * Alternatively, the contents of this file may be used under the
 * terms of the GNU General Public License Version 2 or later (the
 * "GPL") in which case the provisions of the GPL are applicable
 * instead of those above. If you wish to allow use of your version of
 * this file only under the terms of the GPL, and not to allow others
 * to use your version of this file under the terms of either the RPSL
 * or RCSL, indicate your decision by deleting the provisions above
 * and replace them with the notice and other provisions required by
 * the GPL. If you do not delete the provisions above, a recipient may
 * use your version of this file under the terms of any one of the
 * RPSL, the RCSL or the GPL.
 * 
 * This file is part of the Helix DNA Technology. RealNetworks is the
 * developer of the Original Code and owns the copyrights in the
 * portions it created.
 * 
 * This file, and the files included with this file, is distributed
 * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
 * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
 * ENJOYMENT OR NON-INFRINGEMENT.
 * 
 * Technology Compatibility Kit Test Suite(s) Location:
 *    http://www.helixcommunity.org/content/tck
 * 
 * Contributor(s):
 * 
 * ***** END LICENSE BLOCK ***** */

/************************************************************************
 * postinst.cpp - Post-install setup program.
 */


/***********************************************************************
 * includes
 */

#include "hxtypes.h"

// system includes
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <pwd.h>
#include <grp.h>
#include "hlxclib/time.h"

#include <termios.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <errno.h>
#include <sys/types.h>
#include <signal.h>

#if defined _AIX43
#include <strings.h>
#include "dllpath.h"
ENABLE_MULTILOAD_DLLACCESS_PATHS(Postinst);
#endif // _AIX43
#include <ctype.h>

#include "md5.h"

#include "product_version.h"

#include "package_info.h"
#include "package_name.h"
#include "consoleui.h"
#include "prodinstlib.h"
#include "inststrs.h"
#include "postinst.h"
#include "hxplayinst.h"
#include "safestring.h"


/***********************************************************************
 * defines
 */
#define PROG PACKAGE_NAME

/************************************************************************/

UnixInstaller::UnixInstaller(void)
{
    m_pProdInst = new HXPlayerInstaller();
    m_pUI = new ConsoleUI();
}

UnixInstaller::~UnixInstaller()
{
    delete m_pProdInst;
    delete m_pUI;
}


/************************************************************************
 * PromptForSettings
 */
void
UnixInstaller::PromptForSettings(void)
{
    int i=0;
    char* szResp=0;
    BOOL bDone = FALSE;

    m_pUI->ClearScreen();

    //
    // Prompt for destination directory
    //
    m_pUI->PromptForItem("Directory: ",
        m_pProdInst->m_szDestDir, &m_pProdInst->m_szDestDir,
        "Enter the complete path to the directory where you want\n"
        PROG " to be installed.  You must specify the full\n"
        "pathname of the directory and have write privileges to\n"
        "the chosen directory.\n");
    m_pUI->ClearScreen();
}


//
// Status
//
void
UnixInstaller::ShowStatus(BOOL bShowPass)
{
    m_pUI->ShowMessage(
        "You have selected the following " PROG " configuration:\n");
    m_pUI->ShowMessage("\n");

    m_pUI->ShowMessage("Destination:            %s\n",
                       m_pProdInst->m_szDestDir);
    m_pUI->ShowMessage("\n");
}




void
UnixInstaller::Run(int argc, char* argv[])
{
    BOOL bDone = FALSE;
    char szCmd[1024];

    //
    // Initialization
    //
    srandom(time(0));
    m_pProdInst->SetDefaults();
    m_pProdInst->ParseCmdLine(argc, (const char**)argv);

    //
    // Intro message
    //
    if(!m_pProdInst->m_bSilent)
    {
        char szMsg[1024];
        SafeSprintf(szMsg, 1024, "\n"
            "Welcome to the %s (%s) Setup for UNIX\n"
            "Setup will help you get %s running on your computer.\n",
		PACKAGE_NAME, TARVER_STRING_VERSION, PACKAGE_NAME);
//            ProductVersion::ProductName(), ProductVersion::ReleaseName(),
//            ProductVersion::VersionString(), ProductVersion::ProductName());
        m_pUI->ShowMessage(szMsg);
    }

    if (!m_pProdInst->m_bNonInteractive)
    {
        m_pUI->WaitForEnter("Press [Enter] to continue...");
    }

    //
    // Prompt user for configuration information
    //
    if (m_pProdInst->m_bNonInteractive)
    {
        if(!m_pProdInst->m_bSilent)
        {
            ShowStatus(TRUE);
        }
    }
    while (!bDone && !m_pProdInst->m_bNonInteractive)
    {
//        m_pProdInst->m_szAdminPass=0;
        PromptForSettings();
//        m_pProdInst->m_szEncPass = m_pProdInst->m_szAdminPass;
//        m_pProdInst->m_szMonPass = m_pProdInst->m_szAdminPass;
        ShowStatus(FALSE);
        BOOL bAnswered = FALSE;
        while (!bAnswered && !bDone)
        {
            m_pUI->ShowMessage(
                "Enter [F]inish to begin copying files, or [P]revious to go\n"
                "back to the previous prompts:");
            char* szResponse = (char*)"F";
            m_pUI->PromptForItem("", szResponse, &szResponse, "");
            if (strcasecmp(szResponse, "f") == 0)
                bDone = TRUE;
            else if (strcasecmp(szResponse, "p") == 0)
                bAnswered = TRUE;
        }
    }

    //
    // Copy the files to the destination directory
    //
    if (!m_pProdInst->m_bNonInteractive)
    {
        m_pUI->ClearScreen();
        m_pUI->ShowMessage("\n");
    }

    if(!m_pProdInst->m_bSilent)
    {
        m_pUI->ShowMessage("Copying " PROG " files...");
        m_pUI->FlushOutput();
        m_pUI->StartPrintingDots();
    }

    // make sure it exists!
    if (mkdir(m_pProdInst->m_szDestDir, 0755) != 0 && errno != EEXIST)
    {
        if(!m_pProdInst->m_bSilent)
        {
            m_pUI->ShowErrorMessage(
                "Error creating directory %s (%s), exiting...\n",
                m_pProdInst->m_szDestDir, strerror(errno));
        }
        m_pProdInst->CleanUpAndExit(-1, m_pUI);
    }


    const char* pLog = m_pProdInst->GetInstallLog();
    const char* pCmdFormat;

#if defined(_OPENBSD)
    if (pLog)
    {
	pCmdFormat = "tar cf - . | (cd \"%s\"; tar xvf - >> \"%s\")";
    }
    else
    {
	pCmdFormat = "tar cf - . | (cd \"%s\"; tar xf -)";
    }
#else
    if (pLog)
    {
	pCmdFormat = "tar cf - . | (cd \"%s\"; tar xovf - >> \"%s\")";
    }
    else
    {
	pCmdFormat = "tar cf - . | (cd \"%s\"; tar xof -)";
    }
#endif

    if (pLog)
    {
	time_t t = time(NULL);
	SafeSprintf(szCmd, 1024, "echo \"%s %s installation log %s\" > %s/%s",
		    ProductVersion::ProductName(),
		    ProductVersion::VersionString(),
		    ctime(&t),
		    m_pProdInst->m_szDestDir,
		    pLog);
	m_pProdInst->System(szCmd);
	SafeSprintf(szCmd, 1024, "echo \"files extracted to %s:\" >> %s/%s",
		    m_pProdInst->m_szDestDir,
		    m_pProdInst->m_szDestDir,
		    pLog);
	m_pProdInst->System(szCmd);
    }

    SafeSprintf(szCmd, 1024, pCmdFormat, m_pProdInst->m_szDestDir, pLog);
    m_pProdInst->System(szCmd);

    // execute our post-install scripts
    const char* pSetupFormat;
    if (pLog)
    {
	SafeSprintf(szCmd, 1024, 
		    "echo \"\npost-install setup commands:\" >> %s/%s",
		    m_pProdInst->m_szDestDir,
		    pLog);
	m_pProdInst->System(szCmd);

	pSetupFormat = "(cd \"%s\"; ./postinst/postinst.sh %s %s)";
    }
    else
    {
	pSetupFormat = "(cd \"%s\"; ./postinst/postinst.sh %s)";
    }
    SafeSprintf(szCmd, 1024, pSetupFormat,
		m_pProdInst->m_szDestDir, m_pProdInst->m_szDestDir, pLog);
    m_pProdInst->System(szCmd);

    //
    // Final Status message
    //
    if(!m_pProdInst->m_bSilent)
    {
        m_pUI->StopPrintingDots();
        m_pUI->ShowMessage("\n" STR_DONE_MESSAGE "\n");
    }

    //
    // Cleanup and exit
    //
    m_pProdInst->CleanUpAndExit(0, m_pUI);
}


/************************************************************************/
/************************************************************************
 * main()
 */
int
main(int argc, char* argv[])
{
    UnixInstaller* pInstaller = new UnixInstaller();
    pInstaller->Run(argc, argv); // does not return...
}
