campo-sirio/ba/ba1700.cpp
luca 06fb206415 Patch level :10.0 538
Files correlati     :
Ricompilazione Demo : [ ]
Commento            :
preservato l'oem anche in aggiornamento da disco e non solo da internet


git-svn-id: svn://10.65.10.50/trunk@19709 c028cbd2-c16b-5b4b-a496-9718f37d4682
2009-12-02 12:13:00 +00:00

1931 lines
56 KiB
C++
Executable File
Raw Blame History

#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 "ba1500.h"
#include "ba1600.h"
#include "ba1700a.h"
// definizioni delle colonne dello sheet
#define C_MODULE 1
#define C_CODE 2
#define C_RELEASE 3
#define C_PATCH 4
#define C_DATAREL 5
#define C_CURRRELEASE 6
#define C_CURRPATCH 7
#define C_CURRDATAREL 8
#define C_ISPATCH 9
#define C_BASEPATCH 10
///////////////////////////////////////////////////////
// Metodi di utility
///////////////////////////////////////////////////////
HIDDEN const TString& http_default_path()
{
//nuovo modo di gettare il producer da oem.ini
TConfig oemini(CONFIG_OEM, "MAIN");
const int oem = oemini.get_int("OEM", NULL, -1, -1);
TString& tmp = get_tmp_string();
if (oem >= 0)
{
TString8 para; para << "OEM_" << oem;
tmp = oemini.get("Web", para);
}
if (tmp.blank())
tmp = "www.aga.it/release100/";
return tmp;
}
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;
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;
const TString& module = ini.get_paragraph();
CHECKS(module.len() == 2, "Invalid module ", (const char*)module);
const int mod = dongle().module_name2code(module);
if (mod > BAAUT && mod < ENDAUT)
{
TAuto_token_string oem = ini.get("OEM");
if (oem.blank())
{
// Pezza temporanea: assegno OEM noti
switch (mod)
{
case LVAUT: oem = "2,4"; break;
case PEAUT: oem = "3"; break;
case COAUT: oem = "5"; break;
default: break;
};
}
if (oem.full())
yes = oem.get_pos(dongle().oem()) >= 0;
else
{
// Pezza temporanea: Ee significava AGA only
const bool ee = ini.get_bool("Ee");
if (ee && dongle().oem() != 0)
yes = false;
}
}
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);
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 == 0;
if (!ok)
{
const TDongle& d = dongle();
if (station_type() == 2)
{
//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
TString_array& a = rows_array();
FOR_EACH_ARRAY_ROW(a, r, row)
{
TToken_string& rigar = *row;
cod_module = rigar.get(C_CODE);
release = rigar.get(C_RELEASE);
patchlevel = rigar.get_int(C_PATCH);
currrelease = rigar.get(C_CURRRELEASE);
currpatch = rigar.get_int(C_CURRPATCH);
modnumber = get_module_number(cod_module);
if (modnumber >= 0 && 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 (chk && cod_module == "sr" && test_station_type() != 2)
chk = false;
if (check_enabled)
check(r, chk);
if (chk && only_newer && cod_module == "sy") //se viene checkato il modulo sy (sistema) deve togliere..
{ //..la possibilita' di installare altri moduli..
for (int i = 0; i < a.items(); i++)
disable_row(i); //disabilita tutte le righe dello sheet
disable(DLG_USER);
check_enabled = false; //..ed uscire
}
} //if(modnumber>=0...
} //FOR_EACH_ARRAY_ROW...
force_update(); // Indispensabile per vedere le righe aggiornate sullo sheet
return items();
}
int TInstaller_mask::get_module_number(const TString& module) const
{
int aut = -1;
bool ok = false;
if (module.full())
{
if (module == "ba" || module == "sy") //moduli base e sistema: deve ritornare 0;
return 0;
aut = dongle().module_name2code(module);
ok = aut < ENDAUT;
}
return ok ? aut : -1;
}
void TInstaller_mask::update_version()
{
TInstall_ini ini;
TString_array& a = rows_array();
FOR_EACH_ARRAY_ROW_BACK(a, m, row)
{
if (*row->get(C_CODE) != ' ')
{
const 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();
}
// Cerca nel percorso specificato sulla maschera tutti i possibili files .ini
// utilizzabili per un'installazione e li inserisce nello spreadsheet
bool TInstaller_mask::autoload()
{
TString_array& mask_rows = rows_array();
TString http_server;
TFilename http_path, path, ininame;
//controla se si e' scelto un path di installazione internet o da disco
const bool internet = get_patches_path(path);
//se e' un aggiornamento via internet...
if (internet)
{
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;
::list_files(ininame, list);
FOR_EACH_ARRAY_ROW(list, i, row)
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();
{
TTimerind contacting(30*1000, TR("Connessione al server HTTP..."), false, false);
http_get(http_server, remote_ini, ininame);
}
}
} //if(internet...
if (path.exist())
{
ininame = path;
ininame.add(TInstall_ini::default_name());
}
else
return error_box(TR("Specificare un percorso valido"));
TWait_cursor hourglass;
destroy();
force_update();
TString_array modules;
//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
{
http_dir(http_server, http_path, modules);
for (int i = modules.last(); i >= 0; i--)
{
TString& str = modules.row(i);
if (str.match("??????A.INI", true))
{
TFilename remote = http_path;
remote << str;
ininame = path;
ininame.add(str);
if (!ininame.exist() && !http_get(http_server, remote, ininame))
{
error_box(FR("Errore di trasferimento del file %s"), (const char*)remote);
modules.destroy(i);
}
str = ininame;
}
else
modules.destroy(i);
}
modules.pack();
}
else //normal patches
{
ininame = path;
ininame.add("??????a.ini");
list_files(ininame, modules);
}
if (modules.items() > 0) //ordina i moduli come sull'install.ini locale (per avere SY come primo
{ //modulo e via via gli altri)
TInstall_ini installini;
TString_array paragrafi;
TFilename file;
installini.list_paragraphs(paragrafi);
// rimozione del produttore sull'install.ini locale ora obsoleto..
installini.remove("Producer");
FOR_EACH_ARRAY_ROW(modules, am, arow)
{
file = *arow;
file = file.name();
int pos = paragrafi.find(file.left(2));
if (pos <= 0)
pos = 10000+am;
TString8 str;
str.format("%05d", pos); //aggiunge un numero d'ordine sulla sinistra del nome del file..
arow->insert(str);
}
modules.sort(); //..cosi' che la sort (che ordina alfabeticamente) sistemi la lista moduli
FOR_EACH_ARRAY_ROW(modules, bm, brow) //rimette i nomi dei moduli a posto (toglie il numero d'ordine)
brow->ltrim(5);
}
//genera le righe dello sheet di installazione
FOR_EACH_ARRAY_ROW(modules, am, arow)
{
TString& ininame = *arow;
ininame.lower();
const int pos = ininame.find("a.ini");
CHECKS(pos >= 6, TR("Configurazione di installazione non valida: "), (const char*)ininame);
const TString4 module = ininame.mid(pos-6, 2);
TConfig ini(ininame, module);
ini.write_protect();
int r;
for (r = int(items()-1); r >= 0; r--)
{
if (module == row(r).get(C_CODE))
break;
}
if (r >= 0)
{
if (is_visible_patch(ini))
{
const TString16 patchversion = ini.get("Versione");
const int patchlevel = ini.get_int("Patch");
TToken_string& row = mask_rows.row(r);
const TString16 release(row.get(C_RELEASE));
if (patchversion.mid(4) == release.mid(4) // se le versioni corrispondono ...
&& patchlevel > row.get_int(C_PATCH)) // ..e il patchlevel <20> superiore
{
TString4 patch; patch.format("%04d", patchlevel); //aggiunge zeri per avere 3 cifre sempre
row.add(patch, C_PATCH); // aggiorna il patchlevel mostrato per il modulo
row.add(ini.get("Data"), C_DATAREL); // aggiorna data di rilascio
if (row.get_char(C_ISPATCH)<=' ') // se era un modulo ...
{
row.add("+", C_ISPATCH); // .....setta la presenza di patches
row.add(row.get(C_PATCH), C_BASEPATCH); // memorizza patch del modulo
}
if (release < patchversion)
row.add(patchversion, C_RELEASE);
}
}
else
destroy(r); // Elimina patch di altri OEM erroneamente inserite
}
else
add_module(ini, module, true);
}
update_version();
const bool ok = precheck_modules() > 0;
if (!ok)
error_box(FR("Non e' stato trovato nessun modulo da installare\nin %s"), (const char*)path);
return ok;
}
bool TInstaller_mask::do_process(TToken_string& commands) const
{
bool ok = true;
TFilename cmd;
for (const char* c = commands.get(0); c && ok; c = commands.get())
{
cmd = c;
if (cmd.full())
{
TWait_cursor hourglass;
TExternal_app app(cmd);
ok = app.run(false,3,true) == 0;
}
}
return ok;
}
bool TInstaller_mask::pre_process(TInstall_ini& ini, const char* module) const
{
TAuto_token_string commands(ini.get("PreProcess", module));
bool ok = do_process(commands);
return ok;
}
bool TInstaller_mask::post_process(TInstall_ini& ini, const char* module) const
{
TAuto_token_string commands(ini.get("PostProcess", module));
return do_process(commands);
}
bool TInstaller_mask::can_install(const char* module, TInstall_ini& ini)
{
ini.set_paragraph(module);
if (!is_visible_patch(ini))
return false;
TInstall_ini curini;
if (curini.demo() != ini.demo())
{
TString msg;
msg << TR("Attenzione: Non e' possibile installare la versione ");
msg << (ini.demo() ? TR("dimostrativa") : TR("normale"));
msg << TR(" nella cartella della versione ");
msg << (curini.demo() ? TR("dimostrativa") : TR("normale"));
return error_box(msg);
}
const TString& version = ini.version(module);
const word year = version2year(version);
if (year < 2009)
return error_box(FR("Il modulo '%s' non ha una versione valida."), module);
if (year > dongle().year_assist())
{
if (!update_assistance_year())
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;
for (const char* mod = altri.get(0); mod && ok; mod = altri.get())
{
submodule = mod;
if (submodule.len() == 2)
{
if (curini.get("Versione", submodule).empty())
{
TString msg;
msg.format(FR("L'installazione del modulo %s richiede la presenza del modulo %s."),
(const char*)module, (const char*)submodule);
msg << '\n' << TR("Si desidera procedere alla sua installazione?");
ok = yesno_box(msg);
if (ok)
ok = install(submodule, 0);
}
}
}
return ok;
}
int TInstaller_mask::needs_reboot(const TFilename& file) const
{
char fname[_MAX_FNAME], ext[_MAX_EXT];
xvt_fsys_parse_pathname(file, NULL, NULL, fname, ext, NULL);
int underscore = NONE;
if (xvt_str_compare_ignoring_case(ext, "exe") == 0)
{
if (xvt_str_compare_ignoring_case(fname, "ba0") == 0)
underscore = NEW_MENUPRG; else
if (xvt_str_compare_ignoring_case(fname, "ba1") == 0)
underscore = NEW_INSTALLER;
} else
if (xvt_str_compare_ignoring_case(ext, "dll") == 0)
underscore = NEW_DLL; else
if (xvt_str_compare_ignoring_case(ext, "men") == 0)
underscore = NEW_MENU; else
if (xvt_str_compare_ignoring_case(ext, "trr") == 0 || xvt_str_compare_ignoring_case(ext, "dir") == 0)
underscore = NEW_TRR;
return underscore;
}
// Controlla se un file puo' essere scompattato.
// Attenzione: dninst.zip e' un falso zip
bool TInstaller_mask::is_zip_file(const TFilename& n) const
{
bool yes = xvt_str_compare_ignoring_case(n.ext(), "zip") == 0 &&
xvt_str_compare_ignoring_case(n.name_only(), "dninst") != 0;
return yes;
}
bool TInstaller_mask::copy_file(const TFilename& src, const TFilename& dst) const
{
// Crea la cartella di destinazione se necessario
const char* dstdir = dst.path();
if (*dstdir && !xvt_fsys_mkdir(dstdir))
return error_box(FR("Impossibile creare la cartella %s"), dst.path());
// Copia veramente il file
return ::fcopy(src, dst);
}
// sposta il file dal direttorio temporaneo a quello passato come destinazione
bool TInstaller_mask::move_file(const TFilename& src, const TFilename& dst) const
{
TFilename dest = dst;
const int reboot = needs_reboot(dest);
if ((reboot & NEW_SYS)!=0 && dst.exist())
{
dest.rtrim(1);
dest << '_';
}
const bool is_zip = is_zip_file(src);
const long filesize = fsize(src) * (is_zip ? 4 : 1);
if (xvt_fsys_test_disk_free_space(dest.path(), filesize) == 0)
return error_box(TR("Lo spazio disponibile e' insufficiente!"));
const bool write_ok = copy_file(src, dest);
if (write_ok && is_zip)
aga_unzip(src, dest.path());
if (write_ok)
src.fremove();
if (write_ok)
{
(int&)_reboot_program |= reboot; // Skip const!
}
return write_ok;
}
bool TInstaller_mask::move_module(const TString& module, TInstall_ini& ini, bool update) const
{
bool ok = true;
TFilename tempdir; tempdir.tempdir();
const TString& destdir = get(F_CURPATH);
TString_array list;
ini.build_list(module, list);
FOR_EACH_ARRAY_ROW(list, f, file)
{
TFilename src = tempdir;
src.add(file->get(0));
if (update)
{
TFilename dst = destdir;
dst.add(file->get(0));
const bool move_ok = move_file(src, dst);
if (!move_ok)
ok = update = false;
}
if (!update)
src.fremove();
}
return ok;
}
bool TInstaller_mask::copy_tree(const char* src_study, const char* dst_study) const
{
xvt_fsys_save_dir();
TFilename mask(src_study); mask.add("*.");
SLIST dlist = xvt_fsys_list_files(DIR_TYPE, mask, TRUE);
xvt_fsys_restore_dir();
TProgind pd(xvt_slist_count(dlist), TR("Copia cartelle"), true, true);
TString msg; // Messaggio di progresso
bool go_on = true;
for (SLIST_ELT d = xvt_slist_get_first(dlist); d && go_on; d = xvt_slist_get_next(dlist, d))
{
if (!pd.addstatus(1))
{
go_on = false;
break;
}
const TFilename dir = xvt_slist_get(dlist, d, NULL);
TString name = dir.name(); name.lower();
if (name == "cesp") // Ignora la vetusta cartella Cespiti in FoxPro
continue;
msg.cut(0) << TR("Copia di ") << name;
pd.set_text(msg);
mask = dir; mask.add("*.*");
TString_array files; list_files(mask, files);
TProgind pi(files.items(), "Copia file", true, true);
TFilename dst;
FOR_EACH_ARRAY_ROW(files, i, f)
{
if (!pi.addstatus(1))
{
go_on = false;
break;
}
TFilename src(*f);
TString16 ext(src.ext()); ext.lower();
if (ext != "zip" && ext != "rar" && ext != "mdb" && ext != "inf")
{
msg.cut(0) << TR("Copia di ") << src;
pi.set_text(msg);
dst = dst_study;
dst.add(name);
dst.add(src.name());
copy_file(src, dst);
}
}
}
xvt_slist_destroy(dlist);
return go_on;
}
void TInstaller_mask::backup() const
{
TFilename src = firm2dir(-1);
if (!isalnum(src.right(1)[0]))
src.rtrim(1);
TFilename dst(src);
dst << ' ' << TDate(TODAY).date2ansi(); // Lo spazio rende inutilizzabile lo studio
TToken_string msg(256, '\n');
msg.add(TR("Si consiglia creare una copia dello studio ")); msg << src.name();
msg.add(TR("nella cartella ")); msg << dst;
msg.add(TR("L'operazione potrebbe richiedere alcuni minuti."));
msg.add("");
msg.add(TR("Si desidera effetture la copia?"));
if (yesno_box(msg))
copy_tree(src, dst);
}
KEY TInstaller_mask::askdisk(TString & path, TFilename & cmdline, int d, int dischi, const char * modulo)
{
TMask retry_mask(TR("Inserimento disco"),1,80,10);
retry_mask.add_static((F_PATH==101 ? 102:101),0,
format(FR("Inserire il disco %d di %d del modulo '%s' nell'unit<69>"), d, dischi, modulo)
,2,2);
retry_mask.add_static(F_PATH+3,0,TR("oppure indicare un percorso diverso"),2,3);
retry_mask.add_string(F_PATH,0,"",2,5,48);
retry_mask.add_button(DLG_OK,0,TR("Riprova"),-12,7,9,2);
retry_mask.add_button(DLG_QUIT,0,"",-22,7,9,2);
retry_mask.set(F_PATH,path);
KEY k;
do {
if ((k=retry_mask.run())==K_QUIT )
break;
if (!retry_mask.get(F_PATH).blank())
{
if (fexist(retry_mask.get(F_PATH)))
{
TString16 tmpname(cmdline.name() );
cmdline= path = retry_mask.get(F_PATH);
cmdline.add(tmpname);
break;
}
else
error_box(TR("Il percorso indicato non e' valido"));
}
} while (true);
return k;
}
//rimozione da disco dei files da eliminare indicati nei paragrafi kill..
//..e successivo aggiornamento dell'install.ini in modo da non avere pi<70> tra i piedi i files killati
void TInstaller_mask::kill_files()
{
//apre l'install.ini locale per effettuare l'aggiornamento
TInstall_ini ini;
//giro su tutti i sottomoduli di tipo 99 con l'elenco dei files da uccidere
TString_array paragraph_names;
ini.list_paragraphs(paragraph_names);
FOR_EACH_ARRAY_ROW(paragraph_names, nriga, riga)
{
//interessano solo i paragrafi con le killer list
if (riga->ends_with("99") && ini.set_paragraph(*riga))
{
TString_array killed;
TToken_string rigaini;
TFilename filetokill;
for (int k = 0;; k++)
{
rigaini = ini.get("Kill", NULL, k, "");
if (rigaini.empty())
break;
filetokill = rigaini.get(0);
if (filetokill.find('*') >= 0 || filetokill.find('?') >= 0)
{
TString_array filelist;
list_files (filetokill, filelist);
FOR_EACH_ARRAY_ROW(filelist, r, file)
{
filetokill = *file;
if (filetokill.exist())
filetokill.fremove();
killed.add(filetokill);
}
}
else
{
if (filetokill.exist())
filetokill.fremove();
killed.add(filetokill);
}
} //for(int k=0...
for (int s = 0; s <= 9 && !killed.empty(); s++)
{
const TString4 mod = riga->left(2);
const int cicli = mod == "ba" ? 2 : 1;
for (int c = 1; c <= cicli; c++)
{
TString4 module = c == 1 ? mod : "sy";
module << s;
TAssoc_array& vars = ini.list_variables(module);
FOR_EACH_ASSOC_STRING(vars, hobj, key, str)
{
const int idx = killed.find(str);
if (idx >= 0)
{
ini.remove(key);
killed.destroy(idx, true);
}
}
}
} //for (int s...
} //if (riga->ends_with...
} //FOR_EACH_ARRAY_ROW(...
}
bool TInstaller_mask::install(const TString& module, int patchlevel)
{
bool cancelled = false;
bool ok = false;
TString msg; // stringa per i messaggi
TString16 lastrelease; // release che sto installando
int lastpatch = patchlevel; // patchlevel che sto installando
TFilename path ;
TString http_server;
TFilename http_path;
const bool internet = get_patches_path(path);
if (internet)
parse_internet_path(http_server,http_path );
const bool is_a_patch = (patchlevel > 0);
//file .ini con le info di installazione (es. bainst.ini o ba0883.ini)
TFilename remote_ininame = path;
remote_ininame.add(module);
//completa il nome del file .ini controllando se <20> una patch (es. ba0883a.ini) o se <20> un pacco (es. bainst.ini)
if (is_a_patch)
{
TString16 name;
name.format("%04da.ini", patchlevel);
remote_ininame << name;
}
else
remote_ininame << "inst.ini";
if (internet && !remote_ininame.exist())
{
TFilename remote = remote_ininame.name();
remote.insert(http_path, 0);
http_get(http_server, remote, remote_ininame);
}
if (remote_ininame.exist())
{
// esiste un particolare .ini con formato XXinst.ini (moduli) o con XX9999a.ini (patch)
//----------------------------------------------
// (INSTALLAZIONE DA DIRECTORY CON FILES .ZIP)
//----------------------------------------------
//remote_ini <20> il file .ini con le info di installazione (es. ba0883a.ini, bainst.ini)
TInstall_ini* remote_ini = new TInstall_ini(remote_ininame);
remote_ini->write_protect();
lastpatch = remote_ini->get_int("Patch", module);
lastrelease = remote_ini->get("Versione", module);
//se non pu<70> installare il modulo chiude il remote_ini
if (!can_install(module, *remote_ini))
{
delete remote_ini;
return false;
}
//antico controllo del numero di dischetti (ora sempre = 1)
const int dischi = remote_ini->get_int("Dischi", module);
ok = dischi > 0;
if (!ok)
return error_box(FR("Impossibile determinare il numero dei dischetti in %s"), remote_ininame.name());
else
{
if (patchlevel == 0)
ok = pre_process(*remote_ini, module);
if (!ok)
{
delete remote_ini;
return false;
}
}
// DECOMPRESSIONE
// ----------------
// viene decompresso il file .zip collegato al file remote_ini (es. ba0883a1.zip, bainst.zip)
TProgind* pi = NULL;
if (dischi > 1)
{
msg = TR("Decompressione");
if (is_a_patch)
msg << TR(" della patch ") << patchlevel ;
msg << TR(" del modulo '") << module << TR("' in corso...");
pi = new TProgind(dischi, msg, false, true);
}
TFilename tempdir;
tempdir.tempdir();
// File tottale dei vari sotto-zip
TFilename totti = tempdir;
totti.add(module);
totti.ext("zip");
//si costruisce il nome dello zip
for (int d = 1; d <= dischi && ok; d++)
{
TFilename chunk = path;
chunk.add(module);
if (patchlevel > 0)
{
TString8 name;
name.format("%04da", patchlevel);
chunk << name;
}
else
chunk << "inst";
chunk << d << ".zip";
if (internet && !chunk.exist())
{
TFilename remote = chunk.name();
remote.insert(http_path, 0);
if (!http_get(http_server, remote, chunk))
error_box(FR("Errore di trasferimento del file '%s'"), (const char*)remote);
}
//antichi controlli in caso di multidischetto
ok = chunk.exist();
if (!ok && !internet) // Chiedi cambio disco (solo se non sta scaricando da internet)
{
while (!ok)
{
if (askdisk(path, chunk, d, dischi, (const char*)remote_ini->get("Descrizione")) == K_QUIT)
break;
ok = chunk.exist();
if (!ok)
message_box(FR("Impossibile trovare il file '%s'"), (const char*)chunk);
}
}
if (ok)
{
const long required = fsize(chunk) * (dischi - d + 1) * 4;
if (!xvt_fsys_test_disk_free_space(tempdir, required))
{
ok = yesno_box(TR("Lo spazio su disco potrebbe essere insufficiente:\nSi desidera continuare ugualmente?"));
}
}
if (ok)
::fcopy(chunk, totti, d > 1); // Somma il chunk al totale
}
if (pi != NULL)
{
delete pi;
pi = NULL;
}
//scompattamento vero e proprio dello zip
aga_unzip(totti, tempdir); // Scompatta il file totale zip
totti.fremove(); // Elimina il file totale zip
// TRASFERIMENTO
// -----------------
if (ok)
{
// si assicura che sia leggibile il .ini del primo disco
do
{
TFilename cmdline = path;
cmdline.add(remote_ininame.name());
ok = cmdline.exist();
if (!ok)
{
if (askdisk(path, cmdline, 1, dischi, (const char*)remote_ini->get("Descrizione")) == K_QUIT)
break;
ok = fexist(cmdline);
if (!ok)
message_box(FR("Impossibile trovare %s\n"), (const char*)cmdline);
else
{
delete remote_ini;
remote_ini = new TInstall_ini (cmdline);
}
}
} while (!ok);
if (ok)
{
TWait_cursor hourglass;
msg.cut(0);
msg << TR("Aggiornamento del modulo '") << module << TR("' in corso...");
xvtil_statbar_set(msg);
ok = move_module(module, *remote_ini, true);
if (ok)
{
TAuto_token_string altri(remote_ini->get("Moduli", module));
FOR_EACH_TOKEN(altri, mod)
{
const TString16 submod = mod;
if (submod.len() > 2) // sposta sottomoduli esterni
{
bool upd = ok;
if (ok)
{
TInstall_ini local_cur_ini;
const TString16 curver = local_cur_ini.version(submod);
const int curpatch = local_cur_ini.patch(submod);
const TString16 reqver = remote_ini->version(submod);
const int reqpatch = remote_ini->patch(submod);
int distance = compare_version(reqver, reqpatch, curver, curpatch);
upd = distance > 0;
}
ok &= move_module(submod, *remote_ini, upd);
if (upd && ok) // marca sull'install.ini di destinazione l'avvenuta installazione del sottomodulo "esterno"
remote_ini->export_paragraph(submod, TInstall_ini::default_name(), !is_a_patch);
}
}
}
xvtil_statbar_set("");
} //if(ok)..
} //if(ok)..
if (ok) // marca sull'install.ini di destinazione l'avvenuta installazione del modulo
remote_ini->export_module_paragraphs(module, TInstall_ini::default_name(), !is_a_patch);
} // installazione da directory con zip
else
if (!is_a_patch)
{
// non c'e' il .ini del modulo ma un unico "install.ini" (es. aggiornamento client)
//------------------------------------------------
// (INSTALLAZIONE DA DIRECTORY CON ESEGUIBILI)
//------------------------------------------------
remote_ininame = path;
remote_ininame.add(TInstall_ini::default_name());
ok = fexist(remote_ininame);
if (ok)
{
TInstall_ini ini(remote_ininame);
ini.write_protect();
lastpatch = ini.get_int("Patch", module);
lastrelease = ini.get("Versione", module);
if (!can_install(module, ini))
return false;
TString_array list;
const int files = ini.build_complete_list(module, list);
if (files > 0)
{
if (patchlevel == 0)
ok = pre_process(ini, module);
if (ok)
{
msg.cut(0) << TR("Copia del modulo ") << module;
TProgind pi(files, msg, true, true);
TFilename src, dst;
for (int f = 0; f < files && ok; f++)
{
pi.addstatus(1);
dst = list.row(f).get(0);
dst.lower();
src = path;
src.add(dst);
const int reboot = needs_reboot(dst);
if ((reboot & NEW_SYS) != 0 && dst.exist())
{
dst.rtrim(1);
dst << '_';
}
//copia il file dalla dir sorgenti
ok = copy_file(src, dst);
if (ok)
{
if (ok && is_zip_file(src))
aga_unzip(src, dst.path());
if (ok && reboot != NONE)
_reboot_program |= reboot;
}
else //se non riesce chiede se proseguire ugualmente
ok = yesno_box(TR("Continuare ugualmente ?"));
cancelled = pi.iscancelled();
}
ok &= !cancelled;
}
if (ok) // marca sull'install.ini di destinazione l'avvenuta installazione del modulo
ini.export_module_paragraphs(module, ini.default_name(), true);
} // controllo esistenza lista di file non vuota per questo modulo
} // controllo esistenza install.ini
} // fine installazione da directory con eseguibili
if (ok)
{
{
TInstall_ini ini;
ini.set("Data", TDate(TODAY), module);
ini.update_prices(remote_ininame);
}
// Non togliere le parentesi graffe soprastanti per permettere l'aggiornamento fisico del .ini (CON LA CHIAMATA DEL DISTRUTTORE)
update_version();
}
if (ok && patchlevel == 0) // Se installo un modulo pricipale ...
{
// ... installo DOPO tutte le patches successive
install_patches(module, lastrelease, lastpatch);
TInstall_ini ini;
ok &= post_process(ini, module);
}
return ok;
}
bool TInstaller_mask::get_patches_path(TFilename& path) const
{
const TEdit_field& www = efield(F_WEB);
path = 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 TString16 patchmodule = ininame.mid(pos-6, 2);
TConfig ini(ininame, patchmodule);
const int patchlevel = ini.get_int("Patch");
const TString16 patchversion = ini.get("Versione");
if (ok && lastrelease.mid(4) == patchversion.mid(4) // installa solo le patch della stessa ver..
&& (only_newer ? lastpatch < patchlevel : lastpatch <= patchlevel)) // ... e patch superiore o uguale (reinstalla l'ultima patch)
ok = install(module, patchlevel);
}
return ok;
}
bool TInstaller_mask::update_handler(TMask_field& f, KEY k)
{
if (k == K_SPACE)
{
TInstaller_mask& m = (TInstaller_mask&)f.mask();
m.autoload();
}
return true;
}
bool TInstaller_mask::path_handler(TMask_field& fld, KEY key)
{
bool ok = true;
if (key == K_TAB && fld.focusdirty())
{
TFilename path = fld.get();
if (path.not_empty())
{
if (path.len() == 2 && isalpha(path[0]) && path[1] == ':')
{
path << SLASH;
fld.set(path);
}
if (path.exist() || ::is_internet_path(path))
_curr_mask->autoload();
else
ok = fld.error_box(TR("Specificare un percorso valido"));
}
}
return ok;
}
bool TInstaller_mask::web_handler(TMask_field& fld, KEY key)
{
bool ok = true;
if (key == K_TAB && fld.focusdirty())
{
TFilename path = fld.get();
if (path.not_empty())
{
if (!path.ends_with("/"))
{
path << '/';
fld.set(path);
}
ok = ::is_internet_path(path);
if (!ok)
ok = fld.error_box(TR("Specificare un indirizzo valido"));
}
}
return ok;
}
// Aggiorna l'install.ini con eventuali modifiche dell'utente 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, "Installazione", true, true);
FOR_EACH_ARRAY_ROW(arr, r, row) if (checked(r))
{
if (!pi.addstatus(1))
break;
const TString newver = row->get(C_RELEASE);
if (newver.blank())
{
check(r, false);
continue;
}
const TString4 modulo = row->get(C_CODE);
const TString modesc = dongle().module_name2desc(modulo);
const int newpatch = row->get_int(C_PATCH);
const TString oldver = row->get(C_CURRRELEASE);
const int oldpatch = row->get_int(C_CURRPATCH);
pi.set_text(format(FR("Installazione modulo '%s'"), (const char*)modesc));
if (version2year(newver) < 2008)
{
error_box(FR("Il modulo '%s' non ha una versione valida."), (const char*)modesc);
continue;
}
bool ok = true;
bool is_patch = row->get_char(C_ISPATCH) == 'X';
bool has_patch = row->get_char(C_ISPATCH) == '+';
const int cmp = compare_version(oldver, oldpatch, newver, newpatch);
//versione e patch coincidono
if (cmp == 0)
ok = noyes_box(FR("Si desidera reinstallare la versione %s.%d del modulo '%s' ?"), (const char*)newver, newpatch, (const char*)modesc);
//ci sono ANCHE i pacchi
if (!is_patch && cmp > 0)
{
TString256 msg;
msg.format(FR("Si desidera ritornare alla versione %s.%d del modulo '%s' ?\nAttenzione: non e' garantito il corretto\nfunzionamento di tutti i programmi!"), (const char*)newver, newpatch, (const char*)modesc);
ok = noyes_box(msg);
}
//ci sono SOLO patch da installare
if (ok && is_patch)
{
// installo le patch solo se esiste gi<67> un modulo installato della stessa versione
if (!oldver.blank() )
{
if (compare_version(oldver, 0, newver, 0)) //controlla SOLO la versione indipendentemente dall'anno!
ok = error_box(FR("Il modulo '%s' installato ha versione %s:\nimpossibile installare le patch della versione %s"),(const char *)modulo,(const char *)oldver,(const char *)newver);
} else
if (newpatch < oldpatch)
{
TString256 msg;
msg.format(FR("Si desidera ritornare alla patch %s.%d del modulo '%s' ?\nAttenzione: non e' garantito il corretto\nfunzionamento di tutti i programmi!"), (const char*)newver, newpatch, (const char*)modesc);
ok = noyes_box(msg);
}
} //if(ok&&is_patch...
if (ok)
{
if (has_patch)
{
if (newver == oldver && newpatch >= oldpatch)
{
const int basepatch = row->get_int(C_BASEPATCH);
if (oldpatch >= basepatch)
is_patch = !noyes_box(FR("Si desidera reinstallare l'intero modulo '%s'?"
"\nRispondendo NO verranno installate le sole patch"),
(const char *)modesc);
else
is_patch = false; // Quando la versione installata precede la patch base devo reinstallare il modulo!
}
}
TFilename path;
const bool internet = get_patches_path(path);
//richiesto aggiornamento da disco del modulo SY o del modulo SR da manutenzione/installazione moduli!
if (modulo == "sy" || modulo == "sr")
{
if (!internet)
{
bool file_copied = false;
//trova il path della directory setup che e' nell'area con gli zip del cd
TFilename disk_path = path;
disk_path.add("setup/");
TString_array ar;
const int items = disk_path.exist() ? list_files(disk_path, ar) : 0;
if (items > 0)
{
//copia la dir setup dal disco sovrascrivendo eventuali files gia' presenti
make_dir("setup");
TFilename local_file, remote_file;
//preserva l'OEM contenuto in oem.ini della directory setup
const int old_oem = ini_get_int("setup/oem.ini", "MAIN", "OEM");
FOR_EACH_ARRAY_ROW(ar, r, row)
{
local_file = row->mid(path.len() + 1);
remote_file = *row;
file_copied = fcopy(remote_file, local_file); //occhio alle maiuscole!!!!
}
//riscrive il vecchio valore di oem in oem.ini
ini_set_int("setup/oem.ini", "MAIN", "OEM", old_oem);
}
update_disk_and_web_path(); //aggiorna l'install.ini
//lancia setup in modalita' aggiornamento da disco
if (test_station_type() == 3)
_setup_run = xvt_sys_execute("setup\\setup.exe -uc", false, false) !=0;
else
_setup_run = xvt_sys_execute("setup\\setup.exe -ud", false, false) !=0;
}
//richiesto aggiornamento via web del modulo SY da manutenzione/installazione moduli!
else
{
bool file_copied = false;
//trova l'indirizzo web completo
TString http_server;
TFilename http_path;
parse_internet_path(http_server, http_path);
//copia la dir setup dalla remote dir sovrascrivendo eventuali files gia' presenti
http_path.add("setup/");
TString_array ar;
http_dir(http_server, http_path, ar);
if (ar.items() > 0)
{
make_dir("setup");
TFilename local_file, remote_file;
FOR_EACH_ARRAY_ROW(ar, r, row)
{
local_file = "setup";
local_file.add(*row);
remote_file = http_path;
remote_file.add(*row);
//via web NON deve copiare oem.ini perch<63> NON deve poter cambiare il reseller (solo via disco sar<61>..
//..possibile)
const bool is_oem_ini = xvt_str_compare_ignoring_case(remote_file.name(), "oem.ini") == 0;
if (is_oem_ini)
{
const int old_oem = xvt_sys_get_profile_int(local_file, "MAIN", "OEM", -1);
file_copied = http_get(http_server, remote_file, local_file); //occhio alle maiuscole!!!!
const int new_oem = xvt_sys_get_profile_int(local_file, "MAIN", "OEM", -1);
if (new_oem != old_oem)
{
TString4 str_oem; str_oem << ' ' << old_oem;
xvt_sys_set_profile_string(local_file, "MAIN", "OEM", str_oem);
}
}
else
file_copied = http_get(http_server, remote_file, local_file); //occhio alle maiuscole!!!!
}
}
update_disk_and_web_path(); //aggiorna l'install.ini
//lancia setup in modalita' aggiornamento web
_setup_run = xvt_sys_execute("setup\\setup.exe -uw", false, false) != 0;
}
if (_setup_run) //se riesce a lanciare setup.exe...
{
//si suicida...Banzai!
uncheck(r);
send_key(K_SPACE, DLG_QUIT);
return;
}
}
//installa solo le patch del modulo...
if (is_patch)
{
ok = install_patches(modulo, oldver, oldpatch, false) ; // installa l'ultima patch
if (!ok)
message_box(TR("Impossibile installare le patch del modulo '%s'"),(const char *)modesc);
}
else //..installa anche il pacco del modulo
{
ok = install(modulo, 0); // installa il modulo
}
if (ok)
{
_installed = true; // Setta il flag di almeno un modulo installato
uncheck(r); //finalmente unchecka i moduli installati
}
} //if(ok)...
else
uncheck(r); // se non ci sono patch o moduli -> uncheck
} //FOR_EACH_ARRAY_ROW(arr...
//aggiorna definitivamente i path su install.ini
update_disk_and_web_path();
//accoppa i files nelle kill lists e aggiorna install.ini
kill_files();
//serve per togliere il check al modulo 'sy' quando viene installato
force_update();
}
bool TInstaller_mask::install_handler(TMask_field& fld, KEY key)
{
if (key == K_SPACE)
{
if (_curr_mask->items() == 1)
_curr_mask->check(0);
const bool check_on = _curr_mask->check_enabled();
_curr_mask->enable_check(true);
const bool some = _curr_mask->one_checked();
_curr_mask->enable_check(check_on);
if (some)
_curr_mask->install_selection();
else
error_box(TR("Selezionare uno o piu' moduli da installare."));
}
return true;
}
bool TInstaller_mask::tutti_handler(TMask_field& f, KEY k)
{
if (k == K_SPACE)
{
TInstaller_mask & m=(TInstaller_mask &) f.mask();
if (m.check_enabled())
{
if (m.one_checked())
m.uncheck(-1);
else
m.precheck_modules(false);
}
}
return true;
}
bool TInstaller_mask::on_key(KEY key)
{
bool ok = true;
switch (key)
{
case K_F7: autoload(); break;
case K_F8: field(DLG_USER).on_hit(); break;
default : ok = TArray_sheet::on_key(key); break;
}
return ok;
}
//metodo per controllare se la directory indicata contiene una installazione buona di campo
bool TInstaller_mask::is_program_dir(const TFilename& path)
{
bool ok = false;
TFilename work_path = path;
//controlla l'esistenza di alcuni files chiave di campo
work_path.add("install.ini");
if (work_path.exist())
{
work_path = path;
work_path.add("campo.ini");
if (work_path.exist())
{
work_path = path;
work_path.add("campo.aut");
if (work_path.exist())
{
work_path = path;
work_path.add("ba0.exe");
if (work_path.exist())
{
work_path = path;
work_path.add("xvaga.dll");
if (work_path.exist())
ok = true; //minchia che diffidente!
}
}
}
}
return ok;
}
TInstaller_mask::TInstaller_mask()
: TArray_sheet(0, 0, 0, 0, TR("Installazione"),
HR("@1|Modulo@32|Cod.@3|Versione da\ninstallare@11|Liv.\nPatch@6|Data\nRilascio@10|Versione\nInstallata@10|Liv.\nPatch@6|Data\nInstallazione@13|Aggiornamento|Patch Base"),
0x18, 4)
{
add_button(F_INSTALL, TR("Installa"), '\0', TOOL_ELABORA); // NON mettere 'I'
add_button(F_UPDATE, TR("Rileggi"), '\0', TOOL_CONVERT);
add_button(DLG_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(TR("Installa da disco"));
installada.add(TR("Installa da web "));
TRadio_field& rf = add_radio(F_TYPE, 0, "", 1, 0, 21, "0|1", installada);
*rf.message(0, true) = "DISABLE,207|ENABLE,201";
*rf.message(1, true) = "DISABLE,201|ENABLE,207";
add_string(F_PATH, 0, "", 23, 1, 256, "B", 56).set_selector('D', EMPTY_STRING);
add_string(F_WEB, 0, "", 23, 2, 256, "", 56);
set(F_TYPE, "0", 0x1);
//deve conoscere i path adesso per poter testare se sono ok
TInstall_ini ini;
TFilename path = ini.get("DiskPath");
TFilename webpath = ini.get("WebPath");
//un client non puo' scegliere a caso da dove aggiornarsi!Solo dal suo server!
if (_station_type == 3)
{
rf.disable();
bool ko = !is_program_dir(path);
if (ko)
warning_box(TR("La cartella origine dei programmi NON <20> valida!\nSelezionarne una valida e premere 'Invio'."));
enable(F_PATH, ko);
}
add_string(F_CURPATH, 0, PR("Installa in "), 1, 3, 80, "D", 56);
set_handler(F_PATH, path_handler);
set_handler(F_WEB, web_handler);
set_handler(F_INSTALL, install_handler);
set_handler(F_UPDATE, update_handler);
set_handler(DLG_USER, tutti_handler);
//se il webpath <20> vuoto o di test, propone quello in oem.ini; non ammette che possa essere proposto un path..
//..di tipo test per impedire all'utonto di aggiornarsi da test prima di essere passato da release
if (webpath.empty() || webpath.find("test"))
{
TConfig oemini(CONFIG_OEM, "MAIN");
const int oem = oemini.get_int("OEM", NULL, -1, -1);
if (oem >= 0)
{
TString8 para; para << "OEM_" << oem;
webpath = oemini.get("Web", para);
}
}
set(F_PATH, path);
set(F_WEB, webpath);
//..fine costruzione maschera di installazione
//decide quale e' il percorso di installazione
//ha un cd o un disco di rete -> si aggiorna da questo...
if (path.exist())
autoload();
else //senno' cerca su internet se trova un path internet completo e la connessione funzionante
{
if (_station_type != 3 && webpath.full())
{
set(F_TYPE, "1", 0x1);
if (xvt_net_get_status() & 0x2) //la connessione web funziona?...
//if (yesno_box(TR("E' possibile l'aggiornamento via internet. Si desidera connettersi ora?")))
autoload(); //...quindi scarica l'elenco dei moduli da aggiornare!
}
}
DIRECTORY dir;
xvt_fsys_get_dir(&dir);
xvt_fsys_convert_dir_to_str(&dir, path.get_buffer(), path.size());
set(F_CURPATH, path);
}
TInstaller_mask::~TInstaller_mask()
{
_curr_mask = NULL;
}
///////////////////////////////////////////////////////////
// Programma principale
///////////////////////////////////////////////////////////
class TInstaller : public TSkeleton_application
{
protected:
TInstaller_mask* _m;
protected:
virtual bool create();
virtual bool use_files() const { return false; }
virtual bool test_assistance_year() const;
virtual void main_loop();
void convert_archives();
};
bool TInstaller::test_assistance_year() const
{
// Per il momento lascia continuare: ci pensa poi la create
return true;
}
bool TInstaller::create()
{
if (!TApplication::test_assistance_year())
{
TExternal_app attivazione("ba1 -4");
attivazione.run();
dongle().login(); // Rilegge anno assistenza
}
else
update_dninst(false); // Aggiorna se necessario
//crea la maschera di installazione
_m = new TInstaller_mask();
//se e' un client
if (_m->station_type() == 3)
{
_m->disable_check();
_m->disable(F_UPDATE);
_m->disable(DLG_USER);
}
else //se e' standalone o server...
{
if (user() != ::dongle().administrator())
return error_box(TR("Solo l'utente amministratore puo' aggiornare questa postazione!"));
}
return TSkeleton_application::create();
}
void TInstaller::convert_archives()
{
bool conv = true;
if (is_power_station())
conv = yesno_box(TR("Si desidera convertire gli archivi ora?"));
if (conv)
{
_m->backup();
// Lancia conversione: ba1 -0 -C -uADMIN
TExternal_app conversion("ba1 -0 -C");
conversion.run();
}
}
void TInstaller::main_loop()
{
_m->run();
if (_m->run_conversion() && _m->station_type() < 3) // Almeno un trr installato e non e' client->conversione ammessa
{
convert_archives();
}
//controlla se ha lanciato setup.exe prima di chiudersi; se non lo ha fatto -> e' a fine installazione..
//..normale (moduli non SY) e quindi lancia ba0.exe
const bool setup_launched = _m->setup_run();
delete _m; _m = NULL;
if (!setup_launched)
{
TExternal_app ba0("ba0.exe");
ba0.run(true, true, false); // run asynchronous and not iconized!
}
}
int ba1700(int argc, char* argv[])
{
TInstaller app;
app.run(argc, argv, TR("Installazione moduli"));
return 0;
}