#include #include #include #include #include #include #include #include #include #include #include #include /////////////////////////////////////////////////////////// // TArchive /////////////////////////////////////////////////////////// int TArchive::build_backup_list(int mode, long firm, TString_array& fl) const { fl.destroy(); if (mode & 0x1) fl.add(firm2dir(0L)); if (mode & 0x2) { if (firm <= 0L) { TLocalisamfile ditte(LF_NDITTE); for (int err = ditte.first(); err == NOERR; err = ditte.next()) { const char* dir = firm2dir(ditte.get_long("CODDITTA")); if (fexist(dir)) fl.add(dir); } } else fl.add(firm2dir(firm)); } if (mode & 0x4) { TFilename name(firm2dir(-1)); // __ptprf name.add("config"); // Aggiungi configurazioni if (name.exist()) fl.add(name); } if (mode & 0x8) { TFilename name(firm2dir(-1)); // __ptprf name.add("M770"); // Aggiungi 770 if (fexist(name)) fl.add(name); } return fl.items(); } // @doc EXTERNAL // @mfunc Costruisce la lista delle directory da scompattare // // @rdesc Ritorna il numero di cartelle da ripristinare int TArchive::build_restore_list( int& mode, long firm, // @parm Ditta di cui effettuare il salvataggio char floppy, // @parm Floppy su cui effettuare il backup TString_array& fl) const // @parm Nomi dell cartelle da ripristinare { fl.destroy(); if (!yesno_box("Inserire il dischetto nel drive %c e continuare?\n" "(Rispondere NO se si desidera interrompere la procedura)", floppy)) return -1; TFilename name("a:/backup.ini"); name[0] = floppy; TConfig ini(name); TString_array pl; const int max = ini.list_paragraphs(pl); // Lista degli archivi for (int i = 0; i < max; i++) { const TString& name = pl.row(i); const int disk = ini.get_int("Disk", name); if (disk == 1) { if (atol(name) > 0L) { if (mode & 0x2) { const long frm = atol(name); if (firm <= 0L || firm == frm) fl.add(firm2dir(frm)); // Aggiungi gli archivi della ditta if (firm > 0L) mode &= ~0x2; } } else { if (name.compare("com", -1, TRUE) == 0) { if (mode & 0x1) mode &= ~0x1; else continue; } if (name.compare("config", -1, TRUE) == 0) { if (mode & 0x4) mode &= ~0x4; else continue; } if (name.compare("m770", -1, TRUE) == 0) { if (mode & 0x8) mode &= ~0x8; else continue; } TFilename fn(firm2dir(-1)); // __ptprf fn.add(name); fl.add(fn); } } } return fl.items(); } // @doc EXTERNAL // @mfunc Scrive il file backup.ini sul drive indicato // // @rdesc Ritorna se e' riuscito a scrivere il file bool TArchive::write_ini(TFilename& work, int disk, long tot, const char* desc, char floppy) const { TFilename parag(work.name()); parag.ext(""); TFilename ini("a:/backup.ini"); ini[0] = floppy; bool ok = TRUE; if (fexist(ini)) { TConfig c(ini, parag); const int d = c.get_int("Disk"); if (d == disk) { ok = yesno_box("Il disco %d contiene gia' un backup della cartella %s del %s" "\nSi desidera continuare?", disk, (const char*)parag, (const char*)c.get("Date")); } } else { FILE* i = fopen(ini, "w"); // Crea il file backup.ini per evitare messaggi fclose(i); } if (ok) { TConfig c(ini, parag); const char* oggi = TDate(TODAY).string(); c.set("Size", tot , NULL, TRUE); c.set("Disk", disk, NULL, TRUE); c.set("Description", desc, NULL, TRUE); c.set("Date", oggi, NULL, TRUE); } return ok; } bool TArchive::move_file(const TFilename& file, const char* dir) const { TFilename dest(dir); dest.add(file.name()); long filesize = ::fsize(file); filesize -= ::fsize(dest); bool space_ok = filesize <= 0; while (!space_ok) { space_ok = ::os_test_disk_free_space(dest, filesize); if (!space_ok) { TString msg(128); msg << "Lo spazio sull'unita' e' insufficiente:\n"; if (::os_is_removable_drive(dest)) msg << "Inserire un nuovo disco e ritentare?"; else msg << "Liberare dello spazio e ritentare?"; if (!yesno_box(msg)) return FALSE; } } bool write_ok = TRUE; bool user_abort = FALSE; do { write_ok = ::fcopy(file, dest); if (write_ok) ::remove(file); else { if (!yesno_box("Errore di copia del file %s.\nSi desidera riprovare?", (const char*)file)) user_abort = TRUE; } } while (!write_ok && !user_abort); return write_ok; } bool TArchive::split_file(const TFilename& archive, unsigned long max_chunk) const { 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); TString16 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); return ok; } bool TArchive::fsplit_zip( const char* filename, // @parm Nome del file da spezzare char floppy, // @parm Floppy su cui scaricare il file const char* desc) const // @parm Descrizione dell'archivio { const TFilename archive(filename); unsigned long size = 0; TFilename path; path << floppy << ':'; while (size <= 0) { message_box("Inserire il disco 1 nel drive %c:", floppy); size = os_get_disk_size(path) - (64L*1024L); if (size <= 0) { if (!yesno_box("Errore di accesso al drive %c\nSi desidera ritentare?", floppy)) return FALSE; } do_events(); } const long minsize = 360*1024L; if (size < minsize) size = minsize; if (!split_file(archive, size)) return error_box("Errore durante lo splitting del file %s", (const char*)archive); size = ::fsize(archive); ::remove(archive); for (int d = 0; ; d++) { TString16 ext; ext.format("z%02d", d); TFilename src(archive); src.ext(ext); if (src.exist()) { if (d > 0) { message_box("Inserire il disco %d nel drive %c:", d+1, floppy); do_events(); } if (move_file(src, path)) { TFilename ini(path); ini.add("backup.ini"); TConfig c(ini, archive.name()); c.set("Size", size); c.set("Disk", d+1); c.set("Description", desc); c.set("Date", TDate(TODAY).string()); } else break; } else break; } return TRUE; } // @doc EXTERNAL // @mfunc Effettua il backup della directory // // @rdesc Ritorna il risultato dell'operazione bool TArchive::zip( const char* dir, // @parm Directory di cui effettuare il backup char floppy, // @parm Floppy su cui effettuare il backup const char* desc) // @parm Descrizione da assegnare al backup // @parm long | firm | Ditta di cui effettuare il backup // @syntax bool backup(const char* dir, char floppy, const char* desc, bool pr_set); // @syntax bool backup(long firm, char floppy, const char* desc, bool pr_set); // @comm Il parametro

