home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 3 / Meeting_Pearls_III.iso / Pearls / disk / Backup / SkBackup / Sources / SKBACKUP.C next >
C/C++ Source or Header  |  1994-10-10  |  27KB  |  1,152 lines

  1.                     /********************************************************
  2.                     *                                                        *
  3.                     *     $TITLE        :    Backup.c                            *
  4.                     *    $AUTHOR        :    Pozzoli Alessandro                    *
  5.                     *     $STARTDATE    :    24/3/1994                            *
  6.                     *                                                        *
  7.                     *     $DATE        :    26/4/1994                            *
  8.                     *    $VERSION    :    1.1                                    *
  9.                     *                                                        *
  10.                     *     $DATE        :    20/5/1994                            *
  11.                     *    $VERSION    :    1.2                                    *
  12.                     *                                                        *
  13.                     *    $NOTE        :    Creazione di file di backup per        *
  14.                     *                     Amiga Unix & PC                    *
  15.                     *                                                        *
  16.                     *********************************************************/
  17.  
  18.  
  19.         /*            Include         */
  20.  
  21. #include<stdio.h>
  22. #include<string.h>
  23. #ifdef AMIGA
  24. #include<sys/dir.h>
  25. #else
  26. #include<sys/dirent.h>
  27. #endif
  28. #include<sys/stat.h>
  29.  
  30.  
  31.         /*          Macro         */
  32.  
  33. #define SET_MASK(a,b)        a|=b
  34. #define CLR_MASK(a,b)        a&=(UBYTE)(0xFF&~(b))
  35. #define CHECK_MASK(a,b)        a&b
  36.  
  37.         /*              Costanti         */
  38.  
  39. #define BUFLEN         2048*300                                    /* Grandezza del Buffer dati           */
  40.  
  41.  
  42.         /*    Proto di programma     */
  43.  
  44. void StripNewLinee();
  45. int IsSpecDevice();
  46. void Presentation();
  47. void Usage();
  48. void CheckInput();
  49. void Incremento();
  50.  
  51.         /*          Strutture        */
  52.  
  53. struct Backup
  54. {
  55.     void             *Buffer;                    /* Buffer per lettura e scrittura            */
  56.     FILE             *BackupFile;                /* File di Backup                            */
  57.     FILE             *file;                        /* File di cui fare il Backup                */
  58.     char             Name[100];                    /* Nome della directory da Backup            */
  59.     char            Old[100];                    /* Nome della directory attuale                */
  60.     char            FileName[100];                /* Nome File Di Backup                        */
  61.     int                Size;                        /* Grandezza del file di cui fare il Backup    */
  62.     int                Length;                        /* Lunghezza degli archivi                    */
  63.     int                AttualLength;                /* Posizione attuale nel file Di Backup        */
  64.     int                Files;                        /* Numero dei Files nel Backup                */
  65.     int                FilesBack;                    /* Numero dei Files di Backup                */
  66.     int                Total;                        /* Lunghezza dati nel Backup                */
  67.     int                TotalBack;                    /* Lunghezza reale dei File Di Backup        */
  68.     int                Flags;                        /* Flags di controllo vedere sotto            */
  69. };
  70.  
  71.  
  72. /* Flags Bit */
  73.  
  74. #define DELETE_BIT         0
  75. #define RECURSIVELY_BIT    1
  76. #define BYTE_BIT        2
  77. #define VERBOSE_BIT        3
  78. #define ADD_BIT            4
  79. #define EXTRACT_BIT        5
  80. #define LIST_BIT        6
  81. #define COMMAND_BIT        7
  82. #define STATISTIC_BIT    8
  83. #define DISKREQUEST_BIT    9
  84. #define NEW_BIT            10
  85.  
  86.  
  87. /* Flags */
  88.  
  89. #define DELETE             1<<DELETE_BIT
  90. #define RECURSIVELY     1<<RECURSIVELY_BIT
  91. #define BYTE            1<<BYTE_BIT
  92. #define VERBOSE            1<<VERBOSE_BIT
  93. #define ADD                1<<ADD_BIT
  94. #define EXTRACT            1<<EXTRACT_BIT
  95. #define LIST            1<<LIST_BIT
  96. #define COMMAND            1<<COMMAND_BIT
  97. #define STATISTIC        1<<STATISTIC_BIT
  98. #define DISKREQUEST        1<<DISKREQUEST_BIT
  99. #define NEW                1<<NEW_BIT
  100.  
  101.  
  102.         /* Variabili Globali */
  103.  
  104. char FileNameBackup[100];
  105. struct Backup Backup = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,0,0,0,0,0,0,0};
  106.  
  107.  
  108. /********************************************************
  109. *                                                        *
  110. *    void                                                *
  111. *    StripNewLinee(Stringa)                                *
  112. *                                                        *
  113. *    $INPUT    :    Puntatore alla Stringa da elaborare        *
  114. *    $OUTPUT    :    NULL                                    *
  115. *                                                        *
  116. *    $NOTE:    Funzione che elimina il carattere di di     *
  117. *                        RETURN     alla Stringa            *
  118. *                                                        *
  119. ********************************************************/
  120. void
  121. StripNewLinee(Stringa)
  122. char *Stringa;
  123. {
  124.     while(*Stringa && *Stringa!='\n')
  125.           Stringa++;
  126.     *Stringa='\0';
  127. }
  128.  
  129. /********************************************************
  130. *  int                                                    *
  131. *  IsSpecDevice(char *Stringa)                            *
  132. *                                                        *
  133. *    $NOTE:     Dice se in un Path completo e speciaficato    *
  134. *            anche il device o solo la directory            *
  135. *                    Amiga-Ibm                            *
  136. *                                                        *
  137. *********************************************************/
  138. int
  139. IsSpecDevice(Stringa)
  140. char *Stringa;
  141. {
  142. #ifndef AMIGA
  143.     if(*Stringa=='/')
  144.         return(1);
  145. #endif
  146.     while(*Stringa!='\0' && *Stringa!=':')
  147.         Stringa++;
  148.     if(*Stringa==':')
  149.         return(1);
  150.     else
  151.         return(0);
  152. }
  153.  
  154. /********************************************************
  155. *  char *                                                *
  156. *  OnlyFileName(char *Stringa)                            *
  157. *                                                        *
  158. *    $NOTE:     Prende da un Path Completo solo il file        *
  159. *                                                        *
  160. *********************************************************/
  161. char    FileNameOnly[100];
  162.  
  163. char *
  164. OnlyFileName(Stringa)
  165. char *Stringa;
  166. {
  167.     int     i;
  168.  
  169.     i=strlen(Stringa);
  170.     while(*Stringa!='\0')
  171.         Stringa++;
  172.     while(*Stringa!='/' && *Stringa!=':' && i)
  173.     {
  174.         Stringa--;
  175.         i--;
  176.     }
  177.     Stringa++;
  178.     strcpy(FileNameOnly,Stringa);
  179.     return(FileNameOnly);
  180. }
  181.  
  182. /********************************************************
  183. *  void                                                    *
  184. *  OnlyPathName(char *Stringa)                            *
  185. *                                                        *
  186. *    $NOTE:     Prende da un Path Completo solo le directory*
  187. *                                                        *
  188. *********************************************************/
  189. int
  190. OnlyPathName(Stringa)
  191. char *Stringa;
  192. {
  193.     int     i=0;
  194.     char *c=NULL;
  195.  
  196.     while(*Stringa!='\0')
  197.     {
  198.         Stringa++;
  199.         if(*Stringa=='/')
  200.         {
  201.             c=Stringa;
  202.             i++;
  203.         }
  204.  
  205.     }
  206.     if(c)
  207.         *c='\0';
  208.     return(i);
  209. }
  210.  
  211. /********************************************************
  212. *  void                                                    *
  213. *  AddPoint(char *Stringa)                                *
  214. *                                                        *
  215. *    $NOTE    Aggiunge estensione Numerata al file        *
  216. *                                                        *
  217. *********************************************************/
  218. void
  219. AddPoint(Stringa)
  220. char *Stringa;
  221. {
  222.     while(*Stringa!='.' && *Stringa!='\0')
  223.         Stringa++;
  224.     *Stringa='\0';
  225.     strcat(Stringa,".000");
  226. }
  227.  
  228. /********************************************************
  229. *                                                        *
  230. *    void                                                *
  231. *    CloseAll()                                            *
  232. *                                                        *
  233. *  Chiusura genarale del programma                        *
  234. *                                                        *
  235. ********************************************************/
  236. void
  237. CloseAll(String)
  238. {
  239.     printf("\t%s\n\n",String);
  240.     if(Backup.Buffer)
  241.          free(Backup.Buffer);
  242.     if(Backup.BackupFile)
  243.         fclose(Backup.BackupFile);
  244.     exit(0);
  245. }
  246.  
  247. /********************************************************
  248. *                                                        *
  249. *    void                                                *
  250. *    FindLastBackupFile(char *)                            *
  251. *                                                        *
  252. *    Ricerca ultimo file di Backup per fare l'append        *
  253. *                                                        *
  254. ********************************************************/
  255. void
  256. FindLastBackupFile(FileName)
  257. char *FileName;
  258. {
  259.         struct stat          InfoFile;                    /* Struttura info del File          */
  260.         struct stat          InfoFileBack;                /* Struttura info del File copy  */
  261.         char            FileNameBack[100];            /* Vecchio nome da conservare    */
  262.         int                controllo=0;
  263.  
  264.         while(!stat(FileName,&InfoFile))
  265.         {
  266.             memcpy(&InfoFileBack,&InfoFile,sizeof(InfoFile));
  267.             strcpy(FileNameBack,FileName);
  268.             Incremento(FileName);
  269.             controllo=1;                            /*         Animalata             */
  270.         }
  271.         if(controllo)
  272.         {
  273.             strcpy(FileName,FileNameBack);
  274.             Backup.AttualLength=InfoFileBack.st_size;
  275.         }
  276. }
  277.  
  278. /********************************************************
  279. *                                                        *
  280. *    void                                                *
  281. *    OpenUp()                                            *
  282. *                                                        *
  283. *    Apertura generale                                    *
  284. *                                                        *
  285. ********************************************************/
  286. void
  287. OpenUp(argc,argv)
  288. int     argc;
  289. char    **argv;
  290. {
  291.     char    Dir[100];
  292.  
  293.     Presentation();
  294.     if(argc<3)
  295.         Usage();
  296.     getcwd(Backup.Old,100);
  297.     CheckInput(argc,argv);
  298.     if(!(Backup.Buffer=(void *)malloc(BUFLEN)))
  299.         CloseAll("No enought memory");
  300.  
  301.     strcpy(Dir,Backup.Old);
  302.     if(Dir[strlen(Dir)-1]!=':')
  303.         strcat(Dir,"/");
  304.  
  305.     strcpy(FileNameBackup,OnlyFileName(Backup.FileName));
  306.     if(!IsSpecDevice(Backup.FileName))
  307.     {
  308.         strcat(Dir,Backup.FileName);
  309.         strcpy(Backup.FileName,Dir);
  310.     }
  311.     AddPoint(Backup.FileName);
  312.  
  313. }
  314.  
  315.  
  316. /********************************************************
  317. *                                                        *
  318. *    void                                                *
  319. *    Incremento()                                        *
  320. *                                                        *
  321. *   incrementa ad una stringa del tipo name000            *
  322. *    il numero Finale                                    *
  323. *                                                        *
  324. ********************************************************/
  325.  
  326. void Incremento(c)
  327. char    *c;
  328. {
  329.     int  valore;
  330.     int  cent,dec,un;
  331.  
  332. while (*c!='\0')
  333.     c++;
  334.     c-=3;
  335.     valore=atoi(c);
  336.     valore++;
  337.     cent=valore/100;
  338.     valore=valore-100*cent;
  339.     dec=valore/10;
  340.     valore=valore-10*dec;
  341.     un=valore;
  342.     *c=cent+48;
  343.     c++;
  344.     *c=dec+48;
  345.     c++;
  346.     *c=un+48;
  347.  
  348. }
  349.  
  350. /********************************************************
  351. *                                                        *
  352. *    void                                                *
  353. *    OpenBackupFile()                                    *
  354. *                                                        *
  355. *    Apre il file per Il Backup                            *
  356. *                                                        *
  357. ********************************************************/
  358. void
  359. OpenBackupFile(Name)
  360. char *Name;
  361. {
  362.     if(!(CHECK_MASK(Backup.Flags,DISKREQUEST)))
  363.     {
  364.         printf("\nInsert disk to save file: %s and press Return",Name);
  365.         (void)getchar();
  366.     }
  367.     if(CHECK_MASK(Backup.Flags,NEW))
  368.     {
  369.         if(!(Backup.BackupFile=fopen(Name,"wb")))
  370.             CloseAll("Can't open Backup file");
  371.     }
  372.     else
  373.     {
  374.         if(!(Backup.BackupFile=fopen(Name,"ab")))
  375.             CloseAll("Can't open Backup file");
  376.     }
  377.     if(!(CHECK_MASK(Backup.Flags,VERBOSE)))
  378.         printf("\n\tMake %s Backup File\n\n",Name);
  379.     Backup.FilesBack++;
  380. }
  381.  
  382. /********************************************************
  383. *                                                        *
  384. *    void                                                *
  385. *    OpenRestoreFile()                                    *
  386. *                                                        *
  387. *    Apre il file per Il Backup                            *
  388. *                                                        *
  389. ********************************************************/
  390. void
  391. OpenRestoreFile(Name)
  392. char *Name;
  393. {
  394.     char Risposta[100];
  395.  
  396.     if(!(CHECK_MASK(Backup.Flags,DISKREQUEST)))
  397.     {
  398.         printf("\nInsert disk with file: %s and press Return",Name);
  399.         (void)getchar();
  400.     }
  401. riprova:
  402.     if(!(Backup.BackupFile=fopen(Name,"rb")))
  403.     {
  404.         printf("\n\tFile %s not found check disk please \n",Name);
  405.         printf("Do you want continue (y/n) : ");
  406.         fgets(Risposta,100,stdin);
  407.         if(Risposta[0]=='n')
  408.             CloseAll("Can't open Backup file");
  409.         else
  410.             goto riprova;
  411.     }
  412.     fseek(Backup.BackupFile,0,SEEK_END);
  413.     Backup.Length=ftell(Backup.BackupFile);
  414.     rewind(Backup.BackupFile);
  415.     Backup.AttualLength=0;
  416.     Backup.FilesBack++;
  417. }
  418.  
  419.  
  420. /********************************************************
  421. *                                                        *
  422. *    void                                                *
  423. *    BackupDirectory()                                    *
  424. *                                                        *
  425. *    Aggiunge una Directory intera al Backup al file     *
  426. *    di Backup                                            *
  427. *                                                        *
  428. ********************************************************/
  429. void
  430. BackupDirectory(DirName)
  431. char *DirName;
  432. {
  433. int             ret;
  434. DIR             *Dir;                        /*Struttura direttory*/
  435. struct dirent     *dptr;                        /*Struttura contenuto directory*/
  436. struct stat          InfoFile;                    /*Struttura info del File*/
  437. char            FileName[100];
  438.  
  439.     if(!(Dir=opendir(DirName)))
  440.         CloseAll("Directory not Found");
  441. #ifndef Amiga
  442.     if(DirName[0]=='.')
  443.         strcpy(DirName,"");
  444. #endif
  445.     while(dptr=readdir(Dir))
  446.     {
  447. #ifndef AMIGA                                                /* UNIX & PC */
  448.         if(!(strcmp(dptr->d_name,".") && strcmp(dptr->d_name,"..")))
  449.             continue;
  450. #endif
  451.         strcpy(FileName,DirName);
  452.         if(FileName[0]!='\0')
  453.             if(FileName[strlen(FileName)-1]!=':')
  454.                 strcat(FileName,"/");
  455.         strcat(FileName,dptr->d_name);
  456.         stat(FileName,&InfoFile);
  457. #ifdef AMIGA
  458.         if(!(InfoFile.st_mode&S_IFDIR))
  459.             ret=JoinToBackup(FileName,&InfoFile);
  460.         else if(CHECK_MASK(Backup.Flags,RECURSIVELY))
  461.             BackupDirectory(FileName);
  462. #else                                                        /*  UNIX   */
  463.         if(S_ISREG(InfoFile.st_mode))
  464.             ret=JoinToBackup(FileName,&InfoFile);
  465.         else if(CHECK_MASK(Backup.Flags,RECURSIVELY))
  466.         {
  467.             if(S_ISDIR(InfoFile.st_mode))
  468.                 BackupDirectory(FileName);
  469.         }
  470. #endif
  471.         if((CHECK_MASK(Backup.Flags,DELETE)) && ret)
  472.             remove(FileName);
  473.     }
  474.     closedir(Dir);
  475. }
  476.  
  477. /********************************************************
  478. *                                                        *
  479. *    void                                                *
  480. *    CheckWrite()                                        *
  481. *                                                        *
  482. *    Controlla che nella scrittura tutto e' andato bene    *
  483. *                                                        *
  484. ********************************************************/
  485. void
  486. CheckWrite(AttualWrite,RealWrite,Name)
  487. int AttualWrite;
  488. int RealWrite;
  489. char *Name;
  490. {
  491.     char Result[80];
  492.  
  493.     printf("\t\t\n\nError in Add file %s\n",Name);
  494.     printf("Do you want continue (y/n) : ");
  495.     fgets(Result,80,stdin);
  496.     if(Result[0]=='y')
  497.     {
  498.  
  499.     }
  500.     else
  501.     {
  502.  
  503.     }
  504.  
  505. }
  506.  
  507. /********************************************************
  508. *                                                        *
  509. *    void                                                *
  510. *    JoinToBackup()                                        *
  511. *                                                        *
  512. *    Aggiunge un file Al file di Backup                    *
  513. *                                                        *
  514. ********************************************************/
  515. int
  516. JoinToBackup(Name,Info)
  517. char             *Name;
  518. struct stat          *Info;
  519. {
  520.  
  521.     char NameTmp[100],NameTmp2[100],Length[12];
  522.     char *WriteName;
  523.     int length;
  524.  
  525.     Backup.Size=Info->st_size;
  526.     Backup.Total+=Backup.Size;
  527.     Backup.TotalBack+=Backup.Size;
  528.  
  529.     strcpy(NameTmp,Name);
  530.     NameTmp[strlen(NameTmp)-4]='\0';
  531.     if(!(strcmp(OnlyFileName(NameTmp),FileNameBackup)))
  532.         return(0);                                            /* Salta i file di Backup */
  533.     if(!(Backup.file=fopen(Name,"rb")))
  534.     {
  535.         printf("Can't open file: %s Skip\n",Name);
  536.         return(0);
  537.     }
  538.     Backup.Files++;
  539.  
  540.     strcpy(NameTmp,Name);
  541.     strcpy(NameTmp2,Name);
  542.  
  543.     WriteName=strtok(NameTmp2,":");
  544.     if(strcmp(WriteName,NameTmp))
  545.         WriteName=strtok(NULL,":");
  546.  
  547.     strcpy(NameTmp,WriteName);
  548.  
  549.     sprintf(Length,"%10d\n",Backup.Size);
  550.  
  551.     length=strlen(WriteName);            /* add \n all nome */
  552.     WriteName[length]='\n';
  553.     WriteName[length+1]='\0';
  554.  
  555.     fputs(WriteName,Backup.BackupFile);
  556.     fputs(Length,Backup.BackupFile);
  557.  
  558.     Backup.AttualLength+=length+12;
  559.     Backup.TotalBack+=length+12;
  560.  
  561. restart:
  562.     if(!(CHECK_MASK(Backup.Flags,VERBOSE)))
  563.     {
  564.         if(CHECK_MASK(Backup.Flags,DELETE))
  565.             printf("Add file: %8d  %s & Delete\n",Backup.Size,NameTmp);
  566.         else
  567.             printf("Add file: %8d  %s\n",Backup.Size,NameTmp);
  568.     }
  569.     while((Backup.Size>=BUFLEN) && ((Backup.Length-Backup.AttualLength)>=BUFLEN))
  570.     {
  571.         fread(Backup.Buffer,sizeof(char),BUFLEN,Backup.file);
  572.         CheckWrite(fwrite(Backup.Buffer,sizeof(char),BUFLEN,Backup.BackupFile),BUFLEN,NameTmp);
  573.         Backup.Size-=BUFLEN;
  574.         Backup.AttualLength+=BUFLEN;
  575.     }
  576.     if(Backup.Size<BUFLEN && ((Backup.Length-Backup.AttualLength)>=Backup.Size))
  577.     {
  578.         fread(Backup.Buffer,sizeof(char),Backup.Size,Backup.file);
  579.         fwrite(Backup.Buffer,sizeof(char),Backup.Size,Backup.BackupFile);
  580.         Backup.AttualLength+=Backup.Size;
  581.         fclose(Backup.file);
  582.         return(1);
  583.     }                    /*finito il file da fare Backup*/
  584.     else
  585.     {
  586.         fread(Backup.Buffer,sizeof(char),Backup.Length-Backup.AttualLength,Backup.file);
  587.         fwrite(Backup.Buffer,sizeof(char),Backup.Length-Backup.AttualLength,Backup.BackupFile);
  588.  
  589.         Backup.Size-=(Backup.Length-Backup.AttualLength);
  590.         fclose(Backup.BackupFile);
  591.         Incremento(Backup.FileName);
  592.         OpenBackupFile(Backup.FileName);
  593.         Backup.AttualLength=0;
  594.         goto    restart;
  595.     }                    /*finito il file di Backup*/
  596. }
  597.  
  598. /********************************************************
  599. *                                                        *
  600. *    void                                                *
  601. *    SkipToNext()                                        *
  602. *                                                        *
  603. *    Salta al prossimo file di Backup                    *
  604. *                                                        *
  605. ********************************************************/
  606. void
  607. SkipToNext()
  608. {
  609.  
  610. NewFile:
  611.  
  612.     if((Backup.Length-Backup.AttualLength)>=Backup.Size)
  613.     {
  614.         fseek(Backup.BackupFile,Backup.Size,SEEK_CUR);
  615.         Backup.AttualLength+=Backup.Size;
  616.         return;
  617.     }
  618.     else
  619.     {
  620.  
  621.         Backup.Size-=Backup.Length-Backup.AttualLength;
  622.         fclose(Backup.BackupFile);
  623.         Incremento(Backup.FileName);
  624.         OpenRestoreFile(Backup.FileName);
  625.         goto    NewFile;
  626.     }
  627. }
  628.  
  629. /********************************************************
  630. *                                                        *
  631. *    void                                                *
  632. *    MakeDirectory(char *)                                *
  633. *                                                        *
  634. *    Crea le directory del Path se non esistono            *
  635. *                                                        *
  636. ********************************************************/
  637. void
  638. MakeDirectory(Path)
  639. char *Path;
  640. {
  641.     DIR             *Dir;                        /*Struttura direttory*/
  642.     char            *DirName;
  643.     char            Directory[100];
  644.     int                c,i;
  645.     char            OldDir[100];
  646.  
  647.     getcwd(OldDir,100);
  648.     strcpy(Directory,Path);
  649.     c=OnlyPathName(Directory);
  650.     DirName=strtok(Directory,"/");
  651.  
  652.     for(i=0;i<c;i++)
  653.     {
  654.  
  655.         if(!(Dir=opendir(DirName)))
  656.         {
  657. #ifdef AMIGA
  658.             if(mkdir(DirName))
  659. #else
  660.             if(mkdir(DirName,S_IRWXU))
  661. #endif
  662.                 CloseAll("Can't create directory");
  663.         }
  664.         else
  665.             closedir(Dir);
  666.         chdir(DirName);
  667.         DirName=strtok(NULL,"/");
  668.  
  669.     }
  670.     chdir(OldDir);
  671.  
  672. }
  673.  
  674. /********************************************************
  675. *                                                        *
  676. *    void                                                *
  677. *    RestoreFile()                                        *
  678. *                                                        *
  679. *    Estrae i file dal Backup                            *
  680. *                                                        *
  681. ********************************************************/
  682. void
  683. RestoreFile()
  684. {
  685.     char FileName[100];
  686.     char Length[12];
  687.     char OldFileName[100];
  688.  
  689.     chdir(Backup.Name);
  690.  
  691. restart:
  692.     fgets(FileName,100,Backup.BackupFile);
  693.     fgets(Length,11,Backup.BackupFile);
  694.     fgetc(Backup.BackupFile);
  695.     Backup.Size=atoi(Length);
  696.     if(strcmp(FileName,OldFileName))
  697.     {
  698.         Backup.Files++;
  699.         Backup.AttualLength+=(strlen(FileName)+strlen(Length)+1);
  700.         Backup.Total+=Backup.Size;
  701.         StripNewLinee(FileName);
  702.         strcpy(OldFileName,FileName);
  703.         if(!(CHECK_MASK(Backup.Flags,VERBOSE)))
  704.             printf("Extract file: %8d  %s\n",Backup.Size,FileName);
  705.         MakeDirectory(FileName);
  706.         if(!(Backup.file=fopen(FileName,"wb")))
  707.         {
  708.             printf("Can't open file: %s Skip\n",FileName);
  709.             SkipToNext();
  710.             goto restart;
  711.         }
  712.     }
  713.     else
  714.     {
  715.         fclose(Backup.BackupFile);
  716.         if(CHECK_MASK(Backup.Flags,DELETE))
  717.         {
  718.             if(!(CHECK_MASK(Backup.Flags,VERBOSE)))
  719.                 printf("Delete Backup File: %s\n",Backup.FileName);
  720.             remove(Backup.FileName);
  721.         }
  722.         chdir(Backup.Old);
  723.         printf("\n\tRestore Complete\n");
  724.         printf("\t\tNumber of File              : %8d\n",Backup.Files);
  725.         printf("\t\tTotal Byte Restored            : %8d\n",Backup.Total);
  726.         printf("\t\tNumber of Backup File       : %8d\n",Backup.FilesBack);
  727.         CloseAll("");
  728.     }
  729. NewFile:
  730.     while((Backup.Size>=BUFLEN) && ((Backup.Length-Backup.AttualLength)>=BUFLEN))
  731.     {
  732.         fread(Backup.Buffer,sizeof(char),BUFLEN,Backup.BackupFile);
  733.         fwrite(Backup.Buffer,sizeof(char),BUFLEN,Backup.file);
  734.         Backup.Size-=BUFLEN;
  735.         Backup.AttualLength+=BUFLEN;
  736.     }
  737.     if(Backup.Size<BUFLEN && ((Backup.Length-Backup.AttualLength)>=Backup.Size))
  738.     {
  739.         fread(Backup.Buffer,sizeof(char),Backup.Size,Backup.BackupFile);
  740.         fwrite(Backup.Buffer,sizeof(char),Backup.Size,Backup.file);
  741.         Backup.AttualLength+=Backup.Size;
  742.         fclose(Backup.file);
  743.         goto restart;
  744.     }                    /*finito il file da fare Backup*/
  745.     else
  746.     {
  747.         fread(Backup.Buffer,sizeof(char),Backup.Length-Backup.AttualLength,Backup.BackupFile);
  748.         fwrite(Backup.Buffer,sizeof(char),Backup.Length-Backup.AttualLength,Backup.file);
  749.  
  750.         Backup.Size-=(Backup.Length-Backup.AttualLength);
  751.         fclose(Backup.BackupFile);
  752.         if(CHECK_MASK(Backup.Flags,DELETE))
  753.         {
  754.             if(!(CHECK_MASK(Backup.Flags,VERBOSE)))
  755.                 printf("Delete Backup File: %s\n",Backup.FileName);
  756.             remove(Backup.FileName);
  757.         }
  758.         Incremento(Backup.FileName);
  759.         OpenRestoreFile(Backup.FileName);
  760.         goto    NewFile;
  761.     }                    /*finito il file di Backup*/
  762.  
  763. }
  764.  
  765. /********************************************************
  766. *                                                        *
  767. *    void                                                *
  768. *    ListBackupFile()                                    *
  769. *                                                        *
  770. *    Visualizza i file dal Backup                        *
  771. *                                                        *
  772. ********************************************************/
  773. void
  774. ListBackupFile()
  775. {
  776.     char FileName[256],Length[12];
  777.     char OldFileName[100];
  778.  
  779. restart:
  780.     fgets(FileName,100,Backup.BackupFile);
  781.     fgets(Length,11,Backup.BackupFile);
  782.     fgetc(Backup.BackupFile);
  783.     Backup.Size=atoi(Length);
  784.  
  785.     if(strcmp(FileName,OldFileName))
  786.     {
  787.         Backup.Files++;
  788.         Backup.Total+=Backup.Size;
  789.         Backup.TotalBack+=strlen(FileName)+11+Backup.Size;
  790.         Backup.AttualLength+=(strlen(FileName)+11);
  791.         StripNewLinee(FileName);
  792.         strcpy(OldFileName,FileName);
  793.         printf("List file: %8d  %s\n",Backup.Size,FileName);
  794.     }
  795.     else
  796.     {
  797.         printf("\n");
  798.         printf("\tList Complete\n");
  799.         printf("\t\tNumber of file                 : %8d\n",Backup.Files);
  800.         printf("\t\tTotal byte                       : %8d\n",Backup.Total);
  801.         printf("\t\tTotal byte backup file            : %8d\n",Backup.TotalBack);
  802.         printf("\t\tNumber of backup File          : %8d\n",Backup.FilesBack);
  803.         printf("\t\tLength of last backup file     : %8d\n",Backup.Length);
  804.         CloseAll("");
  805.     }
  806.     SkipToNext();
  807.     goto restart;
  808. }
  809.  
  810. /********************************************************
  811. *                                                        *
  812. *    void                                                *
  813. *    DirectoryStat()                                        *
  814. *                                                        *
  815. *    Calcola lo spazio di occupazione di una directory     *
  816. *    per il Backup                                        *
  817. *                                                        *
  818. ********************************************************/
  819. void
  820. DirectoryStat(DirName)
  821. char *DirName;
  822. {
  823. DIR             *Dir;                        /* Struttura direttory                */
  824. struct dirent     *dptr;                        /* Struttura contenuto directory    */
  825. struct stat          InfoFile;                    /* Struttura info del File            */
  826. char            FileName[100],NameTmp[100],NameTmp2[100];
  827. char            *WriteName;
  828.  
  829.     if(!(Dir=opendir(DirName)))
  830.         CloseAll("Directory not Found");
  831.     while(dptr=readdir(Dir))
  832.     {
  833. #ifndef AMIGA
  834.         if(!(strcmp(dptr->d_name,".") && strcmp(dptr->d_name,"..")))
  835.             continue;
  836. #endif
  837.         strcpy(FileName,DirName);
  838.         if(FileName[0]!='\0')
  839.             if(FileName[strlen(FileName)-1]!=':')
  840.                 strcat(FileName,"/");
  841.         strcat(FileName,dptr->d_name);
  842.         stat(FileName,&InfoFile);
  843.  
  844.         strcpy(NameTmp,FileName);
  845.         strcpy(NameTmp2,FileName);
  846.  
  847.         WriteName=strtok(NameTmp2,":");
  848.         if(strcmp(WriteName,NameTmp))
  849.             WriteName=strtok(NULL,":");
  850.  
  851. #ifdef AMIGA
  852.         if(!(InfoFile.st_mode&S_IFDIR))
  853.         {
  854.             Backup.Files++;
  855.             Backup.TotalBack+=strlen(WriteName)+12+InfoFile.st_size;     /* Lunghezza file + spazio occupato per il nome e
  856.                                                                                 i dati per la lunghezza */
  857.             Backup.Total+=InfoFile.st_size;
  858.         }
  859.         else if(CHECK_MASK(Backup.Flags,RECURSIVELY))
  860.             DirectoryStat(FileName);
  861. #else
  862.         if(S_ISREG(InfoFile.st_mode))
  863.         {
  864.             Backup.Files++;
  865.             Backup.TotalBack+=strlen(WriteName)+12+InfoFile.st_size;
  866.             Backup.Total+=InfoFile.st_size;
  867.     }
  868.         else if(CHECK_MASK(Backup.Flags,RECURSIVELY))
  869.         {
  870.             if(S_ISDIR(InfoFile.st_mode))
  871.                 DirectoryStat(FileName);
  872.         }
  873. #endif
  874.     }
  875.     closedir(Dir);
  876. }
  877.  
  878. /********************************************************
  879. *                                                        *
  880. *    void                                                *
  881. *    Presentation()                                        *
  882. *                                                        *
  883. *    Presentazione                                        *
  884. *                                                        *
  885. ********************************************************/
  886. void
  887. Presentation()
  888. {
  889.     printf("\n");
  890.     printf("                    Skandal Backup Program V1.1\n");
  891.     printf("                     Author Pozzoli Alessandro\n");
  892.     printf("                          Copyright 1994\n");
  893. #ifdef AMIGA
  894.     printf("                           Amiga Version\n\n");
  895. #else
  896.     printf("                            Unix Version\n\n");
  897. #endif
  898.     printf("All rights reserved. Not for commercial use.\n");
  899.     printf("Compatibility:  Amiga - Unix - Ms-Dos\n");
  900.     printf("For Infos or Bug Mail pozzoli@ghost.dsi.unimi.it University of Milano\n\n");
  901. }
  902.  
  903. /********************************************************
  904. *                                                        *
  905. *    void                                                *
  906. *    Usage()                                                *
  907. *                                                        *
  908. *    Semplice Manuale                                    *
  909. *                                                        *
  910. ********************************************************/
  911. void
  912. Usage()
  913. {
  914.     printf("Usage : Backup [-<option>] <command) Backup_File length_archive [Dir]\n");
  915.     printf("                                       (a,e,l)       (a,s)\n\n");
  916.     printf(" Command:\n");
  917.     printf("   a  add files \n");
  918.     printf("   e  extract files \n");
  919.     printf("   l  list files \n");
  920.     printf("   s  statistic files occupation\n\n");
  921.  
  922.     printf(" Option:\n");
  923.     printf("  -n  Create new backup file (not append) (a)\n");
  924.     printf("  -d  delete  files (a,e)\n");
  925.     printf("  -r  recursively directory (a,s) \n");
  926.     printf("  -b  length in byte (a,s) \n");
  927.     printf("  -v  verbose mode off (a,e)\n");
  928.     printf("  -k  disk request off (a,e,l)\n\n");
  929.  
  930.     CloseAll("");
  931. }
  932.  
  933. /********************************************************
  934. *                                                        *
  935. *    void                                                *
  936. *    CheckInput(argc,argv)                                *
  937. *                                                        *
  938. *    Contolla Parametri in Ingresso                        *
  939. *                                                        *
  940. ********************************************************/
  941. void
  942. CheckInput(argc,argv)
  943. int        argc;
  944. char    *argv[];
  945. {
  946.     char    Command[50];
  947.     int        i=0;
  948.  
  949.     strcpy(Command,argv[1]);                /*Copia opzioni*/
  950.  
  951.     if(Command[i]=='-')      /* sono delle opzioni */
  952.     {
  953.         i++;
  954.         do
  955.         {
  956.             switch(Command[i])
  957.             {
  958.                 case    'n':
  959.                                 SET_MASK(Backup.Flags,NEW);
  960.                                 break;
  961.                 case    'd':
  962.                                 SET_MASK(Backup.Flags,DELETE);
  963.                                 break;
  964.                 case    'v':
  965.                                 SET_MASK(Backup.Flags,VERBOSE);
  966.                                 break;
  967.                 case    'b':
  968.                                 SET_MASK(Backup.Flags,BYTE);
  969.                                 break;
  970.                 case    'r':
  971.                                 SET_MASK(Backup.Flags,RECURSIVELY);
  972.                                 break;
  973.                 case    'k':
  974.                                 SET_MASK(Backup.Flags,DISKREQUEST);
  975.                                 break;
  976.                 default:
  977.                                 Usage();
  978.                                 break;
  979.             }
  980.             i++;
  981.         }while(Command[i]!='\0');
  982.         strcpy(Command,argv[2]);                /*Copia comandi*/
  983.         strcpy(Backup.FileName,argv[3]);
  984.         SET_MASK(Backup.Flags,COMMAND);
  985.     }
  986.     else
  987.     {
  988.         strcpy(Command,argv[1]);                /*Copia comandi*/
  989.         strcpy(Backup.FileName,argv[2]);
  990.     }
  991.     if(Command[1]=='\0')
  992.     {    switch(Command[0])
  993.         {
  994.             case    'a':
  995.                             SET_MASK(Backup.Flags,ADD);
  996.                             break;
  997.             case    'e':
  998.                             SET_MASK(Backup.Flags,EXTRACT);
  999.                             break;
  1000.             case    'l':
  1001.                             SET_MASK(Backup.Flags,LIST);
  1002.                             break;
  1003.             case    's':
  1004.                             SET_MASK(Backup.Flags,STATISTIC);
  1005.                             break;
  1006.             default:
  1007.                             Usage();
  1008.                             break;
  1009.         }
  1010.     }
  1011.     else
  1012.         Usage();
  1013.  
  1014.     if(CHECK_MASK(Backup.Flags,COMMAND) && CHECK_MASK(Backup.Flags,STATISTIC))
  1015.     {
  1016.  
  1017.         if(argc==5)
  1018.             strcpy(Backup.Name,argv[4]);
  1019.         else
  1020. #ifdef AMIGA
  1021.             strcpy(Backup.Name,"");
  1022. #else
  1023.             strcpy(Backup.Name,".");
  1024. #endif
  1025.         if(!(Backup.Length=atoi(argv[3])))
  1026.             Usage();
  1027.     }
  1028.     else if(CHECK_MASK(Backup.Flags,STATISTIC))
  1029.     {
  1030.  
  1031.         if(argc==4)
  1032.             strcpy(Backup.Name,argv[3]);
  1033.         else
  1034. #ifdef AMIGA
  1035.             strcpy(Backup.Name,"");
  1036. #else
  1037.             strcpy(Backup.Name,".");
  1038. #endif
  1039.         if(!(Backup.Length=atoi(argv[2])))
  1040.             Usage();
  1041.     }
  1042.     else if( CHECK_MASK(Backup.Flags,COMMAND) && CHECK_MASK(Backup.Flags,ADD))
  1043.     {
  1044.         if(argc==6)
  1045.             strcpy(Backup.Name,argv[5]);
  1046.         else
  1047. #ifdef AMIGA
  1048.             strcpy(Backup.Name,"");
  1049. #else
  1050.             strcpy(Backup.Name,".");
  1051. #endif
  1052.         if(!(Backup.Length=atoi(argv[4])))
  1053.             Usage();
  1054.     }
  1055.     else if(CHECK_MASK(Backup.Flags,ADD))
  1056.     {
  1057.         if(argc==5)
  1058.             strcpy(Backup.Name,argv[4]);
  1059.         else
  1060. #ifdef AMIGA
  1061.             strcpy(Backup.Name,"");
  1062. #else
  1063.             strcpy(Backup.Name,".");
  1064. #endif
  1065.         if(!(Backup.Length=atoi(argv[3])))
  1066.         Usage();
  1067.     }
  1068.     else if(CHECK_MASK(Backup.Flags,COMMAND))
  1069.     {
  1070.         if(argc==5)
  1071.             strcpy(Backup.Name,argv[4]);
  1072.         else
  1073. #ifdef AMIGA
  1074.             strcpy(Backup.Name,"");
  1075. #else
  1076.             strcpy(Backup.Name,".");
  1077. #endif
  1078.     }
  1079.     else
  1080.     {
  1081.         if(argc==4)
  1082.             strcpy(Backup.Name,argv[3]);
  1083.         else
  1084. #ifdef AMIGA
  1085.             strcpy(Backup.Name,"");
  1086. #else
  1087.             strcpy(Backup.Name,".");
  1088. #endif
  1089.     }
  1090.     if(!(CHECK_MASK(Backup.Flags,BYTE)))
  1091.         Backup.Length*=1024;
  1092. }
  1093.  
  1094. /********************************************************
  1095. *                                                        *
  1096. *    void                                                *
  1097. *    main()                                                *
  1098. *                                                        *
  1099. *    Programma principale                                *
  1100. *                                                        *
  1101. ********************************************************/
  1102. main(argc,argv)
  1103. int argc;
  1104. char **argv;
  1105. {
  1106.     OpenUp(argc,argv);
  1107.  
  1108.     if(CHECK_MASK(Backup.Flags,ADD))
  1109.     {
  1110.         if(!(CHECK_MASK(Backup.Flags,NEW)))
  1111.             FindLastBackupFile(Backup.FileName);
  1112.         OpenBackupFile(Backup.FileName);
  1113.         BackupDirectory(Backup.Name);
  1114.         printf("\n\tBackup Complete\n");
  1115.         printf("\t\tNumber of file                 : %8d\n",Backup.Files);
  1116.         printf("\t\tTotal byte                       : %8d\n",Backup.Total);
  1117.         printf("\t\tTotal byte backup file            : %8d\n",Backup.TotalBack);
  1118.         printf("\t\tNumber of backup File          : %8d\n",Backup.FilesBack);
  1119.         printf("\t\tSpace left on last backup file : %8d\n",Backup.Length-Backup.AttualLength);
  1120.     }
  1121.     else if(CHECK_MASK(Backup.Flags,EXTRACT))
  1122.     {
  1123.         OpenRestoreFile(Backup.FileName);
  1124.         RestoreFile();
  1125.     }
  1126.     else if(CHECK_MASK(Backup.Flags,LIST))
  1127.     {
  1128.         OpenRestoreFile(Backup.FileName);
  1129.         ListBackupFile();
  1130.     }
  1131.     else if(CHECK_MASK(Backup.Flags,STATISTIC))
  1132.     {
  1133.         DirectoryStat(Backup.Name);
  1134.         if((Backup.AttualLength=Backup.TotalBack%Backup.Length))
  1135.             Backup.FilesBack=Backup.TotalBack/Backup.Length+1;
  1136.         else
  1137.         {
  1138.             Backup.FilesBack=Backup.TotalBack/Backup.Length;
  1139.             Backup.AttualLength++;
  1140.         }
  1141.  
  1142.  
  1143.         printf("\n\tStatistic Complete\n");
  1144.         printf("\t\tNumber of File                 : %8d\n",Backup.Files);
  1145.         printf("\t\tTotal byte                     : %8d\n",Backup.Total);
  1146.         printf("\t\tTotal byte backup file            : %8d\n",Backup.TotalBack);
  1147.         printf("\t\tNumber of Backup File          : %8d\n",Backup.FilesBack);
  1148.         printf("\t\tSpace left on last backup file : %8d\n",Backup.Length-Backup.AttualLength);
  1149.     }
  1150.     CloseAll("");
  1151. }
  1152.