#!/bin/ch
/* Ch package installer script in Ch
=======================================================================

                          Ch Package Installer
               Proprietary and Confidential Information

 This material contains, and is part of a computer software program
 which is, proprietary and confidential information owned by 
 SoftIntegration, Inc.  The program, including this material,
 may not be duplicated, disclosed or reproduced in whole or in part for
 any purpose without the express written authorization of 
 SoftIntegration, Inc. All authorized reproductions must be marked with 
 this legend.

                       Copyright (c) 2001-2002
                        SoftIntegration, Inc.
                         All rights reserved
========================================================================

       installpkg.ch -- Install Ch package

       Use:  ch  ./installpkg.ch
       Description:    This script installs a Ch package on a Unix machine
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>
#define NUMTRYTIMES 3   /* maximum number of try */

int main(int argc, char **argv)
{

   char usage[] = 
      "Usage: installpkg.ch [-ut] package_name\n"
      "       -u will uninstall the ch package 'package_name'\n"
      "          ex: installpkg.ch -u chpackage\n";
   string_t str_copyright = 
	  "==================================================================\n\n"
      "                    Ch Package Installation                       \n"
      "        Copyright (c) 2001-2002 by SoftIntegration, Inc.          \n\n"
      "==================================================================\n\n"
      "  BY INSTALLING THIS SOFTWARE YOU ARE CONSENTING TO BE BOUND BY   \n"
      "  AND ARE BECOMING A PARTY TO THE AGREEMENT FOUND IN THE          \n"
      "  FOLLOWING LICENSE FILE. IF YOU DO NOT AGREE TO ALL OF THE TERMS \n"
      "  OF THIS AGREEMENT, PLEASE DO NOT INSTALL OR USE THIS SOFTWARE.  \n\n";
   string_t user;
   string_t cmd;
   string_t ch_home;
   string_t str_pkgname;
   string_t str_pkgname_path;
   string_t str_pkgname_bin;
   string_t str_pkgname_tar;
   string_t str_pkgname_tgz;
   string_t str_installation_file;
   string_t str_installation_file_path; 
   string_t str_token;
   string_t str_temp;
   string_t str_tinclude_dir;
   string_t str_chrc_file;
   char check;
   char command_dir[512];
   char *s, *arg;
   int flag, numtrytimes;
   int u_option = false;
   int i_option = false;
   int got_pkgname = false;
   int install_file_ok = 0;
   int pkg_dir_ok = 0;
   FILE *fptr_install;
   FILE *fptr_chrc;

   argc--; argv++;
   while(argc>0 && **argv =='-')
   {
      for(s = argv[0]+1; *s&&*s!=' '; s++)  /* empty space not valid option */
      switch(*s)
      {
         case 'u':
            u_option = true;   /* uninstall package */
            break;
         default:
            fprintf(stderr,"Warning: invalid option %c\n\n", *s);
            fprintf(stderr,usage);
		    exit(1);
            break;
         }
      argc--; argv++;
   } 

   while(argc>0)            /* process list of argument */
   {
      arg = *argv;
      argc--; argv++;
      if(strcmp(arg, "-u") == 0) /* optional arg ? */
      {
         u_option = true;      /* option -u */
         continue;
      }
      if(!got_pkgname)
      {
	     str_pkgname_path = arg;
         got_pkgname = true;
	     continue;
      }
   
      fprintf(stderr,"Warning: Too many arguments.\n\n");
      fprintf(stderr,usage);
      exit(1);
   }

   if( u_option && (!got_pkgname)) 
   {	
      fprintf(stderr,"\nWarning: Found '-u' with no package name.\n\n");
      fprintf(stderr,usage);
      exit(1);
   }

   if( !got_pkgname )
   {
	  fprintf(stderr,"\nYou did not specify a package to install.\n\n");
      fprintf(stderr,usage);
      exit(1);
   }

   foreach(str_temp;str_pkgname_path;"\0";"/")
   {
      if(str_temp == NULL)
	     break;
	  str_pkgname = str_temp;
   } 
   if(strstr(str_pkgname_path, "/"))
   {
      strncpy(str_pkgname_path, str_pkgname_path, strlen(str_pkgname_path)-strlen(str_pkgname)-1);
   }
   else
   {
      strncpy(str_pkgname_path, str_pkgname_path, strlen(str_pkgname_path)-strlen(str_pkgname));
   }


   str_temp = strstr(str_pkgname, ".bin");
   if(str_temp == NULL)
      str_pkgname_bin = stradd(str_pkgname, ".bin");
   else
   {
      str_pkgname_bin = str_pkgname;
      strncpy(str_pkgname, str_pkgname, strlen(str_pkgname)-strlen(".bin")); 
   }

   str_temp = strstr(str_pkgname, "\\"); 
   if(str_temp != NULL)
   {
      strncpy(str_pkgname, str_pkgname, strlen(str_pkgname)-1); 
   }

   str_pkgname_tar = stradd(str_pkgname, ".tar");
   str_pkgname_tgz = stradd(str_pkgname_tar, ".gz");
  
   /* Get installation directory for ch toolkit */
   ch_home=getenv("CHHOME");
   if (ch_home==NULL) {
      printf("Sorry, CHHOME cannot be found\n");
      printf("Please install Ch first from http://www.softintegration.com\n");
      exit(0);
   }

   if(access(ch_home, W_OK))
   {
      fprintf(stderr, "You do not have enough privileges to add or remove this package.\n");
      exit(0);
   }

   if(u_option)
   {
	  // installation file exists ?
      if(!access(stradd(ch_home, "/package/installed/", str_pkgname), R_OK))
      {
		  install_file_ok = 1;
	  }

	  // package exists ?
      if(!access(stradd(ch_home, "/package/", str_pkgname), R_OK)) 
      {
		  pkg_dir_ok = 1;
      } 

	  if( pkg_dir_ok && !install_file_ok)
      {
		  fprintf(stderr, "\nThe Ch package %s appears to have been installed\n"
             "but the Installation information file does not exist.\n"
             "Would you like to completely remove the directory? (Y or N): "
			 , str_pkgname);

          check = getchar();
          if (!(check=='y' || check == 'Y')) 
          {
            exit(1);
          } 
          while(getchar() != '\n');
		  printf("\n");
		  str_temp = stradd(ch_home, "/package/", str_pkgname);
		  rm -rf $str_temp
      }
      else if( !pkg_dir_ok && !install_file_ok)
	  {
          fprintf(stderr, "\nThe Ch package %s does not appear to be"
				          " installed\n\n", str_pkgname);
          exit(0);
	  }
	  else
	  {
		 if(!pkg_dir_ok)
		 {
         printf("\nThe package directory does not exist but an installation"
		        " file for the\npackage was found.  Removing possible"
				" remaining files.\n");
		 }

         str_temp = stradd(ch_home, "/package/installed/", str_pkgname); 
         str_installation_file = `cat $str_temp`;
   
         foreach( str_token; str_installation_file )
         {
            rm -rf $str_token
         }

         str_temp = stradd(ch_home, "/package/installed/", str_pkgname); 
         rm -rf $str_temp
	  }
      
      printf("\nThe Ch package %s has been uninstalled.\n\n", str_pkgname);
      exit(0);
   }
   /* end uninstall option */

   cmd = `ch -rv`;
   if(strstr(cmd, "ERROR")) 
   {
      printf("Error: The Ch version installed is too old for this package,\n"
             "please download a new version from http://www.softintegration.com\n");
      exit(0);
   }

   if(access(stradd(str_pkgname_path, str_pkgname_bin), R_OK))
   {
      fprintf(stderr, "\nPackage %s not found.\n\n", stradd(str_pkgname_path, str_pkgname_bin));
      fprintf(stderr, "It might have been removed after the first successful installation.\n");
      fprintf(stderr, "You may need to unpack the downloaded file again for reinstallation\n\n");
      exit(1);
   }

   /* check for write permission */
   if(access(ch_home, W_OK))  /* writable ? */
   {
      fprintf(stderr, "You have no write permision in the Ch home\n");
      fprintf(stderr, "directory %s to install this package.\n", ch_home);
      exit(1);
   }

   printf("%s\n", str_copyright);
   
   if(!access("./LICENSE.TXT", R_OK)) 
   {
      more LICENSE.TXT
   }
   else if (!access("./LICENSE", R_OK)) 
   {
      more LICENSE
   }
   else if(!access("./license.txt", R_OK)) 
   {
      more license.txt
   }
   else if(!access("./license", R_OK)) 
   {
      more license
   }
   
   printf("Do you agree to the license terms? (y/n)[n] ");

   check = getchar();
   if (!(check=='y' || check == 'Y')) 
   {
     exit(1);
   } 
   while(getchar() != '\n');

   /* Create license */
   /*
   if(!access("license.gen", R_OK&X_OK))  
   {
      if(system("./license.gen") != 0) 
         exit(-1);
   }
   */


   str_installation_file_path = stradd(ch_home, "/package/installed/", str_pkgname);

   if( !access(str_installation_file_path, R_OK))
   {
      printf("\nPrevious %s package already installed.\n"
			 "Uninstall before continuing? (Y or N): ", str_pkgname);
      check = getchar();
      if( check != 'y' && check != 'Y' )
         exit(0);
      while(getchar() != '\n');
      installpkg.ch -u $str_pkgname
   }
   
   if( !access(stradd(ch_home, "/package/", str_pkgname), R_OK))
   {
      fprintf(stderr, "\n\nIt appears that the %s package was insalled by hand without running\n"
                      "the installation file or the package directory was not completely removed\n" 
					  "during previous uninstallation.\n"
					  "Overwrite and continue installations(Y or N)?: ", str_pkgname);

      check = getchar();
      if (!(check=='y' || check == 'Y')) 
      {
         exit(1);
      } 
      while(getchar() != '\n');
	  printf("\n");
   }

   printf("Installing the Ch package to %s now, please wait...\n", stradd(ch_home,"/package"));

   str_temp = stradd(ch_home, "/package/installed");
   if( access(str_temp, R_OK) )
   {
      mkdir $str_temp
   }  
   
   if( (fptr_install = fopen(str_installation_file_path, "w")) == NULL)
   {
      fprintf(stderr, "\n\nERROR: fopen: Cannot open file %s for write.\n\n", str_installation_file_path); 
      exit(1);
   }
   
#ifdef _WIN32_
   str_temp = stradd(str_pkgname_path, str_pkgname_bin);
   cp -f $str_temp $ch_home
   cd $ch_home;
   mv -f $str_pkgname_bin $str_pkgname_tgz
   gzip -d $str_pkgname_tgz
   tar -xf $str_pkgname_tar
   rm -rf $str_pkgname_tar
   cd -;
#else
   if(!access("README", R_OK) || !access("README.install", R_OK) || !access("README.txt", R_OK) || !access("README.TXT", R_OK))
   {
	  str_temp = stradd(str_pkgname_path,str_pkgname_bin);
      gzip -dc $str_temp | (cd $ch_home; tar -xmf -)
   }
   else 
   {
	  str_temp = stradd(str_pkgname_path,str_pkgname_bin);
      cat $str_temp | (cd $ch_home; tar -zxmf -)
   }
#endif

   fprintf(fptr_install, "%s\n", stradd(ch_home,"/package/", str_pkgname));

   str_tinclude_dir = stradd(ch_home, "/package/", str_pkgname, "/tinclude");
   if(!access(str_tinclude_dir, R_OK))
   {
      cd $str_tinclude_dir;
      str_tinclude_dir = `ls`;
      str_temp = stradd(ch_home, "/toolkit/include");
      foreach(str_token; str_tinclude_dir)
      {
         cp -rf $str_token $str_temp
         fprintf(fptr_install, "%s\n", stradd(str_temp, "/",str_token));
      }
   }
   else
   {
      cd ~
      #if defined(_WIN32_)
         str_chrc_file = `cat _chrc`;
      #else
         str_chrc_file = `cat .chrc`;
      #endif
     
	  str_temp = stradd("_ipath=stradd(_ipath,\"",ch_home,"/package/", str_pkgname, "/include;\");");
      foreach(str_token;str_chrc_file;"\0";" ")
	  {
		  if(!strcmp(str_token, str_temp))
		  {
			  str_token = "found";
			  break;
		  }
	  }
	  if(str_token == NULL)
	  {

#if defined(_WIN32_)
        if( (fptr_chrc = fopen("_chrc", "a")) == NULL)
#else
        if( (fptr_chrc = fopen(".chrc", "a")) == NULL)
#endif
        {
           fprintf(stderr, "\nERROR: fopen: Unable to open ~/_chrc for append\n"
	                   "You must add %s to your\n"
			   "_chrc file and restart ch before running any demos.\n"
                  ,str_temp);
	  } 
	  else
	  {
	     fprintf(fptr_chrc, "%s\n", str_temp);
         fclose( fptr_chrc);
		 printf("\nNOTE: You must restart Ch before running any demos.\n\n");
	  }
	  }
	  cd -
   }
   fclose( fptr_install);

   /* Create license */
   /*
   if(!access("license.gen", R_OK&X_OK))  
   {
      if(!access("/tmp/ChToolkit_license.key", R_OK)) 
      {
         cat /tmp/ChToolkit_license.key >> $(ch_home)/toolkit/license/license.key
      }
   //else 
   //{
   //  printf("Error: failed to generate license file \n");
   //}
   }
   */

   printf("Files has been successfully installed.\n"
          "The Ch Package installation is complete.\n\n");

   printf("Garbage cleaning begins...\n");

/*
   if(!access("README", R_OK) || !access("README.install", R_OK)) 
   {
	  str_temp = stradd(str_pkgname_path, str_pkgname_bin);
      rm -f $str_temp
      
	  if(!access(stradd(str_pkgname_path,"license.gen"), R_OK&X_OK))  
      {
	     str_temp = stradd(str_pkgname_path, "license.gen");
         rm -f $str_temp
      }
   }
*/

   printf("Garbage cleaning ends... \n"); 

   printf("\nPlease read the %s\n", stradd(ch_home,"/package/", str_pkgname, "/README")); 
   printf("Please try demo the available programs for this package\n"
          "   in %s\n\n", stradd(ch_home, "/package/", str_pkgname, "/demos")); 

   if(!access(stradd(ch_home,"/package/", str_pkgname, "/postinstall.ch"), R_OK))
   {
      printf("You must run the post install file,\n"
             "   %s\nbefore running any demos.\n\n\n",
              stradd(ch_home,"/package/", str_pkgname, "/postinstall.ch"));
   }

  return 0;
}
