campo-sirio/include/archives.cpp
luca 235bbdcbad Patch level :2.1 118
Files correlati     :ve5.exe
Ricompilazione Demo : [ ]
Commento            :
AO21039  e bug 0000228
Il ripristino dei documenti non funziona correttamente, in sostanza il programma si aspetta che sul Floppy ci sia un file di nome "VE.zipVE.z00" mentre invece c'è un file "VE.z00", tant'è vero che se lo ridenomino col nome che si aspetta, funziona correttamente.


git-svn-id: svn://10.65.10.50/trunk@12320 c028cbd2-c16b-5b4b-a496-9718f37d4682
2004-09-22 10:24:54 +00:00

530 lines
13 KiB
C++
Executable File
Raw Blame History

#include <agasys.h>
#include <archives.h>
#include <config.h>
#include <isam.h>
#include <mask.h>
#include <prefix.h>
#include <progind.h>
#include <utility.h>
///////////////////////////////////////////////////////////
// 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 = xvt_fsys_test_disk_free_space(dest, filesize) != 0;
if (!space_ok)
{
TString msg(128);
msg << "Lo spazio sull'unita' e' insufficiente:\n";
if (xvt_fsys_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)
{
if (xvt_fsys_is_removable_drive(path))
message_box("Inserire il disco 1 nel drive %c:", floppy);
size = xvt_fsys_get_disk_size(path, 'K') - 64;
if (size <= 0)
{
if (!yesno_box("Errore di accesso al drive %c\nSi desidera ritentare?", floppy))
return FALSE;
}
do_events();
}
const unsigned 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 <p pr_set> e' utilizzato per evitare errori di riaperture di files.
{
safely_close_closeable_isamfiles();
DIRECTORY currdir, newdir;
xvt_fsys_get_dir( &currdir); //memorizza la directory dove e'
xvt_fsys_convert_str_to_dir(dir, &newdir); //converte il nome della directory
xvt_fsys_set_dir( &newdir); //passa alla directory dir che gli viene passata
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;
TString_array filenames;
list_files("*.*", filenames);
// Crea il file con la lista dei file da comprimere
const char* const ZIPLIST = "ziplist.txt";
FILE* flist = fopen(ZIPLIST, "w");
FOR_EACH_ARRAY_ROW(filenames, r, row)
fprintf(flist, "%s\n",(const char *)*row);
fclose(flist);
bool ok = ::aga_zip_filelist(ZIPLIST, work);
remove(ZIPLIST); //elimina il file di testo con la lista dei files
xvt_fsys_set_dir( &currdir); //torna a posizionarsi nella directory iniziale
if (ok)
ok = fsplit_zip(work, floppy, desc);
else
error_box("Compressione degli archivi errata o incompleta");
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 Unita' 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 <p pr_set> 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);
safely_close_closeable_isamfiles();
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.tempdir();
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;
src << output.name();
src.ext(ext);
if (xvt_fsys_is_removable_drive(src))
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);
if (ok)
remove(restored);
}
else
error_box("Il file %s non <20> stato ripristinato completamente", (const char*)restored);
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);
}