#include #include #include #include #include #include #include #include #include #include #include #include #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 has_module(int modnumber) const; bool is_zip_file(const TFilename& n) const; void create_dirs(const char* path) 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); 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; // 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 Enterprise Edition ad occhi indiscreti const bool ee = ini.get_bool("Ee"); if (ee && !dongle().active(EEAUT)) 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::has_module(int modnumber) const { //se sei un server hai tutti i moduli da installare if (station_type() == 2) return true; //senno' sei sfigato e ti installa solo i moduli sulla chiave return main_app().has_module(modnumber, CHK_DONGLE); } //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& array = rows_array(); FOR_EACH_ARRAY_ROW(array, 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 && has_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 sui client 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 < array.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(); { TIndwin contacting(60,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) { 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 è 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 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.blank()) { 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) { 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 < 2007) return error_box(FR("Il modulo '%s' non ha una versione valida."), module); #ifndef _DEMO_ if (year > dongle().year_assist()) { if (!update_assistance_year()) return false; } #endif 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(), "dninst.zip") != 0; return yes; } void TInstaller_mask::create_dirs(const char* path) const { TToken_string dirs(path, SLASH); if (SLASH == '\\') dirs.replace('/', SLASH); else dirs.replace('\\', SLASH); // file contains non existent subdir specification ? TFilename subdir; for (int c=0; c < dirs.items()-1; c++) { subdir.add(dirs.get(c)); if (subdir.right(1) == ":" ) subdir << SLASH; if (!subdir.exist() ) // build destination directory make_dir(subdir); } } // 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 << '_'; } if (!dest.exist()) create_dirs(dest.path()); 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 = ::fcopy(src, dest); if (write_ok && is_zip) aga_unzip(src, dest.path()); if (write_ok) ::remove(src); 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) ::remove(src); } 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") 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()); create_dirs(dst); fcopy(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à"), 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ù 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) { if (fexist(*file)) ::remove_file(*file); killed.add(*file); } } else { if (fexist(filetokill)) ::remove_file(filetokill); 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 è una patch (es. ba0883a.ini) o se è 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 è 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ò 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 ::remove(totti); // 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 << '_'; } if (!dst.exist()) create_dirs(dst.path()); ok = ::fcopy(src, dst); if (ok && is_zip_file(src)) aga_unzip(src, dst.path()); if (ok && reboot != NONE) _reboot_program |= reboot; 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); 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.compare("http://", 7, true) == 0) 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à 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; 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!!!! } } update_disk_and_web_path(); //aggiorna l'install.ini //lancia setup in modalita' aggiornamento da disco _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è NON deve poter cambiare il reseller (solo via disco sarà.. //..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 è valida!\nSelezionarne una valida e premere 'Invio'.")); enable(F_PATH, ko); } add_string(F_CURPATH, 0, PR("Installa in "), 1, 3, 80, "D", 58); 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 è 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; }