1997-10-30 15:13:59 +00:00
# include <applicat.h>
# include <colors.h>
1998-08-21 10:58:38 +00:00
# include <defmask.h>
1998-02-24 10:30:04 +00:00
# include <execp.h>
1998-08-21 10:58:38 +00:00
# include <isamrpc.h>
1998-02-24 10:30:04 +00:00
# include <os_dep.h>
1997-10-30 15:13:59 +00:00
# include <progind.h>
1997-12-04 14:07:49 +00:00
# include <sheet.h>
1997-10-30 15:13:59 +00:00
# include <utility.h>
1998-08-21 10:58:38 +00:00
1997-10-30 15:13:59 +00:00
# include "ba1.h"
1997-12-15 15:11:40 +00:00
# include "ba1500.h"
1997-10-30 15:13:59 +00:00
# include "ba1600.h"
# include "ba1700a.h"
1998-02-24 10:30:04 +00:00
1998-02-18 13:46:52 +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
1998-01-29 13:42:30 +00:00
1998-08-21 10:58:38 +00:00
const char * const http_default_path = " /aga/campo/ " ;
1998-04-30 14:38:35 +00:00
1998-01-23 14:55:34 +00:00
HIDDEN int compare_version ( const char * v1 , int p1 , const char * v2 , int p2 )
1997-10-30 15:13:59 +00:00
{
TString16 ver1 ( v1 ) , ver2 ( v2 ) ;
ver1 . trim ( ) ;
if ( ver1 . len ( ) = = 4 )
ver1 . insert ( ( v1 [ 0 ] = = ' 9 ' ) ? " 19 " : " 20 " , 0 ) ;
ver2 . trim ( ) ;
if ( ver2 . len ( ) = = 4 )
ver2 . insert ( ( v2 [ 0 ] = = ' 9 ' ) ? " 19 " : " 20 " , 0 ) ;
1998-01-22 11:56:14 +00:00
int res = ver1 . compare ( ver2 , - 1 , TRUE ) ;
if ( res = = 0 )
1998-01-23 14:55:34 +00:00
res = p1 - p2 ;
1998-01-22 11:56:14 +00:00
return res ;
1997-10-30 15:13:59 +00:00
}
1997-12-15 15:11:40 +00:00
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 ) ;
}
1997-10-30 15:13:59 +00:00
///////////////////////////////////////////////////////////
// Maschera principale
///////////////////////////////////////////////////////////
1997-12-04 14:07:49 +00:00
class TInstaller_mask : public TArray_sheet
1997-10-30 15:13:59 +00:00
{
1997-12-04 14:07:49 +00:00
static TInstaller_mask * _curr_mask ;
1997-12-17 13:40:59 +00:00
word _year_assist ;
1998-01-29 13:42:30 +00:00
bool _installed ; // Flag per verificare se almeno un modulo e' stato installato
1997-12-04 14:07:49 +00:00
protected : // TSheet
1997-12-15 15:11:40 +00:00
virtual bool on_key ( KEY key ) ;
1998-02-09 12:06:44 +00:00
static bool tutti_handler ( TMask_field & f , KEY k ) ;
1998-08-21 10:58:38 +00:00
static bool update_handler ( TMask_field & f , KEY k ) ;
1997-12-04 14:07:49 +00:00
1997-10-30 15:13:59 +00:00
protected :
static bool path_handler ( TMask_field & fld , KEY key ) ;
static bool sheet_notify ( TSheet_field & s , int r , KEY k ) ;
static bool install_handler ( TMask_field & fld , KEY key ) ;
1998-02-18 13:46:52 +00:00
bool add_module ( TConfig & ini , const TString & module , bool patch , int pos = - 1 ) ;
1998-02-09 12:06:44 +00:00
bool add_header ( TConfig & ini , const TString & module , bool patch ) ;
1998-01-22 11:56:14 +00:00
int sort_modules ( ) ;
1997-10-30 15:13:59 +00:00
void update_version ( ) ;
1997-12-15 15:11:40 +00:00
1998-01-29 13:42:30 +00:00
bool move_file ( const TFilename & fromdir , const TFilename & file , const char * dir ) const ;
1997-12-15 15:11:40 +00:00
bool move_module ( const TString & module , TInstall_ini & ini , bool update ) const ;
bool can_install ( const char * module , TInstall_ini & ini ) ;
1997-12-04 14:07:49 +00:00
void install_selection ( ) ;
1998-04-30 14:38:35 +00:00
bool install_patches ( const TString & module , const TString & lastrelease , int lastpatch ) ;
1997-10-30 15:13:59 +00:00
1997-12-15 15:11:40 +00:00
bool do_process ( TToken_string & commands ) const ;
1997-10-30 15:13:59 +00:00
bool pre_process ( TInstall_ini & ini , const char * module ) const ;
bool post_process ( TInstall_ini & ini , const char * module ) const ;
1998-01-29 13:42:30 +00:00
public :
bool installed ( ) { return _installed ; }
1997-10-30 15:13:59 +00:00
bool autoload ( ) ;
1998-01-23 14:55:34 +00:00
bool install ( const TString & module , int patch ) ;
1997-10-30 15:13:59 +00:00
TInstaller_mask ( ) ;
1997-12-04 14:07:49 +00:00
virtual ~ TInstaller_mask ( ) ;
1997-10-30 15:13:59 +00:00
} ;
1997-12-04 14:07:49 +00:00
TInstaller_mask * TInstaller_mask : : _curr_mask = NULL ;
1997-10-30 15:13:59 +00:00
// Copia nello sheet i dati di un modulo prendendoli da un .ini
1998-02-18 13:46:52 +00:00
bool TInstaller_mask : : add_module ( TConfig & ini , const TString & module , bool patch , int pos )
1997-10-30 15:13:59 +00:00
{
1998-01-26 10:45:15 +00:00
ini . write_protect ( ) ;
1997-10-30 15:13:59 +00:00
bool ok = ini . set_paragraph ( module ) ;
if ( ok )
{
1997-12-04 14:07:49 +00:00
TToken_string row ;
row = " " ; // Not selected
row . add ( ini . get ( " Descrizione " ) ) ;
1997-10-30 15:13:59 +00:00
row . add ( module ) ;
row . add ( ini . get ( " Versione " ) ) ;
1998-01-22 11:56:14 +00:00
row . add ( ini . get ( " Patch " ) ) ;
1997-10-30 15:13:59 +00:00
row . add ( ini . get ( " Data " ) ) ;
1998-01-23 14:55:34 +00:00
row . add ( patch ? " X " : " " , 9 ) ;
1998-02-18 13:46:52 +00:00
if ( pos = = - 1 )
add ( row ) ;
else
insert ( row , pos ) ;
1997-10-30 15:13:59 +00:00
}
return ok ;
}
1998-02-09 12:06:44 +00:00
// Copia nello sheet i dati di un modulo prendendoli da un .ini
bool TInstaller_mask : : add_header ( TConfig & ini , const TString & module , bool patch )
{
ini . write_protect ( ) ;
bool ok = ini . set_paragraph ( module ) ;
if ( ok )
{
TToken_string row ;
row = " " ; // Not selected
row . add ( ini . get ( " Descrizione " ) ) ;
row . add ( ini . get ( " " ) ) ;
enable_row ( add ( row ) , FALSE ) ;
}
return ok ;
}
1998-01-22 11:56:14 +00:00
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 ;
1998-01-23 14:55:34 +00:00
for ( int i = 2 ; i < 5 & & res = = 0 ; i + + )
1998-01-22 11:56:14 +00:00
{
TString16 s1 = ts1 . get ( i ) ;
const char * s2 = ts2 . get ( i ) ;
res = s1 . compare ( s2 ) ;
}
return res ;
}
int TInstaller_mask : : sort_modules ( )
{
1998-02-18 13:46:52 +00:00
// sort
1998-01-22 11:56:14 +00:00
const int tot = int ( items ( ) ) ;
1998-02-18 13:46:52 +00:00
return tot ;
// vecchio codice per bubblare
1998-01-22 11:56:14 +00:00
for ( int r = 0 ; r < tot ; r + + )
{
1998-02-18 13:46:52 +00:00
const bool patch = row ( r ) . get_char ( C_ISPATCH ) > ' ' ;
const char * mod = row ( r ) . get ( C_CODE ) ;
if ( patch )
{
TString16 dis = mod ;
const int patchlevel = row ( r ) . get_int ( C_PATCH ) ;
// pop the patch line up to the module one
int br = r - 1 ;
while ( br & & ! ( dis = = row ( br ) . get ( C_CODE ) & & row ( br ) . get_int ( C_PATCH ) < patchlevel ) )
{
// Swap rows
rows_array ( ) . TArray : : swap ( br , br + 1 ) ;
const bool enab = row_enabled ( br ) ;
const bool enab1 = row_enabled ( br + 1 ) ;
enable_row ( br + 1 , enab ) ;
enable_row ( br , enab1 ) ;
br - - ;
1998-02-09 12:06:44 +00:00
}
1998-01-22 11:56:14 +00:00
}
}
return tot ;
}
1997-10-30 15:13:59 +00:00
void TInstaller_mask : : update_version ( )
{
TInstall_ini ini ;
1997-11-06 10:05:56 +00:00
1997-12-04 14:07:49 +00:00
TString_array & array = rows_array ( ) ;
FOR_EACH_ARRAY_ROW_BACK ( array , m , row )
1997-10-30 15:13:59 +00:00
{
1998-02-18 13:46:52 +00:00
if ( * row - > get ( C_CODE ) ! = ' ' )
1998-02-09 12:06:44 +00:00
{
1998-02-18 13:46:52 +00:00
const TString16 module = row - > get ( C_CODE ) ;
1998-02-09 12:06:44 +00:00
ini . set_paragraph ( module ) ;
1998-02-18 13:46:52 +00:00
const TString16 newver = row - > get ( C_RELEASE ) ;
1998-02-09 12:06:44 +00:00
const TString16 oldver = ini . get ( " Versione " ) ;
1998-02-18 13:46:52 +00:00
row - > add ( oldver , C_CURRRELEASE ) ;
row - > add ( ini . get ( " Patch " ) , C_CURRPATCH ) ;
row - > add ( ini . get ( " Data " ) , C_CURRDATAREL ) ;
1998-02-09 12:06:44 +00:00
}
1997-10-30 15:13:59 +00:00
}
1997-12-04 14:07:49 +00:00
force_update ( ) ;
1997-10-30 15:13:59 +00:00
}
1998-08-21 10:58:38 +00:00
bool is_internet_path ( const TString & addr )
{
if ( addr . compare ( " www. " , 4 , TRUE ) = = 0 )
return TRUE ;
if ( addr . compare ( " http: " , 5 , TRUE ) = = 0 )
return TRUE ;
int a1 , a2 , a3 , a4 ;
if ( sscanf ( addr , " %d.%d.%d.%d " , & a1 , & a2 , & a3 , & a4 ) = = 4 )
return TRUE ;
return FALSE ;
}
1997-10-30 15:13:59 +00:00
// Cerca nel percorso specificato sulla maschera tutti i possibili files .ini
// utilizzabili per un'installazione e li inserisce nello spreadsheet
bool TInstaller_mask : : autoload ( )
{
1998-02-18 13:46:52 +00:00
TString_array & mask_rows = rows_array ( ) ;
1998-08-21 10:58:38 +00:00
TFilename path = get ( F_PATH ) ;
TString http_server ;
TFilename http_path ;
TFilename ininame ;
const bool internet = is_internet_path ( path ) ;
if ( internet )
{
http_server = path ;
if ( http_server . compare ( " http:// " , 7 , TRUE ) = = 0 )
http_server . ltrim ( 7 ) ;
const int slash = http_server . find ( ' / ' ) ;
if ( slash > 0 )
{
http_path = http_server . mid ( slash ) ;
if ( http_path . right ( 1 ) ! = " / " )
http_path < < ' / ' ;
http_server . cut ( slash ) ;
}
else
http_path = http_default_path ;
path . tempdir ( ) ;
path . add ( " www " ) ;
make_dir ( path ) ;
ininame = path ;
ininame . add ( TInstall_ini : : default_name ( ) ) ;
if ( ininame . exist ( ) & & yesno_box ( " Si desidera svuotare la cache dei files scaricati dal sito? " ) )
{
TString_array list ;
TFilename name = path ; name . add ( " *.* " ) ;
: : list_files ( name , list ) ;
FOR_EACH_ARRAY_ROW ( list , i , row )
: : remove ( * row ) ;
}
if ( ! ininame . exist ( ) )
{
TFilename remote_ini = http_path ;
remote_ini < < TInstall_ini : : default_name ( ) ;
if ( ! http_get ( http_server , remote_ini , ininame ) )
return error_box ( " Impossibile trasferire %s da %s " ,
( const char * ) remote_ini , ( const char * ) http_server ) ;
}
}
if ( fexist ( path ) )
{
ininame = path ;
ininame . add ( TInstall_ini : : default_name ( ) ) ;
}
else
1997-10-30 15:13:59 +00:00
return error_box ( " Specificare un percorso valido " ) ;
TWait_cursor hourglass ;
1997-12-04 14:07:49 +00:00
destroy ( ) ;
1997-10-30 15:13:59 +00:00
TString_array modules ;
if ( fexist ( ininame ) )
{
TInstall_ini ini ( ininame ) ;
1998-01-28 08:53:28 +00:00
1997-10-30 15:13:59 +00:00
ini . list_paragraphs ( modules ) ;
1997-12-15 15:11:40 +00:00
FOR_EACH_ARRAY_ROW ( modules , i , row )
1997-10-30 15:13:59 +00:00
{
1997-11-06 15:05:42 +00:00
const TString & module = * row ;
1998-02-09 12:06:44 +00:00
if ( module [ 0 ] = = ' _ ' | | module . len ( ) = = 2 )
{
if ( module [ 0 ] = = ' _ ' )
add_header ( ini , module , FALSE ) ;
else
add_module ( ini , module , FALSE ) ;
}
1997-10-30 15:13:59 +00:00
}
}
else
{
ininame = path ;
ininame . add ( " ??inst.ini " ) ;
1997-11-06 15:05:42 +00:00
list_files ( ininame , modules ) ;
1997-12-15 15:11:40 +00:00
FOR_EACH_ARRAY_ROW ( modules , m , row )
1997-10-30 15:13:59 +00:00
{
1997-11-06 15:05:42 +00:00
TString & ininame = * row ;
1997-10-30 15:13:59 +00:00
ininame . lower ( ) ;
const int pos = ininame . find ( " inst.ini " ) ;
1998-01-22 11:56:14 +00:00
CHECKS ( pos > = 2 , " Invalid installation configuration: " , ( const char * ) ininame ) ;
1997-10-30 15:13:59 +00:00
const TString16 module = ininame . mid ( pos - 2 , 2 ) ;
TConfig ini ( ininame , module ) ;
1998-01-23 14:55:34 +00:00
add_module ( ini , module , FALSE ) ;
1998-08-21 10:58:38 +00:00
}
1998-02-18 13:46:52 +00:00
}
1998-08-21 10:58:38 +00:00
1998-02-18 13:46:52 +00:00
// add patches
modules . destroy ( ) ;
1998-08-21 10:58:38 +00:00
if ( internet )
{
http_dir ( http_server , http_path , modules ) ;
for ( int i = modules . last ( ) ; i > = 0 ; i - - )
{
TString & str = modules . row ( i ) ;
if ( str . match ( " ??0???A.INI " ) | | str . match ( " ??0???a.ini " ) )
{
TFilename remote = http_path ;
remote < < str ;
ininame = path ;
ininame . add ( str ) ;
if ( ! ininame . exist ( ) & & ! http_get ( http_server , remote , ininame ) )
{
error_box ( " Errore di trasferimento del file %s " , ( const char * ) remote ) ;
modules . destroy ( i ) ;
}
str = ininame ;
}
else
modules . destroy ( i ) ;
}
modules . pack ( ) ;
}
else
{
ininame = path ;
ininame . add ( " ??0???a.ini " ) ;
list_files ( ininame , modules ) ;
}
1998-02-18 13:46:52 +00:00
modules . sort ( ) ; // sort to have patches in patchlevel order
1998-08-21 10:58:38 +00:00
1998-02-18 13:46:52 +00:00
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 module = ininame . mid ( pos - 6 , 2 ) ;
TConfig ini ( ininame , module ) ;
const int patchlevel = ini . get_int ( " Patch " ) ;
const int maxrows = int ( items ( ) ) ;
bool found = FALSE ;
for ( int r = maxrows - 1 ; r > = 0 & & ! found ; r - - )
found = ( module = = row ( r ) . get ( C_CODE ) ) ;
if ( found )
{
1998-04-30 14:38:35 +00:00
TString16 patchversion = ini . get ( " Versione " ) ;
if ( patchversion = = mask_rows . row ( r + 1 ) . get ( C_RELEASE ) // se le versioni corrispondono ...
& & patchlevel > atoi ( mask_rows . row ( r + 1 ) . get ( C_PATCH ) ) ) // ..e il patchlevel <20> superiore
{
mask_rows . row ( r + 1 ) . add ( patchlevel , C_PATCH ) ; // aggiorna il patchlevel mostrato per il modulo
force_update ( r + 1 ) ;
}
1998-08-21 10:58:38 +00:00
}
else
1998-01-23 14:55:34 +00:00
add_module ( ini , module , TRUE ) ;
1997-10-30 15:13:59 +00:00
}
1998-01-22 11:56:14 +00:00
const bool ok = sort_modules ( ) > 0 ;
1997-10-30 15:13:59 +00:00
if ( ok )
update_version ( ) ;
else
1997-12-04 14:07:49 +00:00
error_box ( " Non e' stato trovato nessun modulo da installare \n "
" in %s " , ( const char * ) path ) ;
1998-08-21 10:58:38 +00:00
1997-10-30 15:13:59 +00:00
return ok ;
}
1997-12-15 15:11:40 +00:00
bool TInstaller_mask : : do_process ( TToken_string & commands ) const
1997-10-30 15:13:59 +00:00
{
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 ( ) = = 0 ;
}
}
return ok ;
}
bool TInstaller_mask : : pre_process ( TInstall_ini & ini , const char * module ) const
1997-11-06 10:05:56 +00:00
{
1997-12-17 13:40:59 +00:00
TAuto_token_string commands ( ini . get ( " PreProcess " , module ) ) ;
bool ok = do_process ( commands ) ;
1997-11-06 10:05:56 +00:00
return ok ;
1997-10-30 15:13:59 +00:00
}
bool TInstaller_mask : : post_process ( TInstall_ini & ini , const char * module ) const
{
TAuto_token_string commands ( ini . get ( " PostProcess " , module ) ) ;
return do_process ( commands ) ;
}
1997-12-15 15:11:40 +00:00
bool TInstaller_mask : : can_install ( const char * module , TInstall_ini & ini )
{
TInstall_ini curini ;
if ( curini . demo ( ) ! = ini . demo ( ) )
{
TString msg ;
msg < < " Attenzione: Non e' possibile installare la versione " ;
msg < < ( ini . demo ( ) ? " dimostrativa " : " normale " ) ;
msg < < " nella cartella della versione " ;
msg < < ( curini . demo ( ) ? " dimostrativa " : " normale " ) ;
return error_box ( msg ) ;
}
const TString & version = ini . version ( module ) ;
1997-12-17 13:40:59 +00:00
const word year = version2year ( version ) ;
1997-12-15 15:11:40 +00:00
if ( year < 1997 )
return error_box ( " Il modulo '%s' non ha una versione valida. " , module ) ;
1998-02-09 12:06:44 +00:00
# ifndef _DEMO_
1997-12-17 13:40:59 +00:00
if ( year > _year_assist )
return error_box ( " Per installare la versione %s del modulo '%s' \n "
" occorre il contratto di assistenza per l'anno %d. " ,
( const char * ) version , module , year ) ;
1998-02-09 12:06:44 +00:00
# endif
1997-12-15 15:11:40 +00:00
TAuto_token_string altri ( ini . get ( " Moduli " , module ) ) ;
if ( stricmp ( module , " ba " ) ! = 0 & & altri . get_pos ( " ba " ) < 0 )
altri . add ( " ba " ) ; // La base e' obbligatoria per tutti
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 ;
1997-12-17 13:40:59 +00:00
msg < < " L'installazione del modulo ' " < < module
< < " ' \n richiede la presenza del modulo ' " < < submodule
< < " ': \n Si desidera procedere alla sua installazione? " ;
1997-12-15 15:11:40 +00:00
ok = yesno_box ( msg ) ;
if ( ok )
1998-01-22 11:56:14 +00:00
ok = install ( submodule , 0 ) ;
1997-12-15 15:11:40 +00:00
}
}
}
return ok ;
}
1998-01-29 13:42:30 +00:00
// sposta il file dal direttorio temporaneo a quello passato come destinazione
1998-02-18 13:46:52 +00:00
// from: direttorio di partenza
// file: nome del file con path completo da spostare (pu<70> includere sottodirettori)
// todir: direttorio destinazione (si assume che esista gi<67> )
bool TInstaller_mask : : move_file ( const TFilename & from , const TFilename & file , const char * todir ) const
1997-12-15 15:11:40 +00:00
{
1998-02-18 13:46:52 +00:00
TFilename dest ( todir ) ;
dest . add ( file . mid ( from . len ( ) + 1 ) ) ;
if ( ! fexist ( dest . path ( ) ) )
{
// file contains non existent subdir specification
TToken_string dirs ( ( const char * ) ( dest . path ( ) ) , ' \\ ' ) ;
TFilename subdir ;
for ( int c = 0 ; c < dirs . items ( ) - 1 ; c + + )
{
subdir . add ( dirs . get ( c ) ) ;
if ( ! fexist ( subdir ) )
// build destination directory
make_dir ( subdir ) ;
}
}
1997-12-15 15:11:40 +00:00
const long filesize = fsize ( file ) ;
bool space_ok = FALSE ;
while ( ! space_ok )
{
int disk = 0 ;
if ( dest [ 1 ] = = ' : ' )
{
const char letter = toupper ( dest [ 0 ] ) ;
disk = ' A ' - letter + 1 ;
}
1998-02-24 10:30:04 +00:00
1998-08-21 10:58:38 +00:00
space_ok = : : os_test_disk_free_space ( todir , filesize ) ;
1997-12-15 15:11:40 +00:00
if ( ! space_ok )
{
TString msg ;
1998-08-21 10:58:38 +00:00
msg < < " Lo spazio su disco e' insufficiente: \n " ;
if ( : : os_is_removable_drive ( todir ) )
1997-12-15 15:11:40 +00:00
{
1998-08-21 10:58:38 +00:00
msg < < " Inserire un nuovo disco e ritentare? " ;
1997-12-15 15:11:40 +00:00
if ( ! yesno_box ( msg ) )
return FALSE ;
}
else
1998-08-21 10:58:38 +00:00
{
msg < < " Si desidera proseguire ugualmente? " ;
if ( ! noyes_box ( msg ) )
return FALSE ;
}
1997-12-15 15:11:40 +00:00
}
}
bool write_ok = TRUE ;
1998-01-29 13:42:30 +00:00
bool user_retry = FALSE ;
1997-12-15 15:11:40 +00:00
do
{
write_ok = : : fcopy ( file , dest ) ;
if ( write_ok )
: : remove ( file ) ;
else
1998-01-29 13:42:30 +00:00
user_retry = yesno_box ( " Errore di copia del file %s. \n Si desidera ritentare? " ,
( const char * ) file ) ;
} while ( ! write_ok & & user_retry ) ;
1997-12-15 15:11:40 +00:00
return write_ok ;
}
bool TInstaller_mask : : move_module ( const TString & module , TInstall_ini & ini , bool update ) const
{
bool ok = TRUE ;
1997-12-17 13:40:59 +00:00
TFilename src ; src . tempdir ( ) ;
const TFilename tempdir ( src ) ;
1998-08-21 10:58:38 +00:00
const TString & dst = get ( F_CURPATH ) ;
1997-12-17 13:40:59 +00:00
1997-12-15 15:11:40 +00:00
TString_array list ;
ini . build_list ( module , list ) ;
FOR_EACH_ARRAY_ROW ( list , f , file )
{
1997-12-17 13:40:59 +00:00
src = tempdir ;
1997-12-15 15:11:40 +00:00
src . add ( file - > get ( 0 ) ) ;
if ( update )
{
1998-08-21 10:58:38 +00:00
const bool move_ok = move_file ( tempdir , src , dst ) ;
1997-12-15 15:11:40 +00:00
if ( ! move_ok )
ok = update = FALSE ;
}
if ( ! update )
: : remove ( src ) ;
}
if ( update )
ini . export_paragraph ( module , ini . default_name ( ) ) ;
return ok ;
}
1998-01-23 14:55:34 +00:00
bool TInstaller_mask : : install ( const TString & module , int patchlevel )
1997-10-30 15:13:59 +00:00
{
1998-08-21 10:58:38 +00:00
TInstall_ini * ini = NULL ;
1997-10-30 15:13:59 +00:00
bool ok = FALSE ;
1998-04-30 14:38:35 +00:00
TString16 lastrelease ; // release che sto installando
int lastpatch = patchlevel ; // patchlevel che sto installando
1998-08-21 10:58:38 +00:00
TFilename path = get ( F_PATH ) ;
TString http_server ;
TFilename http_path ;
const bool internet = is_internet_path ( path ) ;
if ( internet )
{
http_server = path ;
if ( http_server . compare ( " http:// " , 7 , TRUE ) = = 0 )
http_server . ltrim ( 7 ) ;
const int slash = http_server . find ( ' / ' ) ;
if ( slash > 0 )
{
http_path = http_server . mid ( slash ) ;
if ( http_path . right ( 1 ) ! = " / " )
http_path < < ' / ' ;
http_server . cut ( slash ) ;
}
else
http_path = http_default_path ;
path . tempdir ( ) ;
path . add ( " www " ) ;
}
1997-10-30 15:13:59 +00:00
TFilename ininame = path ;
ininame . add ( module ) ;
1998-01-22 11:56:14 +00:00
if ( patchlevel > 0 )
{
TString16 name ;
1998-01-23 14:55:34 +00:00
name . format ( " %04da.ini " , patchlevel ) ;
1998-01-22 11:56:14 +00:00
ininame < < name ;
}
else
ininame < < " inst.ini " ;
1998-08-21 10:58:38 +00:00
if ( internet & & ! ininame . exist ( ) )
{
TFilename remote = ininame . name ( ) ;
remote . insert ( http_path , 0 ) ;
http_get ( http_server , remote , ininame ) ;
}
1997-10-30 15:13:59 +00:00
1998-08-21 10:58:38 +00:00
if ( ininame . exist ( ) )
1997-10-30 15:13:59 +00:00
{
1998-06-10 16:38:58 +00:00
ini = new TInstall_ini ( ininame ) ;
ini - > write_protect ( ) ;
lastpatch = ini - > get_int ( " Patch " , module ) ;
lastrelease = ini - > get ( " Versione " , module ) ;
if ( ! can_install ( module , * ini ) )
1997-12-15 15:11:40 +00:00
return FALSE ;
1998-06-10 16:38:58 +00:00
const int dischi = ini - > get_int ( " Dischi " , module ) ;
1997-10-30 15:13:59 +00:00
ok = dischi > 0 ;
1997-11-06 10:05:56 +00:00
if ( ! ok )
{
1998-02-18 13:46:52 +00:00
return error_box ( " Impossibile determinare il numero dei dischetti in %s " , ininame . name ( ) ) ;
1997-11-06 10:05:56 +00:00
}
else
{
1998-06-10 16:38:58 +00:00
if ( patchlevel = = 0 )
ok = pre_process ( * ini , module ) ;
1997-11-06 10:05:56 +00:00
if ( ! ok ) return FALSE ;
}
1998-04-30 14:38:35 +00:00
1998-08-21 10:58:38 +00:00
TString msg ;
msg < < " Decompressione " ;
1998-02-18 13:46:52 +00:00
if ( patchlevel > 0 )
msg < < " della patch " < < patchlevel ;
msg < < " del modulo ' " < < module < < " ' in corso... " ;
1998-08-21 10:58:38 +00:00
1998-01-23 14:55:34 +00:00
TProgind pi ( dischi , msg , FALSE , TRUE ) ;
1997-12-15 15:11:40 +00:00
TFilename tempdir ; tempdir . tempdir ( ) ;
1997-10-30 15:13:59 +00:00
TFilename cmdline ;
for ( int d = 1 ; d < = dischi & & ok ; d + + )
{
1997-11-06 10:05:56 +00:00
cmdline = path ;
1997-10-30 15:13:59 +00:00
cmdline . add ( module ) ;
1998-01-23 14:55:34 +00:00
if ( patchlevel > 0 )
{
TString16 name ;
name . format ( " %04da " , patchlevel ) ;
cmdline < < name ;
}
else
cmdline < < " inst " ;
cmdline < < d < < " .zip " ;
1998-08-21 10:58:38 +00:00
if ( internet & & ! cmdline . exist ( ) )
{
TFilename remote = cmdline . name ( ) ;
remote . insert ( http_path , 0 ) ;
http_get ( http_server , remote , cmdline ) ;
}
1997-10-30 15:13:59 +00:00
1998-01-23 14:55:34 +00:00
ok = cmdline . exist ( ) ;
1997-10-30 15:13:59 +00:00
while ( ! ok )
{
1998-01-29 13:42:30 +00:00
message_box ( " Inserire il disco %d di %d del modulo \n '%s' " ,
1998-06-10 16:38:58 +00:00
d , dischi , ( const char * ) ini - > get ( " Descrizione " ) ) ;
1998-08-21 10:58:38 +00:00
ok = cmdline . exist ( ) ;
1997-10-30 15:13:59 +00:00
if ( ! ok )
{
1997-11-06 10:05:56 +00:00
if ( ! yesno_box ( " Impossibile trovare %s \n Si desidera riprovare? " ,
1997-10-30 15:13:59 +00:00
( const char * ) cmdline ) )
break ;
}
}
if ( ok )
{
1997-12-15 15:11:40 +00:00
const long required = fsize ( cmdline ) * ( dischi - d + 1 ) * 4 ;
1998-08-21 10:58:38 +00:00
const TString & dest = get ( F_CURPATH ) ;
if ( ! : : os_test_disk_free_space ( dest , required ) )
1997-10-30 15:13:59 +00:00
{
ok = yesno_box ( " Lo spazio su disco potrebbe essere insufficiente: \n "
" Si desidera continuare ugualmente? " ) ;
}
}
if ( ok )
{
TWait_cursor hourglass ;
cmdline . insert ( " unzip.pif -o " , 0 ) ;
1997-12-17 13:40:59 +00:00
cmdline < < " -d " < < tempdir ;
1997-12-15 15:11:40 +00:00
1997-10-30 15:13:59 +00:00
TExternal_app app ( cmdline ) ;
ok = app . run ( FALSE , FALSE , FALSE , FALSE ) = = 0 ;
pi . addstatus ( 1 ) ;
}
1997-12-15 15:11:40 +00:00
}
1997-10-30 15:13:59 +00:00
if ( ok )
1998-01-23 14:55:34 +00:00
{
msg . cut ( 0 ) ;
1998-01-29 13:42:30 +00:00
msg < < " Aggiornamento del modulo ' " < < module < < " ' in corso... " ;
1998-01-23 14:55:34 +00:00
pi . set_text ( msg ) ;
1998-06-10 16:38:58 +00:00
ok = move_module ( module , * ini , TRUE ) ;
1997-12-15 15:11:40 +00:00
1998-06-10 16:38:58 +00:00
TAuto_token_string altri ( ini - > get ( " Moduli " , module ) ) ;
1997-12-15 15:11:40 +00:00
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 ) ;
1998-01-23 14:55:34 +00:00
const int curpatch = curini . patch ( submod ) ;
1998-06-10 16:38:58 +00:00
const TString16 reqver = ini - > version ( submod ) ;
const int reqpatch = ini - > patch ( submod ) ;
1998-02-09 12:06:44 +00:00
1998-01-22 11:56:14 +00:00
int distance = compare_version ( reqver , reqpatch , curver , curpatch ) ;
1998-02-09 12:06:44 +00:00
upd = distance > 0 ;
1997-12-15 15:11:40 +00:00
}
1998-06-10 16:38:58 +00:00
ok & = move_module ( submod , * ini , upd ) ;
if ( upd & & ok )
ini - > export_paragraph ( submod , ini - > default_name ( ) ) ;
1997-12-15 15:11:40 +00:00
}
}
1997-10-30 15:13:59 +00:00
}
1997-12-15 15:11:40 +00:00
if ( ok )
1998-06-10 16:38:58 +00:00
{
if ( ok ) ini - > export_paragraph ( module , ini - > default_name ( ) ) ;
}
1997-10-30 15:13:59 +00:00
}
else
{
1998-04-30 14:38:35 +00:00
// non c'e' il .ini del modulo ma un unico "install.ini"
1997-10-30 15:13:59 +00:00
ininame = path ;
ininame . add ( TInstall_ini : : default_name ( ) ) ;
ok = fexist ( ininame ) ;
if ( ok )
{
1998-06-10 16:38:58 +00:00
ini = new TInstall_ini ( ininame ) ;
ini - > write_protect ( ) ;
lastpatch = ini - > get_int ( " Patch " , module ) ;
lastrelease = ini - > get ( " Versione " , module ) ;
if ( ! can_install ( module , * ini ) )
1997-12-15 15:11:40 +00:00
return FALSE ;
1997-10-30 15:13:59 +00:00
TString_array list ;
1998-06-10 16:38:58 +00:00
const int files = ini - > build_complete_list ( module , list ) ;
1997-10-30 15:13:59 +00:00
if ( files > 0 )
{
1998-06-10 16:38:58 +00:00
if ( patchlevel = = 0 )
ok = pre_process ( * ini , module ) ;
1997-11-06 10:05:56 +00:00
if ( ok )
1997-10-30 15:13:59 +00:00
{
1997-11-06 10:05:56 +00:00
TProgind pi ( files , " Copia in corso... " , FALSE , TRUE ) ;
TFilename src , dst ;
for ( int f = 0 ; f < files & & ok ; f + + )
{
pi . addstatus ( 1 ) ;
dst = list . row ( f ) . get ( 0 ) ;
src = path ;
src . add ( dst ) ;
ok = fcopy ( src , dst ) ;
}
1997-10-30 15:13:59 +00:00
}
1997-11-06 10:05:56 +00:00
1997-10-30 15:13:59 +00:00
if ( ok )
{
1998-06-10 16:38:58 +00:00
if ( ok ) ini - > export_module_paragraphs ( module , ini - > default_name ( ) ) ;
1997-10-30 15:13:59 +00:00
}
}
}
}
if ( ok )
{
1998-04-30 14:38:35 +00:00
{
1998-08-21 10:58:38 +00:00
TInstall_ini ini ;
ini . set ( " DiskPath " , get ( F_PATH ) ) ;
ini . set ( " Data " , TDate ( TODAY ) , module ) ;
ini . update_prices ( ininame ) ;
1998-04-30 14:38:35 +00:00
}
// Non togliere le parentesi graffe soprastanti per permettere l'aggiornamento fisico del .ini (CON LA CHIAMATA DEL DISTRUTTORE)
update_version ( ) ;
1997-10-30 15:13:59 +00:00
}
1998-04-30 14:38:35 +00:00
if ( patchlevel = = 0 ) // Se installo un modulo pricipale ...
{
// ... installo DOPO tutte le patches successive
install_patches ( module , lastrelease , lastpatch ) ;
1998-06-10 16:38:58 +00:00
ok & = post_process ( * ini , module ) ;
1998-04-30 14:38:35 +00:00
}
1997-11-06 10:05:56 +00:00
1997-10-30 15:13:59 +00:00
return ok ;
}
1998-04-30 14:38:35 +00:00
bool TInstaller_mask : : install_patches ( const TString & module , const TString & lastrelease , int lastpatch )
{
bool ok = FALSE ;
TString_array modules ;
1998-08-21 10:58:38 +00:00
TFilename ininame = get ( F_PATH ) ;
if ( is_internet_path ( ininame ) )
{
ininame . tempdir ( ) ;
ininame . add ( " www " ) ;
}
1998-04-30 14:38:35 +00:00
ininame . add ( module ) ;
ininame < < " 0???a.ini " ;
modules . destroy ( ) ;
list_files ( ininame , modules ) ;
modules . sort ( ) ; // sort by patch number
FOR_EACH_ARRAY_ROW ( modules , am , arow )
{
TString & ininame = * arow ;
ininame . lower ( ) ;
const int pos = ininame . find ( " a.ini " ) ;
CHECKS ( pos > = 6 , " Invalid installation configuration: " , ( const char * ) ininame ) ;
const TString16 patchmodule = ininame . mid ( pos - 6 , 2 ) ;
TConfig ini ( ininame , patchmodule ) ;
const int patchlevel = ini . get_int ( " Patch " ) ;
const char * patchversion = ini . get ( " Versione " ) ;
if ( lastrelease = = patchversion // installa solo le patch della stessa ver..
& & lastpatch < patchlevel ) // ... e patch superiore
ok = install ( module , patchlevel ) ;
}
return ok ;
}
1997-10-30 15:13:59 +00:00
bool TInstaller_mask : : path_handler ( TMask_field & fld , KEY key )
{
bool ok = TRUE ;
if ( key = = K_TAB & & fld . focusdirty ( ) )
{
1998-01-23 14:55:34 +00:00
TFilename path = fld . get ( ) ;
1998-08-21 10:58:38 +00:00
if ( path . not_empty ( ) )
1997-10-30 15:13:59 +00:00
{
1998-08-21 10:58:38 +00:00
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 ( " Specificare un percorso valido " ) ;
}
1997-10-30 15:13:59 +00:00
}
return ok ;
}
1997-12-04 14:07:49 +00:00
void TInstaller_mask : : install_selection ( )
{
TString_array & arr = rows_array ( ) ;
FOR_EACH_ARRAY_ROW ( arr , r , row ) if ( checked ( r ) )
{
1998-02-18 13:46:52 +00:00
const TString newver = row - > get ( C_RELEASE ) ;
1998-02-09 12:06:44 +00:00
if ( newver . blank ( ) )
{
check ( r , FALSE ) ;
continue ;
}
1998-02-18 13:46:52 +00:00
const TString 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 ) ;
1997-12-15 15:11:40 +00:00
if ( version2year ( newver ) < 1997 )
{
error_box ( " Il modulo '%s' non ha una versione valida. " , ( const char * ) modulo ) ;
continue ;
}
1997-10-30 15:13:59 +00:00
1997-12-04 14:07:49 +00:00
bool ok = TRUE ;
1998-01-22 11:56:14 +00:00
const int cmp = compare_version ( oldver , oldpatch , newver , newpatch ) ;
1997-10-30 15:13:59 +00:00
if ( cmp = = 0 )
1998-08-21 10:58:38 +00:00
ok = noyes_box ( " Si desidera reinstallare la versione %s.%d del modulo '%s' ? " , ( const char * ) newver , newpatch , ( const char * ) modulo ) ;
1997-10-30 15:13:59 +00:00
if ( cmp > 0 )
1998-01-29 13:42:30 +00:00
{
TString256 msg ;
msg . format ( " Si desidera ritornare alla versione %s.%d del modulo '%s' ? \n "
1997-10-30 15:13:59 +00:00
" Attenzione: non e' garantito il corretto \n "
1998-01-29 13:42:30 +00:00
" funzionamento di tutti i programmi! " , ( const char * ) newver , newpatch , ( const char * ) modulo ) ;
ok = noyes_box ( msg ) ;
}
1998-08-21 10:58:38 +00:00
bool is_patch = row - > get_char ( C_ISPATCH ) > ' ' ;
1998-02-18 13:46:52 +00:00
if ( is_patch )
{
// installo le patch solo se esiste gi<67> un modulo installato della stessa versione
if ( ! oldver . blank ( ) )
if ( oldver ! = newver )
ok = error_box ( " Impossibile installare le patch della versione %s \n perch<EFBFBD> il modulo '%s' installato ha versione %s " , ( const char * ) newver , ( const char * ) modulo , ( const char * ) oldver ) ;
}
1998-08-21 10:58:38 +00:00
1997-10-30 15:13:59 +00:00
if ( ok )
1998-01-23 14:55:34 +00:00
{
1998-08-21 10:58:38 +00:00
if ( ! is_patch )
{
if ( newver = = oldver & & newpatch ! = oldpatch & &
! noyes_box ( " Si desidera reinstallare l'intero modulo? \n "
" Rispondendo NO verranno installate le sole patch " ) )
{
is_patch = TRUE ;
}
}
1998-04-30 14:38:35 +00:00
if ( is_patch )
1998-01-23 14:55:34 +00:00
{
1998-04-30 14:38:35 +00:00
ok = install_patches ( modulo , oldver , oldpatch ) ; // installa tutte le patch
if ( ! ok )
ok = install ( modulo , newpatch ) ; // re-installa l'ultima per sicurezza ()
1998-01-23 14:55:34 +00:00
}
1998-04-30 14:38:35 +00:00
else
1998-08-21 10:58:38 +00:00
{
1998-04-30 14:38:35 +00:00
ok = install ( modulo , 0 ) ; // installa il modulo
1998-08-21 10:58:38 +00:00
}
1998-04-30 14:38:35 +00:00
if ( ok )
_installed = TRUE ; // Setta il flag di almeno un modulo installato
1998-02-09 12:06:44 +00:00
if ( ok )
check ( r , FALSE ) ;
1998-01-22 11:56:14 +00:00
}
1998-02-18 13:46:52 +00:00
check ( r , FALSE ) ; // uncheck
1997-10-30 15:13:59 +00:00
}
1997-12-04 14:07:49 +00:00
}
bool TInstaller_mask : : install_handler ( TMask_field & fld , KEY key )
{
if ( key = = K_SPACE )
1997-12-17 13:40:59 +00:00
{
if ( _curr_mask - > items ( ) = = 1 )
_curr_mask - > check ( 0 ) ;
1997-12-04 14:07:49 +00:00
if ( _curr_mask - > one_checked ( ) )
_curr_mask - > install_selection ( ) ;
else
error_box ( " Selezionare uno piu' moduli da installare. " ) ;
}
return TRUE ;
}
1998-02-09 12:06:44 +00:00
bool TInstaller_mask : : tutti_handler ( TMask_field & f , KEY k )
{
if ( k = = K_SPACE )
{
TSheet & s = ( TSheet & ) f . mask ( ) ;
if ( s . check_enabled ( ) )
{
if ( s . one_checked ( ) )
s . uncheck ( - 1 ) ;
else
{
for ( long i = s . items ( ) - 1 ; i > = 0 ; i - - )
{
TToken_string r = s . row ( i ) ;
1998-02-18 13:46:52 +00:00
const TString16 newver = r . get ( C_RELEASE ) ;
const int newpatch = r . get_int ( C_PATCH ) ;
const TString16 curver = r . get ( C_CURRRELEASE ) ;
const int curpatch = r . get_int ( C_CURRPATCH ) ;
1998-02-09 12:06:44 +00:00
s . check ( i , compare_version ( newver , newpatch , curver , curpatch ) > 0 ) ;
}
}
}
}
return TRUE ;
}
1998-08-21 10:58:38 +00:00
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 ;
}
1997-12-04 14:07:49 +00:00
bool TInstaller_mask : : on_key ( KEY key )
{
bool ok = TRUE ;
1998-08-21 10:58:38 +00:00
switch ( key )
{
case K_F7 : autoload ( ) ; break ;
case K_F8 : field ( DLG_USER ) . on_hit ( ) ; break ;
default : ok = TArray_sheet : : on_key ( key ) ; break ;
}
1997-12-04 14:07:49 +00:00
return ok ;
1997-10-30 15:13:59 +00:00
}
TInstaller_mask : : TInstaller_mask ( )
1997-12-04 14:07:49 +00:00
: TArray_sheet ( 0 , 0 , 0 , 0 , " Installazione " ,
1998-02-18 13:46:52 +00:00
" @1|Modulo@30|Cod.|Versione da \n installare@11|Livello \n Patch@8|Data \n Rilascio@10|Versione \n Installata@10|Livello \n Patch@8|Data \n Installazione@13|Aggiornamento " ,
1997-12-04 14:07:49 +00:00
0x18 , 3 )
{
_curr_mask = this ;
1998-01-29 13:42:30 +00:00
_installed = FALSE ;
1998-08-21 10:58:38 +00:00
add_string ( F_PATH , 0 , " Installa da " , 1 , 1 , 50 ) ;
add_string ( F_CURPATH , 0 , " Installa in " , 1 , 2 , 50 , " D " ) ;
add_button ( F_UPDATE , " Lista " , ' \0 ' ) ;
1997-12-04 14:07:49 +00:00
add_button ( F_INSTALL , " Installa " , ' \0 ' ) ; // NON mettere 'I'
1997-10-30 15:13:59 +00:00
set_handler ( F_PATH , path_handler ) ;
1997-12-04 14:07:49 +00:00
set_handler ( F_INSTALL , install_handler ) ;
1998-02-09 12:06:44 +00:00
set_handler ( DLG_USER , tutti_handler ) ;
1998-08-21 10:58:38 +00:00
set_handler ( F_UPDATE , update_handler ) ;
1997-10-30 15:13:59 +00:00
1997-12-17 13:40:59 +00:00
TDongle dongle ; dongle . login ( ) ; dongle . logout ( ) ;
_year_assist = dongle . year_assist ( ) ;
1997-10-30 15:13:59 +00:00
TInstall_ini ini ;
TFilename path = ini . get ( " DiskPath " ) ;
set ( F_PATH , path ) ;
1998-02-24 10:30:04 +00:00
const bool floppy = : : os_is_removable_drive ( path ) ;
1998-08-21 10:58:38 +00:00
if ( path . not_empty ( ) & & ! floppy & & ! is_internet_path ( path ) )
1997-10-30 15:13:59 +00:00
autoload ( ) ;
DIRECTORY dir ;
xvt_fsys_get_dir ( & dir ) ;
xvt_fsys_convert_dir_to_str ( & dir , path . get_buffer ( ) , path . size ( ) ) ;
set ( F_CURPATH , path ) ;
}
1997-12-04 14:07:49 +00:00
TInstaller_mask : : ~ TInstaller_mask ( )
{
_curr_mask = NULL ;
}
1997-10-30 15:13:59 +00:00
///////////////////////////////////////////////////////////
// Programma principale
///////////////////////////////////////////////////////////
class TInstaller : public TSkeleton_application
{
protected :
virtual bool use_files ( ) const { return FALSE ; }
virtual void main_loop ( ) ;
} ;
void TInstaller : : main_loop ( )
{
TInstaller_mask m ;
m . run ( ) ;
1998-01-29 13:42:30 +00:00
if ( m . installed ( ) ) // Almeno 1 modulo installato ?
{
// Lancia conversione: ba1 -0 -C -uPRASSI
TExternal_app conversion ( " ba1 -0 -C " ) ;
conversion . run ( ) ;
}
1997-10-30 15:13:59 +00:00
}
int ba1700 ( int argc , char * argv [ ] )
{
TInstaller app ;
app . run ( argc , argv , " Installer " ) ;
return 0 ;
}