b72d034963
Aggiunti due form IVA git-svn-id: svn://10.65.10.50/trunk@1525 c028cbd2-c16b-5b4b-a496-9718f37d4682
604 lines
15 KiB
C++
Executable File
604 lines
15 KiB
C++
Executable File
#define STRICT
|
|
#include <windows.h>
|
|
#include <al.h>
|
|
#include <direct.h>
|
|
|
|
#include <applicat.h>
|
|
#include <colors.h>
|
|
#include <config.h>
|
|
#include <isam.h>
|
|
#include <mask.h>
|
|
#include <prefix.h>
|
|
#include <progind.h>
|
|
#include <urldefid.h>
|
|
#include <utility.h>
|
|
|
|
#include "ba2200.h"
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TProgress_win declaration
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TArchive;
|
|
|
|
class TProgress_win : public TMask
|
|
{
|
|
ALWindowsMessage* _monitor;
|
|
TArchive* _arc;
|
|
|
|
protected:
|
|
static bool cancel_handler(TMask_field&, KEY k);
|
|
|
|
public:
|
|
ALWindowsMessage* monitor() const { return _monitor; }
|
|
|
|
TProgress_win(const char* title, TArchive* = NULL);
|
|
~TProgress_win();
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TArchive
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TArchive : public TObject
|
|
{
|
|
enum { BUFSIZE = 4096*7 };
|
|
ALArchive* _arc;
|
|
|
|
protected:
|
|
KEY query() const;
|
|
FILE* ask_disk(TFilename& name, int disk, char floppy, bool lettura) const;
|
|
|
|
long fsize(FILE* f) const;
|
|
bool fsplit(const char* filename, char floppy, const char* desc = "") const;
|
|
bool fbuild(const char* filename, char floppy) const;
|
|
|
|
int build_backup_list(long firm, TString_array& fl) const;
|
|
int build_restore_list(long firm, char floppy, TString_array& fl) const;
|
|
|
|
public:
|
|
bool backup(const char* dir, char floppy, const char* desc);
|
|
bool backup(long firm, char floppy, const char* desc);
|
|
|
|
bool restore(const char* dir, char floppy, bool temp);
|
|
bool restore(long firm, char floppy, bool temp);
|
|
|
|
void stop_job();
|
|
};
|
|
|
|
|
|
FILE* TArchive::ask_disk(TFilename& name, int disk, char floppy, bool lettura) const
|
|
{
|
|
message_box("Inserire il disco %d nel drive %c:", disk, floppy);
|
|
|
|
name.ext(format("%03d", disk));
|
|
|
|
FILE* f = NULL;
|
|
bool retry = TRUE;
|
|
while (retry)
|
|
{
|
|
f = fopen(name, lettura ? "rb" : "wb");
|
|
if (f == NULL)
|
|
retry = yesno_box("Il file %s non e' accessibile: riprovare?", (const char*)name);
|
|
else
|
|
{
|
|
setvbuf(f, NULL, _IOFBF, BUFSIZE);
|
|
retry = FALSE;
|
|
}
|
|
}
|
|
|
|
return f;
|
|
}
|
|
|
|
long TArchive::fsize(FILE* f) const
|
|
{
|
|
CHECK(f, "Can't measure NULL file");
|
|
fseek(f, 0, SEEK_END);
|
|
const long s = ftell(f);
|
|
fseek(f, 0, SEEK_SET);
|
|
return s;
|
|
}
|
|
|
|
int TArchive::build_backup_list(long firm, TString_array& fl) const
|
|
{
|
|
fl.destroy();
|
|
if (firm < 0L)
|
|
{
|
|
fl.add(firm2dir(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);
|
|
}
|
|
|
|
TFilename name(firm2dir(-1)); // __ptprf
|
|
name.add("config"); // Aggiungi configurazioni
|
|
if (fexist(name))
|
|
fl.add(name);
|
|
}
|
|
else
|
|
fl.add(firm2dir(firm));
|
|
|
|
return fl.items();
|
|
}
|
|
|
|
|
|
// Costruisce la lista delle directory da scompattare
|
|
int TArchive::build_restore_list(long firm, char floppy, TString_array& fl) const
|
|
{
|
|
if (firm < 0) // Crea lista automaticamente
|
|
{
|
|
TFilename name("a:/backup.ini"); name[0] = floppy;
|
|
TConfig ini(name);
|
|
const int max = ini.list_paragraphs(fl); // Lista degli archivi
|
|
for (int i = max-1; i >= 0; i--)
|
|
{
|
|
const int disk = ini.get_int("Disk", fl.row(i));
|
|
if (disk == 1)
|
|
{
|
|
firm = atol(fl.row(i));
|
|
fl.add(firm2dir(firm), i); // Aggiungi gli archivi che iniziano qui
|
|
}
|
|
else fl.destroy(i, TRUE); // Elimina gli archivi che non iniziano qui
|
|
}
|
|
|
|
name = firm2dir(-1); // __ptprf
|
|
name.add("config"); // Aggiungi configurazioni
|
|
fl.add(name);
|
|
}
|
|
else
|
|
{
|
|
fl.destroy();
|
|
fl.add(firm2dir(firm)); // Inserisci solo una ditta (o COM)
|
|
}
|
|
|
|
return fl.items();
|
|
}
|
|
|
|
|
|
bool TArchive::fsplit(const char* filename, char floppy, const char* desc) const
|
|
{
|
|
const TFilename from(filename); // File da splittare
|
|
|
|
FILE* i = fopen(from, "rb"), *o = NULL;
|
|
if (i == NULL) return error_box("Impossibile aprire il file '%s'", from);
|
|
setvbuf(i, NULL, _IOFBF, BUFSIZE);
|
|
|
|
const long tot = fsize(i);
|
|
|
|
TFilename work;
|
|
work << floppy << ":/" << from.name(); // File su dischetto
|
|
|
|
TString256 msg("Archiviazione di "); msg << work << " (" << (tot/1024) << "K)";
|
|
TProgind w(tot, msg, TRUE, TRUE, 40);
|
|
|
|
int disk = 0;
|
|
TString buffer(BUFSIZE);
|
|
|
|
bool ok = TRUE;
|
|
while (ok)
|
|
{
|
|
const size_t letti = fread((char*)(const char*)buffer, 1, BUFSIZE, i);
|
|
|
|
if (o != NULL)
|
|
ok = (letti > 0) ? (fwrite((char*)(const char*)buffer, letti, 1, o) == 1) : TRUE;
|
|
else
|
|
ok = FALSE;
|
|
|
|
if (!ok)
|
|
{
|
|
if (o != NULL) fclose(o);
|
|
o = ask_disk(work, ++disk, floppy, FALSE);
|
|
ok = o != NULL;
|
|
if (ok)
|
|
{
|
|
TFilename parag(work.name()); parag.ext("");
|
|
TFilename ini("a:/backup.ini"); ini[0] = floppy;
|
|
|
|
bool asked = FALSE;
|
|
while (!asked)
|
|
{
|
|
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 del direttorio %s del %s"
|
|
"\nSi desidera continuare?",
|
|
disk, (const char*)parag, (const char*)c.get("Date"));
|
|
asked = TRUE;
|
|
}
|
|
else
|
|
{
|
|
if (d > 0)
|
|
{
|
|
ok = yesno_box("Inserire il disco %d nel drive %c:"
|
|
"\nSi desidera continuare?", disk, floppy);
|
|
if (!ok) break;
|
|
}
|
|
else
|
|
asked = TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FILE* i = fopen(ini, "w"); // Crea il file backup.ini
|
|
fclose(i);
|
|
asked = TRUE;
|
|
}
|
|
}
|
|
if (!ok) break;
|
|
|
|
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);
|
|
|
|
ok = (letti > 0) ? (fwrite((char*)(const char*)buffer, letti, 1, o) == 1) : TRUE;
|
|
if (!ok) error_box("Impossibile scrivere i dati sul dischetto");
|
|
}
|
|
}
|
|
|
|
w.addstatus(letti);
|
|
if (ok)
|
|
ok = !w.iscancelled();
|
|
if (letti < BUFSIZE)
|
|
break;
|
|
}
|
|
|
|
fclose(i);
|
|
if (o != NULL) fclose(o);
|
|
|
|
return ok;
|
|
}
|
|
|
|
|
|
bool TArchive::fbuild(const char* filename, char floppy) const
|
|
{
|
|
const TFilename work(filename);
|
|
|
|
FILE* o = fopen(work, "wb"), *i = NULL;
|
|
if (o == NULL)
|
|
return error_box("Impossibile creare il file '%s'", (const char*)work);
|
|
setvbuf(o, NULL, _IOFBF, BUFSIZE);
|
|
|
|
long totale = 0L; // Bytes letti
|
|
long max = 1440000L; // Bytes da leggere
|
|
TFilename name; // Nome del file su dischetto
|
|
name << floppy << ":/" << work.name();
|
|
|
|
TString256 msg("Ripristino da "); msg << name;
|
|
TProgind w(max, msg, TRUE, TRUE, 32);
|
|
|
|
int disk = 0;
|
|
TString buffer(BUFSIZE);
|
|
|
|
bool ok = TRUE;
|
|
while (ok)
|
|
{
|
|
size_t letti = 0;
|
|
if (i != NULL)
|
|
{
|
|
letti = fread((char*)(const char*)buffer, 1, BUFSIZE, i);
|
|
ok = letti > 0;
|
|
}
|
|
else
|
|
ok = FALSE;
|
|
|
|
if (!ok) // Richiedi nuovo disco
|
|
{
|
|
if (i != NULL) fclose(i);
|
|
i = ask_disk(name, ++disk, floppy, TRUE);
|
|
ok = i != NULL;
|
|
if (ok)
|
|
{
|
|
if (disk == 1)
|
|
{
|
|
TFilename ini("a:/backup.ini"); ini[0] = floppy;
|
|
if (fexist(ini))
|
|
{
|
|
TFilename parag(name.name()); parag.ext("");
|
|
TConfig c(ini, parag);
|
|
max = c.get_long("Size");
|
|
}
|
|
else ok = yesno_box("Manca il file %s: continuare ugualmente?", (const char*)ini);
|
|
}
|
|
w.setmax(max);
|
|
|
|
if (ok) // Leggi primo blocco di bytes
|
|
{
|
|
letti = fread((char*)(const char*)buffer, 1, BUFSIZE, i);
|
|
ok = letti > 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (ok) // La lettura e stata fatta bene
|
|
{
|
|
ok = fwrite((char*)(const char*)buffer, 1, letti, o) == letti;
|
|
if (ok)
|
|
{
|
|
w.addstatus(letti);
|
|
totale += letti;
|
|
ok = !w.iscancelled();
|
|
}
|
|
else error_box("Impossibile scrivere i dati sul file %s", (const char*)work);
|
|
}
|
|
|
|
if (!ok || totale == max) // Esci in caso di errore o se hai finito
|
|
break;
|
|
}
|
|
|
|
fclose(o);
|
|
if (i != NULL) fclose(i);
|
|
|
|
return ok;
|
|
}
|
|
|
|
bool TArchive::backup(const char* dir, char floppy, const char* desc)
|
|
{
|
|
const TString16 old(prefix().name());
|
|
prefix().set(NULL);
|
|
|
|
xvt_fsys_save_dir();
|
|
chdir(dir);
|
|
|
|
const TFilename d(dir);
|
|
const TString16 name(d.name());
|
|
TFilename work; work.tempdir(); work.add(name); work.ext("gal");
|
|
|
|
_arc = new ALArchive(work);
|
|
|
|
TString256 title("Archiviazione di "); title << name;
|
|
TProgress_win w(title, this);
|
|
ALEntryList list(w.monitor());
|
|
_arc->AddWildCardFiles(list, "*.*");
|
|
|
|
w.open_modal();
|
|
_arc->Create( list );
|
|
w.close_modal();
|
|
|
|
bool ok = _arc->mStatus == AL_SUCCESS;
|
|
if (ok)
|
|
ok = fsplit(work, floppy, desc);
|
|
else
|
|
error_box("Compressione degli archivi errata o incompleta:\n%s",
|
|
_arc->mStatus.GetStatusDetail());
|
|
|
|
delete _arc; _arc = NULL;
|
|
|
|
remove(work);
|
|
xvt_fsys_restore_dir();
|
|
prefix().set(old);
|
|
|
|
return ok;
|
|
}
|
|
|
|
bool TArchive::backup(long firm, char floppy, const char* desc)
|
|
{
|
|
TString_array fl;
|
|
const int num_ditte = build_backup_list(firm, fl);
|
|
|
|
bool ok = TRUE;
|
|
for (int f = 0; f < num_ditte; f++)
|
|
{
|
|
ok = backup(fl.row(f), floppy, desc);
|
|
if (!ok) break;
|
|
}
|
|
|
|
return ok;
|
|
}
|
|
|
|
bool TArchive::restore(const char* dir, char floppy, bool tmp)
|
|
{
|
|
TFilename work;
|
|
if (tmp)
|
|
work.tempdir();
|
|
else
|
|
work = dir;
|
|
|
|
TFilename output(dir);
|
|
output = output.name(); output.ext("gal");
|
|
|
|
if (!yesno_box("Attenzione l'archivio sul disco %c: verra' ripristinato\n"
|
|
"nel direttorio %s. Continuare?", floppy, (const char*)work))
|
|
return FALSE;
|
|
|
|
xvt_fsys_save_dir();
|
|
bool ok = chdir(work) == 0;
|
|
if (!ok)
|
|
{
|
|
ok = yesno_box("Non esiste il direttorio %s: si desidera crearlo?", (const char*)work);
|
|
if (ok)
|
|
{
|
|
make_dir(work);
|
|
ok = chdir(work) == 0;
|
|
}
|
|
if (!ok)
|
|
return error_box("Impossibile accedere a %s", (const char*)work);
|
|
}
|
|
|
|
const TString16 old(prefix().name());
|
|
prefix().set(NULL);
|
|
|
|
ok = fbuild(output, floppy);
|
|
|
|
if (ok)
|
|
{
|
|
_arc = new ALArchive(output);
|
|
|
|
TProgress_win w("Ripristino", this);
|
|
ALEntryList list(w.monitor());
|
|
_arc->ReadDirectory(list);
|
|
|
|
w.open_modal();
|
|
_arc->Extract( list );
|
|
|
|
ok = _arc->mStatus == AL_SUCCESS;
|
|
if (!ok) error_box("Ripristino degli archivi errato o incompleto:\n%s",
|
|
_arc->mStatus.GetStatusString());
|
|
w.close_modal();
|
|
delete _arc; _arc = NULL;
|
|
|
|
remove(output);
|
|
}
|
|
|
|
xvt_fsys_restore_dir();
|
|
prefix().set(old);
|
|
|
|
return ok;
|
|
}
|
|
|
|
bool TArchive::restore(long firm, char floppy, bool temp)
|
|
{
|
|
TString_array fl;
|
|
const int num_ditte = build_restore_list(firm, floppy, fl);
|
|
|
|
bool ok = TRUE;
|
|
for (int f = 0; f < num_ditte; f++)
|
|
{
|
|
ok = restore(fl.row(f), floppy, temp);
|
|
if (!ok) break;
|
|
}
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
void TArchive::stop_job()
|
|
{
|
|
if (_arc != NULL)
|
|
_arc->GetStorageObject()->mStatus.SetError(AL_USER_ABORT, "Interrotto dall'utente");
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TProgress_win implementation
|
|
///////////////////////////////////////////////////////////
|
|
|
|
TProgress_win::TProgress_win(const char* title, TArchive* arc)
|
|
: TMask(title, 1, 60, 5), _arc(arc)
|
|
{
|
|
WINDOW wtxt = add_string(101, 0, "", -11, 1, 56, "D");
|
|
WINDOW wnum = add_number(102, 0, "", -11, 2, 4, "D");
|
|
WINDOW wcan = add_button(DLG_USER, 0, "#102Cancel", -11, 3, 10, 2);
|
|
set_handler(DLG_USER, cancel_handler);
|
|
|
|
#if XVT_OS == XVT_OS_WIN
|
|
HWND txt = (HWND)xvt_vobj_get_attr(wtxt, ATTR_NATIVE_WINDOW);
|
|
HWND num = (HWND)xvt_vobj_get_attr(wnum, ATTR_NATIVE_WINDOW);
|
|
_monitor = new ALWindowsMessage(AL_MONITOR_OBJECTS, txt, AL_SEND_RATIO, num);
|
|
#endif
|
|
}
|
|
|
|
TProgress_win::~TProgress_win()
|
|
{
|
|
if (_monitor) delete _monitor;
|
|
}
|
|
|
|
bool TProgress_win::cancel_handler(TMask_field& f, KEY k)
|
|
{
|
|
if (k == K_SPACE)
|
|
{
|
|
TProgress_win& m = (TProgress_win&)f.mask();
|
|
if (m._arc != NULL)
|
|
m._arc->stop_job();
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Archiving application
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TArchive_app : public TApplication
|
|
{
|
|
TArchive _arc;
|
|
|
|
protected:
|
|
virtual bool create();
|
|
virtual bool menu(MENU_TAG);
|
|
|
|
KEY query(long& firm, char& floppy, TString& desc, bool& tmp) const;
|
|
|
|
public:
|
|
void stop_job();
|
|
|
|
TArchive_app() {}
|
|
virtual ~TArchive_app() {}
|
|
};
|
|
|
|
bool TArchive_app::create()
|
|
{
|
|
TApplication::create();
|
|
|
|
bool ok = TRUE;
|
|
|
|
TIsamfile utenti(LF_USER, FALSE);
|
|
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"))
|
|
{
|
|
ok = error_box("L'archiviazione non puo' essere effettuata\n"
|
|
"se ci sono altri utenti collegati: %s", (const char*)u);
|
|
}
|
|
}
|
|
utenti.close();
|
|
|
|
if (ok)
|
|
dispatch_e_menu(BAR_ITEM(1));
|
|
|
|
return ok;
|
|
}
|
|
|
|
|
|
KEY TArchive_app::query(long& firm, char& floppy, TString& desc, bool& temp) const
|
|
{
|
|
TMask m("ba2200");
|
|
const KEY k = m.run();
|
|
|
|
if (k != K_QUIT)
|
|
{
|
|
if (m.get(F_DATA) == "T")
|
|
firm = -1;
|
|
else
|
|
firm = m.get_long(F_CODDITTA);
|
|
floppy = m.get(F_FLOPPY)[0];
|
|
desc = m.get(F_DESCR);
|
|
temp = m.get_bool(F_TEMP);
|
|
}
|
|
|
|
return k;
|
|
}
|
|
|
|
bool TArchive_app::menu(MENU_TAG)
|
|
{
|
|
KEY k;
|
|
long firm;
|
|
char floppy;
|
|
TString80 desc;
|
|
bool temp;
|
|
|
|
while ((k = query(firm, floppy, desc, temp)) != K_QUIT)
|
|
{
|
|
if (k == K_SAVE) _arc.backup(firm, floppy, desc);
|
|
else _arc.restore(firm, floppy, temp);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
int ba2200(int argc, char* argv[])
|
|
{
|
|
TArchive_app a;
|
|
a.run(argc, argv, "Archiviazione");
|
|
return 0;
|
|
}
|
|
|