#include "ba1.h" #include "ba1100.h" #include "ba1103.h" #include #include #include #include #include #include #include #include #include #ifdef WIN32 #include #include #include #else #include #include #include #endif #define History_file "conv.his" #define Dir_file "dir.gen" #define Trc_file "trc.gen" class TManutenzione_app : public TSkeleton_application { TDir_sheet* _browse; TArray _dirs; TArray _recs; TMask* _mask; long _firm; long _level; long _history_firm; TRec_sheet* _rec; FILE * _log; bool _superprassi; protected: virtual void main_loop(); virtual bool create () ; virtual bool destroy(); void insert_riga(long, TToken_string&); void edit_riga(long, TToken_string&); void edit_riga(const TString&); void delete_riga(long); virtual bool extended_firm() const { return true; } bool recover(TSystemisamfile& f, int err); void update(); void update_dir(); void convert_dir(); virtual void print(); virtual void do_print(TPrinter & p, TRec_sheet & r); const char* dumpfilename(const FileDes& dep) const; void load_des(const int maxfidr = 0); void open_history(); void put_history(const char* firm); void close_history(); void dump_trc(const char * dir, const bool des_too, const long modules); void repair_file(int i); void open_log(); void write_log(const char * line); void close_log(); void save_file(const char * file); bool moveable_file(int file) const; public: TManutenzione_app(); }; HIDDEN bool browse_file_handler(TMask_field& f, KEY k) { if (k == K_F9) { FILE_SPEC fs; memset(&fs, 0, sizeof(FILE_SPEC)); TFilename fname = f.get(); fname.ext("dbf"); xvt_fsys_convert_str_to_fspec(fname, &fs); xvt_fsys_get_default_dir(&fs.dir); xvt_fsys_save_dir(); if (xvt_dm_post_file_open(&fs, TR("Selezione file")) == FL_OK) { TFilename n; xvt_fsys_convert_dir_to_str(&fs.dir, n.get_buffer(n.size()), n.size()); n.add(fs.name); f.set(n); } xvt_fsys_restore_dir(); f.set_focus(); } return true; } TManutenzione_app::TManutenzione_app() : _browse(NULL), _mask(NULL), _firm(0), _level(0), _rec(NULL) { if (!fexist(Dir_file)) // controlla l'esistenza dei direttori standard (dir.gen e trc.gen) { // vengono creati se non esistono TDir d; FileDes* fd = d.filedesc(); strcpy(fd->SysName,"$dir.gen"); fd->LenR =160; fd->EOD = fd->EOX = 1L; fd->Flags = 0; strcpy(fd->Des ,"Directory"); strcpy(fd->FCalc,"0"); strcpy(fd->GenPrompt,""); #ifdef WIN32 int handle = sopen(Dir_file, O_RDWR|O_BINARY|O_CREAT,SH_DENYNO,S_IREAD|S_IWRITE); #else int handle = open(Dir_file, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); #endif if (handle != -1) { if (write( handle, fd, sizeof(FileDes)) == -1) fatal_box("Impossibile scrivere il file dir.gen per dati standard: errore %d",errno); close(handle); } else fatal_box("Impossibile creare il file dir.gen per dati standard: errore %d",errno); } if (!fexist(Trc_file)) { TTrec r; RecDes* rd = r.rec(); #ifdef WIN32 int handle = sopen(Trc_file, O_RDWR|O_BINARY|O_CREAT,SH_DENYNO,S_IREAD|S_IWRITE); #else int handle = open(Trc_file, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); #endif if (handle != -1) { if (write( handle, (char*)rd, sizeof(RecDes)) == -1) fatal_box("Impossibile scrivere il file trc.gen per dati standard: errore %d",errno); close(handle); } else fatal_box("Impossibile creare il file trc.gen per dati standard: errore %d",errno); } } void TManutenzione_app::do_print(TPrinter & p, TRec_sheet & r) { const char* table[] = {"", TR("Alfanumerico"), TR("Intero"), TR("Intero Lungo"), TR("Reale"), TR("Data"), TR("Intero"), TR("Carattere"), TR("Booleano"), TR("Intero Zerofilled"), TR("Intero Lungo Zerofilled"),TR("Memo")}; TPrintrow row; TToken_string s; TParagraph_string d("", 25); TConfig * descr = NULL; TTrec & rec = *r.rec(); TDir & dir = *r.dir(); const char * descfname = r.descfname(); TString4 tab(r.tab()); const bool istab = tab.not_empty(); tab.upper(); if (fexist(descfname)) descr = new TConfig(descfname, DESCPAR); const bool hasdescr = descr != NULL; row.reset(); if (istab) row.put(format(FR("Lista tabella %s "), (const char *) tab), 2); else row.put(format(FR("Lista tracciato %s (%s)"), dir.des(), dir.name()), 2); row.put(TR("Pag. @#"), 69); p.setheaderline(2, row); row.reset(); row.put(HR("Nome"), 7); row.put(HR("Tipo"), 18); row.put(HR("Lun."), 38); row.put(HR("Dec."), 44); row.put(HR("Pos."), 48); row.put(HR("Descrizione"), 53); p.setheaderline(4, row); TString riga(78); riga.fill('-'); row.put(riga, 1); p.setheaderline(5, row); int i; for (i = 0; i < rec.fields(); i ++) { row.reset(); s = rec.fielddef(i); TString16 name = s.get(); row.put(format("%3d", i + 1), 2); row.put(name, 7); row.put(table[s.get_int()], 18); row.put(format("%4d", s.get_int()), 38); row.put(format("%4d", s.get_int()), 43); row.put(format("%4d", rec.rec()->Fd[i].RecOff), 48); const char *wd = NULL; d = ""; if (hasdescr) d = descr->get(name); if (!istab || d.not_empty()) { if (hasdescr) { wd = d.get(); if (wd != NULL) row.put(wd, 53); } p.print(row); wd = d.get(); while(wd != NULL) { row.reset(); row.put(wd, 53); p.print(row); wd = d.get(); } } } row.reset(); p.print(row); row.put(HR("Espressione chiave"), 7); row.put(HR("Duplicabile"), 68); p.setheaderline(4, row); if (p.rows_left() < 5) p.formfeed(); else { p.print(row); row.put(riga, 1); p.print(row); } for (i = 0; i < rec.keys(); i ++) { row.reset(); s = rec.keydef(i); row.put(format("%3d", i + 1), 2); row.put(s.get(), 7); row.put(*s.get() == 'X' ? TR("Si") : TR("No"), 68); p.print(row); } p.formfeed(); if (hasdescr) delete descr; } void TManutenzione_app::print() { TPrinter& p = printer(); p.open(); p.headerlen(6); p.footerlen(4); if (_rec == NULL) { TDir d; d.get(LF_DIR); int items = (int)d.eod(); if (items > 0) { TProgind pi(items, TR("Stampa tracciati record archivi"), true, true); for (int i = LF_USER; pi.setstatus(i) && i <= items; i++) { d.get(i); if (d.len() > 0) { TRec_sheet r(i, ""); do_print(p, r); } } } TString_array list; items = list_files("recdesc/d???.des", list); if (items > 0) { TProgind pi(items, TR("Stampa descrizione tabelle"), true, true); TString16 tab; for (int i = 0; pi.setstatus(i) && i < items; i++) { tab = list.row(i).right(7); tab.cut(3); if (isalpha(tab[0])) { TRec_sheet r(4, tab); do_print(p, r); } } } } else do_print(p, *_rec); p.close(); } bool TManutenzione_app::create() // initvar e arrmask { _firm = get_firm(); TString sw(argc()>2 ? argv(2) : ""); // Posso fare le operazione avanzate solo se sono ammistratore // e NON mi trovo su di una installazione di tipo client _superprassi = user() == ::dongle().administrator(); if (_superprassi) { TConfig campo_ini(CONFIG_INSTALL, "Main"); const int type = campo_ini.get_int("Type"); if (type == 1 || type == 2) _superprassi = true; else _superprassi = campo_ini.get_bool("TestDatabase"); } if (argc() > 2 && sw == "-C") { update(); return false; } else { if (sw == "-D") { const int c = argc(); bool des_too = true; // Anche le descrizioni long modules = -1; // Tutti i moduli if (c < 4) { error_box("Usage: BA1 -0 -D [0|1] []"); return false; } TFilename dir(argv(3)); if (!fexist(dir)) { error_box(FR("Non esiste il direttorio %s"), (const char*)dir); return false; } if (c == 5) des_too = atoi(argv(4)) ? true : false; if (c == 6) modules = atol(argv(5)); prefix().set(""); load_des(); dump_trc(dir,des_too,modules); return false; } #ifndef _DEMO_ else if (!set_firm()) return false; #endif load_des(); _mask = new TMask("ba1100a"); _browse = new TDir_sheet(TR("Manutenzione file di sistema"), _superprassi); if (_superprassi) { _mask->enable(-1); // Abilita campi privilegiati del gruppo 1 } } enable_menu_item(M_FILE_PRINT); return TSkeleton_application::create(); } bool TManutenzione_app::destroy() // releasev e arrmask { if (_firm) set_firm(_firm); if (_browse != NULL) delete _browse; if (_mask != NULL) delete _mask; return TApplication::destroy() ; } void TManutenzione_app::open_log() { TFilename log; log << firm2dir(0L) << '/' << "conv.log"; _log = fopen(log,"a"); if (_log == NULL) fatal_box("Non posso aprire il file di log della conversione(%s)", (const char *) log); } void TManutenzione_app::save_file(const char * file) { TFilename n(file); const TFilename source_path(n.path()); TFilename dest_path(source_path); n.ext("*"); TString_array files_to_copy; list_files(n, files_to_copy); dest_path << "sav"; if (!dest_path.exist()) make_dir(dest_path); FOR_EACH_ARRAY_ROW_BACK(files_to_copy, row, fname) { TFilename source_file(*fname); TFilename dest_file(dest_path); dest_file << '/' << (const char *) source_file.name(); fcopy((const char *) source_file, dest_file); } } void TManutenzione_app::write_log(const char * line) { fprintf(_log,"%s\n", line); } void TManutenzione_app::close_log() { fclose(_log); } void TManutenzione_app::insert_riga (long riga_sel, TToken_string& riga) { const int logicnum = int(riga_sel) + 1; const int num_files = (int)_browse->items(); _mask->disable(DLG_PACK); _mask->disable(DLG_RECORD); _mask->disable(DLG_LOAD); _mask->disable(DLG_DUMP); _mask->show(F_TAB, logicnum >= LF_TABGEN && logicnum <= LF_TAB); _mask->hide(FLD_EXTEND); _mask->hide(FLD_EOX); _mask->set (FLD_NUM, riga.get(0)); _mask->reset (F_TAB); if (_mask->run() == K_ENTER) { /* shift di uno in avanti degli elementi del direttorio partendo dall'ultimo */ for (int i=num_files; i>=logicnum; i--) { _browse->dir()->get (i, _nolock, _nordir, _sysdirop); _browse->dir()->put (i + 1, _nordir, _sysdirop); _browse->rec()->get (i); _browse->rec()->put (i + 1); } _browse->dir()->set(_mask->get(FLD_NOME), _mask->get_long(FLD_EOD), _mask->get_long(FLD_FLAG), _mask->get (FLD_DESC), _mask->get (FLD_FORMULA)); _browse->dir()->put(logicnum, _nordir, _sysdirop); _browse->rec()->zero(); _browse->rec()->put(logicnum); _browse->dir()->get(LF_DIR); _browse->dir()->eod()++; _browse->set_items(_browse->dir()->eod()); _browse->dir()->put(LF_DIR); } } void TManutenzione_app::open_history() { FILE *fp = fopen(History_file,"r"); if (fp != NULL) { char line[16]; fgets(line,16,fp); int l = strlen(line); line[l > 0 ? l -1 : 0 ] = '\0'; if (l==0) _history_firm = -1; else _history_firm = atol(line); } else { fp = fopen(History_file,"w"); _history_firm = -1; } fclose (fp); } void TManutenzione_app::put_history(const char* firm) { FILE * fp = fopen(History_file,"w"); fprintf(fp,"%s\n",firm); fclose (fp); } void TManutenzione_app::close_history() { // Se la conversione non ha rilevato errori rimuove il file di history. remove(History_file); } void TManutenzione_app::dump_trc(const char * dir, const bool des_too, const long modules) { TDir d; d.get(LF_DIR); const int items = (int) d.eod(); const long flags = d.flags(); // livello archivi TFilename fn(dir); fn << "/level.dir"; { ofstream of(fn); of << flags << '\n'; } TString s(TR("Scarico dei tracciati standard in ")); s << dir; TProgind p(items ? items : 1, s, false, true); p.setstatus(1); for (int i=2;i<=items;i++) //Salta il primo (dir.gen) { p.addstatus(1); TTrec& rc = (TTrec&)_recs[i]; TDir& dr = (TDir&)_dirs[i]; const long file_mod = (long)abs((int)dr.flags()); if (modules != -1 && file_mod != modules) continue; // se non fa parte del modulo lo salta TFilename descfname; descfname.format("%s/d%d.des", DESCDIR, i); if (!fexist(descfname)) // crea la descrizione se non esiste { FILE * fd = fopen(descfname, "w"); if (fd != NULL) fclose(fd); } TConfig conf_des(descfname,DESCPAR); if (des_too) rc.set_des(&conf_des); fn = dir; fn << "/f";fn << i; fn.ext("trr"); ofstream out(fn); out << rc; fn.ext("dir"); ofstream out_dir(fn); out_dir << dr; } } const char* TManutenzione_app::dumpfilename(const FileDes& dep) const { TFilename n; n.tempdir(); n.add(dep.SysName); n.strip("$%"); n.ext("txt"); n.lower(); TString & tmp = get_tmp_string(); tmp = n; return tmp; } void TManutenzione_app::edit_riga (const TString& name) { const TFilename n(name); TExternisamfile* f = new TExternisamfile(n); _mask->set (FLD_NUM, ""); _mask->set (FLD_NOME, n); _mask->set (FLD_EOD, f->items()); _mask->set (FLD_EOX, f->items()); _mask->set (F_LEN, f->curr().len()); _mask->set (FLD_DESC, f->description()); _mask->set (FLD_FORMULA, ""); _mask->set (FLD_FLAG, ""); _mask->reset (FLD_EXTEND); _mask->reset (F_TAB); _mask->disable(-1); _mask->enable(DLG_RECORD, _superprassi); KEY tasto = _mask->run(); switch (tasto) { case K_F4: { TEdit_file ef; ef.browse_file(f, n); break; } case K_F6: _rec = new TRec_sheet(f); _rec->edit(); delete _rec; _rec = NULL; delete f; // La delete di TExternisamfile va fatta solo qui perche' in K_F4 viene fatta dalla TRelation interna break; default: break; } } void TManutenzione_app::edit_riga (long riga_sel, TToken_string& riga) { KEY tasto; FileDes dep; TDir d; const int logicnum = int(riga_sel) + 1; _mask->enable(DLG_PACK, _superprassi); _mask->enable(DLG_RECORD, _superprassi); _mask->enable(DLG_LOAD, _superprassi); _mask->enable(DLG_DUMP); _mask->show(F_TAB, logicnum >= LF_TABGEN && logicnum <= LF_TAB); _mask->set (FLD_NUM, riga.get(0)); _mask->set (FLD_NOME, riga.get()); _mask->set (FLD_EOD, riga.get()); _mask->set (FLD_EOX, riga.get()); _mask->set (F_LEN, riga.get()); _mask->set (FLD_DESC, riga.get()); _mask->set (FLD_FORMULA, riga.get()); _mask->set (FLD_FLAG, riga.get()); _mask->reset (FLD_EXTEND); _mask->reset (F_TAB); const TRecnotype oldeox = _mask->get_long(FLD_EOX); const bool com = prefix().is_com() || !*prefix().name(); const char* name = _mask->get(FLD_NOME); const bool enable_extend = (com ? *name != '$' : *name == '$') && (riga_sel > 0) && (_mask->get_int(F_LEN) > 0 || oldeox > 0); _mask->show(FLD_EXTEND, enable_extend); _mask->show(FLD_EOX, enable_extend); tasto = _mask->run(); switch (tasto) { case K_F4: if (logicnum > 1) { const TFilename filename(_mask->get(FLD_NOME)); const TString& tabella = _mask->get(F_TAB); TEdit_file ef; ef.browse_file(logicnum, filename, tabella); } break; case K_F5: case K_F6: case K_F8: if (!_superprassi) { error_box(FR("Funzione non ammessa per l'utente %s"), (const char*)user()); break; } case K_F7: case K_ENTER: { strcpy (dep.SysName,_mask->get (FLD_NOME)); dep.EOD = atol(_mask->get (FLD_EOD)); dep.Flags = atol(_mask->get (FLD_FLAG)); strcpy (dep.Des,_mask->get (FLD_DESC)); strcpy (dep.FCalc,_mask->get (FLD_FORMULA)); const TRecnotype eox = _mask->get_bool(FLD_EXTEND) ? _mask->get_long(FLD_EOX) : oldeox; TDir& dir = *_browse->dir(); dir.get(logicnum, _lock, _nordir, _sysdirop); dir.set(dep.SysName, dep.EOD, dep.Flags, dep.Des, dep.FCalc); dir.put(logicnum, _nordir, _sysdirop); { TSystemisamfile f(logicnum); if (eox != oldeox) { d.get(logicnum); TFilename f_name(d.name()); f_name.ext("dbf"); if (!f_name.exist()) f.build(eox); _browse->dir()->get(logicnum, _nolock, _nordir, _sysdirop); } if (tasto == K_F5 && logicnum > 1) { f.packfile(); f.packindex(); // le 4 righe seguenti servono per allineare i valori di EOD ed EOX dopo una compattazione forzata dir.get(logicnum, _lock, _nordir, _sysdirop); dir.set(dep.SysName, dep.EOD, dep.Flags, dep.Des, dep.FCalc); dir.set_eox(_browse->dir()->eod()); dir.put(logicnum, _nordir, _sysdirop); } else if (tasto == K_F6) { _rec = new TRec_sheet(logicnum, _mask->get(F_TAB)); _rec->edit(); delete _rec; _rec = NULL; } else if (tasto == K_F7) { TMask m("ba1100b"); TFilename nout(dumpfilename(dep)); m.set(FLD_OUTFILE, nout); if (m.run() == K_ENTER) { nout = m.get(FLD_OUTFILE); if (nout.not_empty()) { const char fs = *esc(m.get(FLD_FS)); const char fd = *esc(m.get(FLD_FD)); const char rs = *esc(m.get(FLD_RS)); const bool withdel = m.get_bool(FLD_WITHDEL); const int keyno = m.get_int(FLD_KEYNO); const TString4 tabella(_mask->get(F_TAB)); if (tabella.not_empty()) { TToken_string filter; filter.add("COD"); filter.add(tabella); f.dump(nout, keyno, fs, fd, rs, true, withdel, filter); } else f.dump(nout, keyno, fs, fd, rs, true, withdel); } } } else if (tasto == K_F8) { TMask m("ba1100c"); TFilename ninp(dumpfilename(dep)); m.set(FLD_INFILE, ninp); if (m.run() == K_ENTER) { const char fs = *esc(m.get(FLD_FS)); const char fd = *esc(m.get(FLD_FD)); const char rs = *esc(m.get(FLD_RS)); const bool indexed = !m.get_bool(FLD_WITHKEY); ninp = m.get(FLD_INFILE); f.load(ninp, fs, fd, rs, true, false, indexed); } } } } break; default: break; } } void TManutenzione_app::delete_riga (long riga_sel) { const int logicnum = int(riga_sel) + 1; const int num_files = (int)_browse->items(); TTrec r; /* shift di uno in avanti degli elementi del direttorio partendo dall'ultimo */ for (int i = logicnum + 1; i <= num_files; i++) { _browse->dir()->get (i, _nolock, _nordir, _sysdirop); _browse->dir()->put (i - 1, _nordir, _sysdirop); _browse->rec()->get (i); _browse->rec()->put (i - 1); } _browse->dir()->get(LF_DIR); r.zero(); r.put(_browse->dir()->eod()); _browse->dir()->eod()--; _browse->set_items(_browse->dir()->eod()); _browse->dir()->put(LF_DIR); _browse->force_update(); } bool TManutenzione_app::recover(TSystemisamfile& f, int err) { if (err == -60 || err == -64 || err == _ispatherr || (err > -600 && err <= -300)) { err = f.packindex(); } return err == NOERR; } void TManutenzione_app::repair_file(int i) { TDir d; TString s(_MAX_PATH); d.get(i, _nolock, _nordir, _sysdirop); if (d.eod() == 0) { TFilename n(d.filename()); save_file(n); remove(n); n.ext("cdx"); remove(n); n.ext("fpt"); remove(n); s.format(FR("File n. %d - %s : eliminato file errato"), i, (const char *)d.filename()); write_log(s); } else { d.get(i, _lock, _nordir, _sysdirop); TFilename n(d.filename()); save_file(n); TExternisamfile ef(d.filename()); const RecDes* rd = ef.curr().rec_des(); TTrec rec; rec.get(i); const int oldreclen = rec.len(); const int recsize = sizeof(RecDes); memcpy(rec.rec(), rd, recsize); rec.put(i); const int reclen = rec.len(); d.set_len(reclen); d.put(i, _nordir, _sysdirop); s.format(FR("File n. %d - %s : corretto tracciato da %d a %d bytes"), i, (const char *)d.filename(), oldreclen, reclen); write_log(s); } } bool TManutenzione_app::moveable_file(int file) const { return file == LF_PCON || file == LF_CLIFO || file == LF_CAUSALI || file == LF_RCAUSALI || file == LF_CFVEN || file == LF_INDSP; } void TManutenzione_app::update_dir() { // Particolare significato dei flags oltre i 10000: // trattasi di files PRASSI, (ad esempio i cespiti) che da noi non vengono toccati, // in modo da evitare colpe inutili. Noi aggiorniamo solo i tracciati su dir e trc, // ma il file fisico manco lo tocchiamo!! TString80 s; const TString pref(prefix().name()); const bool is_com = prefix().is_com(); if (prefix().get_codditta() <= _history_firm) return; const int orig_items = _dirs.last(); TDir d ; d.get(LF_DIR); const int items = (int)d.eod(); const int update_items = (orig_items < items) ? orig_items : items; TString prompt(128); if (is_com) prompt << TR("Aggiornamento dati comuni"); else prompt << TR("Aggiornamento ditta") << ' ' << atol(pref) << '.'; TProgind p(update_items ? update_items : 1, prompt, false, true); p.setstatus(1); int i; for (i = LF_USER; i <= update_items; i++) { p.addstatus(1); const TDir & ds = (const TDir &) _dirs[i]; const bool is_firm = ds.is_firm(); const bool to_create = (is_com ? ds.is_com() : ds.is_firm()); TFilename fd(ds.filename()); bool towrite = false; const long flags = ds.flags(); d.get(i, _nolock, _nordir, _sysdirop); const bool old_is_firm = d.is_firm(); d.get(i); TFilename fs(d.filename()); if (strrchr(d.name(),'.') != NULL) // No extension please! { d.get(i, _nolock, _nordir, _sysdirop); TFilename ext(d.name()); ext.ext(""); d.set_name(ext); d.put(i, _nordir, _sysdirop); } if (!fs.exist()) { if (d.eox() > 0L) { d.get(i, _nolock, _nordir, _sysdirop); d.eod() = 0L; d.eox() = 0L; d.put(i, _nordir, _sysdirop); } } else { if (is_com) { if (old_is_firm && !moveable_file(i) && d.eod() == 0L) { TFilename n(d.filename()); save_file(n); remove(n); n.ext("cdx"); remove(n); n.ext("fpt"); remove(n); TString msg(_MAX_PATH); msg.format(FR("File n. %d - %s : eliminato file non utilizzato"), i, (const char *)d.filename()); write_log(msg); } } if (i > 2 && is_firm == old_is_firm) { FILE * f = fopen(fs, "r"); if (f != NULL) { fseek(f, 0L, SEEK_END); const long size = ftell(f); fclose(f); if (flags < 10000L && size > 0L && d.len() > 0) { TSystemisamfile b(i); int err = b.is_valid(true); if ((err == _istrcerr) && (d.eod() == 0) && (fsize(d.filename()) < 4096) && yesno_box(FR("Il tracciato record del file %d e' incoerente:\nSi desidera eliminare il file vuoto %s?"), i, d.filename())) { TFilename n(d.filename()); remove(n); n.ext("cdx"); remove(n); n.ext("fpt"); remove(n); err = NOERR; } if (err != NOERR && flags < 10000L) { if (err == _istrcerr) { repair_file(i); err = NOERR; } if (err != NOERR && flags < 10000L) { if (!recover(b, err)) { TString msg(_MAX_PATH); msg.format(TR("File n. %d - %s : errore n.ro %d"), i, (const char *)d.filename(), err); write_log(msg); } } } } else { if (flags < 10000L && to_create) { remove(d.filename()); TToken_string idx_names; get_idx_names(i, idx_names); for (const char * idx_name = idx_names.get(); idx_name != NULL; idx_name = idx_names.get()) remove(idx_name); d.get(i, _nolock, _nordir, _sysdirop); d.eod() = 0L; d.eox() = 0L; d.put(i, _nordir, _sysdirop); } } } } } d.get(i, _nolock, _nordir, _sysdirop); bool cmn_file = false; bool valid_file = moveable_file(i); if (!is_com && valid_file && d.is_com()) cmn_file = true; // Salta in questo caso: // sto aggiornando le ditte, // il file in questione e' uno di quelli che possono essere comuni // il file e' in comune // Serve per evitare che durante l'aggiornamento i file // PCON, CLIFO, CAUS ed RCAUS vengano spostati da COM alla // prima ditta if (to_create && !cmn_file) { if (flags < 10000L && flags > -1L && fexist(fs) && (fd != fs)) { bool ok = true; TFilename path(fd.path()); bool found = false; for (int j = i + 1; !found && j <= update_items; j++) { const TDir & dn = (const TDir &) _dirs[j]; TFilename fn(dn.filename()); if (fs == fn) { TTrec wrs; TTrec wrd; wrs.get(i); wrd.get(j); wrd = wrs; wrd.set_num(j); wrd.put(j); wrs.zero(); wrs.put(i); TDir wds; TDir wdd; wds.get(i, _nolock, _nordir, _sysdirop); wdd.get(j, _nolock, _nordir, _sysdirop); wdd.set(wds.name(), wds.eod(), wds.flags(), wds.des(), wds.expr()); wdd.set_eox(wds.eox()); wdd.set_len(wrd.len()); wdd.put(j, _nordir, _sysdirop); wds.set(ds.name(), 0L, 0L, ds.des(), ds.expr()); wds.set_eox(0L); wds.set_len(0); wds.put(i, _nordir, _sysdirop); found = true; } } if (found) continue; path.rtrim(1); if (path.not_empty() && !fexist(path)) ok = make_dir(path); if (ok && fcopy(fs, fd)) { TToken_string ts(10),td(10); td.cut(0); get_idx_names(i,ts); // Get index names of current file in current dir for (int j=1; j<= ts.items() && ok; j++) { const TFilename fsi(ts.get()); TFilename fdi(fd); // Nuovo nome. (Con l'estensione) fdi.ext(""); if (j > 1) // Means that more indexes are in TToken_string ts { TString xx=fdi.name(); if (xx.len() < 8) fdi << ('0' + j); else fdi[8] = ('0' + j); } fdi.ext(fsi.ext()); td.add(fdi); if (!fcopy(fsi, fdi)) ok = false; } if (ok) { remove(fs); // Rimuove i files sorgenti. Crea un eventuale .cgp fd.ext("cgp"); FILE *o=NULL; if (ts.items() > 1) { fs.ext("cgp"); remove(fs); o=fopen(fd,"w"); } ts.restart(); td.restart(); for (int j=1; j<=ts.items(); j++) { remove(ts.get()); if (ts.items() > 1) // Means that fd.cgp must be created { TFilename ff=td.get(); ff.ext(""); ff.rtrim(1); fprintf(o,"%s\n",ff.name()); } } if (o!=NULL) fclose(o); } else { remove(fd); // Remove all destinations written td.restart(); for (int j=1; j<=td.items(); j++) remove(td.get()); } } else ok = false; if (ok) { d.set(ds.name(), d.eox(), 0L, ds.des(), d.expr()); towrite = true; } } if (!fexist(fs) && !valid_file) // Controlla eventali nomi di files non validi (ed es. %.dbf ecc.) { d.set(ds.name(), d.eox(), 0L, ds.des(), d.expr()); towrite = true; } } else { towrite = (TString(ds.des()) != d.des()); if (towrite) { if (!valid_file) d.set(ds.name(), d.eox(), d.eod(), ds.des(), d.expr()); else strcpy((char *) d.des(), ds.des()); } } if (is_com && valid_file && d.name()[0] == '$') { TString name(d.name()); name[0] = '%'; d.set_name(name); towrite = true; } if (towrite) d.put(i, _nordir, _sysdirop); } // end of for scope if (items >= orig_items) return; for (i = items + 1; i <= orig_items; i++) { TDir d1((TDir &) _dirs[i]); d1.set_len(0); d1.eox() = 0L; d1.eod() = 0L; d1.flags() = 0L; d1.put(i, _nordir, _sysdirop); } d.get(LF_DIR, _nolock, _nordir, _sysdirop); d.eod() = orig_items; if (d.eox() < d.eod()) d.eox() = d.eod(); d.put(LF_DIR, _nordir, _sysdirop); } void TManutenzione_app::convert_dir() { if (prefix().get_codditta() <= _history_firm) return; const TString pref(prefix().name()); const bool is_com = prefix().is_com(); const int orig_items = _dirs.last(); TDir d; d.get(LF_DIR); const int items = (int)d.eod(); const int update_items = (orig_items < items) ? orig_items : items; TString s; if (is_com) s = TR("Aggiornamento archivi comuni.\n"); else { s = TR("Aggiornamento archivi della ditta "); s << atol (pref) << ".\n"; } TProgind p(update_items ? update_items : 1, s, false, true); p.setstatus(1); for (int i = LF_USER; i <= update_items; i++) { p.addstatus(1); const TTrec & rs = (const TTrec &) _recs[i]; const TDir & ds = (const TDir &) _dirs[i]; const long flags = ds.flags(); if (ds.len() > 0) { if (flags >= 0L && flags < 10000L) { TSystemisamfile f(i); TString msg = s; msg << prefix().get_filename(i); p.set_text(msg); const int module = abs((int)ds.flags()); int err = f.is_valid(true); if (err == -60 || err == -64) err = NOERR; // verif. d.get(i, _nolock, _nordir, _sysdirop); if (i > LF_USER && err != NOERR && ((is_com && d.is_com()) || (!is_com && d.is_firm()))) { if (err == _istrcerr || err == _isbadtrc) { repair_file(i); err = NOERR; } if (err != NOERR) { if (!yesno_box(FR("Il file %d non puo' essere aperto:\nErrore %d. Continuare ugualmente?"),i,err)) stop_run(); else continue; } } //if (i > 2 && err != NOERR &&... bool to_create = (is_com ? d.is_com() : d.is_firm()); // I files LF_PCON, LF_CAUS, LF_RCAUS, LF_CLIFO, LF_CFVEN, LF_INDSPED // vanno creati comunque nel direttorio COM, vuoti, (se non esistono gia'). if (is_com && !to_create && moveable_file(i)) to_create = true; if (to_create && has_module(module, CHK_DONGLE)) { TDir df; df.get(i); const TFilename fname(df.filename()); //crea il nuovo file in base al tracciato record nuovo! if (!fname.exist() && ds.len() > 0) { set_autoload_new_files(false); f.build(0L,rs); set_autoload_new_files(true); // Anche se il file non esisteva, prosegue, perche' possono esserci conversioni // specificate in FCONV.INI } } f.update(rs, false); if (f.status() == 8) // cio' significa che e' accaduto quasi l'irreparabile... { { TLocalisamfile u(LF_USER); u.zero(); u.put("USERNAME", ::dongle().administrator()); if (u.read() == NOERR) { u.zero("AUTSTR"); u.rewrite(); } } stop_run(); } //if(f.status()... } //if (flags >= 0L && < 10000L... else // altrimenti se i flags sono oltre i fatidici 10000... { TTrec r(rs); d.get(i, _nolock, _nordir, _sysdirop); d.set_len(r.len()); d.put(i, _nordir, _sysdirop); r.put(i); } //else di if(flags>=... } //if (ds.len() > 0... (la dimensione del tracciato e' > 0) else // altrimenti se la dimensione del tracciato e' zero... { TTrec r(rs); r.zero(); d.get(i, _nolock, _nordir, _sysdirop); d.set_len(r.len()); d.put(i, _nordir, _sysdirop); r.put(i); } //else di if(ds.len()>0... } //for (int i = 2; i <= update_items... d.get(LF_DIR, _nolock, _nordir, _sysdirop); d.flags() = _level; d.put(LF_DIR, _nordir, _sysdirop); put_history(pref); } void TManutenzione_app::load_des(const int maxfdir) { const TString pref(prefix().name()); _dirs.destroy(); _recs.destroy(); _level = prefix().filelevel(); TDir d; TTrec r; d.get(LF_DIR,_nolock, _nordir,_sysdirop); int items = (int)d.eod(); long flags = d.flags(); const bool standard = pref.empty(); if (standard) // carica eventuali nuove descrizioni ed il nuovo livello archivi { // Cerca in RECDESC i files f[nnn].dir TString ws; TFilename fn; TDir td,new_dir; TTrec tr; int ln = items,last_newln = items; tr.zero(); fn << DESCDIR << "/level.dir"; if (fexist(fn)) { ifstream infile(fn); long fl; infile >> fl; if (fl > flags) flags = fl; } // scandisce *.dir in RECDESC // eventuali "buchi" oltre al numero attuale di items vengono rimpiazzati // con tracciati vuoti. fn.format("%s/f*.dir",DESCDIR); TString_array list; const int totfiles = list_files(fn, list); for (int n = 0; n < totfiles; n++) { fn = list.row(n); if (fn.exist()) { ifstream infile(fn); infile >> td; } ln = td.num(); const bool is_new = ln > last_newln; // memorizza l'ultimo record scritto come nuovo if (is_new) // aggiunge i files che mancano { for (int i = last_newln+1; i> r; r.put(i); d.set_len(r.len()); d.put(i, _nordir, _sysdirop); r.set_des(); } } } _dirs.add(d, i); _recs.add(r, i); } } void TManutenzione_app::update() { TIsamfile utenti(LF_USER); utenti.open(_excllock); #ifndef DBG bool ok = false; while (!ok) { TToken_string utonti(64, ','); for (int err = utenti.first(); err == NOERR; err = utenti.next()) { const TString& u = utenti.get(USR_USERNAME); if (u != ::dongle().administrator() && utenti.get_bool(USR_CONNECTED)) utonti.add(u); } ok = utonti.empty(); if (!ok) { TToken_string message(80, '\n'); message = TR("Conversione archivi impossibile mentre ci sono utenti collegati!"); message.add(TR("Qualora uno degli utenti elencati non fosse effettivamente connesso, ")); message.add(TR("effettuare una sua connessione e disconnessione immediata per sbloccarlo")); message.add(utonti); error_box(message); break; } } #else bool ok = true; #endif // Scrive CONVERTING solo dopo aver testato che non ci sia nessuno connesso if (ok) { utenti.zero(); utenti.put(USR_USERNAME, dongle().administrator()); ok = utenti.read() == NOERR; if (ok) { utenti.put(USR_AUTSTR, "CONVERTING"); ok = utenti.rewrite() == NOERR; } } utenti.close(); if (!ok) return; open_history(); long firm = get_firm(); TString pref; if (firm == 0) pref = prefix().name(); do_events(); begin_wait(); TDir d; d.get(LF_DIR,_nolock, _nordir, _sysdirop); const int maxfdir = d.items(); prefix().set(""); load_des(maxfdir); prefix().set_codditta(0L); open_log(); TString s; s.format(FR("Conversione del %s"), (const char*)TDate(TODAY).string()); write_log(s); write_log(""); s.format(TR("Dati comuni")); write_log(s); write_log(""); update_dir(); convert_dir(); TSystemisamfile ditte(LF_NDITTE); ditte.open(); s = TR("Conversione archivi ditte."); TProgind p(ditte.items() ? ditte.items() : 1, s, false, true); p.setstatus(1); TString mxs; for (ditte.first(); !ditte.eof(); ditte.next()) { const TRecnotype rec = ditte.recno(); const long codditta = ditte.get_long("CODDITTA"); mxs = s; mxs << TR(" Ditta ") << codditta; p.addstatus(1); p.set_text(mxs); if (codditta > _history_firm && prefix().exist(codditta)) { ditte.close(); set_firm(codditta); write_log(""); write_log(mxs); write_log(""); update_dir(); convert_dir(); ditte.open(); } ditte.readat(rec); } ditte.close(); write_log("--------------------"); write_log(""); close_log(); if (firm > 0) set_firm(firm); else prefix().set(pref); load_des(); ok = false; while (!ok) { utenti.open(_excllock); ok = utenti.ok(); do_events(); } // Azzera la scritta converting utenti.put(USR_USERNAME, ::dongle().administrator()); if (utenti.read() == NOERR) { utenti.zero(USR_AUTSTR); utenti.rewrite(); } utenti.close(); close_history(); send_campo_xml(); // Spedisce situazione via ftp end_wait(); } void TManutenzione_app::main_loop() { TToken_string riga; long riga_selezionata; bool done = false; _browse->rebuild(); while (!done) { disable_menu_item(M_FILE_NEW); KEY key = _browse->run(); if (key != K_ENTER && key != K_QUIT && key != K_ESC && !_superprassi) { error_box(FR("Operazione non permessa all'utente %s"), (const char*)user()); key = 0; } // Si assicura di chiudere tutto prima di conversioni o altro prefix().close_closeable_isamfiles(); switch (key) { case K_F1: dispatch_e_menu(M_HELP_CONTENTS); break; case K_F2: dispatch_e_menu(M_FILE_ABOUT); break; case K_F3: dispatch_e_menu(M_FILE_PRINT); break; case K_F6: riga_selezionata = _browse->selected(); riga = _browse->row(); insert_riga (riga_selezionata, riga); break; case K_ENTER: riga_selezionata = _browse->selected(); riga = _browse->row(); edit_riga (riga_selezionata, riga); break; case K_DEL: riga_selezionata = _browse->selected(); delete_riga(riga_selezionata); break; case K_QUIT: case K_ESC: done = true; close_history(); break; case K_F7: update(); break; case K_F8: _browse->add(); riga_selezionata = _browse->items() - 1; riga = _browse->row(riga_selezionata); edit_riga (riga_selezionata, riga); break; case K_F5: // Other file { TMask other("ba1100g"); other.set_handler(101, browse_file_handler); if (other.run() == K_ENTER) edit_riga(other.get(101)); } break; default: break; } enable_menu_item(M_FILE_NEW); } } int ba1100(int argc, char** argv) { TManutenzione_app a; a.run(argc, argv, TR("Gestione files")); return 0; }