Files correlati : ba2 Ricompilazione Demo : [ ] Commento : ba1700 messi in minuscolo TRUE e FALSE ba2700 corretta lettura dizionari molto grandi git-svn-id: svn://10.65.10.50/trunk@14224 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1502 lines
		
	
	
		
			41 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1502 lines
		
	
	
		
			41 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <stdio.h>
 | 
						||
 | 
						||
#include <cfiles.h>
 | 
						||
 | 
						||
#include <agasys.h>
 | 
						||
#include <applicat.h>
 | 
						||
#include <defmask.h>
 | 
						||
#include <dongle.h>
 | 
						||
#include <execp.h>
 | 
						||
#include <isamrpc.h>
 | 
						||
#include <modaut.h>
 | 
						||
#include <progind.h>
 | 
						||
#include <sheet.h>
 | 
						||
#include <utility.h>
 | 
						||
 | 
						||
#include "ba1.h"
 | 
						||
#include "ba1500.h"
 | 
						||
#include "ba1600.h"
 | 
						||
#include "ba1700a.h"
 | 
						||
 | 
						||
// definizioni delle colonne dello sheet
 | 
						||
#define C_MODULE 1
 | 
						||
#define C_CODE 2
 | 
						||
#define C_RELEASE 3
 | 
						||
#define C_PATCH 4
 | 
						||
#define C_DATAREL 5
 | 
						||
#define C_CURRRELEASE 6
 | 
						||
#define C_CURRPATCH 7
 | 
						||
#define C_CURRDATAREL 8
 | 
						||
#define C_ISPATCH 9
 | 
						||
#define C_BASEPATCH 10
 | 
						||
 | 
						||
#ifdef _DEMO_
 | 
						||
  const char* const http_default_path = "/aga/demo/zip/";
 | 
						||
#else
 | 
						||
  const char* const http_default_path = "/aga/program/zip/";
 | 
						||
#endif
 | 
						||
 | 
						||
HIDDEN int compare_version(const char* v1, int p1, const char* v2, int p2)
 | 
						||
{
 | 
						||
  TString16 ver1(v1), ver2(v2);
 | 
						||
  ver1.trim();
 | 
						||
  if (ver1.len() == 4)
 | 
						||
    ver1.insert((v1[0] == '9') ? "19" : "20", 0);
 | 
						||
  ver2.trim();
 | 
						||
  if (ver2.len() == 4)
 | 
						||
    ver2.insert((v2[0] == '9') ? "19" : "20", 0);
 | 
						||
 | 
						||
  int res = ver1.compare(ver2, -1, true);
 | 
						||
  if (res == 0)
 | 
						||
    res = p1 - p2;
 | 
						||
 | 
						||
  return res;
 | 
						||
}
 | 
						||
 | 
						||
HIDDEN word version2year(const char* v)
 | 
						||
{
 | 
						||
  TString16 ver(v);
 | 
						||
  if (ver.len() == 4)
 | 
						||
    ver.insert((v[0] == '9') ? "19" : "20", 0);
 | 
						||
  ver.cut(4);
 | 
						||
  return atoi(ver);
 | 
						||
}
 | 
						||
 | 
						||
