Files correlati : ba1 Ricompilazione Demo : [ ] Commento : Migliorata gestione aggiornamenti da internet git-svn-id: svn://10.65.10.50/trunk@17445 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1705 lines
		
	
	
		
			49 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1705 lines
		
	
	
		
			49 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include <agasys.h>
 | ||
| #include <applicat.h>
 | ||
| #include <dongle.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 "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
 | ||
| 
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////
 | ||
| //  Metodi di utility
 | ||
| ///////////////////////////////////////////////////////
 | ||
| HIDDEN const char* http_default_path()
 | ||
| {
 | ||
|   //da compilare in base al producer!
 | ||
|   return "www.aga.it/agarel100/";
 | ||
| }
 | ||
| 
 | ||
| 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 has_module(int modnumber) const;
 | ||
|   bool is_zip_file(const TFilename& n) const;
 | ||
| 
 | ||
|   void create_dirs(const char* path) 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_install_ini() const;
 | ||
| 
 | ||
|   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;
 | ||
| 
 | ||
| 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;
 | ||
| 
 | ||
| // 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 Enterprise Edition ad occhi indiscreti
 | ||
| 	const bool ee = ini.get_bool("Ee");
 | ||
|   if (ee && !dongle().active(EEAUT))
 | ||
|     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);
 | ||
|   if (pos==-1)
 | ||
|     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::has_module(int modnumber) const
 | ||
| {
 | ||
|   //se sei un server hai tutti i moduli da installare
 | ||
|   if (station_type() == 2)
 | ||
|     return true;
 | ||
| 
 | ||
|   //senno' sei sfigato e ti installa solo i moduli sulla chiave
 | ||
|   return main_app().has_module(modnumber, CHK_DONGLE);
 | ||
| }
 | ||
| 
 | ||
| //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
 | ||
| 
 | ||
|   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;
 | ||
| 			if (check_enabled)
 | ||
|         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);
 | ||
|         check_enabled = false;  //..ed uscire
 | ||
|       }
 | ||
|     } //if(modnumber>=0...
 | ||
|   } //FOR_EACH_ARRAY_ROW...
 | ||
|   force_update(); // Indispensabile per vedere le righe aggiornate sullo sheet
 | ||
|   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;
 | ||
| 
 | ||
|     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 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("%04d", 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;
 | ||
| 
 | ||
|   //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)
 | ||
|   {
 | ||
|     parse_internet_path(http_server, http_path);  //controlla il path internet scritto nel campo sulla maschera
 | ||
| 
 | ||
|     make_dir(path); //crea la directory temporanaea di installazione dove depositare e scompattare gli zip
 | ||
| 
 | ||
|     ininame = path;
 | ||
|     ininame.add(TInstall_ini::default_name());
 | ||
| 
 | ||
|     //se si ritrova dei vecchi .ini nella directory temporanea->pulisce la directory temporanea x evitare casini
 | ||
|     if (ininame.exist()) //&& yesno_box(TR("Si desidera svuotare la cache dei files scaricati dal sito?"))) domanda del cazzo!
 | ||
|     {
 | ||
|       TString_array list;
 | ||
|       TFilename name = path; name.add("*.*");
 | ||
|       ::list_files(name, list);
 | ||
| 
 | ||
|       FOR_EACH_ARRAY_ROW(list, i, row)
 | ||
|         ::remove(*row);
 | ||
|     }
 | ||
|     if (!ininame.exist())
 | ||
|     {
 | ||
|       TFilename remote_ini = http_path;
 | ||
| 			remote_ini << TInstall_ini::default_name();
 | ||
|       {
 | ||
|         TIndwin contacting(60,TR("Connessione al server HTTP..."), false, false);
 | ||
|         http_get(http_server, remote_ini, ininame);
 | ||
|       }
 | ||
|     }
 | ||
|   } //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;
 | ||
|   TString producer;
 | ||
| 
 | ||
|   //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);
 | ||
|     //prende il producer dall'install.ini di origine installazione...non si sa mai che sia cambiato..
 | ||
| 		producer = ini.get("Producer", "Main");
 | ||
|     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
 | ||
|   {
 | ||
|     http_dir(http_server, http_path, modules);
 | ||
|     for (int i = modules.last(); i >= 0; i--)
 | ||
|     {
 | ||
|       TString& str = modules.row(i);
 | ||
|       if (str.match("??????A.INI") || str.match("??????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("??????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);
 | ||
| 		//settaggio del produttore sull'install.ini locale nel caso sia cambiato..
 | ||
| 		//..ovvero ad ogni nuova versione prassi..no partners..cioe' doubleone..volevo dire sirio..
 | ||
| 		if (producer.full())
 | ||
| 			installini.set("Producer", (const char*)producer, "Main");
 | ||
| 
 | ||
|     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();
 | ||
|     int r;
 | ||
|     for (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);
 | ||
| 			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
 | ||
|       {   
 | ||
|         TString16 patch; patch.format("%04d", 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
 | ||
| 				if (release < patchversion)
 | ||
| 					row.add(patchversion, C_RELEASE);
 | ||
|       }
 | ||
|     } 
 | ||
|     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 < 2007)
 | ||
|     return error_box(FR("Il modulo '%s' non ha una versione valida."), module);
 | ||
| 
 | ||
| #ifndef _DEMO_
 | ||
|   if (year > dongle().year_assist())
 | ||
|   {
 | ||
|     if (!update_assistance_year())
 | ||
|       return false;
 | ||
|   }
 | ||
| #endif
 | ||
| 
 | ||
|   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;
 | ||
|   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(), "dninst.zip") != 0;
 | ||
| return yes;
 | ||
| }
 | ||
| 
 | ||
| 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_SYS)!=0 && 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.path(), filesize) == 0)
 | ||
