235bbdcbad
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
530 lines
13 KiB
C++
Executable File
530 lines
13 KiB
C++
Executable File
#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);
|
||
}
|
||
|
||
|