e' utilizzato per evitare errori di riaperture di files. { const TString16 old(prefix().name()); prefix().set(NULL); const TFilename workdir = dir; const TString name = workdir.name(); // Nome del file compresso TFilename work; work.tempdir(); work.add(name); work.ext("zip"); TString title("Archiviazione di "); title << workdir; TIndwin waitw(100,title,FALSE,FALSE); TWait_cursor hourglass; // Crea il file con la lista dei file da comprimere const char* const ZIPLIST = "ziplist.txt"; FILE* flist = fopen(ZIPLIST, "w"); fprintf(flist, "*.*"); fclose(flist); bool ok = ::aga_zip_filelist(ZIPLIST, work); if (ok) ok = fsplit_zip(work, floppy, desc); else error_box("Compressione degli archivi errata o incompleta"); prefix().set(old); return ok; } bool TArchive::zip(int mode, long firm, char floppy, const char* desc) { TString_array fl; const int num_ditte = build_backup_list(mode, firm, fl); bool ok = TRUE; for (int f = 0; f < num_ditte; f++) { ok = zip(fl.row(f), floppy, desc); if (!ok) break; } return ok; } // @doc EXTERNAL // @mfunc Effettua il restore della directory // // @rdesc Ritorna il risultato dell'operazione bool TArchive::unzip( const char* dir, // @parm Directory di cui effettuare il restore char floppy, // @parm Floppy da cui leggere i dati bool tmp) // @parm Directory temporanea da utilizzare // @syntax bool restore(const char* dir, char floppy, bool temp, bool pr_set); // @syntax bool restore(long firm, char floppy, bool temp, bool pr_set); // @comm Il parametro

e' utilizzato per evitare errori di riaperture di files. { TFilename work; if (tmp) work.tempdir(); else work = dir; TFilename output(dir); output = output.name(); output.ext("zip"); if (!yesno_box("Attenzione l'archivio %c:%s verra' ripristinato\n" "nel direttorio %s. Continuare?", floppy, (const char*)output, (const char*)work)) return FALSE; bool ok = work.exist(); if (!ok) { ok = yesno_box("Non esiste il direttorio %s: si desidera crearlo?", (const char*)work); if (ok) { make_dir(work); ok = work.exist(); } if (!ok) return error_box("Impossibile accedere a %s", (const char*)work); } TString title("Ripristino di "); title << output; TIndwin waitw(100,title,FALSE,FALSE); const TString16 old(prefix().name()); prefix().set(NULL); TFilename cfg; cfg << floppy << ':'; cfg.add("backup.ini"); TConfig c(cfg, output.name()); const unsigned long total_size = c.get_long("Size"); unsigned long read_size = 0; TFilename restored; restored = work; restored.add(output.name()); restored.ext("zip"); for (int d = 0; read_size < total_size; d++) { TString16 ext; ext.format("z%02d", d); TFilename src; src << floppy << ':' << SLASH << output.name(); src.ext(ext); message_box("Inserire il disco %d contenente il file %s", d+1, (const char*)src); while (!src.exist()) { if (!yesno_box("Impossibile aprire il file %s:\nSi desidera ritentare?", (const char *)src)) break; } if (src.exist()) { fcopy(src, restored, d > 0); read_size = ::fsize(restored); } else break; } ok = read_size == total_size; if (ok) ok = ::aga_unzip(restored, work); else error_box("Il file %s non è stato ripristinato completamente", (const char*)restored); prefix().set(old); return ok; } bool TArchive::unzip(int mode, long firm, char floppy, bool temp) { TString_array fl; const int num_ditte = build_restore_list(mode, firm, floppy, fl); bool ok = TRUE; for (int f = 0; f < num_ditte; f++) { ok = unzip(fl.row(f), floppy, temp); if (!ok) break; } return ok; } bool TArchive::backup(const char* dir, char floppy, const char* desc, bool) { return zip(dir, floppy, desc); } bool TArchive::backup(int mode, long firm, char floppy, const char* desc, bool) { return zip(mode, firm, floppy, desc); } bool TArchive::restore(const char* dir, char floppy, bool tmp, bool) { return unzip(dir, floppy, tmp); } bool TArchive::restore(int mode, long firm, char floppy, bool tmp, bool) { return unzip(mode, firm, floppy, tmp); }