|     return error_box(TR("Lo spazio disponibile 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;
 | ||
| }
 | ||
| 
 | ||
| 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")
 | ||
|       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());
 | ||
|         create_dirs(dst);
 | ||
|         fcopy(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;
 | ||
| }
 | ||
| 
 | ||
| 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);
 | ||
|   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...");
 | ||
|     TProgind pi(dischi, msg, false, true);
 | ||
|     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)
 | ||
|       {
 | ||
|         TString16 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...");
 | ||
|         pi.set_text(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_SYS)!=0 && 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("WebPath", get(F_WEB));
 | ||
|       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_patches_path(TFilename& path) const
 | ||
| {
 | ||
|   const TEdit_field& www = efield(F_WEB);
 | ||
|   path = get(F_WEB);
 | ||
|   if (www.active() && path.full() && is_internet_path(path))
 | ||
|   {
 | ||
|     path.tempdir();
 | ||
|     path.add("www");
 | ||
|     return true;
 | ||
|   }
 | ||
|   else
 | ||
|     path = get(F_PATH);
 | ||
|   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.compare("http://", 7, true) == 0)
 | ||
|     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 TString16 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. 
 | ||
| // Decisivo in caso di cambio path d'installazione
 | ||
| void TInstaller_mask::update_install_ini() const
 | ||
| {
 | ||
|   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, "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) < 2006)
 | ||
|     {
 | ||
|       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);
 | ||
| 
 | ||
| 		//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*)modulo);
 | ||
|     
 | ||
| 		//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*)modulo);
 | ||
|       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*)modulo);
 | ||
| 		    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)
 | ||
|             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!
 | ||
|         }
 | ||
|       }
 | ||
|        
 | ||
|       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;
 | ||
|             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!!!!
 | ||
|             }
 | ||
|           }
 | ||
| 
 | ||
|           update_install_ini(); //aggiorna l'install.ini
 | ||
|           //lancia setup in modalita' aggiornamento da disco
 | ||
|           _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);
 | ||
|               file_copied = http_get(http_server, remote_file, local_file); //occhio alle maiuscole!!!!
 | ||
|             }
 | ||
|           }
 | ||
|           update_install_ini(); //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 *)modulo);
 | ||
|       }
 | ||
|       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...
 | ||
| 
 | ||
|   force_update(); //serve per togliere il check al modulo 'sy' quando viene installato
 | ||
| }
 | ||
| 
 | ||
| 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;
 | ||
| }
 | ||
| 
 | ||
| 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, 4)
 | ||
| {
 | ||
|   add_button(F_INSTALL, TR("Installa"), '\0', TOOL_ELABORA);   // NON mettere 'I'
 | ||
|   add_button(F_UPDATE, TR("Rileggi"), '\0', TOOL_CONVERT);
 | ||
|   add_button(DLG_INFO, TR("Informazioni"), 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(TR("Installa da disco")); 
 | ||
|   installada.add(TR("Installa da internet"));
 | ||
|   TRadio_field& rf = add_radio(F_TYPE, 0, "", 1, 0, 21, "0|1", installada);
 | ||
|   *rf.message(0, true) = "DISABLE,207|ENABLE,201";
 | ||
|   *rf.message(1, true) = "DISABLE,201|ENABLE,207";
 | ||
|   add_string(F_PATH, 0, "", 22, 1, 256, "", 58);
 | ||
|   add_string(F_WEB, 0, "", 22, 2, 256, "", 58);
 | ||
|   set(F_TYPE, "0", 0x1);
 | ||
| 
 | ||
|   //un client non puo' scegliere a caso da dove aggiornarsi!Solo dal suo server!
 | ||
|   if (_station_type == 3)
 | ||
|    rf.disable();
 | ||
| 
 | ||
|   add_string(F_CURPATH, 0, PR("Installa in          "), 1, 3, 80, "D", 58);
 | ||
| 
 | ||
|   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);
 | ||
| 
 | ||
|   TInstall_ini ini;
 | ||
|   TFilename path = ini.get("DiskPath");
 | ||
|   TFilename webpath = ini.get("WebPath");
 | ||
| 
 | ||
|   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.full())
 | ||
|     {
 | ||
|       set(F_TYPE, "1", 0x1);
 | ||
|       if (xvt_net_get_status() & 0x2) //la connessione web funziona?...
 | ||
|         //if (yesno_box(TR("E' possibile l'aggiornamento via internet. Si desidera connettersi ora?")))
 | ||
|           autoload(); //...quindi scarica l'elenco dei moduli da aggiornare!
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   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;
 | ||
| }
 |