Files correlati : batbsta.msk batbiva.msk Ricompilazione Demo : [ ] Commento : Aggiunti alla tabella stata i codici ISTAT e UNICO Tolta da tabella IVA la distinzione tra beni e servizi git-svn-id: svn://10.65.10.50/branches/R_10_00@22531 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1996 lines
		
	
	
		
			60 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1996 lines
		
	
	
		
			60 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <agasys.h>
 | 
						||
#include <applicat.h>
 | 
						||
#include <execp.h>
 | 
						||
#include <isamrpc.h>
 | 
						||
#include <modaut.h>
 | 
						||
#include <prefix.h>
 | 
						||
#include <progind.h>
 | 
						||
#include <sheet.h>
 | 
						||
#include <statbar.h>
 | 
						||
#include <urldefid.h>
 | 
						||
#include <utility.h>
 | 
						||
 | 
						||
#include "ba1.h"
 | 
						||
#include "ba1103.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
 | 
						||
#define C_OEM 11
 | 
						||
 | 
						||
///////////////////////////////////////////////////////
 | 
						||
//  Metodi di utility
 | 
						||
///////////////////////////////////////////////////////
 | 
						||
HIDDEN const TString& http_default_path()
 | 
						||
{ return get_oem_info("Web", "www.aga.it/release100/");}
 | 
						||
 | 
						||
HIDDEN int compare_version(const char* v1, int p1, const char* v2, int p2)
 | 
						||
{
 | 
						||
  TString16 ver1(v1), ver2(v2);
 | 
						||
 | 
						||
  ver1.trim();
 | 
						||
  ver1.ltrim(ver1.len() == 4 ? 2 : 4);
 | 
						||
  ver2.trim();
 | 
						||
  ver2.ltrim(ver2.len() == 4 ? 2 : 4);
 | 
						||
  
 | 
						||
	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);
 | 
						||
}
 | 
						||
 | 
						||
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 is_internet_path(const TString& addr)
 | 
						||
{
 | 
						||
  if (addr.starts_with("www.", true) || addr.starts_with("http:", true))
 | 
						||
    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;
 | 
						||
  int _station_type;  //intero che definisce il tipo di installazione (1=std,2=server,3=client)
 | 
						||
  bool _installed; // Flag per verificare se almeno un modulo e' stato installato
 | 
						||
  bool _setup_run;    //Flag che indica se e' stato lanciato il programma setup.exe
 | 
						||
  
 | 
						||
  enum { NONE=0, NEW_MENU=1, 
 | 
						||
         NEW_MENUPRG=2, NEW_INSTALLER=4, NEW_DLL=8, NEW_SYS=14,
 | 
						||
         NEW_TRR=16 };
 | 
						||
  int _reboot_program;
 | 
						||
 | 
						||
protected: // TSheet
 | 
						||
  virtual bool on_key(KEY key);
 | 
						||
  static bool tutti_handler(TMask_field& f, KEY k);
 | 
						||
  int get_module_number(const TString& module) const;
 | 
						||
  bool should_precheck_module(int modnumber) const;
 | 
						||
  bool is_zip_file(const TFilename& n) const;
 | 
						||
 | 
						||
  bool copy_file(const TFilename& src, const TFilename& dst) const;
 | 
						||
  bool copy_tree(const char* src_study, const char* dst_study) const;
 | 
						||
  int test_station_type() const;
 | 
						||
 | 
						||
protected:
 | 
						||
  static bool path_handler(TMask_field& fld, KEY key);
 | 
						||
  static bool web_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);
 | 
						||
  int precheck_modules(bool only_newer = true);
 | 
						||
  void update_version();
 | 
						||
  void update_disk_and_web_path();
 | 
						||
  void kill_files();
 | 
						||
 | 
						||
  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_patches_path(TFilename& path) const;
 | 
						||
  void parse_internet_path(TString& http_server, TFilename& http_path) const;
 | 
						||
  bool is_program_dir(const TFilename& path);
 | 
						||
  bool is_visible_patch(TConfig& ini) const;
 | 
						||
  bool check_customer() const;
 | 
						||
 | 
						||
public:
 | 
						||
  bool installed() const { return _installed;}
 | 
						||
  bool setup_run() const { return _setup_run; }
 | 
						||
  int station_type() const {return _station_type;} 
 | 
						||
  bool autoload();
 | 
						||
  bool install(const TString& module, int patch);
 | 
						||
 | 
						||
  void backup() const;
 | 
						||
  
 | 
						||
  bool run_conversion() const 
 | 
						||
  { return installed() && (_reboot_program & NEW_TRR) != 0; } 
 | 
						||
 | 
						||
  TInstaller_mask();
 | 
						||
  virtual ~TInstaller_mask();
 | 
						||
};
 | 
						||
 | 
						||
TInstaller_mask* TInstaller_mask::_curr_mask = NULL;
 | 
						||
 | 
						||
