2012-04-24 10:19:45 +00:00
# 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"
2012-06-07 15:56:38 +00:00
# include "ba1701.h"
2012-04-24 10:19:45 +00:00
// 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
///////////////////////////////////////////////////////
2012-04-10 07:38:03 +00:00
HIDDEN const TString & http_default_path ( )
{
int y , r , t , p ;
main_app ( ) . get_version_info ( y , r , t , p ) ;
TString & site = get_tmp_string ( ) ;
site . format ( " http://85.18.53.183/release%02d0/ " , r ) ;
return site ;
}
2012-04-24 10:19:45 +00:00
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 . 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
2012-06-07 15:56:38 +00:00
if ( ! run_as_admin ( ) )
warning_box ( " Per installare il modulo <20> necessario eseguire l'applicazione come amministratore. " ) ;
2012-04-24 10:19:45 +00:00
}
} //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> "
2013-12-13 09:18:24 +00:00
< < " <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 registrazioni, "
< < " 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>Casella vocale Hotline Campo: <br /> "
< < " <a href=mailto:hotlinecampo@sirio-is.it>hotlinecampo@sirio-is.it</a> Tel. 02-36583540</li></ul> "
< < " </body></html> " ;
2012-04-24 10:19:45 +00:00
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 ;
2013-01-30 16:54:59 +00:00
//controlla se si e' scelto un path di installazione internet o da disco
2012-04-24 10:19:45 +00:00
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 \n Verificare 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
{
2013-01-30 16:54:59 +00:00
TProgind pi ( 1 , TR ( " Controllo lista aggiornamenti " ) , false ) ; // progind NON bloccabile: causa errore impossibile!
2012-04-24 10:19:45 +00:00
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 ) ;
2012-11-30 14:35:55 +00:00
if ( str . ends_with ( " a.ini " , true ) )
2012-04-24 10:19:45 +00:00
{
2013-01-30 16:54:59 +00:00
/* Triste nescessita': si rischia di non caricare nessuna patch
2012-04-24 10:19:45 +00:00
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 )
2012-07-10 13:43:39 +00:00
{
modules . destroy ( i ) ;
2012-04-24 10:19:45 +00:00
continue ; // Non fare il download delle patch inutili
2012-07-10 13:43:39 +00:00
}
2013-01-30 16:54:59 +00:00
*/
2012-04-24 10:19:45 +00:00
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 ( ) ;
2012-07-10 13:43:39 +00:00
if ( fsize ( ininame ) < 8 )
{
xvt_fsys_remove_file ( ininame ) ;
continue ;
}
2012-04-24 10:19:45 +00:00
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 \n in %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: \n Si 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 ) ) ;
2013-01-30 16:54:59 +00:00
if ( version2year ( newver ) < 2012 )
2012-04-24 10:19:45 +00:00
{
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 ;
2013-01-30 16:54:59 +00:00
msg . format ( FR ( " Si desidera ritornare alla versione %s.%d del modulo '%s' ? \n Attenzione: non <20> garantito il corretto \n funzionamento di tutti i programmi! " ) , ( const char * ) newver , newpatch , ( const char * ) modesc ) ;
2012-04-24 10:19:45 +00:00
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: \n impossibile 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' ? \n Attenzione: non e' garantito il corretto \n funzionamento 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'? "
" \n Rispondendo 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 " )
{
2012-06-07 15:56:38 +00:00
if ( ! run_as_admin ( ) )
{
error_box ( " Per installare il modulo sistema <20> necessario eseguire l'applicazione come amministratore " ) ;
break ;
}
2012-04-24 10:19:45 +00:00
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 )
2012-06-18 14:02:41 +00:00
_setup_run = xvt_sys_execute ( " setup \\ SetCmpUp.exe -uc " , false , false ) ! = 0 ;
2012-04-24 10:19:45 +00:00
else
2012-06-18 14:02:41 +00:00
_setup_run = xvt_sys_execute ( " setup \\ SetCmpUp.exe -ud " , false , false ) ! = 0 ;
2012-04-24 10:19:45 +00:00
}
//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
2012-06-18 14:02:41 +00:00
_setup_run = xvt_sys_execute ( " setup \\ SetCmpUp.exe -uw " , false , false ) ! = 0 ;
2012-04-24 10:19:45 +00:00
}
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
2013-01-30 16:54:59 +00:00
error_box ( TR ( " Selezionare uno o pi<70> moduli da installare. " ) ) ;
2012-04-24 10:19:45 +00:00
}
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 \n installare@11|Liv. \n Patch@6|Data \n Rilascio@10|Versione \n Installata@10|Liv. \n Patch@6|Data \n Installazione@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! \n Selezionarne 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 ( " // " ) > 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 ;
}