Files correlati : Ricompilazione Demo : [ ] Commento : Riportata la versione 3.1 patch 766 git-svn-id: svn://10.65.10.50/trunk@14628 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			529 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			529 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include <agasys.h>
 | ||
| #include <archives.h>
 | ||
| #include <config.h>
 | ||
| #include <isam.h>
 | ||
| #include <mask.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);
 | ||
| }
 | ||
| 
 | ||
| 
 |