bool is_internet_path(const TString& addr)
 | 
						||
{
 | 
						||
  if (addr.compare("www.", 4, true) == 0)
 | 
						||
    return true;
 | 
						||
 | 
						||
  if (addr.compare("http:", 5, true) == 0)
 | 
						||
    return true;
 | 
						||
 | 
						||
  int a1, a2, a3, a4;
 | 
						||
  if (sscanf(addr, "%d.%d.%d.%d", &a1, &a2, &a3, &a4) == 4)
 | 
						||
    return true;
 | 
						||
 | 
						||
  return false;
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// Maschera principale
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
class TInstaller_mask : public TArray_sheet
 | 
						||
{
 | 
						||
  static TInstaller_mask* _curr_mask;
 | 
						||
  bool _installed; // Flag per verificare se almeno un modulo e' stato installato
 | 
						||
  bool _sys_installed; //Flag per controllare l'installazione del modulo di sistema SY
 | 
						||
  
 | 
						||
  enum { NONE = 0, NEW_MENU = 1, NEW_MENUPRG = 2, NEW_INSTALLER = 4, NEW_DLL = 8 };
 | 
						||
  int _reboot_program;
 | 
						||
 | 
						||
protected: // TSheet
 | 
						||
  virtual bool on_key(KEY key);
 | 
						||
  static bool quit_handler(TMask_field& f, KEY k);
 | 
						||
  static bool tutti_handler(TMask_field& f, KEY k);
 | 
						||
  int get_module_number(const TString& module) const;
 | 
						||
  bool has_module(int modnumber) const;
 | 
						||
  bool is_zip_file(const TFilename& n) const;
 | 
						||
 | 
						||
  void create_dirs(const char* path) const;
 | 
						||
 | 
						||
protected:
 | 
						||
  static bool path_handler(TMask_field& fld, KEY key);
 | 
						||
  static bool sheet_notify(TSheet_field& s, int r, KEY k);
 | 
						||
  static bool install_handler(TMask_field& fld, KEY key);
 | 
						||
  static bool update_handler(TMask_field& f, KEY k);
 | 
						||
 | 
						||
  bool add_module(TConfig& ini, const TString& module, bool patch, int pos=-1);
 | 
						||
  bool add_header(TConfig& ini, const TString& module, bool patch);
 | 
						||
  int precheck_modules(bool only_newer=true);
 | 
						||
  void update_version();
 | 
						||
 | 
						||
  int needs_reboot(const TFilename& file) const;
 | 
						||
  bool move_file(const TFilename& src, const TFilename& dst) const;
 | 
						||
  bool move_module(const TString& module, TInstall_ini& ini, bool update) const;
 | 
						||
 | 
						||
  bool can_install(const char* module, TInstall_ini& ini);
 | 
						||
  void install_selection();
 | 
						||
  bool install_patches(const TString& module, const TString& lastrelease, int lastpatch , bool onlynew=true);
 | 
						||
  KEY askdisk(TString & path, TFilename & cmdline, int d, int dischi, const char * modulo);
 | 
						||
 | 
						||
  bool do_process(TToken_string& commands) const;
 | 
						||
  bool pre_process(TInstall_ini& ini, const char* module) const;
 | 
						||
  bool post_process(TInstall_ini& ini, const char* module) const;
 | 
						||
  bool get_internet_path(TFilename& ininame) const;
 | 
						||
  void parse_internet_path(TString& http_server, TFilename& http_path) const;
 | 
						||
 | 
						||
public:
 | 
						||
  bool installed() const { return _installed;}
 | 
						||
  bool sys_installed() const { return _sys_installed;}
 | 
						||
  bool autoload();
 | 
						||
  bool install(const TString& module, int patch);
 | 
						||
  bool run_ba0close() const { return _reboot_program >= NEW_MENUPRG; } 
 | 
						||
 | 
						||
  TInstaller_mask();
 | 
						||
  virtual ~TInstaller_mask();
 | 
						||
};
 | 
						||
 | 
						||
TInstaller_mask* TInstaller_mask::_curr_mask = NULL;
 | 
						||
 | 
						||
// Copia nello sheet i dati di un modulo prendendoli da un .ini
 | 
						||
bool TInstaller_mask::add_module(TConfig& ini, const TString& module, bool patch, int pos)
 | 
						||
{
 | 
						||
  ini.write_protect();
 | 
						||
  bool ok = ini.set_paragraph(module);
 | 
						||
  if (ok)
 | 
						||
  {                     
 | 
						||
    const int numpatch = ini.get_int("Patch");
 | 
						||
    TString16 strpatch; 
 | 
						||
    if (numpatch > 0)
 | 
						||
      strpatch.format("%03d", numpatch);
 | 
						||
 | 
						||
    TToken_string row;
 | 
						||
    row = " ";   // Not selected
 | 
						||
    row.add(ini.get("Descrizione"));
 | 
						||
    row.add(module);
 | 
						||
    row.add(ini.get("Versione"));
 | 
						||
    row.add(strpatch);
 | 
						||
    row.add(ini.get("Data"));
 | 
						||
    row.add(patch ? "X" : " ", C_ISPATCH);
 | 
						||
    if (pos==-1)
 | 
						||
      add(row);
 | 
						||
    else
 | 
						||
      insert(row,pos);
 | 
						||
  }
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
// Copia nello sheet i dati di un modulo prendendoli da un .ini
 | 
						||
bool TInstaller_mask::add_header(TConfig& ini, const TString& module, bool patch)
 | 
						||
{
 | 
						||
  ini.write_protect();
 | 
						||
  bool ok = ini.set_paragraph(module);
 | 
						||
  if (ok)
 | 
						||
  {
 | 
						||
    TToken_string row;
 | 
						||
    row = " ";   // Not selected
 | 
						||
    row.add(ini.get("Descrizione"));
 | 
						||
    row.add(ini.get("  "));
 | 
						||
    enable_row(add(row),false);
 | 
						||
  }
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
static int compare_modules(const TObject** o1, const TObject** o2)
 | 
						||
{
 | 
						||
  TToken_string& ts1 = *(TToken_string*)(*o1);
 | 
						||
  TToken_string& ts2 = *(TToken_string*)(*o2);
 | 
						||
 | 
						||
  int res = 0;
 | 
						||
  for (int i = 2; i < 5 && res == 0; i++)
 | 
						||
  {
 | 
						||
    TString16 s1 = ts1.get(i);
 | 
						||
    const char* s2 = ts2.get(i);
 | 
						||
    res = s1.compare(s2);
 | 
						||
  }
 | 
						||
  return res;
 | 
						||
}
 | 
						||
 | 
						||
bool TInstaller_mask::has_module(int modnumber) const
 | 
						||
{
 | 
						||
  if (modnumber == SRAUT)
 | 
						||
  {
 | 
						||
    char s[16];
 | 
						||
    if (xvt_fsys_get_campo_stp_value("Servers", s, sizeof(s)) || xvt_fsys_get_campo_stp_value("Sy", s, sizeof(s))) //***aggiunto il modulo sy
 | 
						||
      return atoi(s) > 0;
 | 
						||
  }
 | 
						||
  return main_app().has_module(modnumber, CHK_DONGLE);
 | 
						||
}
 | 
						||
 | 
						||
int TInstaller_mask::precheck_modules(bool only_newer)
 | 
						||
{
 | 
						||
  TString16 release,currrelease;
 | 
						||
  TString4 cod_module;
 | 
						||
  int patchlevel,modnumber,currpatch;
 | 
						||
 | 
						||
  TString_array& array = rows_array();
 | 
						||
  FOR_EACH_ARRAY_ROW(array, r, row)
 | 
						||
  {
 | 
						||
    TToken_string& rigar = *row;
 | 
						||
    cod_module = rigar.get(C_CODE);
 | 
						||
    release = rigar.get(C_RELEASE);
 | 
						||
    patchlevel = rigar.get_int(C_PATCH);
 | 
						||
    currrelease = rigar.get(C_CURRRELEASE);
 | 
						||
    currpatch = rigar.get_int(C_CURRPATCH);
 | 
						||
    modnumber = get_module_number(cod_module);
 | 
						||
    if (modnumber >= 0 && has_module(modnumber) && 
 | 
						||
        !release.blank() &&
 | 
						||
        ((release > currrelease) || 
 | 
						||
         (release == currrelease &&  (only_newer ? patchlevel>currpatch: patchlevel>=currpatch) )) 
 | 
						||
       )    
 | 
						||
    {
 | 
						||
      // checca il modulo o la patch se ho installata la stessa versione
 | 
						||
      const bool chk = rigar.get_char(C_ISPATCH) != 'X' || release == currrelease;
 | 
						||
      check(r, chk);
 | 
						||
      if (chk && only_newer && cod_module == "sy")  //se viene checkato il modulo sy (sistema) deve togliere..
 | 
						||
      {                               //..la possibilita' di installare altri moduli..
 | 
						||
        for (int i = 0; i < array.items(); i++)
 | 
						||
          disable_row(i); //disabilita tutte le righe dello sheet
 | 
						||
        disable(DLG_USER);
 | 
						||
        break;  //..ed uscire
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
  force_update(); // Indispensabile per vedere le righe aggiornate
 | 
						||
  return items();
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
int TInstaller_mask::get_module_number(const TString& module) const
 | 
						||
{
 | 
						||
  int aut = -1;
 | 
						||
  bool ok = false;
 | 
						||
  if (module.full())
 | 
						||
  {
 | 
						||
    if (module == "ba" || module == "sy") //moduli base e sistema: deve ritornare 0;
 | 
						||
      return 0;
 | 
						||
 | 
						||
    TScanner scanner(AUT_FILE);
 | 
						||
    for (aut = 0; scanner.line() != ""; aut++)
 | 
						||
      if (scanner.token().starts_with(module)) 
 | 
						||
      { ok = true; break; }
 | 
						||
  }
 | 
						||
  return ok ? aut : -1;
 | 
						||
}
 | 
						||
 | 
						||
void TInstaller_mask::update_version()
 | 
						||
{
 | 
						||
  TInstall_ini ini;
 | 
						||
 | 
						||
  TString_array& array = rows_array();
 | 
						||
  FOR_EACH_ARRAY_ROW_BACK(array, m, row)
 | 
						||
  {
 | 
						||
    if (*row->get(C_CODE) != ' ')
 | 
						||
    {
 | 
						||
      const TString16 module = row->get(C_CODE);
 | 
						||
      ini.set_paragraph(module);
 | 
						||
 | 
						||
      const TString16 newver = row->get(C_RELEASE);
 | 
						||
      const TString16 oldver = ini.get("Versione");
 | 
						||
      const int numpatch = ini.get_int("Patch");
 | 
						||
      TString16 strpatch; 
 | 
						||
      if (numpatch > 0) strpatch.format("%03d", numpatch);
 | 
						||
      row->add(oldver, C_CURRRELEASE);
 | 
						||
      row->add(strpatch, C_CURRPATCH);
 | 
						||
      row->add(ini.get("Data"), C_CURRDATAREL);
 | 
						||
    }
 | 
						||
  }
 | 
						||
  force_update();
 | 
						||
}
 | 
						||
 | 
						||
// Cerca nel percorso specificato sulla maschera tutti i possibili files .ini
 | 
						||
// utilizzabili per un'installazione e li inserisce nello spreadsheet
 | 
						||
bool TInstaller_mask::autoload()
 | 
						||
{
 | 
						||
  TString_array& mask_rows = rows_array();
 | 
						||
 | 
						||
  TString http_server;
 | 
						||
  TFilename http_path;
 | 
						||
 | 
						||
  TFilename path ;
 | 
						||
  TFilename ininame;
 | 
						||
 | 
						||
  const bool internet = get_internet_path(path);
 | 
						||
 | 
						||
  if (internet)
 | 
						||
  {
 | 
						||
    parse_internet_path(http_server,http_path);
 | 
						||
 | 
						||
    make_dir(path);
 | 
						||
 | 
						||
    ininame = path;
 | 
						||
    ininame.add(TInstall_ini::default_name());
 | 
						||
 | 
						||
    if (ininame.exist() && yesno_box(TR("Si desidera svuotare la cache dei files scaricati dal sito?")))
 | 
						||
    {
 | 
						||
      TString_array list;
 | 
						||
      TFilename name = path; name.add("*.*");
 | 
						||
      ::list_files(name, list);
 | 
						||
 | 
						||
      FOR_EACH_ARRAY_ROW(list, i, row)
 | 
						||
        ::remove(*row);
 | 
						||
    }
 | 
						||
    if (!ininame.exist())
 | 
						||
    {
 | 
						||
      bool httpresult;
 | 
						||
      TFilename remote_ini = http_path;
 | 
						||
      remote_ini << TInstall_ini::default_name();
 | 
						||
      {
 | 
						||
        TIndwin contacting(60,TR("Connessione al server HTTP..."),false,false);
 | 
						||
        httpresult=http_get(http_server, remote_ini, ininame);
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  if (path.exist())
 | 
						||
  {
 | 
						||
    ininame = path;
 | 
						||
    ininame.add(TInstall_ini::default_name());
 | 
						||
  }
 | 
						||
  else
 | 
						||
    return error_box(TR("Specificare un percorso valido"));
 | 
						||
 | 
						||
  TWait_cursor hourglass;
 | 
						||
  destroy();
 | 
						||
  force_update();
 | 
						||
 | 
						||
  TString_array modules;
 | 
						||
  
 | 
						||
  if (ininame.exist())
 | 
						||
  {
 | 
						||
    // Presente il file ini generale "install.ini" (moduli;immagine cd)
 | 
						||
    TInstall_ini ini(ininame);
 | 
						||
    ini.list_paragraphs(modules); //riempie modules con la lista dei paragrafi sul .ini ***
 | 
						||
 | 
						||
    FOR_EACH_ARRAY_ROW(modules, i, row)
 | 
						||
    {
 | 
						||
      const TString& module = *row;
 | 
						||
      if (module[0] == '_' || module.len() == 2)
 | 
						||
      {
 | 
						||
 | 
						||
        if (module[0] == '_')
 | 
						||
          add_header(ini, module, false);
 | 
						||
        else
 | 
						||
        {
 | 
						||
          TFilename mod_ini = ininame.path();
 | 
						||
          mod_ini.add(module);
 | 
						||
          mod_ini << "inst.ini";
 | 
						||
          if (mod_ini.exist())
 | 
						||
          {
 | 
						||
            TInstall_ini moduleini(mod_ini);
 | 
						||
            add_module(moduleini, module, false);
 | 
						||
          }
 | 
						||
          else
 | 
						||
            add_module(ini, module, false);
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    // Presenti i singoli file .ini dei moduli (pacchi ma non patches!)
 | 
						||
    ininame = path;
 | 
						||
    ininame.add("??inst.ini");
 | 
						||
    list_files(ininame, modules); //ritorna la lista dei files presenti nel .ini della patch ***
 | 
						||
    FOR_EACH_ARRAY_ROW(modules, m, row)
 | 
						||
    {
 | 
						||
      TString& ininame = *row;
 | 
						||
      ininame.lower();
 | 
						||
      const int pos = ininame.find("inst.ini");
 | 
						||
      CHECKS(pos >= 2, "Invalid installation configuration: ", (const char*)ininame);
 | 
						||
      const TString16 module = ininame.mid(pos-2, 2);
 | 
						||
      TConfig ini(ininame, module);
 | 
						||
      add_module(ini, module, false);
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  modules.destroy();
 | 
						||
 | 
						||
  if (internet) //internet patches
 | 
						||
  {
 | 
						||
    http_dir(http_server, http_path, modules);
 | 
						||
    for (int i = modules.last(); i >= 0; i--)
 | 
						||
    {
 | 
						||
      TString& str = modules.row(i);
 | 
						||
      if (str.match("??0???A.INI") || str.match("??0???a.ini"))
 | 
						||
      {
 | 
						||
        TFilename remote = http_path;
 | 
						||
        remote << str;
 | 
						||
 | 
						||
        ininame = path;
 | 
						||
        ininame.add(str);
 | 
						||
 | 
						||
        if (!ininame.exist() && !http_get(http_server, remote, ininame))
 | 
						||
        {
 | 
						||
          error_box(FR("Errore di trasferimento del file %s"), (const char*)remote);
 | 
						||
          modules.destroy(i);
 | 
						||
        }
 | 
						||
        str = ininame;
 | 
						||
      }
 | 
						||
      else
 | 
						||
       modules.destroy(i);
 | 
						||
    }
 | 
						||
    modules.pack();
 | 
						||
  }
 | 
						||
  else  //normal patches
 | 
						||
  {
 | 
						||
    ininame = path;
 | 
						||
    ininame.add("??0???a.ini");
 | 
						||
    list_files(ininame, modules); 
 | 
						||
  }
 | 
						||
 | 
						||
  if (modules.items() > 0)  //ordina i moduli come sull'install.ini locale (per avere SY come primo
 | 
						||
  {                         //modulo e via via gli altri)
 | 
						||
    TInstall_ini installini;
 | 
						||
    TString_array paragrafi;
 | 
						||
    installini.list_paragraphs(paragrafi);
 | 
						||
    TFilename file;
 | 
						||
    FOR_EACH_ARRAY_ROW(modules, am, arow)
 | 
						||
    {
 | 
						||
      file = *arow;
 | 
						||
      file = file.name();
 | 
						||
      int pos = paragrafi.find(file.left(2));
 | 
						||
      if (pos <= 0)
 | 
						||
        pos = 10000+am;
 | 
						||
      TString8 str;
 | 
						||
      str.format("%05d", pos);  //aggiunge un numero d'ordine sulla sinistra del nome del file..
 | 
						||
      arow->insert(str);
 | 
						||
    }
 | 
						||
    modules.sort(); //..cosi' che la sort (che ordina alfabeticamente) sistemi la lista moduli
 | 
						||
 | 
						||
    FOR_EACH_ARRAY_ROW(modules, bm, brow) //rimette i nomi dei moduli a posto (toglie il numero d'ordine)
 | 
						||
      brow->ltrim(5);
 | 
						||
  }
 | 
						||
//genera le righe dello sheet di installazione
 | 
						||
  FOR_EACH_ARRAY_ROW(modules, am, arow)
 | 
						||
  {
 | 
						||
    TString& ininame = *arow;
 | 
						||
    ininame.lower();
 | 
						||
    const int pos = ininame.find("a.ini");
 | 
						||
    CHECKS(pos >= 6, TR("Configurazione di installazione non valida: "), (const char*)ininame);
 | 
						||
    const TString16 module = ininame.mid(pos-6, 2);
 | 
						||
    TConfig ini(ininame, module); 
 | 
						||
    ini.write_protect();
 | 
						||
    for (int r = int(items()-1); r >=0; r--)
 | 
						||
      if (module == row(r).get(C_CODE))
 | 
						||
        break;
 | 
						||
    if (r >= 0)
 | 
						||
    {
 | 
						||
      const TString16 patchversion = ini.get("Versione");
 | 
						||
      const int patchlevel = ini.get_int("Patch");
 | 
						||
      TToken_string& row = mask_rows.row(r);
 | 
						||
      if (patchversion == row.get(C_RELEASE) // se le versioni corrispondono ...
 | 
						||
        && patchlevel > row.get_int(C_PATCH)) // ..e il patchlevel <20> superiore
 | 
						||
      {   
 | 
						||
        TString16 patch; patch.format("%03d", patchlevel);  //aggiunge zeri per avere 3 cifre sempre
 | 
						||
        if (*row.get(C_ISPATCH)<=' ') // se era un modulo ...
 | 
						||
        {
 | 
						||
          row.add("+", C_ISPATCH); // .....setta la presenza di patches
 | 
						||
          row.add(row.get(C_PATCH), C_BASEPATCH); // memorizza patch del modulo
 | 
						||
        }
 | 
						||
        row.add(patch, C_PATCH); // aggiorna il patchlevel mostrato per il modulo
 | 
						||
      }
 | 
						||
    } 
 | 
						||
    else
 | 
						||
      add_module(ini, module, true);
 | 
						||
  }
 | 
						||
  update_version();
 | 
						||
  const bool ok = precheck_modules() > 0;
 | 
						||
 | 
						||
  if (!ok)
 | 
						||
    error_box(FR("Non e' stato trovato nessun modulo da installare\nin %s"), (const char*)path);
 | 
						||
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
bool TInstaller_mask::do_process(TToken_string& commands) const
 | 
						||
{
 | 
						||
  bool ok = true;
 | 
						||
  TFilename cmd;
 | 
						||
  for (const char* c = commands.get(0); c && ok; c = commands.get())
 | 
						||
  {
 | 
						||
    cmd = c;
 | 
						||
    if (!cmd.blank())
 | 
						||
    {
 | 
						||
      TWait_cursor hourglass;
 | 
						||
      TExternal_app app(cmd);
 | 
						||
      ok = app.run(false,3,true) == 0;
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
bool TInstaller_mask::pre_process(TInstall_ini& ini, const char* module) const
 | 
						||
{
 | 
						||
  TAuto_token_string commands(ini.get("PreProcess", module));
 | 
						||
  bool ok = do_process(commands);
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
bool TInstaller_mask::post_process(TInstall_ini& ini, const char* module) const
 | 
						||
{
 | 
						||
  TAuto_token_string commands(ini.get("PostProcess", module));
 | 
						||
  return do_process(commands);
 | 
						||
}
 | 
						||
 | 
						||
bool TInstaller_mask::can_install(const char* module, TInstall_ini& ini)
 | 
						||
{
 | 
						||
  TInstall_ini curini;
 | 
						||
  if (curini.demo() != ini.demo())
 | 
						||
  {
 | 
						||
    TString msg;
 | 
						||
    msg << TR("Attenzione: Non e' possibile installare la versione ");
 | 
						||
    msg << (ini.demo() ? TR("dimostrativa") : TR("normale"));
 | 
						||
    msg << TR(" nella cartella della versione ");
 | 
						||
    msg << (curini.demo() ? TR("dimostrativa") : TR("normale"));
 | 
						||
    return error_box(msg);
 | 
						||
  }
 | 
						||
 | 
						||
  const TString& version = ini.version(module);
 | 
						||
  const word year = version2year(version);
 | 
						||
  if (year < 1997)
 | 
						||
    return error_box(FR("Il modulo '%s' non ha una versione valida."), module);
 | 
						||
 | 
						||
#ifndef _DEMO_
 | 
						||
  if (year > dongle().year_assist())
 | 
						||
    return error_box(FR("Per installare la versione %s del modulo '%s'\noccorre il contratto di assistenza per l'anno %d."),
 | 
						||
 | 
						||
                     (const char*)version, module, year);
 | 
						||
#endif
 | 
						||
 | 
						||
  TAuto_token_string altri(ini.get("Moduli", module));
 | 
						||
  if (stricmp(module, "sy") != 0) //SY e' indipendente dagli altri moduli
 | 
						||
  {
 | 
						||
    if (stricmp(module, "ba") != 0 && altri.get_pos("ba") < 0)
 | 
						||
      altri.add("ba");
 | 
						||
  }
 | 
						||
 | 
						||
  bool ok = true;
 | 
						||
  TString submodule;
 | 
						||
  for (const char* mod = altri.get(0); mod && ok; mod = altri.get())
 | 
						||
  {
 | 
						||
    submodule = mod;
 | 
						||
    if (submodule.len() == 2)
 | 
						||
    {
 | 
						||
      if (curini.get("Versione", submodule).empty())
 | 
						||
      {
 | 
						||
        TString msg;
 | 
						||
        msg.format(FR("L'installazione del modulo %s richiede la presenza del modulo %s."), 
 | 
						||
                   (const char*)module, (const char*)submodule);
 | 
						||
        msg << '\n' << TR("Si desidera procedere alla sua installazione?");
 | 
						||
        ok = yesno_box(msg);
 | 
						||
        if (ok)
 | 
						||
          ok = install(submodule, 0);
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
int TInstaller_mask::needs_reboot(const TFilename& file) const
 | 
						||
{ 
 | 
						||
  char fname[_MAX_FNAME], ext[_MAX_EXT];
 | 
						||
  xvt_fsys_parse_pathname(file, NULL, NULL, fname, ext, NULL);
 | 
						||
 | 
						||
  int underscore = NONE;
 | 
						||
  if (xvt_str_compare_ignoring_case(ext, "exe") == 0)
 | 
						||
  {
 | 
						||
    if (xvt_str_compare_ignoring_case(fname, "ba0") == 0)
 | 
						||
      underscore = NEW_MENUPRG; else
 | 
						||
    if (xvt_str_compare_ignoring_case(fname, "ba1") == 0)
 | 
						||
      underscore = NEW_INSTALLER;
 | 
						||
  } else
 | 
						||
  if (xvt_str_compare_ignoring_case(ext, "dll") == 0)
 | 
						||
    underscore = NEW_DLL; else
 | 
						||
  if (xvt_str_compare_ignoring_case(ext, "men") == 0)
 | 
						||
    underscore = NEW_MENU;
 | 
						||
  return underscore;
 | 
						||
}
 | 
						||
 | 
						||
bool TInstaller_mask::is_zip_file(const TFilename& n) const
 | 
						||
{
 | 
						||
  const char* ext = n.ext();
 | 
						||
  return xvt_str_compare_ignoring_case(ext, "zip") == 0;
 | 
						||
}
 | 
						||
 | 
						||
void TInstaller_mask::create_dirs(const char* path) const
 | 
						||
{
 | 
						||
  TToken_string dirs(path, SLASH);
 | 
						||
  if (SLASH == '\\')
 | 
						||
    dirs.replace('/', SLASH);
 | 
						||
  else
 | 
						||
    dirs.replace('\\', SLASH);
 | 
						||
 | 
						||
  // file contains non existent subdir specification ?
 | 
						||
  TFilename subdir;
 | 
						||
  for (int c=0; c < dirs.items()-1; c++)
 | 
						||
  {
 | 
						||
    subdir.add(dirs.get(c));
 | 
						||
    if (subdir.right(1) == ":" )
 | 
						||
      subdir << SLASH;
 | 
						||
    if (!subdir.exist() )
 | 
						||
      // build destination directory
 | 
						||
      make_dir(subdir);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
// sposta il file dal direttorio temporaneo a quello passato come destinazione
 | 
						||
bool TInstaller_mask::move_file(const TFilename& src, const TFilename& dst) const
 | 
						||
{
 | 
						||
  TFilename dest = dst;
 | 
						||
  const int reboot = needs_reboot(dest);
 | 
						||
  if (reboot > NEW_MENU && dst.exist())
 | 
						||
  {
 | 
						||
    dest.rtrim(1);
 | 
						||
    dest << '_';
 | 
						||
  }
 | 
						||
 | 
						||
  if (!dest.exist())
 | 
						||
    create_dirs(dest.path());
 | 
						||
 | 
						||
  const bool is_zip = is_zip_file(src);
 | 
						||
  const long filesize = fsize(src) * (is_zip ? 4 : 1);
 | 
						||
 | 
						||
  if (xvt_fsys_test_disk_free_space(dest, filesize) == 0)
 | 
						||
    return error_box(TR("Lo spazio sull'unita' di destinazione e' insufficiente"));
 | 
						||
 | 
						||
  const bool write_ok = ::fcopy(src, dest);
 | 
						||
  if (write_ok && is_zip)
 | 
						||
    aga_unzip(src, dest.path());
 | 
						||
    
 | 
						||
  if (write_ok)
 | 
						||
    ::remove(src);
 | 
						||
 | 
						||
  if (write_ok)
 | 
						||
  {
 | 
						||
    (int&)_reboot_program |= reboot; // Skip const!
 | 
						||
  }
 | 
						||
  return write_ok;
 | 
						||
}
 | 
						||
 | 
						||
bool TInstaller_mask::move_module(const TString& module, TInstall_ini& ini, bool update) const
 | 
						||
{
 | 
						||
  bool ok = true;
 | 
						||
 | 
						||
  TFilename tempdir; tempdir.tempdir();
 | 
						||
  const TString& destdir = get(F_CURPATH);
 | 
						||
 | 
						||
  TString_array list;
 | 
						||
  ini.build_list(module, list);
 | 
						||
  FOR_EACH_ARRAY_ROW(list, f, file)
 | 
						||
  {
 | 
						||
    TFilename src = tempdir;
 | 
						||
    src.add(file->get(0));
 | 
						||
    if (update)
 | 
						||
    {
 | 
						||
      TFilename dst = destdir;
 | 
						||
      dst.add(file->get(0));
 | 
						||
      const bool move_ok = move_file(src, dst);
 | 
						||
      if (!move_ok)
 | 
						||
        ok = update = false;
 | 
						||
    }
 | 
						||
    if (!update)
 | 
						||
      ::remove(src);
 | 
						||
  }
 | 
						||
  
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
KEY TInstaller_mask::askdisk(TString & path, TFilename & cmdline, int d, int dischi, const char * modulo)
 | 
						||
{
 | 
						||
  TMask retry_mask(TR("Inserimento disco"),1,80,10);
 | 
						||
 | 
						||
  retry_mask.add_static((F_PATH==101 ? 102:101),0,
 | 
						||
    format(FR("Inserire il disco %d di %d del modulo'%s' nell'unit<69>"), d, dischi, modulo)
 | 
						||
      ,2,2);
 | 
						||
  retry_mask.add_static(F_PATH+3,0,TR("oppure indicare un percorso diverso"),2,3);
 | 
						||
 | 
						||
  retry_mask.add_string(F_PATH,0,"",2,5,48);
 | 
						||
  retry_mask.add_button(DLG_OK,0,TR("Riprova"),-12,7,9,2);
 | 
						||
  retry_mask.add_button(DLG_QUIT,0,"",-22,7,9,2);
 | 
						||
  retry_mask.set(F_PATH,path);
 | 
						||
  KEY k;
 | 
						||
  do {
 | 
						||
    if ((k=retry_mask.run())==K_QUIT )
 | 
						||
      break;
 | 
						||
    if (!retry_mask.get(F_PATH).blank())
 | 
						||
    {
 | 
						||
      if (fexist(retry_mask.get(F_PATH)))
 | 
						||
      {
 | 
						||
        TString16 tmpname(cmdline.name() );
 | 
						||
        cmdline= path = retry_mask.get(F_PATH);
 | 
						||
        cmdline.add(tmpname);
 | 
						||
        break;
 | 
						||
      }
 | 
						||
      else
 | 
						||
        error_box(TR("Il percorso indicato non e' valido"));
 | 
						||
    }
 | 
						||
  } while (true);
 | 
						||
  return k;
 | 
						||
}
 | 
						||
 | 
						||
bool TInstaller_mask::install(const TString& module, int patchlevel)
 | 
						||
{
 | 
						||
  bool cancelled=false;
 | 
						||
  bool ok = false;
 | 
						||
  TString msg;              // stringa per i messaggi
 | 
						||
  TString16 lastrelease;    // release che sto installando
 | 
						||
  int lastpatch=patchlevel; // patchlevel che sto installando
 | 
						||
 | 
						||
  TFilename path ;
 | 
						||
  TString http_server;
 | 
						||
  TFilename http_path;
 | 
						||
  
 | 
						||
  const bool internet = get_internet_path(path);
 | 
						||
  if (internet)
 | 
						||
    parse_internet_path(http_server,http_path );
 | 
						||
 | 
						||
  const bool is_a_patch=(patchlevel > 0);
 | 
						||
  TFilename ininame = path;
 | 
						||
  ininame.add(module);
 | 
						||
 | 
						||
  if (is_a_patch)
 | 
						||
  {
 | 
						||
    TString16 name;
 | 
						||
    name.format("%04da.ini", patchlevel);
 | 
						||
    ininame << name;
 | 
						||
  }
 | 
						||
  else
 | 
						||
    ininame << "inst.ini";
 | 
						||
 | 
						||
  if (internet && !ininame.exist())
 | 
						||
  {
 | 
						||
    TFilename remote = ininame.name();
 | 
						||
    remote.insert(http_path, 0);
 | 
						||
    http_get(http_server, remote, ininame);
 | 
						||
  }
 | 
						||
 | 
						||
  if (ininame.exist())
 | 
						||
  {
 | 
						||
    // esiste un particolare .ini con formato XXinst.ini (moduli) o con XX9999a.ini (patch)
 | 
						||
    // (installazione da directory con .zip)
 | 
						||
    TInstall_ini* ini = new TInstall_ini(ininame);
 | 
						||
    ini->write_protect();
 | 
						||
    lastpatch=ini->get_int("Patch",module);
 | 
						||
    lastrelease=ini->get("Versione",module);
 | 
						||
    if (!can_install(module, *ini))
 | 
						||
    {
 | 
						||
      delete ini;
 | 
						||
      return false;
 | 
						||
    }
 | 
						||
    const int dischi = ini->get_int("Dischi", module);
 | 
						||
    ok = dischi > 0;
 | 
						||
    if (!ok)
 | 
						||
      return error_box(FR("Impossibile determinare il numero dei dischetti in %s"),ininame.name());
 | 
						||
    else
 | 
						||
    {
 | 
						||
      if (patchlevel==0)
 | 
						||
        ok = pre_process(*ini, module);
 | 
						||
      if (!ok)
 | 
						||
      {
 | 
						||
        delete ini;
 | 
						||
        return false;
 | 
						||
      }
 | 
						||
    }
 | 
						||
    // ==============
 | 
						||
    // decompressione
 | 
						||
    msg = TR("Decompressione");
 | 
						||
    if (is_a_patch)
 | 
						||
      msg << TR(" della patch ") << patchlevel ;
 | 
						||
    msg  << TR(" del modulo '") << module << TR("' in corso...");
 | 
						||
    xvtil_statbar_set(msg);
 | 
						||
    
 | 
						||
    TFilename tempdir; tempdir.tempdir();
 | 
						||
    
 | 
						||
		// File tottale dei vari sotto-zip
 | 
						||
		TFilename totti = tempdir; totti.add(module); totti.ext("zip");
 | 
						||
    
 | 
						||
    for (int d = 1; d <= dischi && ok; d++)
 | 
						||
    {
 | 
						||
      TFilename chunk = path;
 | 
						||
      chunk.add(module);
 | 
						||
      if (patchlevel > 0)
 | 
						||
      {
 | 
						||
        TString8 name;
 | 
						||
        name.format("%04da", patchlevel);
 | 
						||
        chunk << name;
 | 
						||
      }
 | 
						||
      else
 | 
						||
        chunk << "inst";
 | 
						||
      chunk << d << ".zip";
 | 
						||
 | 
						||
      if (internet && !chunk.exist())
 | 
						||
      {
 | 
						||
        TFilename remote = chunk.name();
 | 
						||
        remote.insert(http_path, 0);
 | 
						||
        if (!http_get(http_server, remote, chunk))
 | 
						||
          error_box(FR("Errore di trasferimento del file '%s'"), (const char*)remote);
 | 
						||
      }
 | 
						||
 | 
						||
      ok = chunk.exist();
 | 
						||
      if (!ok && !internet)  // Chiedi cambio disco (solo se non sta scaricando da internet)
 | 
						||
      {
 | 
						||
        while (!ok)
 | 
						||
        {
 | 
						||
          if (askdisk(path,chunk,d,dischi,(const char*)ini->get("Descrizione"))==K_QUIT)
 | 
						||
            break;
 | 
						||
          ok = chunk.exist();
 | 
						||
          if (!ok)
 | 
						||
            message_box(FR("Impossibile trovare il file '%s'"),(const char*)chunk);
 | 
						||
        }
 | 
						||
      }
 | 
						||
 | 
						||
      if (ok)
 | 
						||
      {
 | 
						||
        const long required = fsize(chunk) * (dischi-d+1) * 4;
 | 
						||
        if (!xvt_fsys_test_disk_free_space(tempdir, required))        
 | 
						||
        {
 | 
						||
          ok = yesno_box(TR("Lo spazio su disco potrebbe essere insufficiente:\nSi desidera continuare ugualmente?"));
 | 
						||
        }
 | 
						||
      }
 | 
						||
 | 
						||
      if (ok)
 | 
						||
        ::fcopy(chunk, totti, d > 1);  // Somma il chunk al totale
 | 
						||
    }
 | 
						||
  	aga_unzip(totti, tempdir); // Scompatta il file totale
 | 
						||
		::remove(totti);
 | 
						||
 | 
						||
    // =============
 | 
						||
    // trasferimento
 | 
						||
    if (ok)
 | 
						||
    {
 | 
						||
      // si assicura che sia leggibile il .ini del primo disco
 | 
						||
      do 
 | 
						||
			{
 | 
						||
        TFilename cmdline = path;
 | 
						||
        cmdline.add(ininame.name());
 | 
						||
        ok = cmdline.exist();
 | 
						||
        if (!ok)
 | 
						||
        {
 | 
						||
          if (askdisk(path,cmdline,1,dischi,(const char*)ini->get("Descrizione"))==K_QUIT)
 | 
						||
           break;
 | 
						||
          ok = fexist(cmdline);
 | 
						||
          if (!ok)
 | 
						||
            message_box(FR("Impossibile trovare %s\n"),(const char*)cmdline);
 | 
						||
          else
 | 
						||
          {
 | 
						||
            delete ini;
 | 
						||
            ini = new TInstall_ini (cmdline);
 | 
						||
          }
 | 
						||
        }
 | 
						||
      } while (!ok);
 | 
						||
      if (ok)
 | 
						||
      {
 | 
						||
        msg.cut(0);
 | 
						||
        msg << TR("Aggiornamento del modulo '") << module << TR("' in corso...");
 | 
						||
        xvtil_statbar_set(msg);
 | 
						||
 | 
						||
        ok = move_module(module, *ini, true);
 | 
						||
 | 
						||
        if (ok)
 | 
						||
        {
 | 
						||
          TAuto_token_string altri(ini->get("Moduli", module));
 | 
						||
          FOR_EACH_TOKEN(altri, mod)
 | 
						||
          {
 | 
						||
            const TString16 submod = mod;
 | 
						||
            if (submod.len() > 2) // sposta sottomoduli esterni
 | 
						||
            {
 | 
						||
              bool upd = ok;
 | 
						||
              if (ok)
 | 
						||
              {
 | 
						||
                TInstall_ini curini;
 | 
						||
                const TString16 curver = curini.version(submod);
 | 
						||
                const int curpatch = curini.patch(submod);
 | 
						||
                const TString16 reqver = ini->version(submod);
 | 
						||
                const int reqpatch = ini->patch(submod);
 | 
						||
  
 | 
						||
                int distance = compare_version(reqver, reqpatch, curver, curpatch);
 | 
						||
                upd = distance > 0;
 | 
						||
              }
 | 
						||
              ok &= move_module(submod, *ini, upd);
 | 
						||
              if (upd && ok)  // marca sull'install.ini di destinazione l'avvenuta installazione del sottomodulo "esterno"
 | 
						||
                ini->export_paragraph(submod, ini->default_name(), !is_a_patch);
 | 
						||
            }
 | 
						||
          }
 | 
						||
        }
 | 
						||
        if (ok) //rimozione files da eliminare indicati nel .ini
 | 
						||
        {
 | 
						||
          TString killmod;
 | 
						||
          killmod << module << 99;
 | 
						||
          if (ini->set_paragraph(killmod))
 | 
						||
          { 
 | 
						||
            TToken_string rigaini;
 | 
						||
            TFilename filetokill;
 | 
						||
            for (int k=0; ;k++)
 | 
						||
            {
 | 
						||
              rigaini = ini->get("Kill", NULL, k, "");
 | 
						||
              if (rigaini.empty())
 | 
						||
                break;
 | 
						||
              filetokill = rigaini.get(0);
 | 
						||
              if (filetokill.find('*') >= 0 || filetokill.find('?') >=0)
 | 
						||
              {
 | 
						||
                TString_array filelist;
 | 
						||
                list_files (filetokill, filelist);
 | 
						||
                FOR_EACH_ARRAY_ROW(filelist, r, file)
 | 
						||
                {
 | 
						||
                  ::remove_file((const char *)file);
 | 
						||
                }
 | 
						||
 | 
						||
              }
 | 
						||
              else
 | 
						||
                ::remove_file(filetokill);
 | 
						||
            }
 | 
						||
          }
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
    if (ok) // marca sull'install.ini di destinazione l'avvenuta installazione del modulo
 | 
						||
      ini->export_module_paragraphs(module, ini->default_name(),!is_a_patch);
 | 
						||
  } // installazione da directory con zip
 | 
						||
  else
 | 
						||
    if (!is_a_patch)
 | 
						||
    {
 | 
						||
      //
 | 
						||
      // non c'e' il .ini del modulo ma un unico "install.ini"
 | 
						||
      // (installazione da directory con eseguibili)
 | 
						||
      ininame = path;
 | 
						||
      ininame.add(TInstall_ini::default_name());
 | 
						||
      ok = fexist(ininame);
 | 
						||
      if (ok)
 | 
						||
      {
 | 
						||
        TInstall_ini ini(ininame);
 | 
						||
        ini.write_protect();
 | 
						||
        lastpatch=ini.get_int("Patch",module);
 | 
						||
        lastrelease=ini.get("Versione",module);
 | 
						||
        if (!can_install(module, ini))
 | 
						||
          return false;
 | 
						||
  
 | 
						||
        TString_array list;
 | 
						||
        const int files = ini.build_complete_list(module, list);
 | 
						||
        if (files > 0)
 | 
						||
        {
 | 
						||
          if (patchlevel==0)
 | 
						||
            ok = pre_process(ini, module);
 | 
						||
  
 | 
						||
          if (ok)
 | 
						||
          {
 | 
						||
            msg.cut(0) << TR("Copia del modulo ") << module;
 | 
						||
            TProgind pi(files, msg, true, true);
 | 
						||
            TFilename src, dst;
 | 
						||
            for (int f = 0; f < files && ok; f++)
 | 
						||
            {
 | 
						||
              pi.addstatus(1);
 | 
						||
              dst = list.row(f).get(0);
 | 
						||
              dst.lower();
 | 
						||
              src = path;
 | 
						||
              src.add(dst);
 | 
						||
              const int reboot = needs_reboot(dst);
 | 
						||
              if (reboot > NEW_MENU && dst.exist())
 | 
						||
              {
 | 
						||
                dst.rtrim(1);
 | 
						||
                dst << '_';
 | 
						||
              }
 | 
						||
              if (!dst.exist())
 | 
						||
                create_dirs(dst.path());
 | 
						||
 | 
						||
              ok = ::fcopy(src, dst);
 | 
						||
              if (ok && is_zip_file(src))
 | 
						||
                aga_unzip(src, dst.path());
 | 
						||
              
 | 
						||
              if (ok && reboot != NONE)
 | 
						||
                _reboot_program |= reboot;
 | 
						||
 | 
						||
              cancelled = pi.iscancelled();
 | 
						||
            }
 | 
						||
            ok &= !cancelled;
 | 
						||
          }
 | 
						||
  
 | 
						||
          if (ok)  // marca sull'install.ini di destinazione l'avvenuta installazione del modulo
 | 
						||
            ini.export_module_paragraphs(module, ini.default_name(),true);
 | 
						||
        } // controllo  esistenza lista di file non vuota per questo modulo
 | 
						||
      } // controllo esistenza install.ini
 | 
						||
    } // fine installazione da directory con eseguibili
 | 
						||
 | 
						||
  if (ok)
 | 
						||
  {
 | 
						||
    {
 | 
						||
      TInstall_ini ini;
 | 
						||
      ini.set("DiskPath", get(F_PATH));
 | 
						||
      ini.set("Data", TDate(TODAY), module);
 | 
						||
      ini.update_prices(ininame);
 | 
						||
    }
 | 
						||
    // Non togliere le parentesi graffe soprastanti per permettere l'aggiornamento fisico del .ini (CON LA CHIAMATA DEL DISTRUTTORE)
 | 
						||
    update_version();
 | 
						||
  }
 | 
						||
 | 
						||
 | 
						||
  if (ok && patchlevel == 0)          // Se installo un modulo pricipale ...
 | 
						||
  {
 | 
						||
    // ... installo DOPO tutte le patches successive
 | 
						||
    install_patches(module, lastrelease, lastpatch);
 | 
						||
    TInstall_ini ini;
 | 
						||
    ok &= post_process(ini, module);
 | 
						||
  }
 | 
						||
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
bool TInstaller_mask::get_internet_path(TFilename &ininame) const
 | 
						||
{
 | 
						||
  ininame = get(F_PATH);
 | 
						||
  if (is_internet_path(ininame))
 | 
						||
  {
 | 
						||
    ininame.tempdir();
 | 
						||
    ininame.add("www");
 | 
						||
    return true;
 | 
						||
  }
 | 
						||
  return false;
 | 
						||
}
 | 
						||
 | 
						||
void TInstaller_mask::parse_internet_path(TString & http_server, TFilename &http_path) const
 | 
						||
{
 | 
						||
  http_server = get(F_PATH);
 | 
						||
  if (http_server.compare("http://", 7, true) == 0)
 | 
						||
    http_server.ltrim(7);
 | 
						||
 | 
						||
  const int slash =  http_server.find('/');
 | 
						||
  if (slash > 0)
 | 
						||
  {
 | 
						||
    http_path = http_server.mid(slash);
 | 
						||
    if (http_path.right(1) != "/")
 | 
						||
      http_path << '/';
 | 
						||
    http_server.cut(slash);
 | 
						||
  }
 | 
						||
  else
 | 
						||
    http_path = http_default_path;
 | 
						||
}
 | 
						||
 | 
						||
bool TInstaller_mask::install_patches(const TString& module, const TString& lastrelease, int lastpatch, bool only_newer)
 | 
						||
{
 | 
						||
  bool ok = true;
 | 
						||
  TString_array modules;
 | 
						||
  TFilename ininame;
 | 
						||
  get_internet_path(ininame);
 | 
						||
 | 
						||
  ininame.add(module);
 | 
						||
  ininame << "0???a.ini";
 | 
						||
  modules.destroy();
 | 
						||
  list_files(ininame, modules);
 | 
						||
  modules.sort();
 | 
						||
  FOR_EACH_ARRAY_ROW(modules, am, arow)
 | 
						||
  {
 | 
						||
    TString& ininame = *arow;
 | 
						||
    ininame.lower();
 | 
						||
    const int pos = ininame.find("a.ini");
 | 
						||
    CHECKS(pos >= 6, "Invalid installation configuration: ", (const char*)ininame);
 | 
						||
    const TString16 patchmodule = ininame.mid(pos-6, 2);
 | 
						||
    TConfig ini(ininame, patchmodule);
 | 
						||
    const int patchlevel = ini.get_int("Patch");
 | 
						||
    const char * patchversion = ini.get("Versione");
 | 
						||
    if (ok && lastrelease == patchversion // installa solo le patch della stessa ver..
 | 
						||
        && (only_newer ? lastpatch < patchlevel : lastpatch <= patchlevel)) // ... e patch superiore o uguale (reinstalla l'ultima patch)
 | 
						||
      ok = install(module, patchlevel);
 | 
						||
  }
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
bool TInstaller_mask::update_handler(TMask_field& f, KEY k)
 | 
						||
{
 | 
						||
  if (k == K_SPACE)
 | 
						||
  {
 | 
						||
    TInstaller_mask& m = (TInstaller_mask&)f.mask();
 | 
						||
    m.autoload();
 | 
						||
  }
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
bool TInstaller_mask::path_handler(TMask_field& fld, KEY key)
 | 
						||
{
 | 
						||
  bool ok = true;
 | 
						||
  if (key == K_TAB && fld.focusdirty())
 | 
						||
  {
 | 
						||
    TFilename path = fld.get();
 | 
						||
    if (path.not_empty())
 | 
						||
    {
 | 
						||
      if (path.len() == 2 && isalpha(path[0]) && path[1] == ':')
 | 
						||
      {
 | 
						||
        path << SLASH;
 | 
						||
        fld.set(path);
 | 
						||
      }
 | 
						||
      if (path.exist() || ::is_internet_path(path))
 | 
						||
        _curr_mask->autoload();
 | 
						||
      else
 | 
						||
        ok = fld.error_box(TR("Specificare un percorso valido"));
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
void TInstaller_mask::install_selection()
 | 
						||
{
 | 
						||
  TString_array& arr = rows_array();
 | 
						||
  _sys_installed = false;
 | 
						||
 | 
						||
  int nModules = 0;
 | 
						||
  {
 | 
						||
    FOR_EACH_ARRAY_ROW(arr, r, row) 
 | 
						||
    {
 | 
						||
      if (checked(r)) 
 | 
						||
        nModules++;
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  TProgind pi(nModules, "Installazione", true, true);
 | 
						||
  
 | 
						||
  FOR_EACH_ARRAY_ROW(arr, r, row) if (checked(r))
 | 
						||
  {
 | 
						||
    if (!pi.addstatus(1))
 | 
						||
      break;
 | 
						||
 | 
						||
    const TString newver = row->get(C_RELEASE);
 | 
						||
    if (newver.blank())
 | 
						||
    {
 | 
						||
      check(r, false);
 | 
						||
      continue;
 | 
						||
    }
 | 
						||
 | 
						||
    const TString4 modulo = row->get(C_CODE);
 | 
						||
    const int newpatch = row->get_int(C_PATCH);
 | 
						||
    const TString oldver = row->get(C_CURRRELEASE);
 | 
						||
    const int oldpatch = row->get_int(C_CURRPATCH);
 | 
						||
 | 
						||
    pi.set_text(format(FR("Installazione modulo '%s'"), (const char*)modulo));
 | 
						||
    if (version2year(newver) < 2003)
 | 
						||
    {
 | 
						||
      error_box(FR("Il modulo '%s' non ha una versione valida."), (const char*)modulo);
 | 
						||
      continue;
 | 
						||
    }
 | 
						||
 | 
						||
    bool ok = true;
 | 
						||
    bool is_patch = row->get_char(C_ISPATCH) == 'X';
 | 
						||
    bool has_patch = row->get_char(C_ISPATCH) == '+';
 | 
						||
    const int cmp = compare_version(oldver, oldpatch, newver, newpatch);
 | 
						||
    if (cmp == 0)
 | 
						||
      ok = noyes_box(FR("Si desidera reinstallare la versione %s.%d del modulo '%s' ?"), (const char*)newver, newpatch, (const char*)modulo);
 | 
						||
    if (!is_patch && cmp > 0)
 | 
						||
    {
 | 
						||
      TString256 msg;
 | 
						||
      msg.format(FR("Si desidera ritornare alla versione %s.%d del modulo '%s' ?\nAttenzione: non e' garantito il corretto\nfunzionamento di tutti i programmi!"), (const char*)newver, newpatch, (const char*)modulo);
 | 
						||
      ok = noyes_box(msg);
 | 
						||
    }
 | 
						||
    if (ok && is_patch)
 | 
						||
    {
 | 
						||
      // installo le patch solo se esiste gi<67> un modulo installato della stessa versione
 | 
						||
      if (!oldver.blank() )
 | 
						||
      {
 | 
						||
        if (oldver != newver)
 | 
						||
          ok = error_box(FR("Il modulo '%s' installato ha versione %s:\nimpossibile installare le patch della versione %s"),(const char *)modulo,(const char *)oldver,(const char *)newver);
 | 
						||
      } else
 | 
						||
        ok =false;//error_box("Impossibile installare le patch perche' il modulo '%s' non e' installato",(const char *)modulo);
 | 
						||
    }
 | 
						||
    if (ok)
 | 
						||
    {
 | 
						||
      if (has_patch)
 | 
						||
      {
 | 
						||
        if (newver == oldver && newpatch >= oldpatch)
 | 
						||
        {
 | 
						||
          const int basepatch = row->get_int(C_BASEPATCH);
 | 
						||
          if (oldpatch >= basepatch)
 | 
						||
            is_patch = !noyes_box(FR("Si desidera reinstallare l'intero modulo '%s'?"
 | 
						||
                                     "\nRispondendo NO verranno installate le sole patch"),
 | 
						||
                                  (const char *)modulo);
 | 
						||
          else 
 | 
						||
            is_patch = false; // Quando la versione installata precede la patch base devo reinstallare il modulo!
 | 
						||
        }
 | 
						||
      }
 | 
						||
            
 | 
						||
      if (is_patch)
 | 
						||
      {
 | 
						||
        ok = install_patches(modulo, oldver, oldpatch, false) ; // installa l'ultima patch
 | 
						||
        if (!ok)
 | 
						||
          message_box(TR("Impossibile installare le patch del modulo '%s'"),(const char *)modulo);
 | 
						||
      }
 | 
						||
      else
 | 
						||
      {
 | 
						||
        ok = install(modulo, 0); // installa il modulo
 | 
						||
      }
 | 
						||
      if (ok)
 | 
						||
      {
 | 
						||
        _installed = true; // Setta il flag di almeno un modulo installato
 | 
						||
        if (modulo == "sy") //se ha installato il modulo 'sy' esce
 | 
						||
        {
 | 
						||
          _sys_installed = true;
 | 
						||
          enable_row(r);  //deve abilitare la riga di system senno' non la puo' uncheckare dopo
 | 
						||
          uncheck(-1);  //uncheck di tutti i moduli
 | 
						||
          break;
 | 
						||
        }
 | 
						||
        uncheck(r);  //finalmente unchecka i moduli installati
 | 
						||
      }
 | 
						||
    }
 | 
						||
    else
 | 
						||
      uncheck(r); // se non ci sono patch o moduli -> uncheck
 | 
						||
  }
 | 
						||
  force_update(); //serve per togliere il check al modulo 'sy' quando viene installato
 | 
						||
  if (installed())
 | 
						||
  {
 | 
						||
    if (_sys_installed)
 | 
						||
    {
 | 
						||
      warning_box("Modulo SY installato: altri moduli presenti dovranno essere installati successivamente");
 | 
						||
      send_key(K_SPACE, DLG_QUIT);
 | 
						||
    }
 | 
						||
    else
 | 
						||
      message_box(TR("Installazione conclusa"));
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
bool TInstaller_mask::install_handler(TMask_field& fld, KEY key)
 | 
						||
{
 | 
						||
  if (key == K_SPACE)
 | 
						||
  {
 | 
						||
    if (_curr_mask->items() == 1)
 | 
						||
      _curr_mask->check(0);
 | 
						||
    const bool check_on = _curr_mask->check_enabled();
 | 
						||
    _curr_mask->enable_check(true);
 | 
						||
    const bool some = _curr_mask->one_checked();
 | 
						||
    _curr_mask->enable_check(check_on);
 | 
						||
    if (some)
 | 
						||
      _curr_mask->install_selection();
 | 
						||
    else
 | 
						||
      error_box(TR("Selezionare uno o piu' moduli da installare."));
 | 
						||
  }
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
bool TInstaller_mask::quit_handler(TMask_field& f, KEY k)
 | 
						||
{
 | 
						||
  if (k == K_SPACE)
 | 
						||
  {
 | 
						||
    TInstaller_mask & m=(TInstaller_mask &) f.mask();
 | 
						||
    const bool check_on = _curr_mask->check_enabled();
 | 
						||
    _curr_mask->enable_check(true);
 | 
						||
    const bool some = _curr_mask->one_checked();
 | 
						||
    _curr_mask->enable_check(check_on);
 | 
						||
    if (some)
 | 
						||
      return noyes_box(TR("Alcuni moduli sono selezionati per l'installazione.\nConfermare l'uscita"));
 | 
						||
  }
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
bool TInstaller_mask::tutti_handler(TMask_field& f, KEY k)
 | 
						||
{
 | 
						||
  if (k == K_SPACE)
 | 
						||
  {
 | 
						||
    TInstaller_mask & m=(TInstaller_mask &) f.mask();
 | 
						||
    if (m.check_enabled())
 | 
						||
    {
 | 
						||
      if (m.one_checked())
 | 
						||
        m.uncheck(-1);
 | 
						||
      else
 | 
						||
        m.precheck_modules(false);
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
bool TInstaller_mask::on_key(KEY key)
 | 
						||
{
 | 
						||
  bool ok = true;
 | 
						||
  switch (key)
 | 
						||
  {
 | 
						||
    case K_F7: autoload(); break;
 | 
						||
    case K_F8: field(DLG_USER).on_hit(); break;
 | 
						||
    default  : ok = TArray_sheet::on_key(key); break;
 | 
						||
  }
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
TInstaller_mask::TInstaller_mask()
 | 
						||
               : TArray_sheet(0, 0, 0, 0, TR("Installazione"),
 | 
						||
                HR("@1|Modulo@32|Cod.@3|Versione da\ninstallare@11|Liv.\nPatch@6|Data\nRilascio@10|Versione\nInstallata@10|Liv.\nPatch@6|Data\nInstallazione@13|Aggiornamento|Patch Base"),
 | 
						||
                0x18, 3)
 | 
						||
{
 | 
						||
  _curr_mask = this;
 | 
						||
  _installed = false;
 | 
						||
  _reboot_program= NONE;
 | 
						||
 | 
						||
  add_string(F_PATH, 0, PR("Installa da "), 1, 1, 80, "", 60);
 | 
						||
  add_string(F_CURPATH, 0, PR("Installa in "), 1, 2, 80, "D", 60);
 | 
						||
 | 
						||
  add_button(F_UPDATE, BR("Rileggi", 9), '\0');
 | 
						||
  add_button(F_INSTALL, BR("Installa", 9), '\0');   // NON mettere 'I'
 | 
						||
 | 
						||
  set_handler(F_PATH, path_handler);
 | 
						||
  set_handler(F_INSTALL, install_handler);
 | 
						||
  set_handler(F_UPDATE, update_handler);
 | 
						||
  set_handler(DLG_QUIT, quit_handler);
 | 
						||
  set_handler(DLG_USER, tutti_handler);
 | 
						||
 | 
						||
  TInstall_ini ini;
 | 
						||
  TFilename path = ini.get("DiskPath");
 | 
						||
  set(F_PATH, path);
 | 
						||
 | 
						||
  const bool floppy = xvt_fsys_is_removable_drive(path) != 0;
 | 
						||
  if (path.not_empty() && !floppy && !is_internet_path(path))
 | 
						||
    autoload();
 | 
						||
 | 
						||
  DIRECTORY dir;
 | 
						||
  xvt_fsys_get_dir(&dir);
 | 
						||
  xvt_fsys_convert_dir_to_str(&dir, path.get_buffer(), path.size());
 | 
						||
  set(F_CURPATH, path);
 | 
						||
}
 | 
						||
 | 
						||
TInstaller_mask::~TInstaller_mask()
 | 
						||
{
 | 
						||
  _curr_mask = NULL;
 | 
						||
 | 
						||
  if (_reboot_program != NONE)
 | 
						||
  {
 | 
						||
    TString msg;
 | 
						||
    msg << TR("Sono stati aggiornati i seguenti elementi:") < '\n';
 | 
						||
    
 | 
						||
    if (_reboot_program & NEW_MENU)
 | 
						||
      msg << TR("voci di menu;");
 | 
						||
    if (_reboot_program & NEW_MENUPRG)
 | 
						||
       msg << TR("navigatore dei menu;");
 | 
						||
    if (_reboot_program & NEW_INSTALLER)
 | 
						||
      msg << TR("installatore;");
 | 
						||
    if (_reboot_program & NEW_DLL)
 | 
						||
      msg << TR("librerie di base;");
 | 
						||
 | 
						||
    msg.rtrim(1);
 | 
						||
    msg << '\n' << TR("E' necessario uscire e rientrare dal programma.");
 | 
						||
    warning_box(msg);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// Programma principale
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
class TInstaller : public TSkeleton_application
 | 
						||
{
 | 
						||
protected:
 | 
						||
  TInstaller_mask* _m;
 | 
						||
 | 
						||
protected:
 | 
						||
  virtual bool create();
 | 
						||
  virtual bool use_files() const { return false; }
 | 
						||
  virtual bool test_assistance_year() const;
 | 
						||
  virtual void main_loop();
 | 
						||
 | 
						||
  bool testdatabase() const; 
 | 
						||
  bool testprograms() const;
 | 
						||
  void convert_archives();
 | 
						||
};
 | 
						||
 | 
						||
bool TInstaller::testdatabase() const
 | 
						||
{
 | 
						||
  TConfig ini(CONFIG_INSTALL, "Main");
 | 
						||
  return ini.get("TestDatabase","Main",-1,"Y")  != "N";
 | 
						||
}
 | 
						||
 | 
						||
bool TInstaller::testprograms() const
 | 
						||
{
 | 
						||
  TConfig ini(CONFIG_INSTALL, "Main");
 | 
						||
  char c = ini.get("TestPrograms","Main",-1,"N")[0];
 | 
						||
  return  c == 'X' || c == 'Y';
 | 
						||
}
 | 
						||
 | 
						||
bool TInstaller::test_assistance_year() const
 | 
						||
{  
 | 
						||
  // Per il momento lascia continuare: ci pensa poi la create
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
bool TInstaller::create()
 | 
						||
{
 | 
						||
  if (!TApplication::test_assistance_year())
 | 
						||
  {
 | 
						||
    TExternal_app attivazione("ba1 -4");
 | 
						||
    attivazione.run();
 | 
						||
    dongle().login();  // Rilegge anno assistenza
 | 
						||
  }
 | 
						||
  else
 | 
						||
    update_dninst(false);  // Aggiorna se necessario
 | 
						||
 | 
						||
  if (testprograms())
 | 
						||
  {
 | 
						||
    _m = new TInstaller_mask() ;
 | 
						||
    _m->disable_check();
 | 
						||
    _m->disable(F_PATH);
 | 
						||
    _m->disable(F_UPDATE);
 | 
						||
    _m->disable(DLG_USER);
 | 
						||
    return TSkeleton_application::create();
 | 
						||
  } 
 | 
						||
 | 
						||
  return error_box(FR("L'utente %s non <20> abilitato all'uso di questo programma"), (const char *)user());
 | 
						||
}
 | 
						||
 | 
						||
void TInstaller::convert_archives()
 | 
						||
{
 | 
						||
  bool conv = true;
 | 
						||
  if (is_power_station())
 | 
						||
    conv = yesno_box(TR("Si desidera convertire gli archivi ora?"));
 | 
						||
  if (conv)
 | 
						||
  {
 | 
						||
    // Lancia conversione: ba1 -0 -C -uADMIN
 | 
						||
    TExternal_app conversion("ba1 -0 -C");
 | 
						||
    conversion.run();
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
void TInstaller::main_loop()
 | 
						||
{
 | 
						||
  _m->run();
 | 
						||
  if (_m->installed() && !_m->sys_installed() && testdatabase()) // Almeno 1 modulo installato ?
 | 
						||
  {
 | 
						||
    convert_archives();
 | 
						||
  }
 | 
						||
  delete _m; _m = NULL;
 | 
						||
}
 | 
						||
 | 
						||
class TExtendedInstaller : public TInstaller
 | 
						||
{
 | 
						||
protected:
 | 
						||
  virtual bool create();
 | 
						||
  virtual void main_loop();
 | 
						||
};
 | 
						||
 | 
						||
bool TExtendedInstaller::create()
 | 
						||
{
 | 
						||
  if (!TApplication::test_assistance_year())
 | 
						||
  {
 | 
						||
    TExternal_app attivazione("ba1 -4");
 | 
						||
    attivazione.run();
 | 
						||
    dongle().login();  // Rilegge anno assistenza
 | 
						||
  }
 | 
						||
  else
 | 
						||
    update_dninst(false);  // Aggiorna se necessario
 | 
						||
 | 
						||
  _m = new TInstaller_mask() ;
 | 
						||
  return TSkeleton_application::create();
 | 
						||
}
 | 
						||
 | 
						||
void TExtendedInstaller::main_loop()
 | 
						||
{
 | 
						||
  _m->run();
 | 
						||
  if (_m->installed() && !_m->sys_installed() && testdatabase()) // Almeno 1 modulo installato ?
 | 
						||
    convert_archives();
 | 
						||
 | 
						||
  const bool reboot = _m->run_ba0close();
 | 
						||
  delete _m; _m = NULL;
 | 
						||
 | 
						||
  if (reboot && !fexist("ba3.exe")) //e' una prima installazione (non ha ancora installato la base)
 | 
						||
  {
 | 
						||
    TExternal_app ba0close("ba0close.exe");
 | 
						||
    ba0close.run(true,true,true); // run asynchronous...
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
int ba1700(int argc, char* argv[])
 | 
						||
{
 | 
						||
  const char* const PROGNAME = TR("Installazione moduli");
 | 
						||
  
 | 
						||
  if (user() != ::dongle().administrator())
 | 
						||
  {
 | 
						||
    TInstaller app;
 | 
						||
    app.run(argc, argv, PROGNAME);
 | 
						||
  } 
 | 
						||
  else 
 | 
						||
  {
 | 
						||
    TExtendedInstaller app;
 | 
						||
    app.run(argc, argv, PROGNAME);
 | 
						||
  }
 | 
						||
  return 0;
 | 
						||
} |