bool TInstaller_mask::is_visible_patch(TConfig& ini) const
 | 
						||
{
 | 
						||
  bool yes = true;
 | 
						||
 | 
						||
  TAuto_token_string oem = ini.get("OEM");
 | 
						||
  if (oem.blank()) 
 | 
						||
  {
 | 
						||
    const TString& module = ini.get_paragraph();
 | 
						||
    CHECKS(module.len() == 2, "Invalid module ", (const char*)module);
 | 
						||
    const int mod = dongle().module_name2code(module);
 | 
						||
    if (mod > BAAUT && mod < ENDAUT)
 | 
						||
    {
 | 
						||
      // Pezza temporanea: assegno OEM noti eventualmente assenti dalla patch
 | 
						||
      switch (mod)
 | 
						||
      {
 | 
						||
      case COAUT: oem = "5";   break;
 | 
						||
      case HAAUT: oem = "0,3"; break;
 | 
						||
      case LVAUT: oem = "2,4"; break;
 | 
						||
      case PEAUT: oem = "3";   break;
 | 
						||
      case RIAUT: oem = "0,6"; break;
 | 
						||
      default: break;
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  if (oem.full())
 | 
						||
  {
 | 
						||
    const int my_oem = dongle().oem();
 | 
						||
    yes = oem.get_pos(my_oem) >= 0;
 | 
						||
    if (!yes) 
 | 
						||
    {
 | 
						||
      // Stando alla patch non sarei visibile ma devo controllare anche l'install.ini locale
 | 
						||
      // in modo da permettere l'aggiunta e la rimozione di nuovi OEM alla lista
 | 
						||
      const TString& module = ini.get_paragraph();
 | 
						||
      const TString& loc_oem = ini_get_string(CONFIG_GENERAL, module, "OEM");
 | 
						||
      if (loc_oem != oem)
 | 
						||
        ini_set_string(CONFIG_GENERAL, module, "OEM", oem);
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  return yes;
 | 
						||
}
 | 
						||
 | 
						||
// 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();
 | 
						||
  if (!ini.set_paragraph(module))
 | 
						||
    return false;
 | 
						||
 | 
						||
  // Nasconde i moduli riservati da occhi indiscreti
 | 
						||
  if (!is_visible_patch(ini))
 | 
						||
    return false;
 | 
						||
  
 | 
						||
  const int numpatch = ini.get_int("Patch");
 | 
						||
  TString4 strpatch; 
 | 
						||
  if (numpatch > 0)
 | 
						||
    strpatch.format("%04d", 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);
 | 
						||
  row.add(ini.get("OEM"), C_OEM);
 | 
						||
  
 | 
						||
  if (pos < 0)
 | 
						||
    add(row);
 | 
						||
  else
 | 
						||
    insert(row,pos);
 | 
						||
  
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
// Copia nello sheet l'intestazione di un modulo prendendola da un .ini
 | 
						||
bool TInstaller_mask::add_header(TConfig& ini, const TString& module)
 | 
						||
{
 | 
						||
  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;
 | 
						||
}
 | 
						||
 | 
						||
bool TInstaller_mask::should_precheck_module(int modnumber) const
 | 
						||
{
 | 
						||
  bool ok = modnumber == BAAUT;
 | 
						||
  
 | 
						||
  if (!ok)
 | 
						||
  {
 | 
						||
    //se l'installazione <20> un server, prechecka tutti i moduli, a meno che non sia in funzione il server..
 | 
						||
    //..di chiavi; in questo caso infatti la chiave <20> unica, ha dunque sicuramente tutti i moduli comuni..
 | 
						||
    //..alle varie installazioni client, e quindi basta checkare i moduli sulla chiave come per qualsiasi..
 | 
						||
    //..altra installazione
 | 
						||
    const TDongle& d = dongle();
 | 
						||
    if (station_type() == 2 && d.hardware() != _dongle_network)
 | 
						||
    {
 | 
						||
      //se sei un server hai tutti i moduli da installare
 | 
						||
      ok = d.shown(modnumber);
 | 
						||
    }
 | 
						||
    else
 | 
						||
    {
 | 
						||
      //senno' sei sfigato e ti installa solo i moduli sulla chiave
 | 
						||
      ok = d.active(modnumber);
 | 
						||
      if (!ok) // Se non hai un modulo ... potresti avere un suo modulo sottinteso
 | 
						||
      {
 | 
						||
        switch (modnumber)
 | 
						||
        {
 | 
						||
        case CAAUT: ok = d.active(CMAUT); break; // Se non hai l'analitica ritenta con le commesse
 | 
						||
        case TPAUT: ok = d.active(DCAUT); break; // Se non hai Pack ritenta con il CONAI
 | 
						||
        default: break;
 | 
						||
        }
 | 
						||
      } 
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
//che tipo di installazione e'?
 | 
						||
int TInstaller_mask::test_station_type() const
 | 
						||
{
 | 
						||
  TConfig ini(CONFIG_INSTALL, "Main");
 | 
						||
  int type = ini.get_int("Type");
 | 
						||
  //se type non e' definito nei valori giusti (1=standard,2=server,3=client)
 | 
						||
  if (type < 1 || type > 3)
 | 
						||
  {
 | 
						||
    const bool testdb = ini.get_bool("TestDatabase");
 | 
						||
    //const bool testprg = ini.get_bool("TestPrograms");
 | 
						||
    if (testdb)
 | 
						||
    {
 | 
						||
      if (dongle().hardware() == _dongle_network) //se usa un server di chiavi->server
 | 
						||
        type = 2;
 | 
						||
      else
 | 
						||
        type = 1;
 | 
						||
    }
 | 
						||
    else
 | 
						||
      type = 3;
 | 
						||
 | 
						||
    ini.set("Type", type);  //cosi' lo definisce se non c'e'
 | 
						||
  }
 | 
						||
  return type;
 | 
						||
}
 | 
						||
 | 
						||
int TInstaller_mask::precheck_modules(bool only_newer)
 | 
						||
{
 | 
						||
  TString16 release, currrelease;
 | 
						||
  TString4 cod_module;
 | 
						||
  int patchlevel, modnumber, currpatch;
 | 
						||
 | 
						||
	bool check_enabled = true;
 | 
						||
  _setup_run = false; //inizializzazione del flag di controllo di lancio di setup.exe
 | 
						||
 | 
						||
  const bool good_customer = check_customer();
 | 
						||
 | 
						||
  TString_array& a = rows_array();
 | 
						||
  FOR_EACH_ARRAY_ROW(a, r, row)
 | 
						||
  {
 | 
						||
    TToken_string& rigar = *row;
 | 
						||
    cod_module = rigar.get(C_CODE);
 | 
						||
    modnumber = get_module_number(cod_module);
 | 
						||
    release = rigar.get(C_RELEASE);
 | 
						||
    patchlevel = rigar.get_int(C_PATCH);
 | 
						||
    currrelease = rigar.get(C_CURRRELEASE);
 | 
						||
    currpatch = rigar.get_int(C_CURRPATCH);
 | 
						||
    if (modnumber >= BAAUT && should_precheck_module(modnumber) && 
 | 
						||
        release.full() && ((release > currrelease) || 
 | 
						||
        (release == currrelease &&  (only_newer ? patchlevel > currpatch : patchlevel >= currpatch) )) 
 | 
						||
       )    
 | 
						||
    {
 | 
						||
      // spunta il modulo o la patch se ho installata la stessa versione
 | 
						||
      bool chk = rigar.get_char(C_ISPATCH) != 'X' || release == currrelease;
 | 
						||
 | 
						||
      // non spunta automaticamente il modulo server su installazioni che non siano server
 | 
						||
      if (cod_module == "sr" && (test_station_type() != 2 || !xvt_sys_dongle_server_is_running()))
 | 
						||
      {
 | 
						||
        chk = false;
 | 
						||
        disable_row(r);
 | 
						||
      }
 | 
						||
 | 
						||
      if (chk && !good_customer && cod_module != "sy")
 | 
						||
        chk = false;
 | 
						||
 | 
						||
			if (check_enabled)
 | 
						||
        check(r, chk);
 | 
						||
 | 
						||
      if (chk && only_newer && (cod_module == "sy" || cod_module == "sr")) // se viene checkato il modulo sy (sistema) e/o sr (servers)
 | 
						||
      {                                                                    // deve togliere la possibilita' di installare altri moduli.
 | 
						||
        for (int i = 0; i < a.items(); i++)
 | 
						||
        {
 | 
						||
          if (i != r) 
 | 
						||
            uncheck(i);     // puo' succedere che il modulo sy o sr non sia il primo
 | 
						||
 | 
						||
          disable_row(i);   // disabilita tutte le righe dello sheet (va fatto DOPO l'uncheck!!!)
 | 
						||
        }
 | 
						||
        disable(DLG_USER);
 | 
						||
        check_enabled = false;  //..ed uscire
 | 
						||
      }
 | 
						||
    } //if(modnumber>=0...
 | 
						||
  } //FOR_EACH_ARRAY_ROW...
 | 
						||
  force_update(); // Indispensabile per vedere le righe aggiornate sullo sheet
 | 
						||
 | 
						||
  enable(F_INSTALL, good_customer);
 | 
						||
  if (!good_customer)
 | 
						||
  {
 | 
						||
    send_campo_xml();
 | 
						||
 | 
						||
    TString html;
 | 
						||
    html << "<html><body>"
 | 
						||
         << "<h5>Attenzione: chiave " << dongle().number() << " non riconosciuta.</h5>\n" 
 | 
						||
         << "<p align=justify>Al fine di poter riattivare la chiave <b>" << dongle().product().before(" ") 
 | 
						||
         << "</b> in oggetto e poter quindi effettuare il download di eventuali aggiornamenti software, "
 | 
						||
         << "La preghiamo di contattare Sirio informatica e sistemi ai seguenti riferimenti:</p><br/>"
 | 
						||
         << "<ul><li>Sara Coppini, segreteria commerciale: <br />"
 | 
						||
         << "<a href=mailto:scoppini@sirio-is.it>scoppini@sirio-is.it</a> Tel. 348-9897249</li>"
 | 
						||
         << "<li>Morena Martini, responsabile commerciale canale: <br />"
 | 
						||
         << "<a href=mailto:mmartini@sirio-is.it>mmartini@sirio-is.it</a> Tel. 349-3421433</li></ul>"
 | 
						||
         << "</body></html>";
 | 
						||
    error_box(html);
 | 
						||
  }
 | 
						||
 | 
						||
  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 BAAUT;
 | 
						||
 | 
						||
    aut = dongle().module_name2code(module);
 | 
						||
    ok = aut < ENDAUT;
 | 
						||
  }
 | 
						||
  return ok ? aut : -1;
 | 
						||
}
 | 
						||
 | 
						||
void TInstaller_mask::update_version()
 | 
						||
{
 | 
						||
  TInstall_ini ini;
 | 
						||
 | 
						||
  TString_array& a = rows_array();
 | 
						||
  FOR_EACH_ARRAY_ROW_BACK(a, m, row)
 | 
						||
  {
 | 
						||
    if (*row->get(C_CODE) != ' ')
 | 
						||
    {
 | 
						||
      const TString4 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");
 | 
						||
      TString4 strpatch; 
 | 
						||
      if (numpatch > 0) 
 | 
						||
        strpatch.format("%04d", numpatch);
 | 
						||
      row->add(oldver, C_CURRRELEASE);
 | 
						||
      row->add(strpatch, C_CURRPATCH);
 | 
						||
      row->add(ini.get("Data"), C_CURRDATAREL);
 | 
						||
    }
 | 
						||
  }
 | 
						||
  force_update();
 | 
						||
}
 | 
						||
 | 
						||
bool TInstaller_mask::check_customer() const
 | 
						||
{
 | 
						||
  Tdninst dninst;
 | 
						||
  return dninst.check_customer() == 0;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// 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, path, ininame;
 | 
						||
 | 
						||
  //controla se si e' scelto un path di installazione internet o da disco
 | 
						||
  const bool internet = get_patches_path(path);
 | 
						||
  //se e' un aggiornamento via internet...
 | 
						||
  if (internet)
 | 
						||
  {
 | 
						||
    if (!(xvt_net_get_status() & 0x4)) //la connessione web funziona?...
 | 
						||
      return warning_box("Impossibile connettersi al sito con gli aggiornamenti\nVerificare che la connessione Internet sia attiva !");
 | 
						||
 | 
						||
    parse_internet_path(http_server, http_path);  //controlla il path internet scritto nel campo sulla maschera
 | 
						||
 | 
						||
    //se si ritrova dei vecchi file nella directory temporanea, la pulisce per evitare casini
 | 
						||
    ininame = path; ininame.add("*.*");
 | 
						||
    TString_array list;
 | 
						||
    const int cache_files = ::list_files(ininame, list);
 | 
						||
    if (cache_files > 0)
 | 
						||
    {
 | 
						||
      TProgind pi(cache_files, TR("Azzeramento cache"), false, true);
 | 
						||
      FOR_EACH_ARRAY_ROW(list, i, row)
 | 
						||
      {
 | 
						||
        pi.addstatus(1);
 | 
						||
        xvt_fsys_remove_file(*row);
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    ininame = path;
 | 
						||
    ininame.add(TInstall_ini::default_name());
 | 
						||
    if (!ininame.exist())
 | 
						||
    {
 | 
						||
      TFilename remote_ini = http_path;
 | 
						||
			remote_ini << TInstall_ini::default_name();
 | 
						||
 | 
						||
      if (remote_ini.full()) // dummy test
 | 
						||
      {
 | 
						||
        TTimerind contacting(30*1000, TR("Connessione al server HTTP..."), false, false);
 | 
						||
        http_get(http_server, remote_ini, ininame);
 | 
						||
 | 
						||
        // Cerca di prelevare anche dninst.zip
 | 
						||
        const char* const local_dninst = "setup/dninst.zip";
 | 
						||
        TFilename remote_dninst = http_path;
 | 
						||
        remote_dninst << local_dninst;
 | 
						||
        if (!http_get(http_server, remote_dninst, local_dninst))
 | 
						||
        {
 | 
						||
          // Se non aggiorno da release riprovo con l'indirizzo dell'OEM
 | 
						||
          remote_dninst = http_default_path();
 | 
						||
          remote_dninst << local_dninst;
 | 
						||
          const int slash = remote_dninst.find('/');
 | 
						||
          if (slash > 0)
 | 
						||
            http_get(remote_dninst.left(slash), remote_dninst.mid(slash), local_dninst);
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
  } //if(internet...
 | 
						||
 | 
						||
  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;
 | 
						||
 | 
						||
  //cerca sull'install.ini di origine se lo trova (ininame e' il path dell'install.ini remoto)
 | 
						||
  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);
 | 
						||
        else
 | 
						||
        {
 | 
						||
          TFilename mod_ini = ininame.path();
 | 
						||
          mod_ini.add(module);
 | 
						||
          mod_ini << "inst.ini";
 | 
						||
          //controlla se esiste il pacco zippato del modulo attraverso l'esistenza del file..
 | 
						||
					//..XXinst.ini
 | 
						||
          if (mod_ini.exist())
 | 
						||
          {
 | 
						||
            TInstall_ini moduleini(mod_ini);
 | 
						||
            add_module(moduleini, module, false);
 | 
						||
          }
 | 
						||
          else
 | 
						||
            add_module(ini, module, false);
 | 
						||
        }
 | 
						||
      } //if(module[0]...
 | 
						||
    } //FOR_EACH_ARRAY_ROW(...
 | 
						||
  }
 | 
						||
  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 TString4 module = ininame.mid(pos-2, 2);
 | 
						||
      TConfig ini(ininame, module);
 | 
						||
      add_module(ini, module, false);
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  modules.destroy();
 | 
						||
 | 
						||
  if (internet) //internet patches
 | 
						||
  {
 | 
						||
    TProgind pi(1, TR("Controllo lista aggiornamenti"), false); //progind NON bloccabile: causa errore impossibile!
 | 
						||
    http_dir(http_server, http_path, modules);
 | 
						||
    pi.setmax(modules.items());
 | 
						||
    pi.set_text(TR("Download lista aggiornamenti"));
 | 
						||
    for (int i = modules.last(); i >= 0; i--)
 | 
						||
    {
 | 
						||
      if (!pi.addstatus(1))
 | 
						||
        break;
 | 
						||
      TString& str = modules.row(i);
 | 
						||
      if (str.match("??????a.ini", true))
 | 
						||
      {
 | 
						||
        const TString& module = str.left(2);
 | 
						||
        const int patch = atoi(str.mid(2, 4));
 | 
						||
        const int mypatch = ini_get_int(CONFIG_GENERAL, module, "Patch");
 | 
						||
        if (patch > 0 && patch < mypatch) 
 | 
						||
          continue; // Non fare il download delle patch inutili
 | 
						||
 | 
						||
        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("??????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;
 | 
						||
    TFilename file;
 | 
						||
 | 
						||
    installini.list_paragraphs(paragrafi);
 | 
						||
		// rimozione del produttore sull'install.ini locale ora obsoleto..
 | 
						||
  	installini.remove("Producer");
 | 
						||
 | 
						||
    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 TString4 module = ininame.mid(pos-6, 2);
 | 
						||
    TConfig ini(ininame, module); 
 | 
						||
    ini.write_protect();
 | 
						||
    int r;
 | 
						||
    for (r = int(items()-1); r >= 0; r--)
 | 
						||
    {
 | 
						||
      if (module == row(r).get(C_CODE))
 | 
						||
        break;
 | 
						||
    }
 | 
						||
 | 
						||
    if (r >= 0)
 | 
						||
    {
 | 
						||
      if (is_visible_patch(ini))
 | 
						||
      {
 | 
						||
        const TString16 patchversion = ini.get("Versione");
 | 
						||
        const int patchlevel = ini.get_int("Patch");
 | 
						||
        TToken_string& row = mask_rows.row(r);
 | 
						||
			  const TString16 release(row.get(C_RELEASE));
 | 
						||
        if (patchversion.mid(4) == release.mid(4) && // se le versioni corrispondono ...
 | 
						||
            patchlevel > row.get_int(C_PATCH))       // ..e il patchlevel <20> superiore
 | 
						||
        {   
 | 
						||
          TString4 patch; patch.format("%04d", patchlevel);  //aggiunge zeri per avere 3 cifre sempre
 | 
						||
          row.add(patch, C_PATCH); // aggiorna il patchlevel mostrato per il modulo
 | 
						||
          row.add(ini.get("Data"), C_DATAREL); // aggiorna data di rilascio
 | 
						||
          if (row.get_char(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
 | 
						||
          }
 | 
						||
				  if (release < patchversion)
 | 
						||
					  row.add(patchversion, C_RELEASE);
 | 
						||
          row.add(ini.get("OEM"), C_OEM);
 | 
						||
        }
 | 
						||
      }
 | 
						||
      else
 | 
						||
        destroy(r); // Elimina patch di altri OEM erroneamente inserite
 | 
						||
    } 
 | 
						||
    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.full())
 | 
						||
    {
 | 
						||
      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)
 | 
						||
{
 | 
						||
  ini.set_paragraph(module);
 | 
						||
  if (!is_visible_patch(ini))
 | 
						||
    return false;
 | 
						||
 | 
						||
  const TString& version = ini.version(module);
 | 
						||
  const word year = version2year(version);
 | 
						||
  if (year < 2091)
 | 
						||
    return error_box(FR("Il modulo '%s' non ha una versione valida."), module);
 | 
						||
 | 
						||
  if (!dongle().demo() && year > dongle().year_assist())  //devo aggiornare l'anno di assistenza?
 | 
						||
  {
 | 
						||
    if (!update_assistance_year())  //sono riuscito ad aggiornare l'anno di assistenza?
 | 
						||
      return false;
 | 
						||
  }
 | 
						||
 | 
						||
  TAuto_token_string altri(ini.get("Moduli", module));
 | 
						||
  if (xvt_str_compare_ignoring_case(module, "sy") != 0) //SY e' indipendente dagli altri moduli
 | 
						||
  {
 | 
						||
    if (xvt_str_compare_ignoring_case(module, "ba") != 0 && altri.get_pos("ba") < 0)
 | 
						||
      altri.add("ba");
 | 
						||
  }
 | 
						||
 | 
						||
  bool ok = true;
 | 
						||
  TString submodule;
 | 
						||
  TInstall_ini curini;
 | 
						||
  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; else
 | 
						||
  if (xvt_str_compare_ignoring_case(ext, "trr") == 0 || xvt_str_compare_ignoring_case(ext, "dir") == 0)
 | 
						||
    underscore = NEW_TRR;
 | 
						||
  return underscore;
 | 
						||
}
 | 
						||
 | 
						||
// Controlla se un file puo' essere scompattato.
 | 
						||
// Attenzione: dninst.zip e' un falso zip
 | 
						||
bool TInstaller_mask::is_zip_file(const TFilename& n) const
 | 
						||
{
 | 
						||
	bool yes = xvt_str_compare_ignoring_case(n.ext(), "zip") == 0 && 
 | 
						||
		         xvt_str_compare_ignoring_case(n.name_only(), "dninst") != 0;
 | 
						||
  return yes;
 | 
						||
}
 | 
						||
 | 
						||
bool TInstaller_mask::copy_file(const TFilename& src, const TFilename& dst) const
 | 
						||
{
 | 
						||
  // Crea la cartella di destinazione se necessario
 | 
						||
  const char* dstdir = dst.path();
 | 
						||
  if (*dstdir && !xvt_fsys_mkdir(dstdir))
 | 
						||
    return error_box(FR("Impossibile creare la cartella %s"), dst.path());
 | 
						||
 | 
						||
  // Copia veramente il file
 | 
						||
  return ::fcopy(src, dst);
 | 
						||
}
 | 
						||
 | 
						||
// 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_SYS)!=0 && dst.exist())
 | 
						||
  {
 | 
						||
    dest.rtrim(1);
 | 
						||
    dest << '_';
 | 
						||
  }
 | 
						||
 | 
						||
  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.path(), filesize) == 0)
 | 
						||
    return error_box(TR("Lo spazio disponibile e' insufficiente!"));
 | 
						||
 | 
						||
  const bool write_ok = copy_file(src, dest);
 | 
						||
  if (write_ok && is_zip)
 | 
						||
    aga_unzip(src, dest.path());
 | 
						||
    
 | 
						||
  if (write_ok)
 | 
						||
    src.fremove();
 | 
						||
 | 
						||
  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)
 | 
						||
      src.fremove();
 | 
						||
  }
 | 
						||
  
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
bool TInstaller_mask::copy_tree(const char* src_study, const char* dst_study) const
 | 
						||
{
 | 
						||
  xvt_fsys_save_dir();
 | 
						||
  TFilename mask(src_study); mask.add("*.");
 | 
						||
  SLIST dlist = xvt_fsys_list_files(DIR_TYPE, mask, TRUE);
 | 
						||
  xvt_fsys_restore_dir();
 | 
						||
  TProgind pd(xvt_slist_count(dlist), TR("Copia cartelle"), true, true);
 | 
						||
 | 
						||
  TString msg; // Messaggio di progresso
 | 
						||
 | 
						||
  bool go_on = true;
 | 
						||
  for (SLIST_ELT d = xvt_slist_get_first(dlist); d && go_on; d = xvt_slist_get_next(dlist, d))
 | 
						||
  { 
 | 
						||
    if (!pd.addstatus(1))
 | 
						||
    {
 | 
						||
      go_on = false;
 | 
						||
      break;
 | 
						||
    }
 | 
						||
 | 
						||
    const TFilename dir = xvt_slist_get(dlist, d, NULL);
 | 
						||
    
 | 
						||
    TString name = dir.name(); name.lower();
 | 
						||
    if (name == "cesp") // Ignora la vetusta cartella Cespiti in FoxPro
 | 
						||
      continue;
 | 
						||
 | 
						||
    msg.cut(0) << TR("Copia di ") << name;
 | 
						||
    pd.set_text(msg);
 | 
						||
 
 | 
						||
    mask = dir; mask.add("*.*");
 | 
						||
    TString_array files; list_files(mask, files);
 | 
						||
 | 
						||
    TProgind pi(files.items(), "Copia file", true, true);
 | 
						||
 | 
						||
    TFilename dst;
 | 
						||
    FOR_EACH_ARRAY_ROW(files, i, f)
 | 
						||
    {
 | 
						||
      if (!pi.addstatus(1))
 | 
						||
      {
 | 
						||
        go_on = false;
 | 
						||
        break;
 | 
						||
      }
 | 
						||
      TFilename src(*f);
 | 
						||
      TString16 ext(src.ext()); ext.lower();
 | 
						||
      if (ext != "zip" && ext != "rar" && ext != "mdb" && ext != "inf") 
 | 
						||
      {
 | 
						||
        msg.cut(0) << TR("Copia di ") << src;
 | 
						||
        pi.set_text(msg);
 | 
						||
 | 
						||
        dst = dst_study;
 | 
						||
        dst.add(name);
 | 
						||
        dst.add(src.name());
 | 
						||
        copy_file(src, dst);
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
  xvt_slist_destroy(dlist);
 | 
						||
 | 
						||
  return go_on;
 | 
						||
}
 | 
						||
	
 | 
						||
void TInstaller_mask::backup() const
 | 
						||
{ 
 | 
						||
  TFilename src = firm2dir(-1);
 | 
						||
  if (!isalnum(src.right(1)[0]))
 | 
						||
    src.rtrim(1);
 | 
						||
  TFilename dst(src); 
 | 
						||
  dst << ' ' << TDate(TODAY).date2ansi(); // Lo spazio rende inutilizzabile lo studio
 | 
						||
 | 
						||
  TToken_string msg(256, '\n');
 | 
						||
  msg.add(TR("Si consiglia creare una copia dello studio ")); msg << src.name(); 
 | 
						||
  msg.add(TR("nella cartella ")); msg << dst; 
 | 
						||
  msg.add(TR("L'operazione potrebbe richiedere alcuni minuti."));
 | 
						||
  msg.add("");
 | 
						||
  msg.add(TR("Si desidera effetture la copia?"));
 | 
						||
  if (yesno_box(msg))
 | 
						||
    copy_tree(src, dst);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
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;
 | 
						||
}
 | 
						||
 | 
						||
//rimozione da disco dei files da eliminare indicati nei paragrafi kill..
 | 
						||
//..e successivo aggiornamento dell'install.ini in modo da non avere pi<70> tra i piedi i files killati
 | 
						||
void TInstaller_mask::kill_files()
 | 
						||
{
 | 
						||
  //apre l'install.ini locale per effettuare l'aggiornamento
 | 
						||
  TInstall_ini ini;
 | 
						||
  //giro su tutti i sottomoduli di tipo 99 con l'elenco dei files da uccidere
 | 
						||
  TString_array paragraph_names;
 | 
						||
  ini.list_paragraphs(paragraph_names);
 | 
						||
 | 
						||
  FOR_EACH_ARRAY_ROW(paragraph_names, nriga, riga)
 | 
						||
  {
 | 
						||
    //interessano solo i paragrafi con le killer list
 | 
						||
    if (riga->ends_with("99") && ini.set_paragraph(*riga))
 | 
						||
    { 
 | 
						||
      TString_array killed;
 | 
						||
 | 
						||
      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)
 | 
						||
          {
 | 
						||
            filetokill = *file;
 | 
						||
            if (filetokill.exist()) 
 | 
						||
              filetokill.fremove();
 | 
						||
            killed.add(filetokill);
 | 
						||
          }
 | 
						||
        }
 | 
						||
        else
 | 
						||
        {
 | 
						||
          if (filetokill.exist()) 
 | 
						||
            filetokill.fremove();
 | 
						||
          killed.add(filetokill);
 | 
						||
        }
 | 
						||
      } //for(int k=0...
 | 
						||
 | 
						||
      for (int s = 0; s <= 9 && !killed.empty(); s++)
 | 
						||
      {
 | 
						||
        const TString4 mod = riga->left(2);
 | 
						||
        const int cicli = mod == "ba" ? 2 : 1;
 | 
						||
        for (int c = 1; c <= cicli; c++)
 | 
						||
        {
 | 
						||
          TString4 module = c == 1 ? mod : "sy";
 | 
						||
          module << s;
 | 
						||
          TAssoc_array& vars = ini.list_variables(module);
 | 
						||
          FOR_EACH_ASSOC_STRING(vars, hobj, key, str)
 | 
						||
          {
 | 
						||
            const int idx = killed.find(str);
 | 
						||
            if (idx >= 0)
 | 
						||
            {
 | 
						||
              ini.remove(key);
 | 
						||
              killed.destroy(idx, true);
 | 
						||
            }
 | 
						||
          }
 | 
						||
        }
 | 
						||
      } //for (int s...
 | 
						||
    } //if (riga->ends_with...
 | 
						||
  } //FOR_EACH_ARRAY_ROW(...
 | 
						||
}
 | 
						||
 | 
						||
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_patches_path(path);
 | 
						||
  if (internet)
 | 
						||
    parse_internet_path(http_server,http_path );
 | 
						||
 | 
						||
  const bool is_a_patch = (patchlevel > 0);
 | 
						||
  //file .ini con le info di installazione (es. bainst.ini o ba0883.ini)
 | 
						||
  TFilename remote_ininame = path;
 | 
						||
  remote_ininame.add(module);
 | 
						||
 | 
						||
  //completa il nome del file .ini controllando se <20> una patch (es. ba0883a.ini) o se <20> un pacco (es. bainst.ini)
 | 
						||
  if (is_a_patch)
 | 
						||
  {
 | 
						||
    TString16 name;
 | 
						||
    name.format("%04da.ini", patchlevel);
 | 
						||
    remote_ininame << name;
 | 
						||
  }
 | 
						||
  else
 | 
						||
    remote_ininame << "inst.ini";
 | 
						||
 | 
						||
  if (internet && !remote_ininame.exist())
 | 
						||
  {
 | 
						||
    TFilename remote = remote_ininame.name();
 | 
						||
    remote.insert(http_path, 0);
 | 
						||
    http_get(http_server, remote, remote_ininame);
 | 
						||
  }
 | 
						||
 | 
						||
  if (remote_ininame.exist())
 | 
						||
  {
 | 
						||
    // esiste un particolare .ini con formato XXinst.ini (moduli) o con XX9999a.ini (patch)
 | 
						||
    //----------------------------------------------
 | 
						||
    // (INSTALLAZIONE DA DIRECTORY CON FILES .ZIP)
 | 
						||
    //----------------------------------------------
 | 
						||
    //remote_ini <20> il file .ini con le info di installazione (es. ba0883a.ini, bainst.ini)
 | 
						||
    TInstall_ini* remote_ini = new TInstall_ini(remote_ininame);
 | 
						||
    remote_ini->write_protect();
 | 
						||
    lastpatch = remote_ini->get_int("Patch", module);
 | 
						||
    lastrelease = remote_ini->get("Versione", module);
 | 
						||
 | 
						||
    //se non pu<70> installare il modulo chiude il remote_ini
 | 
						||
    if (!can_install(module, *remote_ini))
 | 
						||
    {
 | 
						||
      delete remote_ini;
 | 
						||
      return false;
 | 
						||
    }
 | 
						||
 | 
						||
    //antico controllo del numero di dischetti (ora sempre = 1)
 | 
						||
    const int dischi = remote_ini->get_int("Dischi", module);
 | 
						||
    ok = dischi > 0;
 | 
						||
    if (!ok)
 | 
						||
      return error_box(FR("Impossibile determinare il numero dei dischetti in %s"), remote_ininame.name());
 | 
						||
    else
 | 
						||
    {
 | 
						||
      if (patchlevel == 0)
 | 
						||
        ok = pre_process(*remote_ini, module);
 | 
						||
      if (!ok)
 | 
						||
      {
 | 
						||
        delete remote_ini;
 | 
						||
        return false;
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    // DECOMPRESSIONE
 | 
						||
    // ----------------   
 | 
						||
    // viene decompresso il file .zip collegato al file remote_ini (es. ba0883a1.zip, bainst.zip)
 | 
						||
 | 
						||
    TProgind* pi = NULL;
 | 
						||
    if (dischi > 1)
 | 
						||
    {
 | 
						||
      msg = TR("Decompressione");
 | 
						||
      if (is_a_patch)
 | 
						||
        msg << TR(" della patch ") << patchlevel ;
 | 
						||
      msg << TR(" del modulo '") << module << TR("' in corso...");
 | 
						||
      pi = new TProgind(dischi, msg, false, true);
 | 
						||
    }
 | 
						||
 | 
						||
    TFilename tempdir; 
 | 
						||
    tempdir.tempdir();
 | 
						||
    
 | 
						||
		// File tottale dei vari sotto-zip
 | 
						||
		TFilename totti = tempdir; 
 | 
						||
    totti.add(module); 
 | 
						||
    totti.ext("zip");
 | 
						||
    
 | 
						||
    //si costruisce il nome dello 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);
 | 
						||
      }
 | 
						||
 | 
						||
      //antichi controlli in caso di multidischetto
 | 
						||
      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*)remote_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
 | 
						||
    }
 | 
						||
    if (pi != NULL)
 | 
						||
    {
 | 
						||
      delete pi;
 | 
						||
      pi = NULL;
 | 
						||
    }
 | 
						||
 | 
						||
    //scompattamento vero e proprio dello zip
 | 
						||
  	aga_unzip(totti, tempdir); // Scompatta il file totale zip
 | 
						||
		totti.fremove();                // Elimina il file totale zip
 | 
						||
 | 
						||
 | 
						||
    // TRASFERIMENTO
 | 
						||
    // -----------------
 | 
						||
    if (ok)
 | 
						||
    {
 | 
						||
      // si assicura che sia leggibile il .ini del primo disco
 | 
						||
      do 
 | 
						||
			{
 | 
						||
        TFilename cmdline = path;
 | 
						||
        cmdline.add(remote_ininame.name());
 | 
						||
        ok = cmdline.exist();
 | 
						||
        if (!ok)
 | 
						||
        {
 | 
						||
          if (askdisk(path, cmdline, 1, dischi, (const char*)remote_ini->get("Descrizione")) == K_QUIT)
 | 
						||
           break;
 | 
						||
          ok = fexist(cmdline);
 | 
						||
          if (!ok)
 | 
						||
            message_box(FR("Impossibile trovare %s\n"), (const char*)cmdline);
 | 
						||
          else
 | 
						||
          {
 | 
						||
            delete remote_ini;
 | 
						||
            remote_ini = new TInstall_ini (cmdline);
 | 
						||
          }
 | 
						||
        }
 | 
						||
      } while (!ok);
 | 
						||
 | 
						||
      if (ok)
 | 
						||
      {
 | 
						||
        TWait_cursor hourglass;
 | 
						||
        msg.cut(0);
 | 
						||
        msg << TR("Aggiornamento del modulo '") << module << TR("' in corso...");
 | 
						||
        xvtil_statbar_set(msg);
 | 
						||
        ok = move_module(module, *remote_ini, true);
 | 
						||
 | 
						||
        if (ok)
 | 
						||
        {
 | 
						||
          TAuto_token_string altri(remote_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 local_cur_ini;
 | 
						||
                const TString16 curver = local_cur_ini.version(submod);
 | 
						||
                const int curpatch = local_cur_ini.patch(submod);
 | 
						||
                const TString16 reqver = remote_ini->version(submod);
 | 
						||
                const int reqpatch = remote_ini->patch(submod);
 | 
						||
  
 | 
						||
                int distance = compare_version(reqver, reqpatch, curver, curpatch);
 | 
						||
                upd = distance > 0;
 | 
						||
              }
 | 
						||
              ok &= move_module(submod, *remote_ini, upd);
 | 
						||
              if (upd && ok)  // marca sull'install.ini di destinazione l'avvenuta installazione del sottomodulo "esterno"
 | 
						||
                remote_ini->export_paragraph(submod, TInstall_ini::default_name(), !is_a_patch);
 | 
						||
            }
 | 
						||
          }
 | 
						||
        }
 | 
						||
        xvtil_statbar_set("");
 | 
						||
      } //if(ok)..
 | 
						||
    } //if(ok)..
 | 
						||
    if (ok) // marca sull'install.ini di destinazione l'avvenuta installazione del modulo
 | 
						||
      remote_ini->export_module_paragraphs(module, TInstall_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" (es. aggiornamento client)
 | 
						||
      //------------------------------------------------
 | 
						||
      // (INSTALLAZIONE DA DIRECTORY CON ESEGUIBILI)
 | 
						||
      //------------------------------------------------
 | 
						||
      remote_ininame = path;
 | 
						||
      remote_ininame.add(TInstall_ini::default_name());
 | 
						||
      ok = fexist(remote_ininame);
 | 
						||
      if (ok)
 | 
						||
      {
 | 
						||
        TInstall_ini ini(remote_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_SYS) != 0 && dst.exist())
 | 
						||
              {
 | 
						||
                dst.rtrim(1);
 | 
						||
                dst << '_';
 | 
						||
              }
 | 
						||
              //copia il file dalla dir sorgenti
 | 
						||
              ok = copy_file(src, dst);
 | 
						||
              if (ok)
 | 
						||
              {
 | 
						||
                if (ok && is_zip_file(src))
 | 
						||
                  aga_unzip(src, dst.path());
 | 
						||
              
 | 
						||
                if (ok && reboot != NONE)
 | 
						||
                  _reboot_program |= reboot;
 | 
						||
              }
 | 
						||
              else  //se non riesce chiede se proseguire ugualmente
 | 
						||
                ok = yesno_box(TR("Continuare ugualmente ?"));
 | 
						||
 | 
						||
              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("Data", TDate(TODAY), module);
 | 
						||
    }
 | 
						||
    // 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_patches_path(TFilename& path) const
 | 
						||
{
 | 
						||
  const TEdit_field& www = efield(F_WEB);
 | 
						||
  path = www.get();
 | 
						||
  if (www.active() && path.full() && is_internet_path(path))
 | 
						||
  {
 | 
						||
    path.tempdir();
 | 
						||
    path.add("www");
 | 
						||
    make_dir(path); //crea la directory temporanaea di installazione dove depositare e scompattare gli zip
 | 
						||
    return true;
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    path = get(F_PATH);
 | 
						||
    // Toglie l'eventual slash finale
 | 
						||
    const char last = path.right(1)[0];
 | 
						||
    if (last == '/' || last == '\\')
 | 
						||
      path.rtrim(1);
 | 
						||
  }
 | 
						||
  return false;
 | 
						||
}
 | 
						||
 | 
						||
void TInstaller_mask::parse_internet_path(TString & http_server, TFilename &http_path) const
 | 
						||
{
 | 
						||
  http_server = get(F_WEB);
 | 
						||
  if (http_server.blank())
 | 
						||
  {
 | 
						||
    http_server = http_default_path();
 | 
						||
    ((TMask*)this)->set(F_WEB, http_server);
 | 
						||
  }
 | 
						||
 | 
						||
  if (http_server.starts_with("http://"))
 | 
						||
    http_server.ltrim(7);
 | 
						||
 | 
						||
  const int slash = http_server.find('/');
 | 
						||
  if (slash > 0)
 | 
						||
  {
 | 
						||
    http_path = http_server.mid(slash);
 | 
						||
    http_server.cut(slash);
 | 
						||
  }
 | 
						||
 | 
						||
  //aggiunge lo slash finale se l'utonto l'ha omesso
 | 
						||
  if (!http_path.ends_with("/"))
 | 
						||
    http_path << '/';
 | 
						||
 | 
						||
  //e' un server redirezionato?
 | 
						||
  http_isredirected_server(http_server, http_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_patches_path(ininame);
 | 
						||
 | 
						||
  ininame.add(module);
 | 
						||
  ininame << "????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 TString4 patchmodule = ininame.mid(pos-6, 2);
 | 
						||
    TConfig ini(ininame, patchmodule);
 | 
						||
    const int patchlevel = ini.get_int("Patch");
 | 
						||
    const TString16 patchversion = ini.get("Versione");
 | 
						||
    if (ok && lastrelease.mid(4) == patchversion.mid(4) // 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;
 | 
						||
}
 | 
						||
 | 
						||
bool TInstaller_mask::web_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.ends_with("/"))
 | 
						||
      {
 | 
						||
        path << '/';
 | 
						||
        fld.set(path);
 | 
						||
      }
 | 
						||
      ok = ::is_internet_path(path);
 | 
						||
      if (!ok)
 | 
						||
        ok = fld.error_box(TR("Specificare un indirizzo valido"));
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// Aggiorna l'install.ini con eventuali modifiche dell'utente su dispath e/o webpath 
 | 
						||
// Decisivo in caso di cambio path d'installazione
 | 
						||
// Serve a setup (deve essere chiamata in caso di esecuzioni passive di setup, tipo -uw, -uw)
 | 
						||
void TInstaller_mask::update_disk_and_web_path()
 | 
						||
{
 | 
						||
  TInstall_ini ini;
 | 
						||
  ini.set("DiskPath", get(F_PATH));
 | 
						||
  ini.set("WebPath", get(F_WEB));
 | 
						||
}
 | 
						||
 | 
						||
void TInstaller_mask::install_selection()
 | 
						||
{
 | 
						||
  TString_array& arr = rows_array();
 | 
						||
 | 
						||
  int nModules = 0;
 | 
						||
  {
 | 
						||
    FOR_EACH_ARRAY_ROW(arr, r, row) 
 | 
						||
    {
 | 
						||
      if (checked(r)) 
 | 
						||
        nModules++;
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  TProgind pi(nModules, TR("Installazione"), true, true);
 | 
						||
 | 
						||
  //deve poter tener conto del "No Tutti" in caso di installazione da area release
 | 
						||
  bool no_to_all = false;
 | 
						||
  
 | 
						||
  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 TString modesc = dongle().module_name2desc(modulo);
 | 
						||
    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*)modesc));
 | 
						||
    if (version2year(newver) < 2009)
 | 
						||
    {
 | 
						||
      error_box(FR("Il modulo '%s' non ha una versione valida."), (const char*)modesc);
 | 
						||
      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);
 | 
						||
 | 
						||
		//versione e patch coincidono
 | 
						||
    if (cmp == 0)
 | 
						||
      ok = noyes_box(FR("Si desidera reinstallare la versione %s.%d del modulo '%s' ?"), (const char*)newver, newpatch, (const char*)modesc);
 | 
						||
    
 | 
						||
		//ci sono ANCHE i pacchi
 | 
						||
		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*)modesc);
 | 
						||
      ok = noyes_box(msg);
 | 
						||
    }
 | 
						||
 | 
						||
		//ci sono SOLO patch da installare
 | 
						||
    if (ok && is_patch)
 | 
						||
    {
 | 
						||
      // installo le patch solo se esiste gi<67> un modulo installato della stessa versione
 | 
						||
      if (!oldver.blank() )
 | 
						||
      {
 | 
						||
        if (compare_version(oldver, 0, newver, 0))	//controlla SOLO la versione indipendentemente dall'anno!
 | 
						||
          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
 | 
						||
	    if (newpatch < oldpatch)
 | 
						||
		  {
 | 
						||
			TString256 msg;
 | 
						||
			msg.format(FR("Si desidera ritornare alla patch %s.%d del modulo '%s' ?\nAttenzione: non e' garantito il corretto\nfunzionamento di tutti i programmi!"), (const char*)newver, newpatch, (const char*)modesc);
 | 
						||
		    ok = noyes_box(msg);
 | 
						||
		  }    
 | 
						||
    } //if(ok&&is_patch...
 | 
						||
 | 
						||
    if (ok)
 | 
						||
    {
 | 
						||
      if (has_patch)
 | 
						||
      {
 | 
						||
        if (newver == oldver && newpatch >= oldpatch)
 | 
						||
        {
 | 
						||
          const int basepatch = row->get_int(C_BASEPATCH);
 | 
						||
          if (oldpatch >= basepatch)
 | 
						||
          {
 | 
						||
            if (!no_to_all)
 | 
						||
            {
 | 
						||
              const int key = yesnoall_box(FR("Si desidera reinstallare l'intero modulo '%s'?"
 | 
						||
                                              "\nRispondendo NO verranno installate le sole patch"),
 | 
						||
                                              (const char *)modesc);
 | 
						||
              switch (key)
 | 
						||
              {
 | 
						||
              case K_YES:
 | 
						||
                is_patch = true;
 | 
						||
                break;
 | 
						||
              case K_SPACE: //se risponde "No Tutti", non deve pi<70> chiederlo e prenderlo sempre per buono
 | 
						||
                is_patch = true;
 | 
						||
                no_to_all = true;
 | 
						||
                break;
 | 
						||
              default:
 | 
						||
                is_patch = false;
 | 
						||
                break;
 | 
						||
              }
 | 
						||
            }
 | 
						||
            else
 | 
						||
            {
 | 
						||
                //se ha gi<67> deciso di NON reinstallare mai i pacchi ("no tutti") allora is_patch <20> sempre true..
 | 
						||
                //..in modo da installare le sole patch
 | 
						||
              is_patch = true;
 | 
						||
            }
 | 
						||
          }
 | 
						||
          else 
 | 
						||
            is_patch = false; // Quando la versione installata precede la patch base devo reinstallare il modulo!
 | 
						||
        }
 | 
						||
      }
 | 
						||
       
 | 
						||
      TFilename path;
 | 
						||
      const bool internet = get_patches_path(path);
 | 
						||
 | 
						||
      //richiesto aggiornamento da disco del modulo SY o del modulo SR da manutenzione/installazione moduli!
 | 
						||
      if (modulo == "sy" || modulo == "sr")
 | 
						||
      {
 | 
						||
        if (!internet)
 | 
						||
        {
 | 
						||
          bool file_copied = false;
 | 
						||
          //trova il path della directory setup che e' nell'area con gli zip del cd
 | 
						||
          TFilename disk_path = path;
 | 
						||
          disk_path.add("setup/");
 | 
						||
          TString_array ar;
 | 
						||
          const int items = disk_path.exist() ? list_files(disk_path, ar) : 0;
 | 
						||
          if (items > 0)
 | 
						||
          {
 | 
						||
            //copia la dir setup dal disco sovrascrivendo eventuali files gia' presenti
 | 
						||
            make_dir("setup");
 | 
						||
            TFilename local_file, remote_file;
 | 
						||
 | 
						||
            //preserva l'OEM contenuto in oem.ini della directory setup
 | 
						||
            const int old_oem = ini_get_int("setup/oem.ini", "MAIN", "OEM");
 | 
						||
 | 
						||
            FOR_EACH_ARRAY_ROW(ar, r, row)
 | 
						||
            {
 | 
						||
              local_file = row->mid(path.len() + 1);
 | 
						||
              remote_file = *row;
 | 
						||
              file_copied = fcopy(remote_file, local_file); //occhio alle maiuscole!!!!
 | 
						||
            }
 | 
						||
            //riscrive il vecchio valore di oem in oem.ini
 | 
						||
            ini_set_int("setup/oem.ini", "MAIN", "OEM", old_oem);
 | 
						||
          }
 | 
						||
 | 
						||
          update_disk_and_web_path(); //aggiorna l'install.ini
 | 
						||
          //lancia setup in modalita' aggiornamento da disco
 | 
						||
          if (test_station_type() == 3)
 | 
						||
            _setup_run = xvt_sys_execute("setup\\setup.exe -uc", false, false) !=0;
 | 
						||
          else
 | 
						||
            _setup_run = xvt_sys_execute("setup\\setup.exe -ud", false, false) !=0;
 | 
						||
        }
 | 
						||
        //richiesto aggiornamento via web del modulo SY da manutenzione/installazione moduli!
 | 
						||
        else
 | 
						||
        {
 | 
						||
          bool file_copied = false;
 | 
						||
          //trova l'indirizzo web completo
 | 
						||
          TString http_server;
 | 
						||
          TFilename http_path;
 | 
						||
          parse_internet_path(http_server, http_path);
 | 
						||
          //copia la dir setup dalla remote dir sovrascrivendo eventuali files gia' presenti
 | 
						||
          http_path.add("setup/");
 | 
						||
          TString_array ar;
 | 
						||
          http_dir(http_server, http_path, ar);
 | 
						||
          if (ar.items() > 0)
 | 
						||
          {
 | 
						||
            make_dir("setup");
 | 
						||
            TFilename local_file, remote_file;
 | 
						||
            FOR_EACH_ARRAY_ROW(ar, r, row)
 | 
						||
            {
 | 
						||
              local_file = "setup";
 | 
						||
              local_file.add(*row);
 | 
						||
              remote_file = http_path;
 | 
						||
              remote_file.add(*row);
 | 
						||
              //via web NON deve copiare oem.ini perch<63> NON deve poter cambiare il reseller (solo via disco sar<61>..
 | 
						||
              //..possibile)
 | 
						||
              const bool is_oem_ini = xvt_str_compare_ignoring_case(remote_file.name(), "oem.ini") == 0;
 | 
						||
              if (is_oem_ini)
 | 
						||
              {
 | 
						||
                const int old_oem = xvt_sys_get_profile_int(local_file, "MAIN", "OEM", -1);
 | 
						||
                file_copied = http_get(http_server, remote_file, local_file); //occhio alle maiuscole!!!!
 | 
						||
                const int new_oem = xvt_sys_get_profile_int(local_file, "MAIN", "OEM", -1);
 | 
						||
                if (new_oem != old_oem)
 | 
						||
                {
 | 
						||
                  TString4 str_oem; str_oem << ' ' << old_oem;
 | 
						||
                  xvt_sys_set_profile_string(local_file, "MAIN", "OEM", str_oem);
 | 
						||
                }
 | 
						||
              }
 | 
						||
              else
 | 
						||
                file_copied = http_get(http_server, remote_file, local_file); //occhio alle maiuscole!!!!
 | 
						||
            }
 | 
						||
          }
 | 
						||
          update_disk_and_web_path(); //aggiorna l'install.ini
 | 
						||
          //lancia setup in modalita' aggiornamento web 
 | 
						||
          _setup_run = xvt_sys_execute("setup\\setup.exe -uw", false, false) != 0;
 | 
						||
        }
 | 
						||
        if (_setup_run) //se riesce a lanciare setup.exe...
 | 
						||
        {
 | 
						||
          //si suicida...Banzai!
 | 
						||
          uncheck(r);
 | 
						||
          send_key(K_SPACE, DLG_QUIT);
 | 
						||
          return;
 | 
						||
        }
 | 
						||
      }
 | 
						||
 | 
						||
      //installa solo le patch del 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 *)modesc);
 | 
						||
      }
 | 
						||
      else    //..installa anche il pacco del modulo
 | 
						||
      {
 | 
						||
        ok = install(modulo, 0); // installa il modulo
 | 
						||
      }
 | 
						||
      if (ok)
 | 
						||
      {
 | 
						||
        _installed = true; // Setta il flag di almeno un modulo installato
 | 
						||
        uncheck(r);  //finalmente unchecka i moduli installati
 | 
						||
      }
 | 
						||
    } //if(ok)...
 | 
						||
    else
 | 
						||
      uncheck(r); // se non ci sono patch o moduli -> uncheck
 | 
						||
  } //FOR_EACH_ARRAY_ROW(arr...
 | 
						||
  
 | 
						||
  //aggiorna definitivamente i path su install.ini
 | 
						||
  update_disk_and_web_path();
 | 
						||
  //accoppa i files nelle kill lists e aggiorna install.ini
 | 
						||
  kill_files();
 | 
						||
  //serve per togliere il check al modulo 'sy' quando viene installato
 | 
						||
  force_update();
 | 
						||
}
 | 
						||
 | 
						||
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::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;
 | 
						||
}
 | 
						||
 | 
						||
//metodo per controllare se la directory indicata contiene una installazione buona di campo
 | 
						||
bool TInstaller_mask::is_program_dir(const TFilename& path)
 | 
						||
{
 | 
						||
  //controlla l'esistenza di alcuni files chiave di campo
 | 
						||
  const char* const essential[] = {"install.ini", "campo.ini", "campo.aut", "ba0.exe", "xvaga.dll", NULL };
 | 
						||
  bool ok = true;
 | 
						||
  for (int i = 0; ok && essential[i]; i++)
 | 
						||
  {
 | 
						||
    TFilename work_path = path;
 | 
						||
    work_path.add(essential[i]);
 | 
						||
    ok = work_path.exist();
 | 
						||
  }
 | 
						||
  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|OEM@10"),
 | 
						||
                0x18, 4)
 | 
						||
{
 | 
						||
  add_button(F_INSTALL, TR("Installa"), '\0', TOOL_ELABORA);   // NON mettere 'I'
 | 
						||
  add_button(F_UPDATE, TR("Aggiorna Lista"), '\0', TOOL_CONVERT);
 | 
						||
  add_button(DLG_NULL, "", '\0');
 | 
						||
  add_button(DLG_INFO, TR("Info"), K_F2, TOOL_INFO);
 | 
						||
  add_button(DLG_HELP, TR("Help"), K_F1, TOOL_HELP);
 | 
						||
  xvt_toolbar_set_last_tool(toolbar(), DLG_QUIT);
 | 
						||
 | 
						||
  _station_type = test_station_type();
 | 
						||
  _curr_mask = this;
 | 
						||
  _installed = false;
 | 
						||
  _reboot_program= NONE;
 | 
						||
 | 
						||
  //in base al tipo di installazione che rileva decide se puo' effettuare aggiornamenti via web (un client..
 | 
						||
  //..non puo' fare aggiornamenti da web!!!)
 | 
						||
  TToken_string installada; 
 | 
						||
  installada.add(PR("Installa da disco")); 
 | 
						||
  installada.add(PR("Installa da web  "));
 | 
						||
  TRadio_field& rf = add_radio(F_TYPE, 0, "", 0, 0, 23, "0|1", installada);
 | 
						||
  *rf.message(0, true) = "DISABLE,207|ENABLE,201";
 | 
						||
  *rf.message(1, true) = "DISABLE,201|ENABLE,207";
 | 
						||
  add_string(F_PATH, 0, "", 23, 1, 256, "B", 56).set_selector('D', EMPTY_STRING);
 | 
						||
  add_string(F_WEB, 0, "", 23, 2, 256, "", 56);
 | 
						||
  set(F_TYPE, "0", 0x1);
 | 
						||
 | 
						||
  //deve conoscere i path adesso per poter testare se sono ok 
 | 
						||
  TInstall_ini ini;
 | 
						||
  TFilename path = ini.get("DiskPath");
 | 
						||
  TFilename webpath = ini.get("WebPath");
 | 
						||
 | 
						||
  //un client non puo' scegliere a caso da dove aggiornarsi! Solo dal suo server!
 | 
						||
  if (_station_type == 3)
 | 
						||
  {
 | 
						||
    rf.disable();
 | 
						||
    bool ko = !is_program_dir(path);
 | 
						||
    if (ko)
 | 
						||
      warning_box(TR("La cartella origine dei programmi NON <20> valida!\nSelezionarne una valida e premere 'Invio'."));
 | 
						||
    enable(F_PATH, ko);
 | 
						||
  }
 | 
						||
 | 
						||
  add_string(F_CURPATH, 0, PR("Installa in           "), 1, 3, 80, "D", 56);
 | 
						||
 | 
						||
  set_handler(F_PATH, path_handler);
 | 
						||
  set_handler(F_WEB, web_handler);
 | 
						||
  set_handler(F_INSTALL, install_handler);
 | 
						||
  set_handler(F_UPDATE, update_handler);
 | 
						||
  set_handler(DLG_USER, tutti_handler);
 | 
						||
 | 
						||
  //se il webpath <20> vuoto o di test, propone quello in oem.ini; non ammette che possa essere proposto un path..
 | 
						||
  //..di tipo test per impedire all'utonto di aggiornarsi da test prima di essere passato da release
 | 
						||
  if (webpath.empty() || webpath.find("test"))
 | 
						||
    webpath = http_default_path();
 | 
						||
 | 
						||
  set(F_PATH, path);
 | 
						||
  set(F_WEB, webpath);
 | 
						||
  //..fine costruzione maschera di installazione
 | 
						||
 | 
						||
  //decide quale e' il percorso di installazione
 | 
						||
  //ha un cd o un disco di rete -> si aggiorna da questo...
 | 
						||
  if (path.exist())
 | 
						||
    autoload();
 | 
						||
  else  //senno' cerca su internet se trova un path internet completo e la connessione funzionante
 | 
						||
  {
 | 
						||
    if (_station_type != 3 && webpath.find("aga.it") > 0)
 | 
						||
    {
 | 
						||
      set(F_TYPE, "1", 0x1);
 | 
						||
      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;
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// 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();
 | 
						||
  void convert_archives();
 | 
						||
};
 | 
						||
 | 
						||
 | 
						||
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
 | 
						||
 | 
						||
  //crea la maschera di installazione
 | 
						||
   _m = new TInstaller_mask();
 | 
						||
 | 
						||
   //se e' un client
 | 
						||
  if (_m->station_type() == 3)
 | 
						||
  {  
 | 
						||
    _m->disable_check();
 | 
						||
    _m->disable(F_UPDATE);
 | 
						||
    _m->disable(DLG_USER);  
 | 
						||
  } 
 | 
						||
  else  //se e' standalone o server...
 | 
						||
  {
 | 
						||
    if (user() != ::dongle().administrator())
 | 
						||
      return error_box(TR("Solo l'utente amministratore puo' aggiornare questa postazione!"));
 | 
						||
  }
 | 
						||
 | 
						||
  return TSkeleton_application::create();
 | 
						||
}
 | 
						||
 | 
						||
void TInstaller::convert_archives()
 | 
						||
{
 | 
						||
  bool conv = true;
 | 
						||
  if (is_power_station())
 | 
						||
    conv = yesno_box(TR("Si desidera convertire gli archivi ora?"));
 | 
						||
  if (conv)
 | 
						||
  {
 | 
						||
    _m->backup();
 | 
						||
    // Lancia conversione: ba1 -0 -C -uADMIN
 | 
						||
    TExternal_app conversion("ba1 -0 -C");
 | 
						||
    conversion.run();
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
void TInstaller::main_loop()
 | 
						||
{
 | 
						||
  _m->run();
 | 
						||
  if (_m->run_conversion() && _m->station_type() < 3) // Almeno un trr installato e non e' client->conversione ammessa
 | 
						||
  {
 | 
						||
    convert_archives();
 | 
						||
  }
 | 
						||
 | 
						||
  //controlla se ha lanciato setup.exe prima di chiudersi; se non lo ha fatto -> e' a fine installazione..
 | 
						||
  //..normale (moduli non SY) e quindi lancia ba0.exe
 | 
						||
  const bool setup_launched = _m->setup_run();
 | 
						||
  delete _m; _m = NULL;
 | 
						||
  if (!setup_launched)
 | 
						||
  {
 | 
						||
    TExternal_app ba0("ba0.exe");
 | 
						||
    ba0.run(true, true, false); // run asynchronous and not iconized!
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
int ba1700(int argc, char* argv[])
 | 
						||
{
 | 
						||
  TInstaller app;
 | 
						||
  app.run(argc, argv, TR("Installazione moduli"));
 | 
						||
  return 0;
 | 
						||
}
 |