#include #include #include #include #include #include #include #include #include #include "ba2200.h" #include "ba2201.h" struct TAFile_info : public TObject { TFilename _name; long _size; int _disk; int _last_disk; }; /////////////////////////////////////////////////////////// // Archiving mask /////////////////////////////////////////////////////////// class TArchive_mask : public TAutomask { protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); public: TArchive_mask(); }; TArchive_mask::TArchive_mask() : TAutomask("ba2200") { TList_field& lf = (TList_field&)field(F_FLOPPY); TToken_string codes, values; TString4 str; int k = 0; for (int d = 0; d < 26; d++) { str.format("%c:/", d+'A'); const bool isrem = xvt_fsys_is_removable_drive(str) != 0; const bool isfix = !isrem && xvt_fsys_is_fixed_drive(str); if (isrem || isfix) { str.rtrim(1); // Togli slash finale codes.add(str); values.add(str); TToken_string& message = *lf.message(k++, TRUE); if (isrem) message.format("DISABLE,%d", F_PATH); else message.format("ENABLE,%d", F_PATH); } } lf.replace_items(codes, values); } bool TArchive_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case F_PATH: if (e == fe_modify) { TFilename path = o.get(); if (path[1] == ':') { set(F_FLOPPY, path.left(2)); o.set(path.mid(2)); } } break; case F_DITTA: if (e == fe_modify || e == fe_init) { set(F_RAGSOC, (o.get() != "") ? TR("Tutte le ditte") : TR("Nessuna ditta")); } break; case F_CODDITTA: if (e == fe_modify) { if (o.empty()) set(F_RAGSOC, o.active() ? TR("Tutte le ditte") : TR("Nessuna ditta")); } break; case F_SALVA: if (e == fe_button) { const long ditta = get_long(F_CODDITTA); if (ditta > 0L && !prefix().exist(ditta)) return error_box(FR("La ditta %ld non esiste"), ditta); } default: break; } return TRUE; } /////////////////////////////////////////////////////////// // Archiving application /////////////////////////////////////////////////////////// bool TArchive_app::create() { bool ok = TRUE; TIsamfile utenti(LF_USER); utenti.open(_excllock); for (int err = utenti.first(); err == NOERR; err = utenti.next()) { const TString16 u = utenti.get("USERNAME"); if (u != user() && utenti.get_bool("CONNECTED")) #ifdef DBG ok = yesno_box("L'archiviazione non puo' essere effettuata\nse ci sono altri utenti collegati (%s)", (const char*)u); #else ok = error_box(FR("L'archiviazione non puo' essere effettuata\nse ci sono altri utenti collegati (%s)"), (const char*)u); #endif } utenti.close(); if (ok) ok = TSkeleton_application::create(); return ok; } KEY TArchive_app::query(int& mode, long& firm, TFilename& floppy_path, TString& desc) const { TArchive_mask m; const KEY k = m.run(); if (k != K_QUIT) { mode = 0x0; firm = 0L; if (m.get_bool(F_COM)) mode |= 0x1; if (m.get_bool(F_DITTA)) { mode |= 0x2; firm = m.get_long(F_CODDITTA); } if (m.get_bool(F_CONFIG)) mode |= 0x4; if (m.get_bool(F_770)) mode |= 0x8; floppy_path.format("%c:%c", toupper(m.get(F_FLOPPY)[0]), SLASH); floppy_path.add(m.get(F_PATH)); desc = m.get(F_DESCR); } return k; } void TArchive_app::add_file(const TFilename& name) { TAFile_info* fi = new TAFile_info; fi->_name = name; fi->_size = fsize(name); fi->_disk = fi->_last_disk = 1; _zip_list.add(fi); } bool TArchive_app::split_file(const TFilename& archive, unsigned long max_chunk) { TFilename output(archive); output.ext("z00"); int disk = 0; unsigned long scritti = 0; FILE* i = fopen(archive, "rb"); if (i == NULL) return FALSE; FILE* o = fopen(output, "wb"); const int BUFSIZE = 1024*16; TString buf(BUFSIZE); char* buffer = buf.get_buffer(); bool ok = TRUE; while (ok) { const size_t letti = fread(buffer, 1, BUFSIZE, i); if (letti == 0) break; if (scritti >= max_chunk) { fclose(o); add_file(output); TString4 ext; ext.format("z%02d", ++disk); output.ext(ext); o = fopen(output, "wb"); scritti = 0; } ok = fwrite(buffer, letti, 1, o) > 0; scritti += letti; } fclose(i); fclose(o); add_file(output); return ok; } bool TArchive_app::zip_dir(const TFilename& name, unsigned long max_chunk) { TFilename tmp; tmp.tempdir(); tmp.add(name.name()); tmp.ext("zip"); TFilename filenames = name; filenames.add("*.*"); TString msg; msg << TR("Creazione del file temporaneo ") << tmp << "..."; TIndwin waitw(100,msg,FALSE,FALSE); TWait_cursor hourglass; bool ok = aga_zip(filenames, tmp); if (ok && tmp.exist()) { ok = split_file(tmp, max_chunk); remove(tmp); } return ok; } bool TArchive_app::can_save_as(const TFilename& src, const TFilename& dst) const { if (dst.exist()) remove(dst); long s = fsize(src); return xvt_fsys_test_disk_free_space(dst.left(3), s) != 0; } void TArchive_app::save_zip_files(const TFilename& floppy_path, const TString& desc, unsigned long max_chunk) { // Assegna un disco di destinazione a tutti i files int disk = 1; unsigned long written = 0; int i; for (i = 0; i < _zip_list.items(); i++) { TAFile_info& fi = (TAFile_info&)_zip_list[i]; if (written > 0 && (written+fi._size) >= max_chunk) { disk++; written = 0; } fi._disk = disk; written += fi._size; } bool ok = TRUE; if (xvt_fsys_is_removable_drive(floppy_path.left(3))) { const char* msg = TR("Si desidera procedere con l'operazione di salvataggio?"); if (disk == 1) ok = yesno_box(FR("Controllare che il primo disco sia nel drive %c:\n%s"), floppy_path[0], msg); else ok = yesno_box(FR("Preparare %d dischetti vuoti e controllare che il primo sia nel drive %c:\n%s"), disk, floppy_path[0], msg); if (!ok) return; } const TDate oggi(TODAY); TFilename name; name = floppy_path; name.add("backup.ini"); remove(name); TConfig ini(name, "Main"); ini.set("Date", oggi.string()); ini.set("Description", desc); ini.set("Disks", disk); ini.set("Format", "zip"); TFilename last_name; long size = 0; for (i = 0; i < _zip_list.items(); i++) { const TAFile_info& fi = (const TAFile_info&)_zip_list[i]; name = fi._name.name(); name.ext(""); if (name != last_name) { ini.set("FirstDisk", fi._disk, name); last_name = name; size = 0; } ini.set("LastDisk", fi._disk); ini.set("Size", size += fi._size); } ini.set_paragraph("Main"); // Forza scrittura ultimo paragrafo int curr_disk = 1; TProgind pi(_zip_list.items(), TR("Salvataggio dati in corso..."), FALSE, TRUE); for (i = 0; i < _zip_list.items(); i++) { pi.addstatus(1); const TAFile_info& fi = (const TAFile_info&)_zip_list[i]; if (fi._disk != curr_disk) message_box(FR("Inserire il disco vuoto n.%d"), curr_disk = fi._disk); TFilename dest; dest = floppy_path; dest.add(fi._name.name()); while(!can_save_as(fi._name, dest)) { if (!yesno_box(FR("Sul disco %d non c'e' spazio sufficiente per il file %s\nSi desidera sostituire il disco e ritentare?"), curr_disk, (const char*)dest)) return; } fcopy(fi._name, dest); remove(fi._name); } } void TArchive_app::backup(int mode, long firm, const TFilename& floppy_path, const TString& desc) { TPointer_array ditte; if (firm == 0) { TLocalisamfile nditte(LF_NDITTE); for (int err = nditte.first(); err == NOERR; err = nditte.next()) { const long f = nditte.get_long("CODDITTA"); ditte.add_long(f); } } else ditte.add_long(firm); const TString16 old = prefix().name(); prefix().set(NULL); // Libera tutti i lock long max_chunk = LONG_MAX; if (xvt_fsys_is_removable_drive(floppy_path)) { message_box(FR("Inserire un disco vuoto nel drive %c:"), floppy_path[0]); max_chunk = xvt_fsys_get_disk_size(floppy_path, 'B') - (1024L*64L); } _zip_list.destroy(); bool ok = TRUE; TFilename name; if (ok && (mode & 0x1)) { name = firm2dir(0); ok = zip_dir(name, max_chunk); } if (ok && (mode & 0x2)) { for (int i = 0; ok && i < ditte.items(); i++) { firm = ditte.get_long(i); if (prefix().exist(firm)) { name = firm2dir(firm); ok = zip_dir(name, max_chunk); } } } if (ok && (mode & 0x4)) { name = firm2dir(-1); // __ptprf name.add("config"); // Aggiungi configurazioni ok = zip_dir(name, max_chunk); } if (ok && (mode & 0x4)) { name = firm2dir(-1); // __ptprf name.add("custom"); // Aggiungi personalizzazioni if (name.exist()) ok = zip_dir(name, max_chunk); } if (ok && (mode & 0x8)) { name = firm2dir(-1); // __ptprf name.add("m770"); // Aggiungi 770 if (name.exist()) ok = zip_dir(name, max_chunk); } prefix().set(old); // Ripristina prefix if (ok) save_zip_files(floppy_path, desc, max_chunk); else error_box(TR("Si è verificato un errore di accesso al disco:\nVerificare lo spazio disponibile")); } bool TArchive_app::read_paragraph(TConfig& ini, const char* para) { const int first = ini.get_int("FirstDisk", para); const int last = ini.get_int("LastDisk"); const bool ok = first > 0 && last >= first; if (ok) { TFilename dir; dir.tempdir(); TString16 ext; int e = 0; for (int d = first; d <= last; d++) { TAFile_info* fi = new TAFile_info; TFilename& name = fi->_name; ext.format("z%02d", e++); name = dir; name.add(para); name.ext(ext); fi->_disk = d; fi->_last_disk = last; fi->_size = ini.get_int("Size"); _zip_list.add(fi); } } return ok; } void TArchive_app::load_zip_files(const TFilename& floppy_path) { TString msg; TFilename dir; dir.tempdir(); const int files = _zip_list.items(); TProgind pi(files, TR("Ripristino dati in corso..."), TRUE, TRUE); int curr_disk = 1; for (int i = 0; i < files; i++) { const TAFile_info& info = (const TAFile_info&)_zip_list[i]; const int& disk = info._disk; msg = TR("Ripristino "); msg << info._name.name() << TR(" in corso..."); pi.set_text(msg); pi.addstatus(1); if (pi.iscancelled()) break; if (xvt_fsys_is_removable_drive(floppy_path.left(3))) { if (disk != curr_disk) { message_box(FR("Inserire il disco %d del backup"), disk); curr_disk = disk; } } TFilename src; src = floppy_path; src.add(info._name.name()); TFilename dst; dst = dir; dst.add(info._name.name()); dst.ext("zip"); while (!fcopy(src, dst, TRUE)) if (!yesno_box(TR("Si desidera ritentare?"))) return; if (disk == info._last_disk) { TFilename exdir; exdir = firm2dir(-1); exdir.add(dst.name()); exdir.ext(""); aga_unzip(dst, exdir); } } } void TArchive_app::restore(int mode, long firm, const TFilename& floppy_path) { _zip_list.destroy(); TFilename name; name = floppy_path; name.add("backup.ini"); TConfig ini(name, "Main"); ini.write_protect(); if (mode & 0x1) read_paragraph(ini, "com"); if (mode & 0x2) { if (firm > 0) { TString16 para; para.format("%05lda", firm); read_paragraph(ini, para); } else { TString_array para; ini.list_paragraphs(para); for (int i = 0; i < para.items(); i++) { const TString& n = para.row(i); if (atol(n) > 0 && n.right(1) == "a") read_paragraph(ini, n); } } } if (mode & 0x4) { read_paragraph(ini, "config"); read_paragraph(ini, "custom"); } if (mode & 0x8) read_paragraph(ini, "m770"); const int tot = _zip_list.items(); if (tot > 0) { TString fola; fola = TR("Verranno ripristinati i seguenti archivi:\n"); for (int i = 0; i < tot; i++) { const TAFile_info& info = (const TAFile_info&)_zip_list[i]; if (info._disk == info._last_disk) { TFilename n = info._name.name(); n.ext(""); fola << n << ", "; } } fola.rtrim(2); fola << TR(".\nSi desidera continuare?"); if (yesno_box(fola)) { const TString16 old = prefix().name(); prefix().set(NULL); // Libera tutti i lock load_zip_files(floppy_path); // Scompatta i files prefix().set(old); // Ripristina prefix } } else warning_box(TR("I dati richiesti non sono presenti sul backup")); } void TArchive_app::interactive_mode() { KEY k; int mode; long firm; TFilename floppy_path; TString80 desc; while ((k = query(mode, firm, floppy_path, desc)) != K_QUIT) { if (mode) { if (k == K_SAVE) { backup(mode, firm, floppy_path, desc); } else { TFilename ini_name = floppy_path; ini_name.add("backup.ini"); if (xvt_fsys_is_removable_drive(floppy_path.left(3))) message_box(FR("Inserire il primo disco del backup nel drive %c"), floppy_path[0]); if (ini_name.exist()) restore(mode, firm, floppy_path); else error_box(FR("Impossibile trovare il file %s"), (const char*)ini_name); } } else error_box(TR("Non e' stato specificato nessun archivio")); } } void TArchive_app::batch_mode(const TString& cmd) { const int mode = ~0; const long firm = 0; const TFilename floppy_path = cmd; restore(mode, firm, floppy_path); } void TArchive_app::main_loop() { TString cmd; if (argc() > 2) { TFilename ini = argv(2); if (ini.compare("/i", 2, TRUE) == 0) // qui { ini.ltrim(2); TConfig cfg(ini, "Main"); cmd = cfg.get("Action"); if (cmd.compare("Restore ", 8, TRUE) == 0) //qui { cmd.ltrim(8); cmd.trim(); } else cmd.cut(0); } else { if (ini.exist()) cmd = ini; } } if (cmd.empty()) { TMailbox mail; TMessage* msg = mail.next_s("RESTORE"); if (msg == NULL) { mail.restart(); msg = mail.next_s("Restore"); } if (msg) cmd = msg->body(); } if (cmd.empty()) interactive_mode(); else batch_mode(cmd); } int ba2200(int argc, char* argv[]) { TArchive_app a; a.run(argc, argv, TR("Archiviazione")); return 0; }