campo-sirio/ba/ba1600.cpp
guy b88a586759 Patch level : 2.0 nopatch
Files correlati     :
Ricompilazione Demo : [ ]
Commento            :

Eliminate tutte le vecchie chiamate ad os_dep.h


git-svn-id: svn://10.65.10.50/trunk@11025 c028cbd2-c16b-5b4b-a496-9718f37d4682
2003-04-17 08:54:31 +00:00

2246 lines
61 KiB
C++
Executable File
Raw Blame History

#include <sys/stat.h>
#include <agasys.h>
#include <applicat.h>
#include <defmask.h>
#include <dongle.h>
#include <execp.h>
#include <files.h>
#include <golem.h>
#include <lffiles.h>
#include <msksheet.h>
#include <prefix.h>
#include <progind.h>
#include <text.h>
#include <sheet.h>
#include <utility.h>
#include <text.h>
#include "ba1.h"
#include "ba1600.h"
#include "ba1600a.h"
int find(const TString& name, TString_array & rows) ;
///////////////////////////////////////////////////////////
// Configurazione per installazione
///////////////////////////////////////////////////////////
class TFascicolator_mask;
class TCreazione_dischi : public TSkeleton_application
{
protected:
TFascicolator_mask* _mask;
virtual bool use_files() const { return FALSE; }
virtual void main_loop();
public:
virtual bool modify_mode() { return FALSE; }
TFascicolator_mask& mask() const { return *_mask; }
};
class TFascicolator : public TCreazione_dischi
{
protected:
// virtual bool use_files() const { return TRUE; }
virtual void main_loop();
public:
virtual bool modify_mode() { return TRUE;}
};
inline TCreazione_dischi& app() { return (TCreazione_dischi&)main_app(); }
class TFconv_ini : public TConfig
{
public:
void export_module(const char* module, const char* summary);
TFconv_ini(const char* path = "fconv.ini") : TConfig(path) { }
virtual ~TFconv_ini() { }
};
// costruisce la lista del modulo e dei suoi sottomoduli interni
// vengono creati solo i sottomoduli che contengono almeno
// una variabile di tipo File
int TInstall_ini::build_list(const TString& module, TString_array& a,
const char* sommario, bool agg)
{
CHECKS(module.len() >= 2 || module[0]=='_', "Bad module ", (const char*)module);
TConfig* sum = NULL;
if (sommario && *sommario)
sum = new TConfig(sommario, module);
TAssoc_array vars;
TAuto_token_string tmp;
TString paragraph;
for (int sub = 0; sub <= 9; sub++)
{
paragraph = module;
if (module[2] == '\0') // Ho specificato un modulo principale
paragraph << sub;
bool reset_par=TRUE;
vars.destroy();
TAssoc_array& varlist = list_variables(paragraph);
FOR_EACH_ASSOC_STRING(varlist, obj, key, str)
{
const bool is_file = strncmp(key, "File", 4) == 0;
tmp = str; // Nome e aggiornamento
// Quando creo il disco di aggiornamento salto tutti i file
// che non hanno il flag di aggiornamento settato
if (agg && is_file && tmp.get_char(1) != 'X')
continue;
if (sum)
{
if (!is_file && reset_par)
vars.add(key,tmp);
else
{
if (reset_par)
{
reset_par=FALSE;
sum->set_paragraph(paragraph);
sum->remove_all();
FOR_EACH_ASSOC_STRING(vars, obj, key, str)
sum->set(key, str);
}
sum->set(key, tmp);
}
}
if (is_file)
{
tmp.add(paragraph, 2); // Sottomodulo
tmp.lower();
a.add(tmp);
}
}
if (module[2] != '\0')
break;
}
if (sum)
delete sum;
return a.items();
}
int TInstall_ini::build_complete_list(const TString& module, TString_array& a,
const char* sommario, bool agg)
{
if (sommario && *sommario)
{
TConfig sum(sommario, "Main");
sum.set("Demo", demo() ? "X" : "");
}
// Lista dei file appartenenti ai sottomoduli del modulo principale (0-9)
build_list(module, a, sommario, agg);
TString_array b; //array locale temporaneo contenente la lista dei files da uccidere
build_kill_list(module, b, sommario, agg);
TAuto_token_string altri(get("Moduli", module));
FOR_EACH_TOKEN(altri, mod)
{
const TString16 submodule = mod;
// Lista dei files appartenenti ai sottomoduli esterni (moduli esclusi!)
if (submodule.len() > 2)
build_list(submodule, a, sommario, agg);
}
return a.items();
}
// costruisce la lista di programmi di gestione del modulo
int TInstall_ini::build_app_list(const TString& module, TString_array& a)
{
TString paragraph;
TToken_string row;
for (int sub = 0; sub <= 9; sub++)
{
paragraph = module;
if (module[2] == '\0') // Ho specificato un modulo principale
paragraph << sub;
TAssoc_array& varlist = list_variables(paragraph);
FOR_EACH_ASSOC_STRING(varlist, obj, key, str)
{
int num;
if (sscanf(key, "Edit_%d", &num) == 1)
{
row = "Edit";
row.add(num);
row.add(str);
a.add(row);
}
}
if (module[2] != '\0')
break;
}
return a.items();
}
//crea x ogni modulo il sottomodulo 10 con i files da accoppare
int TInstall_ini::build_kill_list(const TString& module, TString_array& a,
const char* sommario, bool agg)
{
CHECKS(module.len() >= 2, "Bad module ", (const char*)module);
TString paragraph;
paragraph << module << 99;
TConfig* sum = NULL;
if (sommario && *sommario)
sum = new TConfig(sommario, paragraph); //va nei sottomoduli 99
TAuto_token_string tmp;
TAssoc_array& varlist = list_variables(paragraph);
FOR_EACH_ASSOC_STRING(varlist, obj, key, str)
{
const bool is_kill = strncmp(key, "Kill", 4) == 0;
// Quando creo il disco di aggiornamento prendo solo i file che devono essere uccisi
if (is_kill)
{
tmp = str; // Nome e aggiornamento
if (agg && tmp.get_char(1) <= ' ') //non e' selezionato
continue;
if (sum)
sum->set(key, tmp);
tmp.lower();
a.add(tmp);
}
}
if (sum)
delete sum;
return a.items();
}
void TInstall_ini::export_paragraph(const char* module, const char* summary,const bool remove_old)
{
CHECK(module && *module > ' ', "Can't export NULL module");
CHECK(summary && *summary > ' ', "Can't export to NULL .ini");
TInstall_ini sum(summary, module);
TString_array old_list;
int last_file_num=0;
const bool is_submodule=(module[2]!='\0');
const int submodule=(module[2]-'0');
char main_module[3]={0,0,0};
strncpy(main_module, module,2);
if (remove_old || !is_submodule )
{
// substitute...
sum.remove_all();
}
else
{
// merge...
sum.build_list(main_module, old_list);
sum.set_paragraph(module);
last_file_num=old_list.items();
}
TAssoc_array& ass = list_variables(module);
TString newkey,tmps;
TToken_string item_value;
TString ;
FOR_EACH_ASSOC_STRING(ass, obj, key, str)
{
if (!remove_old && is_submodule && strncmp(key, "File", 4)==0 )
{
// merging "File(X)" items...
item_value=str;
tmps=item_value.get(0);
int item_number=find(tmps, old_list);
if (item_number>=0)
{
// file sostituito
TString old_smodule(old_list.row(item_number).get(2));
TAssoc_array& oldvars = sum.list_variables(old_smodule);
THash_object* obj;
TToken_string oldvalue;
oldvars.restart();
do
{
obj=oldvars.get_hashobj();
oldvalue=((TString &)obj->obj());
if (tmps == oldvalue.get(0))
break;
}
while (obj);
newkey=obj->key();
if (old_smodule!=module)
{
// devo cancellare il file dal vecchio sottomodulo
sum.set_paragraph(old_smodule);
sum.remove(newkey);
sum.set_paragraph(module);
}
}
else
{
// nuovo file
newkey = "File";
newkey << '(' << last_file_num++ << ')';
}
sum.set(newkey, str);
}
else
{
sum.set(key, str);
}
}
}
void TInstall_ini::export_module_paragraphs(const char* module, const char* summary, const bool remove_old)
{
// esporta le info di composizione del modulo
TString mod;
for (int sub = -1; sub <= 9; sub++)
{
mod = module;
if (sub >= 0) mod << sub;
if (set_paragraph(mod))
export_paragraph(mod, summary,remove_old);
}
// esporta la lista di eventuali files da eliminare (sono i killed)
mod = module;
mod << 99;
if (set_paragraph(mod))
export_paragraph(mod, summary,remove_old);
if (remove_old)
{
// esporta le info di conversione
TFilename path;
TInstall_ini inst(summary);
if (inst.name()==inst.default_name())
{
path = inst.name().path();
path.add(module); path << "fconv.ini";
TFconv_ini fconv(path);
fconv.export_module(module, "fconv.ini");
}
else
{
TFconv_ini fconv; //
path = inst.name().path();
path.add(module); path << "fconv.ini";
fconv.export_module(module, path);
}
}
}
const TString& TInstall_ini::version(const char* module)
{
CHECK(module && *module > ' ', "Can't get version of NULL module");
const TString& ver = get("Versione", module);
if (ver.empty() && strlen(module) > 2)
{
TString16 str;
str.strncpy(module, 2);
return get("Versione", str);
}
return ver;
}
int TInstall_ini::patch(const char* module)
{
CHECK(module && *module > ' ', "Can't get version of NULL module");
int patch = get_int("Patch", module);
if (patch == 0 && strlen(module) > 2)
{
TString16 str;
str.strncpy(module, 2);
patch = get_int("Patch", str);
}
return patch;
}
void TInstall_ini::version_info(const char* module,int& year, int& release,int& tag, int& patchlevel)
{
TString ver = version(module);
if (ver[0] == '9')
ver.insert("19", 0);
year = atoi(ver.left(4));
if (year == 0)
app().get_version_info(year, release, tag, patchlevel);
else
{
release = atoi(ver.mid(4,2));
if (release == 0)
release++;
tag = atoi(ver.mid(6,2));
patchlevel = patch(module);
}
}
bool TInstall_ini::update_prices(const char* from)
{
CHECK(fexist(from), "Can't find listino prezzi");
TConfig from_ini(from);
from_ini.write_protect();
const TDate curr_date(get("Listino","Main"));
const TDate from_date(from_ini.get("Listino","Main"));
if (from_date < curr_date)
return FALSE;
set("Listino", from_date);
TString_array modules;
from_ini.list_paragraphs(modules);
FOR_EACH_ARRAY_ROW_BACK(modules, r, row) if (row->len() == 2)
{
TAssoc_array& prices = from_ini.list_variables(*row);
set_paragraph(*row);
FOR_EACH_ASSOC_STRING(prices, obj, key, str)
{
const TFixed_string price(key);
if (price.compare("Prezzo", 6, TRUE) == 0)
set(key, str);
}
}
return TRUE;
}
void TInstall_ini::prices(const char* module, word users, real& full, real& assist, bool correct_ass)
{
real last_pac, last_ass;
full = assist = 0.0;
for (word u = 1; u <= users; u++)
{
TAuto_token_string prezzi = get("Prezzo", module, int(u));
if (prezzi.not_empty())
{
last_pac = prezzi.get(0);
if (last_pac < 50000.0)
last_pac *= 1000.0;
last_ass = prezzi.get();
if (last_ass < 50000.0)
last_ass *= 1000.0;
const int mese = TDate(TODAY).month();
last_ass = last_ass * (correct_ass ? (12-mese) / 12 : 1);
last_ass.round(-3);
}
full += last_pac;
assist += last_ass;
}
}
///////////////////////////////////////////////////////////
// TFconv_ini
///////////////////////////////////////////////////////////
void TFconv_ini::export_module(const char* module, const char* summary)
{
TScanner scanner(AUT_FILE);
int module_code;
for (module_code = 0; scanner.line().not_empty(); module_code++)
{
if (scanner.token().compare(module, 2, TRUE) == 0)
break;
}
scanner.close();
TConfig sommario(summary);
TString_array paragraphs;
list_paragraphs(paragraphs);
paragraphs.sort();
FOR_EACH_ARRAY_ROW(paragraphs, p, para)
{
TAssoc_array& variables = list_variables(*para);
FOR_EACH_ASSOC_STRING(variables, obj, key, str)
{
const char* parenthesis = strchr(key, '(');
if (parenthesis)
{
const int logic_num = atoi(parenthesis+1);
if (logic_num > 0)
{
TDir dirinfo; dirinfo.get(logic_num);
const long flags = dirinfo.flags() % 10000;
if (flags == module_code)
sommario.set(key, str, module);
}
}
}
}
}
///////////////////////////////////////////////////////////
// Maschera composizione del modulo
///////////////////////////////////////////////////////////
class TMod_composition_msk : public TMask
{
protected:
static bool sheet_notify(TSheet_field& sf, int row, KEY key);
static bool missing_notify(TSheet_field& sf, int row, KEY key);
bool kill_missing(const char* name, bool update);
static bool link_handler(TMask_field& f, KEY k);
static bool kill_notify(TSheet_field& sf, int row, KEY key); //metodo per la gestione della lista dei files da eliminare effettivamente
static bool obsolete_notify(TSheet_field& sf, int row, KEY key); //metodo x riempire la lista dei files che si consiglia di eliminare
bool kill_obsolete(const char* name, bool update); //metodi x eliminare i files dalla lista dei consigliati quando si aggiungono
static bool obs_handler(TMask_field& f, KEY k); //alla lista definitiva di eliminazione
static bool file_handler(TMask_field& f, KEY k);
static bool edit_handler(TMask_field& f, KEY k);
static bool deselect_handler(TMask_field& f, KEY k);
static bool isam_handler(TMask_field& f, KEY k);
static bool kill_handler(TMask_field& f, KEY k);
public:
void load(const TString& module);
void save();
TMod_composition_msk(const bool modify_mode=FALSE);
virtual ~TMod_composition_msk() { }
};
// Toglie il file dallo sheet dei mancanti
bool TMod_composition_msk::kill_missing(const char* name, bool update)
{
TSheet_field& miss = sfield(F_MISSING);
FOR_EACH_SHEET_ROW_BACK(miss, r, row)
{
if (row->compare(name, -1, TRUE) == 0)
{
miss.destroy(r, update);
break;
}
}
return r >= 0;
}
// Toglie il file dallo sheet degli ELIMINABILI
bool TMod_composition_msk::kill_obsolete(const char* name, bool update)
{
TSheet_field& obs = sfield(F_OBSOLETE);
FOR_EACH_SHEET_ROW_BACK(obs, r, row)
{
if (row->compare(name, -1, TRUE) == 0)
{
obs.destroy(r, update);
break;
}
}
return r >= 0;
}
bool TMod_composition_msk::sheet_notify(TSheet_field& sf, int r, KEY key)
{
bool ok = TRUE;
switch(key)
{
case K_TAB:
// Posso cancellare solo le righe abilitate
sf.sheet_mask().enable(DLG_DELREC, !sf.cell_disabled(r, 1));
break;
case K_ENTER:
{
TFilename mask = sf.row(r).get(0);
if (mask.find('*') >= 0 || mask.find('?') >= 0)
{
TString_array arr; list_files(mask, arr);
const int items = arr.items();
if (items > 0)
{
TMod_composition_msk& msk = (TMod_composition_msk&)sf.mask();
TString_array & rows=msk.sfield(F_SHEET).rows_array();
TString16 module = sf.row(r).get(2);
if (module.len() < 3)
module << msk.get(F_MODULE) << '1';
TFilename start;
DIRECTORY dir; xvt_fsys_get_dir(&dir);
xvt_fsys_convert_dir_to_str(&dir, start.get_buffer(), start.size());
const int maxlen = start.len();
bool found = FALSE;
for (int i = 0; i < items; i++)
{
TString& file = arr.row(i);
if (file.compare(start, maxlen, TRUE) == 0)
file.ltrim(maxlen+1);
file.lower();
msk.kill_missing(file, FALSE);
if (::find(file,rows)>=0)
{
TToken_string& row = sf.row(found ? -1 : r);
row = file;
row.add(" ");
row.add(module);
found = TRUE;
}
}
// Se ne ho trovato almeno uno valido allora updato
if (found)
{
sf.force_update();
TSheet_field& miss = msk.sfield(F_MISSING);
miss.force_update();
}
}
else
ok = sf.error_box(FR("Nessun file corrisponde a %s"), mask.get_buffer());
}
}
break;
case K_DEL:
ok = !sf.cell_disabled(r, 1);
if (ok)
{
// Sposto la riga cancellata nello sheet a fianco
TSheet_field& miss = sf.mask().sfield(F_MISSING);
miss.row(-1) = sf.row(r).get(0);
miss.force_update();
}
break;
case K_CTRL+K_INS:
{
// Propongo il sottomodulo automaticamente in inserimento
TString16 module;
module << sf.mask().get(F_MODULE) << '1';
TToken_string& row = sf.row(r);
row.add(module, 2);
}
break;
default:
break;
}
return ok;
}
//metodo per la gestione dello sheet con la lista dei files da ELIMINARE effettivamente
bool TMod_composition_msk::kill_notify(TSheet_field& sf, int r, KEY key)
{
bool ok = TRUE;
switch(key)
{
case K_TAB:
// Posso cancellare solo le righe abilitate
sf.sheet_mask().enable(DLG_DELREC, !sf.cell_disabled(r, 1));
break;
case K_ENTER:
{
TFilename mask = sf.row(r).get(0);
if (mask.find('*') >= 0 || mask.find('?') >= 0)
{
TString_array arr; list_files(mask, arr);
const int items = arr.items();
if (items > 0)
{
TMod_composition_msk& msk = (TMod_composition_msk&)sf.mask();
TString_array & rows=msk.sfield(F_KILL).rows_array();
TFilename start;
DIRECTORY dir; xvt_fsys_get_dir(&dir);
xvt_fsys_convert_dir_to_str(&dir, start.get_buffer(), start.size());
const int maxlen = start.len();
bool found = FALSE;
for (int i = 0; i < items; i++)
{
TString& file = arr.row(i);
if (file.compare(start, maxlen, TRUE) == 0)
file.ltrim(maxlen+1);
file.lower();
msk.kill_obsolete(file, FALSE);
if (::find(file,rows)>=0)
{
TToken_string& row = sf.row(found ? -1 : r);
row = file;
row.add(" ");
found = TRUE;
}
}
// Se ne ho trovato almeno uno valido allora updato
if (found)
{
sf.force_update();
TSheet_field& miss = msk.sfield(F_OBSOLETE);
miss.force_update();
}
}
else
ok = sf.error_box("Nessun file corrisponde a %s", mask.get_buffer());
}
}
break;
case K_DEL:
ok = !sf.cell_disabled(r, 1);
if (ok)
{
// Sposto la riga cancellata nello sheet a fianco
TSheet_field& miss = sf.mask().sfield(F_OBSOLETE);
miss.row(-1) = sf.row(r).get(0);
miss.force_update();
}
break;
default:
break;
}
return ok;
}
bool TMod_composition_msk::missing_notify(TSheet_field& sf, int r, KEY key)
{
bool ok = TRUE;
if (key == K_INS)
{
// Sposto tutte le righe nello spreadsheet a fianco
TMask& mainmask = sf.mask();
TSheet_field& sheet = mainmask.sfield(F_SHEET);
FOR_EACH_SHEET_ROW(sf, idx, riga)
{
TToken_string& newrow = sheet.row(-1);
newrow = *riga;
TString16 submod = newrow.left(2);
submod << '1';
newrow.add(submod, 2);
}
sf.destroy();
sf.force_update();
sheet.force_update();
ok = FALSE;
}
return ok;
}
bool TMod_composition_msk::file_handler(TMask_field& f, KEY k)
{
if (k == K_F9)
{
TFilename start;
DIRECTORY dir; xvt_fsys_get_dir(&dir);
xvt_fsys_convert_dir_to_str(&dir, start.get_buffer(), start.size());
FILE_SPEC fs;
xvt_fsys_get_dir(&fs.dir);
strcpy(fs.type, "");
strcpy(fs.name, "*.*");
strcpy(fs.creator, "SETUP");
FL_STATUS ok = xvt_dm_post_file_open(&fs, TR("Selezionare il file ..."));
xvt_fsys_set_dir(&dir);
if (ok == FL_OK)
{
TFilename file;
xvt_fsys_convert_dir_to_str(&fs.dir, file.get_buffer(), file.size());
const int maxlen = start.len();
if (file.compare(start, maxlen, TRUE) == 0)
{
file.ltrim(maxlen+1);
file.add(fs.name);
file.ext(fs.type);
f.set(file);
k = K_TAB;
}
else
{
return f.error_box(FR("Il file deve trovarsi nel percorso %s"),
start.get_buffer());
}
}
}
if (k = K_TAB && f.focusdirty())
{
TMod_composition_msk& msk = (TMod_composition_msk&)f.mask().get_sheet()->mask();
msk.kill_missing(f.get(), TRUE);
}
return TRUE;
}
bool TMod_composition_msk::kill_handler(TMask_field& f, KEY k)
{
if (k = K_TAB && f.focusdirty())
{
TMod_composition_msk& msk = (TMod_composition_msk&)f.mask().get_sheet()->mask();
msk.kill_obsolete(f.get(), TRUE);
}
return TRUE;
}
bool TMod_composition_msk::edit_handler(TMask_field& f, KEY k)
{
if (k == K_SPACE)
{
TFilename file = f.mask().get(101);
if (stricmp(file.ext(), "exe") == 0)
{
file << " -0";
TExternal_app app(file);
app.run();
}
else
::edit_url(file);
}
return TRUE;
}
bool TMod_composition_msk::link_handler(TMask_field& f, KEY k)
{
if (k == K_SPACE)
{
TMask& modmask = f.mask();
TSheet_field* sf = modmask.get_sheet();
TMask& mainmask = sf->mask();
TSheet_field& sheet = mainmask.sfield(F_SHEET);
TToken_string& newrow = sheet.row(-1);
newrow = modmask.get(101); // Nome del file
newrow.add(" "); // Non e' nell'aggiornamento
newrow.add(mainmask.get(F_MODULE)); // Modulo attuale
newrow << '1'; // Sottomodulo standard
if (modmask.is_running())
{
modmask.stop_run(K_ESC);
do_events();
}
sf->destroy(sf->selected());
sheet.force_update();
sf->force_update();
}
return TRUE;
}
static int obsolete_found(TConfig& cfg, void* jolly)
{
TAssoc_array& list = cfg.list_variables();
TString_array& files = *(TString_array*)jolly; //castato jolly a TString_array; sono i files su disco
FOR_EACH_ASSOC_STRING(list, hash, key, string)
{
if (strncmp(key, "File(", 5) == 0)
{
int pos = files.find(string);
if (pos >=0)
files.destroy(pos, TRUE); //se trova il file sia su disco che nell'ini -> lo toglie dall'elenco su disco
}
}
return 0;
}
// metodo per riempire lo sheet dei file che si CONSIGLIA di eliminare
bool TMod_composition_msk::obsolete_notify(TSheet_field& sf, int r, KEY key)
{
if (key == K_INS) //la compilazione dello sheet avviene solo quando si preme il pulsante +
{
TWait_cursor hourglass;
TString_array& elenco_dir = sf.rows_array(); //string_array che conterra' i files della directory
elenco_dir.destroy(); //resetta l'elenco dei files della directory
list_files("*.*", elenco_dir); //legge tutti i files della dir corrente e li mette in elenco_dir
FOR_EACH_ARRAY_ROW(elenco_dir,i,row) //mette in minuscolo tutti i nomi di files su disco
row->lower();
//e' il file install.ini
TInstall_ini ini;
ini.for_each_paragraph(obsolete_found, &elenco_dir); //per ogni paragrafo dell'install.ini chiama la obsolete_found
sf.force_update(); //aggiornamento dello sheet (di sinistra) sulla maschera
}
return TRUE;
}
//spostamento oggetti da sheet obsoleti a sheet con files da eliminare (sulla mask e' da destra a sinistra)
bool TMod_composition_msk::obs_handler(TMask_field& f, KEY k)
{
if (k == K_SPACE)
{
TMask& modmask = f.mask(); //maschera di riga dello sheet
TSheet_field* sf = modmask.get_sheet();
TMask& mainmask = sf->mask();
TSheet_field& sheet = mainmask.sfield(F_KILL); //sheet sinistro della maschera di Eliminazione
TToken_string& newrow = sheet.row(-1); //aggiunge una riga allo sheet...
newrow = modmask.get(101); //..e ci mette il nome del file
if (modmask.is_running())
{
modmask.stop_run(K_ESC);
do_events();
}
sf->destroy(sf->selected());
sheet.force_update(); //update dello sheet sinistro della maschera di eliminazione (files condannati)
sf->force_update();
}
return TRUE;
}
bool TMod_composition_msk::deselect_handler(TMask_field& f, KEY k)
{
if (k == K_SPACE)
{
TSheet_field& sheet = f.mask().sfield(F_SHEET);
FOR_EACH_SHEET_ROW_BACK(sheet, r, row)
row->add(" ", 1);
sheet.force_update();
}
return TRUE;
}
bool TMod_composition_msk::isam_handler(TMask_field& f, KEY k)
{
if (k == K_F9)
{
TMask& m = f.mask();
TArray_sheet sht(-1,-1,-4,-4,TR("Selezione archivio"), HR("Codice@6R|Descrizione archivio@70"));
const TPrefix& pref = prefix();
const int total = pref.items();
if (total > 0)
{
TWait_cursor hourglass;
for (int i = LF_USER; i < total; i++)
{
TToken_string* row = new TToken_string;
*row << i;
row->add(pref.description(*row));
sht.rows_array().add(row);
}
sht.select(m.get_int(f.dlg()) - LF_USER);
}
if (sht.run() == K_ENTER)
m.set(f.dlg(), sht.selected() + LF_USER);
}
return TRUE;
}
static int file_compare(const TObject** o1, const TObject** o2)
{
TToken_string* r1 = (TToken_string*)*o1;
TToken_string* r2 = (TToken_string*)*o2;
int cmp = stricmp(r1->get(-2), r2->get(-2));
if (cmp == 0)
cmp = stricmp(*r1, *r2);
return cmp;
}
void TMod_composition_msk::load(const TString& module)
{
TWait_cursor hourglass;
set(F_MODULE, module);
TInstall_ini ini; //install.ini
TSheet_field& s = sfield(F_SHEET); //legge da install.ini la lista dei files del modulo
ini.build_list(module, s.rows_array());
s.rows_array().TArray::sort(file_compare);
TSheet_field& p = sfield(F_PROGRAMS); //la lista dei programmi tipo quelli x l'editing
ini.build_app_list(module, p.rows_array());
TFilename mask;
mask << module << "*.*";
TSheet_field& miss = sfield(F_MISSING);
TString_array& arr = miss.rows_array();
list_files(mask, arr);
TSheet_field& kill = sfield(F_KILL); //legge da install.ini la lista dei files da uccidere
ini.build_kill_list(module, kill.rows_array());
const char* bad_ext[] = { "bsc", "mak", "obj", "pdb", "rc",
"res", "sbr", "vcw", "wsp", NULL };
FOR_EACH_ARRAY_ROW_BACK(arr, index, row)
{
mask = *row;
mask.lower();
const TString16 ext = mask.ext();
bool ok = TRUE;
for (int e = 0; bad_ext[e]; e++)
{
if (ext == bad_ext[e])
{
ok = FALSE;
break;
}
}
if (ok)
{
FOR_EACH_SHEET_ROW_BACK(s, i, row)
{
if (mask.compare(row->get(0), -1, TRUE) == 0)
break;
}
ok = i < 0;
}
if (ok)
arr.row(index) = mask;
else
arr.destroy(index);
}
arr.sort();
}
void TMod_composition_msk::save()
{
TWait_cursor hourglass;
TSheet_field& sheet = sfield(F_SHEET);
TInstall_ini ini;
int index;
const TString module = get(F_MODULE);
const TString version = ini.version(module);
const long patch = ini.patch(module);
for (index = 0; index <= 9; index++)
{
TString16 sub; sub << module << index;
if (ini.set_paragraph(sub))
ini.remove_all();
}
TToken_string tmp;
index = 0;
FOR_EACH_SHEET_ROW(sheet, r, row)
{
TString16 sub = row->get(2);
if (sub.blank())
sub << module << '1';
else
{
if (isdigit(sub[0]) && sub[1]=='\0')
{
sub.insert(module, 0);
sub.cut(3);
}
}
if (sub.left(2) == module)
{
tmp = row->get(0); // Nome del file
const bool agg = row->get_char() > ' ';
if (agg) tmp.add("X"); // Flag aggiornamento
ini.set("File", tmp, sub, TRUE, index++);
ini.set("Versione", version); // Aggiorna versione del sottomodulo
ini.set("Patch", patch);
}
}
TSheet_field& sp = sfield(F_PROGRAMS);
FOR_EACH_SHEET_ROW(sp, pr, prow)
{
TString16 var = prow->get(0);
var << '_' << prow->get(1);
TFilename n(prow->get(2));
const int spc = n.find(' ');
if (spc >= 0) n.cut(spc);
n.ext("exe");
TString16 sub = module;
FOR_EACH_SHEET_ROW(sheet, sr, srow)
{
if (n == srow->get(0))
{
sub = srow->get(2);
break;
}
}
n = prow->get(2);
ini.set(var, n, sub);
}
TSheet_field& kp = sfield(F_KILL);
TString16 sub = module;
sub << 99;
FOR_EACH_SHEET_ROW(kp, kr, krow)
{
ini.set("Kill", *krow, sub, TRUE, kr);
}
}
TMod_composition_msk::TMod_composition_msk(const bool modify_mode)
: TMask("ba1600b")
{
TSheet_field& s = sfield(F_SHEET);
TSheet_field& miss = sfield(F_MISSING);
TSheet_field& prog = sfield(F_PROGRAMS);
TSheet_field& kill = sfield(F_KILL);
TSheet_field& obs = sfield(F_OBSOLETE);
set_handler(F_DESELECT, deselect_handler);
if (modify_mode)
{
s.set_notify(sheet_notify);
s.sheet_mask().set_handler(S_FILE, file_handler);
s.sheet_mask().set_handler(DLG_EDIT, edit_handler);
miss.disable(); // Read-only sheet
miss.set_notify(missing_notify);
miss.sheet_mask().set_handler(100, link_handler);
prog.sheet_mask().set_handler(102, isam_handler);
obs.set_notify(obsolete_notify);
obs.sheet_mask().set_handler(100, obs_handler);
kill.set_notify(kill_notify);
kill.sheet_mask().set_handler(101, kill_handler);
}
else
{
s.disable(); // Read-only sheet
miss.hide();
disable_page(1);
}
}
///////////////////////////////////////////////////////////
// Maschera del modulo
///////////////////////////////////////////////////////////
class TModule_mask : public TMask
{
bool _dirty_composition;
bool module_dependent(int row, TString_array &p_submodules, TString &sub_mod, TString &ver, int & patch) const ;
public:
bool list_is_dirty() const { return _dirty_composition;}
void dirty_composition(bool val = TRUE) { _dirty_composition = val; }
bool check_patchlevels(TMod_composition_msk &mm);
virtual ~TModule_mask() {}
};
///////////////////////////////////////////////////////////
// Maschera principale
///////////////////////////////////////////////////////////
class TCreadischi_mask : public TMask
{
protected:
static bool list_handler(TMask_field& f, KEY k);
static bool confirm_handler(TMask_field& f, KEY k);
static bool creazip_handler(TMask_field& f, KEY k);
static bool testpatch_handler(TMask_field& f, KEY k);
static bool why_handler(TMask_field& f, KEY k);
static bool modules_notify(TSheet_field& f, int row, KEY k);
static bool import_export_handler(TMask_field& f, KEY k);
static bool patchl_handler(TMask_field& f, KEY k);
virtual const TFilename& build_export_path(TFilename& path) const;
virtual bool zip_file(const char* archive, const char* file) const;
virtual int split_file(const TFilename& file, size_t size) const;
virtual bool move_file(const TFilename& file, const char* dir) const;
virtual bool zip_module(const TString& module, bool agg, int patch_level) const;
virtual bool set_version_info(const TFilename& filename,
TInstall_ini& ini, const char* module) const;
virtual bool show_all_modules() {return FALSE;}
public:
virtual void save();
virtual void load();
TCreadischi_mask();
virtual ~TCreadischi_mask() { }
};
class TFascicolator_mask : public TCreadischi_mask
{
long find_signature(const TFilename& filename, const char* signature) const;
protected:
static bool list_handler(TMask_field& f, KEY k);
static bool confirm_handler(TMask_field& f, KEY k);
static bool creazip_handler(TMask_field& f, KEY k);
static bool patchl_handler(TMask_field& f, KEY k);
// fuinzioni per la "firma" del file con il numero di release
virtual bool set_version_info(const TFilename& filename,
TInstall_ini& ini, const char* module) const;
virtual bool show_all_modules() {return TRUE;}
public:
virtual void save();
TFascicolator_mask();
virtual ~TFascicolator_mask() { }
};
bool TCreadischi_mask::modules_notify(TSheet_field& f, int row, KEY k)
{
bool ok = TRUE;
if (k == K_INS || k == K_DEL)
ok = FALSE;
if (k == K_TAB)
{
TModule_mask &mm =(TModule_mask &)f.sheet_mask();
mm.dirty_composition(FALSE);
}
return ok;
}
// controlla se il modulo in curr_row dipende da uno dei sottomoduli nell'array p_submodules
// e ne restituisce :
//TString16 &sub_mod, : il codice del (primo) sottomodulo da cui dipende
//TString16 &ver, : la propria versione
//int & patch : la propria patchlevel
bool TModule_mask::module_dependent(int rownum, TString_array &p_submodules, TString &sub_mod, TString &ver, int & patch) const
{
TSheet_field& modsheet = get_sheet()->mask().sfield(F_SHEET);
TToken_string& curr_row=modsheet.row(rownum);
TAuto_token_string ext_mod=curr_row.get(modsheet.cid2index(S_EXTERN));
const int smods = ext_mod.blank() ? 0 : ext_mod.items() ;
for (int c=0; c < smods; c++)
{
// is an external SUB module ?
sub_mod = ext_mod.get(c);
if (sub_mod[2]!='\0' )
{
// check patched submodules
const int pmods = p_submodules.items();
for (int p=0; p < pmods; p++)
{
if (p_submodules.row(p) == sub_mod)
{
ver=curr_row.get(modsheet.cid2index(S_VERSION));
patch=atoi(curr_row.get(modsheet.cid2index(S_PATCHLEVEL)));
return TRUE;
}
} // loop over patched modules
}
} // loop over external modules
return FALSE;
}
bool TModule_mask::check_patchlevels( TMod_composition_msk &mm)
{
const TString& module = get(S_MODULE);
const TString& version =get(S_VERSION);
const int patchlev = get_int(S_PATCHLEVEL);
// crea la lista dei sottomoduli
TSheet_field& sf = mm.sfield(F_SHEET);
TString_array patched_submodules,submodules;
FOR_EACH_SHEET_ROW(sf, idx, riga)
{
TToken_string& curr_row=sf.row(idx);
TString16 submod = curr_row.get(2);
if (*curr_row.get(1)>' ')
{
if (patched_submodules.find(submod)<0)
patched_submodules.add(submod);
} else {
if (submodules.find(submod)<0)
submodules.add(submod);
}
}
// cerca i moduli che includono i sottomoduli patchati
bool need_update(FALSE);
TString16 sub_mod, sub_ver;
int sub_patch;
TSheet_field& modsheet = get_sheet()->mask().sfield(F_SHEET);
FOR_EACH_SHEET_ROW(modsheet, midx, mriga)
{
TToken_string& curr_row=modsheet.row(midx);
TString16 mod_code(curr_row.get(modsheet.cid2index(S_MODULE)));
if (module_dependent(midx,patched_submodules, sub_mod, sub_ver, sub_patch))
{
if (version == sub_ver)
{
if ( patchlev > sub_patch
&& yesno_box(FR("Il modulo '%s' dipende dal sottomodulo '%s'.\n Aggiorno il suo numero di patch a %d ?"),(const char *)mod_code,(const char *)sub_mod,patchlev))
{
curr_row.add(patchlev , modsheet.cid2index(S_PATCHLEVEL));
curr_row.add(get(S_DATE) , modsheet.cid2index(S_DATE));
need_update=TRUE;
}
} else
if (!sub_ver.blank())
warning_box(FR("Il modulo '%s', dipendente dal sottomodulo '%s' \nha codice di release %s"),
(const char *)mod_code, (const char *)sub_mod,(const char *)sub_ver);
}
else if (module_dependent(midx,submodules, sub_mod, sub_ver, sub_patch))
{
if (version == sub_ver)
{
if ( patchlev > sub_patch
&& noyes_box(FR("Il modulo '%s' dipende da sottomoduli del modulo '%s'.\n Aggiorno il suo numero di patch a %d ?"),(const char *)mod_code,(const char *)module,patchlev))
{
curr_row.add(patchlev , modsheet.cid2index(S_PATCHLEVEL));
curr_row.add(get(S_DATE) , modsheet.cid2index(S_DATE));
need_update=TRUE;
}
} else
if (!sub_ver.blank())
warning_box(FR("Il modulo '%s', dipendente da sottomoduli del modulo '%s'\nha codice di release %s"),
(const char *)mod_code, (const char *)sub_mod,(const char *)sub_ver);
}
}
if (need_update)
modsheet.force_update();
return TRUE;
}
bool TFascicolator_mask::patchl_handler(TMask_field& f, KEY k)
{
if (k == K_TAB && f.focusdirty())
{
// TModule_mask& m = (TModule_mask&)f.mask();
// m.dirty_composition();
}
return TRUE;
}
bool TCreadischi_mask::list_handler(TMask_field& f, KEY k)
{
if (k == K_SPACE)
{
TModule_mask& m = (TModule_mask&)f.mask();
const TString& module = m.get(S_MODULE);
if (module.not_empty())
{
TMod_composition_msk mm;
mm.load(module);
if (mm.run() == K_ENTER)
mm.save();
}
}
return TRUE;
}
bool TFascicolator_mask::list_handler(TMask_field& f, KEY k)
{
if (k == K_SPACE)
{
TModule_mask& m = (TModule_mask&)f.mask();
const TString& module = m.get(S_MODULE);
if (module.not_empty())
{
TMod_composition_msk mm(TRUE);
mm.load(module);
if (mm.run() == K_ENTER)
{
// Salvo nel .ini
mm.save();
m.dirty_composition();
}
}
}
return TRUE;
}
bool TCreadischi_mask::confirm_handler(TMask_field& f, KEY k)
{
return TRUE;
}
bool TFascicolator_mask::confirm_handler(TMask_field& f, KEY k)
{
if (k == K_SPACE)
{
TModule_mask& m = (TModule_mask& )f.mask();
const TString& module = m.get(S_MODULE);
const patchlevel=m.get_int(S_PATCHLEVEL);
const bool dirty_module= m.field(S_DATE).dirty() ||
m.field(S_PREPROCESS).dirty() ||
m.field(S_POSTPROCESS).dirty() ||
m.field(S_EXTERN).dirty();
const bool dirty_version= m.field(S_VERSION).dirty() ||
m.field(S_PATCHLEVEL).dirty();
if (dirty_version || dirty_module)
{
TIndwin infobar(60,TR("Salvataggio composizione modulo"),FALSE,FALSE);
TInstall_ini ini;
ini.set_paragraph(module);
ini.set("Versione", m.get(S_VERSION));
ini.set("Patch", patchlevel);
ini.set("Data", m.get(S_DATE));
ini.set("Moduli", m.get(S_EXTERN));
ini.set("PreProcess", m.get(S_PREPROCESS));
ini.set("PostProcess", m.get(S_POSTPROCESS));
// sottomoduli
if (dirty_version)
{
TString16 submodule=module;
submodule<<'0';
for (int i=0; i <=9; i++)
{
submodule[2]='0'+i;
if (ini.set_paragraph(submodule))
{
ini.set("Versione", m.get(S_VERSION));
ini.set("Patch", m.get(S_PATCHLEVEL));
}
}
}
}
if (patchlevel>0 && (m.list_is_dirty() || dirty_version))
{
// controlla le consistenze tra patch di moduli diversi intrinsecamente correlati
TIndwin infobar(60,TR("Controllo dipendenze tra sottomoduli"),FALSE,FALSE);
TMod_composition_msk mc;
mc.load(module);
m.check_patchlevels(mc);
}
}
return TRUE;
}
bool TFascicolator_mask::creazip_handler(TMask_field& f, KEY k)
{
if (k == K_SPACE)
{
TMask& m = f.mask();
TMask_field& fconfirm= m.field(DLG_OK);
confirm_handler(fconfirm, K_SPACE);
TCreadischi_mask::creazip_handler(f,k);
}
return TRUE;
}
bool TCreadischi_mask::creazip_handler(TMask_field& f, KEY k)
{
if (k == K_SPACE)
{
TMask& m = f.mask();
const TString& module = m.get(S_MODULE);
const bool agg = f.dlg() == S_CREATEPATCH;
TCreadischi_mask& fm = (TCreadischi_mask&)m.get_sheet()->mask();
if (fm.zip_module(module, agg, m.get_int(S_PATCHLEVEL)))
{
// creazione XXfconv.ini (esporta le info di conversione )
TFilename fconv_path;
TFconv_ini fconv; //
fconv_path = fm.get(F_DISKPATH);
fconv_path.add(module); fconv_path << "fconv.ini";
fconv.export_module(module, fconv_path);
}
}
return TRUE;
}
bool TCreadischi_mask::why_handler(TMask_field& f, KEY k)
{
if (k != K_SPACE)
return TRUE;
TArray_sheet& main_sheet = (TArray_sheet&)f.mask();
const TFilename stopfile = main_sheet.row(main_sheet.selected()).get(1);
TString16 module = stopfile.name(); module.cut(2);
TFilename path = app().mask().get(F_DISKPATH);
path.add(module); path << "????a.ini";
TString_array inifiles;
list_files(path, inifiles);
inifiles.sort();
TProgind pi(inifiles.items(), TR("Scansione archivi successivi..."), FALSE, TRUE);
TString caption; caption << TR("File eliminabili da ") << stopfile.name();
TArray_sheet sheet(3, 3, -3, -3, caption, HR("Modulo|File@20|Ultima Patch@50"));
TAssoc_array files;
TString_array para;
TToken_string tok;
FOR_EACH_ARRAY_ROW_BACK(inifiles, numf, filename)
{
pi.addstatus(1);
const bool is_last = stopfile == *filename;
TConfig ini(*filename);
ini.list_paragraphs(para);
FOR_EACH_ARRAY_ROW_BACK(para, nump, paraname) if (paraname->len() == 3)
{
ini.set_paragraph(*paraname);
TAssoc_array& vars = ini.list_variables();
FOR_EACH_ASSOC_STRING(vars, obj, key, str)
{
if (strncmp(key, "File(", 5) == 0)
{
tok = str;
const int pipe = tok.find('|');
if (pipe > 0) tok.cut(pipe);
tok.lower();
if (is_last)
{
const TString* nextpatch = (const TString*)files.objptr(tok);
TToken_string row;
row = *paraname;
row.add(tok);
if (nextpatch)
row.add(*nextpatch);
else
row.add(TR("*** Nessuna ***")); // Should never happen!
sheet.add(row);
}
else
{
if (!files.is_key(tok))
files.add(tok, *filename);
}
}
}
}
if (is_last) break;
}
sheet.run();
return FALSE;
}
bool TCreadischi_mask::testpatch_handler(TMask_field& f, KEY k)
{
if (k != K_SPACE)
return TRUE;
TMask& m = f.mask();
const TString& module = m.get(S_MODULE);
TFilename path = app().mask().get(F_DISKPATH);
path.add(module); path << "????a.ini";
TArray_sheet sheet(3, 3, -3, -3, TR("File eliminabili"), HR("@1|Percorso assoluto@70"));
sheet.add_button(DLG_USER+1, "Dettagli", 'D');
sheet.set_handler(DLG_USER+1, why_handler);
TString_array& inifiles = sheet.rows_array();
list_files(path, inifiles);
inifiles.sort();
if (inifiles.items() > 0)
{
TProgind pi(inifiles.items(), TR("Scansione archivi..."), FALSE, TRUE);
TAssoc_array files;
TString_array para;
TToken_string tok;
FOR_EACH_ARRAY_ROW_BACK(inifiles, numf, filename)
{
pi.addstatus(1);
bool can_be_deleted = TRUE;
TConfig ini(*filename, module);
ini.list_paragraphs(para);
FOR_EACH_ARRAY_ROW_BACK(para, nump, paraname) if (paraname->len() == 3)
{
ini.set_paragraph(*paraname);
TAssoc_array& vars = ini.list_variables();
FOR_EACH_ASSOC_STRING(vars, obj, key, str)
{
if (strncmp(key, "File(", 5) == 0)
{
tok = str;
const int pipe = tok.find('|');
if (pipe > 0) tok.cut(pipe);
tok.lower();
if (!files.is_key(tok))
{
files.add(tok);
can_be_deleted = FALSE;
}
}
}
}
if (can_be_deleted)
filename->insert(" |", 0);
else
inifiles.destroy(numf, TRUE);
}
}
if (inifiles.items() == 0)
return message_box(TR("Non e' stato rilevato nessun file eliminabile"));
if (sheet.run() == K_ENTER)
{
const long tot = sheet.checked();
if (tot > 0 && yesno_box(FR("Confermare la cancellazione di %ld file"), tot))
{
TWait_cursor hourglass;
for (long i = sheet.items()-1; i >= 0; i--) if (sheet.checked(i))
{
for (int d = 1; d <= 9; d++)
{
TFilename name = sheet.row(i).get(1);
name.ext(""); name << d << ".zip";
if (::remove(name) != 0)
{
if (d == 1)
error_box(FR("Errore di cancellazione del file %s"), (const char*)name);
break;
}
}
}
}
}
return TRUE;
}
bool TCreadischi_mask::import_export_handler(TMask_field& f, KEY k)
{
if (k == K_SPACE)
{
const bool is_export = f.dlg() == S_EXPORT;
const TMask& m = f.mask();
const TString& module = m.get(S_MODULE);
const TCreadischi_mask& fm = (const TCreadischi_mask&)m.get_sheet()->mask();
TFilename path = module;
fm.build_export_path(path);
FILE_SPEC fs;
xvt_fsys_convert_str_to_dir(path.get_buffer(), &fs.dir);
path.add(module); path << "inst.ini"; path.lower();
strcpy(fs.type, "ini");
strcpy(fs.name, path.name());
strcpy(fs.creator, "INST");
bool ok;
DIRECTORY dir;
xvt_fsys_get_dir(&dir); // Salva directory corrente (Non usare la bacata xvt_fsys_save_dir)
if (is_export)
ok = xvt_dm_post_file_save(&fs, TR("Esporta il modulo in:")) == FL_OK;
else
ok = xvt_dm_post_file_open(&fs, TR("Importa il modulo da:")) == FL_OK;
xvt_fsys_set_dir(&dir); // Ripristina directory corrente
if (ok)
{
path = fs.dir.path;
path.add(fs.name);
if (is_export)
{
TInstall_ini inst;
inst.export_module_paragraphs(module, path, TRUE);
}
else
{
TInstall_ini ini(path);
ini.export_module_paragraphs(module, ini.default_name(), TRUE);
}
}
}
return TRUE;
}
const TFilename& TCreadischi_mask::build_export_path(TFilename& path) const
{
CHECK(path.not_empty(), "Please, specify the module");
const TString module(path);
path.cut(0);
path << SLASH << "src" << SLASH << module;
if (!path.exist())
{
path.cut(0);
path << SLASH << 'u' << SLASH << user() << SLASH << "src" << SLASH << module;
if (!path.exist())
{
path.cut(0);
path << SLASH << 'u' << SLASH << user() << SLASH << "p.due" << SLASH << module;
if (!path.exist())
path.tempdir();
}
}
path.lower();
return path;
}
void TCreadischi_mask::load()
{
TWait_cursor hourglass;
TSheet_field& s = sfield(F_SHEET);
TString tmp;
TString_array modules;
TInstall_ini ini;
ini.list_paragraphs(modules);
set(F_DISKSIZE, ini.get("DiskSize"));
set(F_DISKPATH, ini.get("DiskPath"));
FOR_EACH_ARRAY_ROW(modules, m, riga)
{
const TString& module = *riga;
ini.set_paragraph(module);
tmp = ini.get("Versione");
if (module[0] == '_' || // linea di descrizione area
(module.len() == 2 && // linea di modulo principale
(!tmp.blank() || show_all_modules())))
{
TToken_string& row = s.row(-1);
row = ini.get("Descrizione");
if (module[0] == '_')
{
s.disable_cell(s.items()-1, -1);
}
else
{
row.add(module);
tmp = ini.get("Versione");
row.add(tmp); // versione
tmp = ini.get("Patch");
row.add(tmp);
tmp = ini.get("Data");
row.add(tmp);
tmp = ini.get("Moduli");
row.add(tmp);
tmp = ini.get("PreProcess");
row.add(tmp);
tmp = ini.get("PostProcess");
row.add(tmp);
}
}
}
}
void TCreadischi_mask::save()
{
TInstall_ini ini;
ini.set("DiskSize", get(F_DISKSIZE));
ini.set("DiskPath", get(F_DISKPATH));
}
void TFascicolator_mask::save()
{
TSheet_field& s = sfield(F_SHEET);
TCreadischi_mask::save();
TProgind pi(s.items(), TR("Salvataggio in corso..."), FALSE, TRUE);
TInstall_ini ini;
TString tmp;
FOR_EACH_SHEET_ROW_BACK(s, r, row)
{
pi.addstatus(1);
tmp = row->get(1);
if (tmp.not_empty() && tmp != "xx")
{
ini.set_paragraph(tmp);
tmp = row->get(0);
ini.set("Descrizione", tmp);
tmp = row->get(2);
ini.set("Versione", tmp);
tmp = row->get();
ini.set("Patch", tmp);
tmp = row->get();
ini.set("Data", tmp);
tmp = row->get();
ini.set("Moduli", tmp);
tmp = row->get();
ini.set("PreProcess", tmp);
tmp = row->get();
ini.set("PostProcess", tmp);
}
}
}
bool TCreadischi_mask::zip_file(const char* archive, const char* listfile) const
{
TString msg;
msg << TR("Creazione del file compresso ") << archive << "...";
TIndwin waitw(100,msg,FALSE,FALSE);
TWait_cursor hourglass;
return aga_zip_filelist(listfile, archive);
}
bool TCreadischi_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)
{
space_ok = xvt_fsys_test_disk_free_space(dest, filesize) != 0;
if (!space_ok)
{
TString msg(128);
msg << TR("Lo spazio sull'unita' e' insufficiente");
if (xvt_fsys_is_removable_drive(dest))
{
msg << TR(":\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(FR("Errore di copia del file %s.\nSi desidera riprovare?"),
(const char*)file))
user_abort = TRUE;
}
} while (!write_ok && !user_abort);
return write_ok;
}
// Dato il file Pippo.zip lo splitta in Pippo1.zip, Pippo2.zip, Pippo?.zip
int TCreadischi_mask::split_file(const TFilename& archive, size_t chunk_size) const
{
int disks = 1;
const size_t tot_size = ::fsize(archive);
if (chunk_size > 0 && chunk_size < tot_size)
{
TFilename sommario(archive);
sommario.ext("ini");
chunk_size -= ::fsize(sommario);
const long minsize = 720*1024L;
if (chunk_size < minsize)
chunk_size = minsize;
FILE* inf = fopen(archive, "rb");
if (inf == NULL)
return 0;
TString msg; msg << TR("Separazione del file ") << archive << "...";
TProgind pi(tot_size, msg, FALSE, TRUE);
byte* buff = new byte[chunk_size];
for (int d = 1; ; d++)
{
const size_t r = fread(buff, 1, chunk_size, inf);
pi.addstatus(r);
if (r > 0)
{
TFilename chunk(archive);
chunk.ext(""); chunk << d; chunk.ext("zip");
FILE* ouf = fopen(chunk, "wb");
fwrite(buff, r, 1, ouf);
fclose(ouf);
disks = d;
}
else
break;
}
delete buff;
fclose(inf);
::remove(archive);
}
else
{
TFilename archive1(archive);
archive1.ext("");
archive1 << '1';
archive1.ext("zip");
::rename(archive,archive1);
}
return disks;
}
long TFascicolator_mask::find_signature(const TFilename& filename, const char* signature) const
{
bool found = FALSE;
long position = -1;
int compare = 0;
ifstream infile(filename, ios::nocreate | ios::in | ios::binary);
for (int car = infile.get(); car != EOF; car = infile.get())
{
if (car == signature[compare])
{
if (compare == 0)
position = infile.tellg()-1;
compare++;
if (signature[compare] == '\0')
{
found = TRUE;
break;
}
}
else
{
if (compare > 0)
infile.seekg(position+1, ios::beg);
compare = 0;
}
}
return found ? position : -1;
}
bool TCreadischi_mask::set_version_info(const TFilename& filename,
TInstall_ini& ini, const char* module) const
{
return TRUE;
}
bool TFascicolator_mask::set_version_info(const TFilename& filename,
TInstall_ini& ini, const char* module) const
{
bool ok = FALSE;
TString80 str = "Don't cry for me "; str << "Argentina.";
long position = find_signature(filename, str);
if (position > 0)
{
fstream outfile(filename, ios::in | ios::out | ios::nocreate | ios::binary);
position += str.len();
outfile.seekp(position);
if (outfile.good())
{
int year, release, tag, patch, checksum;
ini.version_info(module, year, release, tag, patch);
checksum = year + release + tag + patch;
str.format("%04d.%02d.%02d.%03d.%04d", year, release, tag, patch, checksum);
TString oldfirm("XXXX.XX.XX.XXX.XXXX");
outfile.read(oldfirm.get_buffer(),19);
if (oldfirm!=str)
{
outfile.seekp(position);
outfile.write(str, str.len());
}
ok = outfile.good() != 0;
if (!ok)
error_box("Error writing signature in %s error n. %d", (const char *) filename, errno);
}
}
return ok;
}
bool TCreadischi_mask::zip_module(const TString& main_module, bool agg, int patch_level) const
{
TString_array arr;
TInstall_ini ini;
TFilename sommario; sommario.tempdir();
sommario.add(main_module);
if (agg)
{
if (patch_level <= 0)
return error_box(TR("Il numero di patch deve essere superiore a zero"));
TString16 name;
name.format("%04da.ini", patch_level);
sommario << name; // Nome del file sommario aggiornamento
}
else
sommario << "inst.ini"; // Nome del file sommario completo
ini.build_complete_list(main_module, arr, sommario, agg);
if (arr.items() == 0)
{
::remove(sommario);
return error_box(TR("Nessun file da compattare"));
}
const TFilename path = get(F_DISKPATH);
// *****************
// creazione ZIP
TFilename archivio(sommario);
archivio.ext("zip"); // Nome del file archivio completo
bool aborted = FALSE;
// ******************
// compilazione lista e relativa firma dei files
TString msg;
if (path.blank())
msg << TR("Controllo dei file per ") << archivio << " ...";
else
msg << TR("Preparazione dei file per ") << archivio << " ...";
TFilename filelist;
filelist.temp("", main_module);
struct _stat info;
long lasttime=0;
// blocco della prima Progind
{
ofstream fileh(filelist);
TProgind pi(arr.items(), msg, TRUE, TRUE);
TFilename cmd;
FOR_EACH_ARRAY_ROW_BACK(arr, i, row)
{
pi.addstatus(1);
if (pi.iscancelled())
{
aborted = TRUE;
break;
}
cmd = row->get(0);
if (cmd.exist())
{
// Aggiungo il nome corrente alla lista dei files da compattare
fileh << cmd << '\n';
if (stricmp(cmd.ext(), "exe") == 0)
{
TString16 submod = row->get(2);
submod.cut(2);
set_version_info(cmd, ini, submod);
}
_stat((const char *)cmd,&info);
lasttime = max(lasttime,info.st_mtime);
}
else
{
// Se non trovo anche uno solo dei files nella lista, <20> un casino
TString msg(128);
msg << TR("Impossibile aprire il file ") << cmd << TR(". Interrompere?");
if (yesno_box(msg))
{
aborted = TRUE;
break;
}
}
}
fileh.close();
}
// Se non specifico un path ho gia' finito
if (path.blank())
{
message_box(TR("Nessun percorso specificato. Il pacchetto non verra' creato"));
return FALSE;
}
TFilename zipfile = path;
zipfile.add(archivio.name());
zipfile.ext("");
zipfile << '1';
zipfile.ext("zip");
if (zipfile.exist())
{
_stat((const char *)zipfile,&info);
if (lasttime <= info.st_mtime)
{
aborted = !yesno_box(FR("Il file %s risulta gi<67> aggiornato.\nSi desidera rigenerarlo comunque?"),(const char *)zipfile);
}
if (!aborted && !agg)
{
// main zip updated; are there some patches?
TFilename patchfile = zipfile.path();
TString16 modpatch;
modpatch.format("%s%04da.ini",(const char *)main_module,patch_level);
patchfile.add(modpatch);
if (patchfile.exist())
{
_stat((const char *)patchfile,&info);
if (lasttime <= info.st_mtime)
aborted = !yesno_box(FR("Il file di patch %s \nrisulta gi<67> aggiornato.\nSi desidera procedere comunque alla generazione di %s ?"),(const char *)patchfile,(const char *)zipfile);
}
}
}
if (aborted)
{
::remove(sommario);
::remove(filelist); // elimina il file lista-file
return TRUE;
}
zip_file(archivio, filelist); // Compatto gli eventuali ultimi rimasti
::remove(filelist); // elimina il file lista-file
const size_t size = get_long(F_DISKSIZE) * 1024;
const int disks = split_file(archivio, size);
// Memorizza il numero dei dischetti nel sommario
ini.set("Dischi", disks, main_module); // Aggiorna install.ini
ini.export_paragraph(main_module, sommario,TRUE); // Aggiorna sommario
const char drive = toupper(path[0]);
const bool floppy = xvt_fsys_is_removable_drive(path) != 0;
msg = TR("Creazione file "); msg << archivio;
TProgind pi(disks, msg, FALSE, TRUE);
for (int d = 1; d <= disks && !aborted; d++)
{
if (floppy)
message_box(TR("Inserire il disco %d di %d nell'unita':"), d, disks);
// Costruisco il nome del file da copiare su dischetto
TFilename src(archivio);
src.ext("");
src << d;
src.ext("zip");
msg.cut(0);
msg << TR("Generazione del disco ") << d << "/" << disks
<< TR(" del modulo ") << main_module << " ...";
pi.set_text(msg);
pi.addstatus(1);
do_events();
bool ok = TRUE;
if (d == 1)
ok = move_file(sommario, path);
if (ok)
ok = move_file(src, path);
aborted = !ok || pi.iscancelled();
}
// scrive il sommario completo
if (!agg && size==0)
{
archivio = path;
archivio.add("install.ini");
fcopy("install.ini",(const char *)archivio);
}
return TRUE;
}
TCreadischi_mask::TCreadischi_mask()
: TMask("ba1600a")
{
TSheet_field& s = sfield(F_SHEET);
s.set_notify(modules_notify);
TMask& m = s.sheet_mask();
m.set_handler(DLG_OK, confirm_handler);
m.set_handler(S_LIST, list_handler);
m.set_handler(S_CREATEZIP, creazip_handler);
m.set_handler(S_CREATEPATCH, creazip_handler);
m.set_handler(S_TESTPATCH, testpatch_handler);
m.hide(S_IMPORT);
m.set_handler(S_EXPORT, import_export_handler);
s.disable();
}
TFascicolator_mask::TFascicolator_mask()
: TCreadischi_mask()
{
TSheet_field& s = sfield(F_SHEET);
s.set_notify(TCreadischi_mask::modules_notify);
TMask& m = s.sheet_mask();
m.set_handler(DLG_OK, confirm_handler);
m.set_handler(S_LIST, list_handler);
m.set_handler(S_CREATEZIP, creazip_handler);
m.set_handler(S_CREATEPATCH, creazip_handler);
m.set_handler(S_PATCHLEVEL, patchl_handler);
m.show(S_IMPORT);
m.set_handler(S_IMPORT, import_export_handler);
s.enable(TRUE);
s.enable_column(S_MODULE,TRUE);
s.enable_column(S_VERSION,TRUE);
s.enable_column(S_PATCHLEVEL,TRUE);
s.enable_column(S_EXTERN,TRUE);
s.enable_column(S_PREPROCESS,TRUE);
s.enable_column(S_POSTPROCESS,TRUE);
}
///////////////////////////////////////////////////////////
// Programma principale
///////////////////////////////////////////////////////////
void TFascicolator::main_loop()
{
_mask = new TFascicolator_mask;
_mask->load();
int key;
do
{
key = _mask->run();
if (key == K_ENTER)
_mask->save();
}
while (key != K_ENTER && key != K_QUIT);
delete _mask; _mask = NULL;
}
void TCreazione_dischi::main_loop()
{
TCreadischi_mask m;
m.load();
int key;
do
{
key=m.run();
if (key == K_ENTER)
m.save();
}
while (key != K_ENTER && key != K_QUIT);
}
// Cerca un file nell'array di colonne e ne restituisce il numero del sottomodulo
// -1 se
int find(const TString& name, TString_array & rows)
{
for(int r=rows.items()-1; r >=0 ; r-- )
{
if (name.compare(rows.row(r).get(0), -1, TRUE) == 0)
break;
}
return r;
}
int ba1600(int argc, char* argv[])
{
if (user() == ::dongle().administrator())
{
if (argc>2 && strcmp(argv[1],"GODMODE"))
{
TFascicolator app;
app.run(argc, argv, "Megascicolator");
}
else
{
TCreazione_dischi app;
app.run(argc, argv, TR("Creazione dischetti"));
}
}
else
error_box(FR("L'utente %s non e' abilitato all'esecuzione di questo programma"), (const char*)user());
return 0;
}