campo-sirio/ba/ba1700.cpp
alex e4ffa3c3d5 Riportata la versione 98.01.01CD sul main trunk
git-svn-id: svn://10.65.10.50/trunk@5981 c028cbd2-c16b-5b4b-a496-9718f37d4682
1998-01-20 15:04:34 +00:00

638 lines
16 KiB
C++
Executable File
Raw Blame History

#include <dos.h>
#define XVT_INCL_NATIVE
#include <applicat.h>
#include <colors.h>
#include <execp.h>
#include <progind.h>
#include <sheet.h>
#include <utility.h>
#include "ba1.h"
#include "ba1500.h"
#include "ba1600.h"
#include "ba1700a.h"
HIDDEN int compare_version(const char* v1, const char* v2)
{
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);
return ver1.compare(ver2, -1, TRUE);
}
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);
}
///////////////////////////////////////////////////////////
// Maschera principale
///////////////////////////////////////////////////////////
class TInstaller_mask : public TArray_sheet
{
static TInstaller_mask* _curr_mask;
word _year_assist;
protected: // TSheet
virtual bool on_key(KEY key);
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);
bool add_module(TConfig& ini, const TString& module);
void update_version();
bool move_file(const TFilename& file, const char* dir) 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 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;
public:
bool autoload();
bool install(const TString& module);
TInstaller_mask();
virtual ~TInstaller_mask();
};
TInstaller_mask* TInstaller_mask::_curr_mask = NULL;
// Copia nello sheet i dati di un modulo prendendoli da un .ini
bool TInstaller_mask::add_module(TConfig& ini, const TString& module)
{
bool ok = ini.set_paragraph(module);
if (ok)
{
TToken_string row;
row = " "; // Not selected
row.add(ini.get("Descrizione"));
row.add(module);
row.add(ini.get("Versione"));
row.add(ini.get("Data"));
add(row);
}
return ok;
}
void TInstaller_mask::update_version()
{
TInstall_ini ini;
TString_array& array = rows_array();
FOR_EACH_ARRAY_ROW_BACK(array, m, row)
{
const TString16 module = row->get(2);
ini.set_paragraph(module);
const TString16 newver = row->get(3);
const TString16 oldver = ini.get("Versione");
row->add(oldver, 5);
row->add(ini.get("Data"), 6);
}
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()
{
const TString& path = get(F_PATH);
if (!fexist(path))
return error_box("Specificare un percorso valido");
TWait_cursor hourglass;
destroy();
TFilename ininame;
ininame = path;
ininame.add(TInstall_ini::default_name());
TString_array modules;
if (fexist(ininame))
{
TInstall_ini ini(ininame);
ini.list_paragraphs(modules);
FOR_EACH_ARRAY_ROW(modules, i, row)
{
const TString& module = *row;
if (module.len() == 2)
add_module(ini, module);
}
}
else
{
ininame = path;
ininame.add("??inst.ini");
list_files(ininame, modules);
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 TString16 module = ininame.mid(pos-2, 2);
TConfig ini(ininame, module);
add_module(ini, module);
}
}
rows_array().sort();
const bool ok = items() > 0;
if (ok)
update_version();
else
error_box("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.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
{
TAuto_token_string commands(ini.get("PreProcess", module));
bool ok = do_process(commands);
return ok;
}
bool TInstaller_mask::post_process(TInstall_ini& ini, const char* module) const
{
TAuto_token_string commands(ini.get("PostProcess", module));
return do_process(commands);
}
bool TInstaller_mask::can_install(const char* module, TInstall_ini& ini)
{
TInstall_ini curini;
if (curini.demo() != ini.demo())
{
TString msg;
msg << "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);
const word year = version2year(version);
if (year < 1997)
return error_box("Il modulo '%s' non ha una versione valida.", module);
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);
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;
msg << "L'installazione del modulo '" << module
<< "'\nrichiede la presenza del modulo '" << submodule
<< "':\nSi desidera procedere alla sua installazione?";
ok = yesno_box(msg);
if (ok)
ok = install(submodule);
}
}
}
return ok;
}
bool TInstaller_mask::move_file(const TFilename& file, const char* dir) const
{
TFilename dest(dir);
dest.add(file.name());
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;
}
struct _diskfree_t drive;
_dos_getdiskfree(disk, &drive);
const unsigned requested_clusters = unsigned(filesize / drive.sectors_per_cluster / drive.bytes_per_sector) + 1;
space_ok = requested_clusters <= drive.avail_clusters;
if (!space_ok)
{
TString msg;
msg << "Lo spazio sull'unita' e' insufficiente";
if (GetDriveType(disk-1) == DRIVE_REMOVABLE)
{
msg << ":\nInserire un nuovo disco e ritentare?";
if (!yesno_box(msg))
return FALSE;
}
else
return error_box(msg);
}
}
bool write_ok = TRUE;
bool user_abort = FALSE;
do
{
write_ok = ::fcopy(file, dest);
if (write_ok)
::remove(file);
else
{
if (!yesno_box("Errore di copia del file %s.\nSi desidera riprovare?",
(const char*)file));
user_abort = TRUE;
}
} while (!write_ok && !user_abort);
return write_ok;
}
bool TInstaller_mask::move_module(const TString& module, TInstall_ini& ini, bool update) const
{
bool ok = TRUE;
TFilename src; src.tempdir();
const TFilename tempdir(src);
TString_array list;
ini.build_list(module, list);
FOR_EACH_ARRAY_ROW(list, f, file)
{
src = tempdir;
src.add(file->get(0));
if (update)
{
const bool move_ok = move_file(src, ".");
if (!move_ok)
ok = update = FALSE;
}
if (!update)
::remove(src);
}
if (update)
ini.export_paragraph(module, ini.default_name());
return ok;
}
bool TInstaller_mask::install(const TString& module)
{
bool ok = FALSE;
const TString& path = get(F_PATH);
TFilename ininame = path;
ininame.add(module);
ininame << "inst.ini";
if (fexist(ininame))
{
TInstall_ini ini(ininame);
if (!can_install(module, ini))
return FALSE;
const int dischi = ini.get_int("Dischi", module);
ok = dischi > 0;
if (!ok)
{
return error_box("Impossibile determinare il numero dei dischetti");
}
else
{
ok = pre_process(ini, module);
if (!ok) return FALSE;
}
TProgind pi(dischi, "Decompressione in corso...", FALSE, TRUE);
TFilename tempdir; tempdir.tempdir();
TFilename cmdline;
for (int d = 1; d <= dischi && ok; d++)
{
cmdline = path;
cmdline.add(module);
cmdline << "inst" << d;
cmdline.ext("zip");
ok = fexist(cmdline);
while (!ok)
{
message_box("Inserire il disco %d di %d del modulo\n%s",
d, dischi, (const char*)ini.get("Descrizione"));
ok = fexist(cmdline);
if (!ok)
{
if (!yesno_box("Impossibile trovare %s\nSi desidera riprovare?",
(const char*)cmdline))
break;
}
}
if (ok)
{
struct _diskfree_t drive;
_dos_getdiskfree(0, &drive);
const long required = fsize(cmdline) * (dischi-d+1) * 4;
const unsigned requested_clusters = unsigned(required / drive.sectors_per_cluster / drive.bytes_per_sector) + 1;
if (requested_clusters >= drive.avail_clusters)
{
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);
cmdline << " -d " << tempdir;
TExternal_app app(cmdline);
ok = app.run(FALSE, FALSE, FALSE, FALSE) == 0;
pi.addstatus(1);
}
}
if (ok)
{
pi.set_text("Aggiornamento in corso...");
ok = move_module(module, ini, TRUE);
TAuto_token_string altri(ini.get("Moduli", module));
FOR_EACH_TOKEN(altri, mod)
{
const TString16 submod = mod;
if (submod.len() > 2) // sposta sottomoduli esterni
{
bool upd = ok;
if (ok)
{
TInstall_ini curini;
const TString16 curver = curini.version(submod);
const TString16 reqver = ini.version(submod);
int distance =compare_version(reqver, curver) ;
upd = distance> 0;
if (!upd)
{
if (distance==0)
upd= yesno_box("Il sottomodulo '%s' versione %s <20> gi<67> installato.\n"
"Confermi la sovrascrittura?",
(const char*)submod, (const char*)reqver);
else
warning_box("Il sottomodulo '%s' e' aggiornato alla versione %s:\n"
"l'installazione della versione %s non verra' effettuata.",
(const char*)submod, (const char*)curver, (const char*)reqver);
}
}
ok &= move_module(submod, ini, upd);
}
}
}
if (ok)
ok = post_process(ini, module);
}
else
{
ininame = path;
ininame.add(TInstall_ini::default_name());
ok = fexist(ininame);
if (ok)
{
TInstall_ini ini(ininame);
if (!can_install(module, ini))
return FALSE;
TString_array list;
const int files = ini.build_complete_list(module, list);
if (files > 0)
{
ok = pre_process(ini, module);
if (ok)
{
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);
}
}
if (ok)
{
ini.export_module_paragraphs(module, ini.default_name());
ok = post_process(ini, module);
}
}
}
}
if (ok)
{
TInstall_ini ini;
ini.set("DiskPath", path);
ini.set("Data", TDate(TODAY), module);
ini.update_prices(ininame);
}
// Non spostare nell'if precedente: permettere l'aggiornamento del .ini
if (ok)
update_version();
return ok;
}
bool TInstaller_mask::path_handler(TMask_field& fld, KEY key)
{
bool ok = TRUE;
if (key == K_TAB && fld.focusdirty())
{
TString path = fld.get();
if (path.len() == 2 && isalpha(path[0]) && path[1] == ':')
{
path << SLASH;
fld.set(path);
}
if (fexist(path))
_curr_mask->autoload();
else
ok = fld.error_box("Specificare un percorso valido");
}
return ok;
}
void TInstaller_mask::install_selection()
{
TString_array& arr = rows_array();
FOR_EACH_ARRAY_ROW(arr, r, row) if (checked(r))
{
const TString modulo = row->get(2);
const TString newver = row->get(3);
const TString oldver = row->get(5);
if (version2year(newver) < 1997)
{
error_box("Il modulo '%s' non ha una versione valida.", (const char*)modulo);
continue;
}
bool ok = TRUE;
const int cmp = compare_version(oldver, newver);
if (cmp < 0)
ok = yesno_box("Si desidera installare la versione %s?", (const char*)newver);
if (cmp == 0)
ok = yesno_box("Si desidera reinstallare la versione %s?", (const char*)newver);
if (cmp > 0)
ok = yesno_box("Si desidera ritornare alla versione %s?\n"
"Attenzione: non e' garantito il corretto\n"
"funzionamento di tutti i programmi!", (const char*)oldver);
if (ok)
install(modulo);
}
}
bool TInstaller_mask::install_handler(TMask_field& fld, KEY key)
{
if (key == K_SPACE)
{
if (_curr_mask->items() == 1)
_curr_mask->check(0);
if (_curr_mask->one_checked())
_curr_mask->install_selection();
else
error_box("Selezionare uno piu' moduli da installare.");
}
return TRUE;
}
bool TInstaller_mask::on_key(KEY key)
{
bool ok = TRUE;
if (key == K_CTRL+'N')
autoload();
else
ok = TArray_sheet::on_key(key);
return ok;
}
TInstaller_mask::TInstaller_mask()
: TArray_sheet(0, 0, 0, 0, "Installazione",
"@1|Modulo@30|Cod.|Versione\nda installare@13|Data\nRilascio@10|Versione\nInstallata@10|Data\nInstallazione@13",
0x18, 3)
{
_curr_mask = this;
add_string(F_PATH, 0, "Percorso da cui installare ", 1, 1, 50);
add_string(F_CURPATH, 0, "Percorso in cui installare ", 1, 2, 50, "D");
add_button(F_INSTALL, "Installa", '\0'); // NON mettere 'I'
set_handler(F_PATH, path_handler);
set_handler(F_INSTALL, install_handler);
TDongle dongle; dongle.login(); dongle.logout();
_year_assist = dongle.year_assist();
TInstall_ini ini;
TFilename path = ini.get("DiskPath");
set(F_PATH, path);
const char lettera = toupper(path[0]);
const bool floppy = (path.len() > 1) && path[1] == ':' &&
GetDriveType(lettera - 'A') == DRIVE_REMOVABLE;
if (path.not_empty() && !floppy)
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:
virtual bool use_files() const { return FALSE; }
virtual void main_loop();
};
void TInstaller::main_loop()
{
TInstaller_mask m;
m.load();
m.run();
}
int ba1700(int argc, char* argv[])
{
TInstaller app;
app.run(argc, argv, "Installer");
return 0;
}