campo-sirio/ba/ba2200.cpp
guy fdae1a4bdb ba0.cpp Aggiunta gestione programmi protetti da password
ba2100b.uml  Modificata maschera scelta profili
ba2100f.uml  Abilitato campo testo fisso nei campi
ba2200.cpp   Controllato meglio il cambio disco da parte dell'utente
ba2400.cpp   Aggiornato uso della funzione TForm::validate
ba3100.cpp   Corretta gestione annullamento configurazione stampa registri
ba3300.cpp   Aggiunta chiamata on_firm_change della classe madre
prassi.mnu   Aggiunto flag di protezione da password ad alcuni programmi


git-svn-id: svn://10.65.10.50/trunk@1612 c028cbd2-c16b-5b4b-a496-9718f37d4682
1995-07-19 09:42:25 +00:00

603 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
{
TFilename prev(name);
prev.ext(format("%03d", disk-1)); // File precedente
bool first = TRUE;
do
{
if (first)
{
message_box("Inserire il disco %d nel drive %c:", disk, floppy);
first = FALSE;
}
else
{
const bool ok = yesno_box("Inserire il disco %d nel drive %c\n"
"Estrarre il disco %d e continuare?", disk, floppy, disk-1);
if (!ok) return NULL;
}
} while (fexist(prev)); // Non facciamo i furbetti!
name.ext(format("%03d", disk)); // File attuale
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;
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"));
}
}
else
{
FILE* i = fopen(ini, "w"); // Crea il file backup.ini per evitare messaggi
fclose(i);
}
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;
}