					/********************************************************
					*														*
					* 	$TITLE		:	Backup.c							*
					*	$AUTHOR		:	Pozzoli Alessandro					*
					* 	$STARTDATE	:	24/3/1994							*
					*														*
					* 	$DATE		:	26/4/1994							*
					*	$VERSION	:	1.1									*
					*														*
					* 	$DATE		:	20/5/1994							*
					*	$VERSION	:	1.2									*
					*														*
					*	$NOTE		:	Creazione di file di backup per		*
					*					 Amiga Unix & PC					*
					*														*
					*********************************************************/


	    /* 		   Include 		*/

#include<stdio.h>
#include<string.h>
#ifdef AMIGA
#include<sys/dir.h>
#else
#include<sys/dirent.h>
#endif
#include<sys/stat.h>


		/*  		Macro 		*/

#define SET_MASK(a,b)		a|=b
#define CLR_MASK(a,b)		a&=(UBYTE)(0xFF&~(b))
#define CHECK_MASK(a,b)		a&b

		/* 	   	  Costanti 		*/

#define BUFLEN 		2048*300									/* Grandezza del Buffer dati 		  */


		/*	Proto di programma 	*/

void StripNewLinee();
int IsSpecDevice();
void Presentation();
void Usage();
void CheckInput();
void Incremento();

		/* 		 Strutture		*/

struct Backup
{
	void 			*Buffer;					/* Buffer per lettura e scrittura			*/
	FILE 			*BackupFile;				/* File di Backup							*/
	FILE 			*file;						/* File di cui fare il Backup				*/
	char 			Name[100];					/* Nome della directory da Backup			*/
	char			Old[100];					/* Nome della directory attuale				*/
	char			FileName[100];				/* Nome File Di Backup						*/
	int				Size;						/* Grandezza del file di cui fare il Backup	*/
	int				Length;						/* Lunghezza degli archivi					*/
	int				AttualLength;				/* Posizione attuale nel file Di Backup		*/
	int				Files;						/* Numero dei Files nel Backup				*/
	int				FilesBack;					/* Numero dei Files di Backup				*/
	int				Total;						/* Lunghezza dati nel Backup				*/
	int				TotalBack;					/* Lunghezza reale dei File Di Backup		*/
	int				Flags;						/* Flags di controllo vedere sotto			*/
};


/* Flags Bit */

#define DELETE_BIT 		0
#define RECURSIVELY_BIT	1
#define BYTE_BIT		2
#define VERBOSE_BIT		3
#define ADD_BIT			4
#define EXTRACT_BIT		5
#define LIST_BIT		6
#define COMMAND_BIT		7
#define STATISTIC_BIT	8
#define DISKREQUEST_BIT	9
#define NEW_BIT			10


/* Flags */

#define DELETE 			1<<DELETE_BIT
#define RECURSIVELY 	1<<RECURSIVELY_BIT
#define BYTE			1<<BYTE_BIT
#define VERBOSE			1<<VERBOSE_BIT
#define ADD				1<<ADD_BIT
#define EXTRACT			1<<EXTRACT_BIT
#define LIST			1<<LIST_BIT
#define COMMAND			1<<COMMAND_BIT
#define STATISTIC		1<<STATISTIC_BIT
#define DISKREQUEST		1<<DISKREQUEST_BIT
#define NEW				1<<NEW_BIT


		/* Variabili Globali */

char FileNameBackup[100];
struct Backup Backup = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,0,0,0,0,0,0,0};


/********************************************************
*														*
*	void												*
*	StripNewLinee(Stringa)								*
*														*
*	$INPUT	:	Puntatore alla Stringa da elaborare		*
*	$OUTPUT	:	NULL									*
*														*
*	$NOTE:	Funzione che elimina il carattere di di 	*
*						RETURN 	alla Stringa			*
*														*
********************************************************/
void
StripNewLinee(Stringa)
char *Stringa;
{
	while(*Stringa && *Stringa!='\n')
		  Stringa++;
	*Stringa='\0';
}

/********************************************************
*  int													*
*  IsSpecDevice(char *Stringa)							*
*														*
*	$NOTE: 	Dice se in un Path completo e speciaficato	*
*			anche il device o solo la directory			*
*					Amiga-Ibm							*
*														*
*********************************************************/
int
IsSpecDevice(Stringa)
char *Stringa;
{
#ifndef AMIGA
	if(*Stringa=='/')
		return(1);
#endif
	while(*Stringa!='\0' && *Stringa!=':')
		Stringa++;
	if(*Stringa==':')
		return(1);
	else
		return(0);
}

/********************************************************
*  char *												*
*  OnlyFileName(char *Stringa)							*
*														*
*	$NOTE: 	Prende da un Path Completo solo il file		*
*														*
*********************************************************/
char	FileNameOnly[100];

char *
OnlyFileName(Stringa)
char *Stringa;
{
	int	 i;

	i=strlen(Stringa);
	while(*Stringa!='\0')
		Stringa++;
	while(*Stringa!='/' && *Stringa!=':' && i)
	{
		Stringa--;
		i--;
	}
	Stringa++;
	strcpy(FileNameOnly,Stringa);
	return(FileNameOnly);
}

/********************************************************
*  void													*
*  OnlyPathName(char *Stringa)							*
*														*
*	$NOTE: 	Prende da un Path Completo solo le directory*
*														*
*********************************************************/
int
OnlyPathName(Stringa)
char *Stringa;
{
	int	 i=0;
	char *c=NULL;

	while(*Stringa!='\0')
	{
		Stringa++;
		if(*Stringa=='/')
		{
			c=Stringa;
			i++;
		}

	}
	if(c)
		*c='\0';
	return(i);
}

/********************************************************
*  void													*
*  AddPoint(char *Stringa)								*
*														*
*	$NOTE	Aggiunge estensione Numerata al file		*
*														*
*********************************************************/
void
AddPoint(Stringa)
char *Stringa;
{
	while(*Stringa!='.' && *Stringa!='\0')
		Stringa++;
	*Stringa='\0';
	strcat(Stringa,".000");
}

/********************************************************
*														*
*	void												*
*	CloseAll()											*
*														*
*  Chiusura genarale del programma						*
*														*
********************************************************/
void
CloseAll(String)
{
	printf("\t%s\n\n",String);
	if(Backup.Buffer)
		 free(Backup.Buffer);
	if(Backup.BackupFile)
		fclose(Backup.BackupFile);
	exit(0);
}

/********************************************************
*														*
*	void												*
*	FindLastBackupFile(char *)							*
*														*
*	Ricerca ultimo file di Backup per fare l'append		*
*														*
********************************************************/
void
FindLastBackupFile(FileName)
char *FileName;
{
		struct stat	  	InfoFile;					/* Struttura info del File 		 */
		struct stat	  	InfoFileBack;				/* Struttura info del File copy  */
		char			FileNameBack[100];			/* Vecchio nome da conservare    */
		int				controllo=0;

		while(!stat(FileName,&InfoFile))
		{
			memcpy(&InfoFileBack,&InfoFile,sizeof(InfoFile));
			strcpy(FileNameBack,FileName);
			Incremento(FileName);
			controllo=1;							/*         Animalata			 */
		}
		if(controllo)
		{
			strcpy(FileName,FileNameBack);
			Backup.AttualLength=InfoFileBack.st_size;
		}
}

/********************************************************
*														*
*	void												*
*	OpenUp()											*
*														*
*	Apertura generale									*
*														*
********************************************************/
void
OpenUp(argc,argv)
int 	argc;
char	**argv;
{
	char	Dir[100];

	Presentation();
	if(argc<3)
		Usage();
	getcwd(Backup.Old,100);
	CheckInput(argc,argv);
	if(!(Backup.Buffer=(void *)malloc(BUFLEN)))
		CloseAll("No enought memory");

	strcpy(Dir,Backup.Old);
	if(Dir[strlen(Dir)-1]!=':')
		strcat(Dir,"/");

	strcpy(FileNameBackup,OnlyFileName(Backup.FileName));
	if(!IsSpecDevice(Backup.FileName))
	{
		strcat(Dir,Backup.FileName);
		strcpy(Backup.FileName,Dir);
	}
	AddPoint(Backup.FileName);

}


/********************************************************
*														*
*	void												*
*	Incremento()										*
*														*
*   incrementa ad una stringa del tipo name000			*
*	il numero Finale									*
*														*
********************************************************/

void Incremento(c)
char	*c;
{
	int  valore;
	int  cent,dec,un;

while (*c!='\0')
	c++;
	c-=3;
	valore=atoi(c);
	valore++;
	cent=valore/100;
	valore=valore-100*cent;
	dec=valore/10;
	valore=valore-10*dec;
	un=valore;
	*c=cent+48;
	c++;
	*c=dec+48;
	c++;
	*c=un+48;

}

/********************************************************
*														*
*	void												*
*	OpenBackupFile()									*
*														*
*	Apre il file per Il Backup							*
*														*
********************************************************/
void
OpenBackupFile(Name)
char *Name;
{
	if(!(CHECK_MASK(Backup.Flags,DISKREQUEST)))
	{
		printf("\nInsert disk to save file: %s and press Return",Name);
		(void)getchar();
	}
	if(CHECK_MASK(Backup.Flags,NEW))
	{
		if(!(Backup.BackupFile=fopen(Name,"wb")))
			CloseAll("Can't open Backup file");
	}
	else
	{
		if(!(Backup.BackupFile=fopen(Name,"ab")))
			CloseAll("Can't open Backup file");
	}
	if(!(CHECK_MASK(Backup.Flags,VERBOSE)))
		printf("\n\tMake %s Backup File\n\n",Name);
	Backup.FilesBack++;
}

/********************************************************
*														*
*	void												*
*	OpenRestoreFile()									*
*														*
*	Apre il file per Il Backup							*
*														*
********************************************************/
void
OpenRestoreFile(Name)
char *Name;
{
	char Risposta[100];

	if(!(CHECK_MASK(Backup.Flags,DISKREQUEST)))
	{
		printf("\nInsert disk with file: %s and press Return",Name);
		(void)getchar();
	}
riprova:
	if(!(Backup.BackupFile=fopen(Name,"rb")))
	{
		printf("\n\tFile %s not found check disk please \n",Name);
		printf("Do you want continue (y/n) : ");
		fgets(Risposta,100,stdin);
		if(Risposta[0]=='n')
			CloseAll("Can't open Backup file");
		else
			goto riprova;
	}
	fseek(Backup.BackupFile,0,SEEK_END);
	Backup.Length=ftell(Backup.BackupFile);
	rewind(Backup.BackupFile);
	Backup.AttualLength=0;
	Backup.FilesBack++;
}


/********************************************************
*														*
*	void												*
*	BackupDirectory()									*
*														*
*	Aggiunge una Directory intera al Backup al file 	*
*	di Backup											*
*														*
********************************************************/
void
BackupDirectory(DirName)
char *DirName;
{
int 			ret;
DIR 			*Dir;						/*Struttura direttory*/
struct dirent 	*dptr;						/*Struttura contenuto directory*/
struct stat	  	InfoFile;					/*Struttura info del File*/
char			FileName[100];

	if(!(Dir=opendir(DirName)))
		CloseAll("Directory not Found");
#ifndef Amiga
	if(DirName[0]=='.')
		strcpy(DirName,"");
#endif
	while(dptr=readdir(Dir))
	{
#ifndef AMIGA												/* UNIX & PC */
		if(!(strcmp(dptr->d_name,".") && strcmp(dptr->d_name,"..")))
			continue;
#endif
		strcpy(FileName,DirName);
		if(FileName[0]!='\0')
			if(FileName[strlen(FileName)-1]!=':')
				strcat(FileName,"/");
		strcat(FileName,dptr->d_name);
		stat(FileName,&InfoFile);
#ifdef AMIGA
		if(!(InfoFile.st_mode&S_IFDIR))
			ret=JoinToBackup(FileName,&InfoFile);
		else if(CHECK_MASK(Backup.Flags,RECURSIVELY))
			BackupDirectory(FileName);
#else														/*  UNIX   */
		if(S_ISREG(InfoFile.st_mode))
			ret=JoinToBackup(FileName,&InfoFile);
		else if(CHECK_MASK(Backup.Flags,RECURSIVELY))
		{
			if(S_ISDIR(InfoFile.st_mode))
				BackupDirectory(FileName);
		}
#endif
		if((CHECK_MASK(Backup.Flags,DELETE)) && ret)
			remove(FileName);
	}
	closedir(Dir);
}

/********************************************************
*														*
*	void												*
*	CheckWrite()										*
*														*
*	Controlla che nella scrittura tutto e' andato bene	*
*														*
********************************************************/
void
CheckWrite(AttualWrite,RealWrite,Name)
int AttualWrite;
int RealWrite;
char *Name;
{
	char Result[80];

	printf("\t\t\n\nError in Add file %s\n",Name);
	printf("Do you want continue (y/n) : ");
	fgets(Result,80,stdin);
	if(Result[0]=='y')
	{

	}
	else
	{

	}

}

/********************************************************
*														*
*	void												*
*	JoinToBackup()										*
*														*
*	Aggiunge un file Al file di Backup					*
*														*
********************************************************/
int
JoinToBackup(Name,Info)
char 			*Name;
struct stat	  	*Info;
{

	char NameTmp[100],NameTmp2[100],Length[12];
	char *WriteName;
	int length;

	Backup.Size=Info->st_size;
	Backup.Total+=Backup.Size;
	Backup.TotalBack+=Backup.Size;

	strcpy(NameTmp,Name);
	NameTmp[strlen(NameTmp)-4]='\0';
	if(!(strcmp(OnlyFileName(NameTmp),FileNameBackup)))
		return(0);											/* Salta i file di Backup */
	if(!(Backup.file=fopen(Name,"rb")))
	{
		printf("Can't open file: %s Skip\n",Name);
		return(0);
	}
	Backup.Files++;

	strcpy(NameTmp,Name);
	strcpy(NameTmp2,Name);

	WriteName=strtok(NameTmp2,":");
	if(strcmp(WriteName,NameTmp))
		WriteName=strtok(NULL,":");

	strcpy(NameTmp,WriteName);

	sprintf(Length,"%10d\n",Backup.Size);

	length=strlen(WriteName);			/* add \n all nome */
	WriteName[length]='\n';
	WriteName[length+1]='\0';

	fputs(WriteName,Backup.BackupFile);
	fputs(Length,Backup.BackupFile);

	Backup.AttualLength+=length+12;
	Backup.TotalBack+=length+12;

restart:
	if(!(CHECK_MASK(Backup.Flags,VERBOSE)))
	{
		if(CHECK_MASK(Backup.Flags,DELETE))
			printf("Add file: %8d  %s & Delete\n",Backup.Size,NameTmp);
		else
			printf("Add file: %8d  %s\n",Backup.Size,NameTmp);
	}
	while((Backup.Size>=BUFLEN) && ((Backup.Length-Backup.AttualLength)>=BUFLEN))
	{
		fread(Backup.Buffer,sizeof(char),BUFLEN,Backup.file);
		CheckWrite(fwrite(Backup.Buffer,sizeof(char),BUFLEN,Backup.BackupFile),BUFLEN,NameTmp);
		Backup.Size-=BUFLEN;
		Backup.AttualLength+=BUFLEN;
	}
	if(Backup.Size<BUFLEN && ((Backup.Length-Backup.AttualLength)>=Backup.Size))
	{
		fread(Backup.Buffer,sizeof(char),Backup.Size,Backup.file);
		fwrite(Backup.Buffer,sizeof(char),Backup.Size,Backup.BackupFile);
		Backup.AttualLength+=Backup.Size;
		fclose(Backup.file);
		return(1);
	}					/*finito il file da fare Backup*/
	else
	{
		fread(Backup.Buffer,sizeof(char),Backup.Length-Backup.AttualLength,Backup.file);
		fwrite(Backup.Buffer,sizeof(char),Backup.Length-Backup.AttualLength,Backup.BackupFile);

		Backup.Size-=(Backup.Length-Backup.AttualLength);
		fclose(Backup.BackupFile);
		Incremento(Backup.FileName);
		OpenBackupFile(Backup.FileName);
		Backup.AttualLength=0;
		goto	restart;
	}					/*finito il file di Backup*/
}

/********************************************************
*														*
*	void												*
*	SkipToNext()										*
*														*
*	Salta al prossimo file di Backup					*
*														*
********************************************************/
void
SkipToNext()
{

NewFile:

	if((Backup.Length-Backup.AttualLength)>=Backup.Size)
	{
		fseek(Backup.BackupFile,Backup.Size,SEEK_CUR);
		Backup.AttualLength+=Backup.Size;
		return;
	}
	else
	{

		Backup.Size-=Backup.Length-Backup.AttualLength;
		fclose(Backup.BackupFile);
		Incremento(Backup.FileName);
		OpenRestoreFile(Backup.FileName);
		goto	NewFile;
	}
}

/********************************************************
*														*
*	void												*
*	MakeDirectory(char *)								*
*														*
*	Crea le directory del Path se non esistono			*
*														*
********************************************************/
void
MakeDirectory(Path)
char *Path;
{
	DIR 			*Dir;						/*Struttura direttory*/
	char			*DirName;
	char			Directory[100];
	int				c,i;
	char			OldDir[100];

	getcwd(OldDir,100);
	strcpy(Directory,Path);
	c=OnlyPathName(Directory);
	DirName=strtok(Directory,"/");

	for(i=0;i<c;i++)
	{

		if(!(Dir=opendir(DirName)))
		{
#ifdef AMIGA
			if(mkdir(DirName))
#else
			if(mkdir(DirName,S_IRWXU))
#endif
				CloseAll("Can't create directory");
		}
		else
			closedir(Dir);
		chdir(DirName);
		DirName=strtok(NULL,"/");

	}
	chdir(OldDir);

}

/********************************************************
*														*
*	void												*
*	RestoreFile()										*
*														*
*	Estrae i file dal Backup							*
*														*
********************************************************/
void
RestoreFile()
{
	char FileName[100];
	char Length[12];
	char OldFileName[100];

	chdir(Backup.Name);

restart:
	fgets(FileName,100,Backup.BackupFile);
	fgets(Length,11,Backup.BackupFile);
	fgetc(Backup.BackupFile);
	Backup.Size=atoi(Length);
	if(strcmp(FileName,OldFileName))
	{
		Backup.Files++;
		Backup.AttualLength+=(strlen(FileName)+strlen(Length)+1);
		Backup.Total+=Backup.Size;
		StripNewLinee(FileName);
		strcpy(OldFileName,FileName);
		if(!(CHECK_MASK(Backup.Flags,VERBOSE)))
			printf("Extract file: %8d  %s\n",Backup.Size,FileName);
		MakeDirectory(FileName);
		if(!(Backup.file=fopen(FileName,"wb")))
		{
			printf("Can't open file: %s Skip\n",FileName);
			SkipToNext();
			goto restart;
		}
	}
	else
	{
		fclose(Backup.BackupFile);
		if(CHECK_MASK(Backup.Flags,DELETE))
		{
			if(!(CHECK_MASK(Backup.Flags,VERBOSE)))
				printf("Delete Backup File: %s\n",Backup.FileName);
			remove(Backup.FileName);
		}
		chdir(Backup.Old);
		printf("\n\tRestore Complete\n");
		printf("\t\tNumber of File              : %8d\n",Backup.Files);
		printf("\t\tTotal Byte Restored    	    : %8d\n",Backup.Total);
		printf("\t\tNumber of Backup File       : %8d\n",Backup.FilesBack);
		CloseAll("");
	}
NewFile:
	while((Backup.Size>=BUFLEN) && ((Backup.Length-Backup.AttualLength)>=BUFLEN))
	{
		fread(Backup.Buffer,sizeof(char),BUFLEN,Backup.BackupFile);
		fwrite(Backup.Buffer,sizeof(char),BUFLEN,Backup.file);
		Backup.Size-=BUFLEN;
		Backup.AttualLength+=BUFLEN;
	}
	if(Backup.Size<BUFLEN && ((Backup.Length-Backup.AttualLength)>=Backup.Size))
	{
		fread(Backup.Buffer,sizeof(char),Backup.Size,Backup.BackupFile);
		fwrite(Backup.Buffer,sizeof(char),Backup.Size,Backup.file);
		Backup.AttualLength+=Backup.Size;
		fclose(Backup.file);
		goto restart;
	}					/*finito il file da fare Backup*/
	else
	{
		fread(Backup.Buffer,sizeof(char),Backup.Length-Backup.AttualLength,Backup.BackupFile);
		fwrite(Backup.Buffer,sizeof(char),Backup.Length-Backup.AttualLength,Backup.file);

		Backup.Size-=(Backup.Length-Backup.AttualLength);
		fclose(Backup.BackupFile);
		if(CHECK_MASK(Backup.Flags,DELETE))
		{
			if(!(CHECK_MASK(Backup.Flags,VERBOSE)))
				printf("Delete Backup File: %s\n",Backup.FileName);
			remove(Backup.FileName);
		}
		Incremento(Backup.FileName);
		OpenRestoreFile(Backup.FileName);
		goto	NewFile;
	}					/*finito il file di Backup*/

}

/********************************************************
*														*
*	void												*
*	ListBackupFile()									*
*														*
*	Visualizza i file dal Backup						*
*														*
********************************************************/
void
ListBackupFile()
{
	char FileName[256],Length[12];
	char OldFileName[100];

restart:
	fgets(FileName,100,Backup.BackupFile);
	fgets(Length,11,Backup.BackupFile);
	fgetc(Backup.BackupFile);
	Backup.Size=atoi(Length);

	if(strcmp(FileName,OldFileName))
	{
		Backup.Files++;
		Backup.Total+=Backup.Size;
		Backup.TotalBack+=strlen(FileName)+11+Backup.Size;
		Backup.AttualLength+=(strlen(FileName)+11);
		StripNewLinee(FileName);
		strcpy(OldFileName,FileName);
		printf("List file: %8d  %s\n",Backup.Size,FileName);
	}
	else
	{
		printf("\n");
		printf("\tList Complete\n");
		printf("\t\tNumber of file                 : %8d\n",Backup.Files);
		printf("\t\tTotal byte            	       : %8d\n",Backup.Total);
		printf("\t\tTotal byte backup file 	       : %8d\n",Backup.TotalBack);
		printf("\t\tNumber of backup File          : %8d\n",Backup.FilesBack);
		printf("\t\tLength of last backup file     : %8d\n",Backup.Length);
		CloseAll("");
	}
	SkipToNext();
	goto restart;
}

/********************************************************
*														*
*	void												*
*	DirectoryStat()										*
*														*
*	Calcola lo spazio di occupazione di una directory 	*
*	per il Backup										*
*														*
********************************************************/
void
DirectoryStat(DirName)
char *DirName;
{
DIR 			*Dir;						/* Struttura direttory				*/
struct dirent 	*dptr;						/* Struttura contenuto directory	*/
struct stat	  	InfoFile;					/* Struttura info del File			*/
char			FileName[100],NameTmp[100],NameTmp2[100];
char			*WriteName;

	if(!(Dir=opendir(DirName)))
		CloseAll("Directory not Found");
	while(dptr=readdir(Dir))
	{
#ifndef AMIGA
		if(!(strcmp(dptr->d_name,".") && strcmp(dptr->d_name,"..")))
			continue;
#endif
		strcpy(FileName,DirName);
		if(FileName[0]!='\0')
			if(FileName[strlen(FileName)-1]!=':')
				strcat(FileName,"/");
		strcat(FileName,dptr->d_name);
		stat(FileName,&InfoFile);

		strcpy(NameTmp,FileName);
		strcpy(NameTmp2,FileName);

		WriteName=strtok(NameTmp2,":");
		if(strcmp(WriteName,NameTmp))
			WriteName=strtok(NULL,":");

#ifdef AMIGA
		if(!(InfoFile.st_mode&S_IFDIR))
		{
			Backup.Files++;
			Backup.TotalBack+=strlen(WriteName)+12+InfoFile.st_size;	 /* Lunghezza file + spazio occupato per il nome e
																				i dati per la lunghezza */
			Backup.Total+=InfoFile.st_size;
		}
		else if(CHECK_MASK(Backup.Flags,RECURSIVELY))
			DirectoryStat(FileName);
#else
		if(S_ISREG(InfoFile.st_mode))
		{
			Backup.Files++;
			Backup.TotalBack+=strlen(WriteName)+12+InfoFile.st_size;
			Backup.Total+=InfoFile.st_size;
	}
		else if(CHECK_MASK(Backup.Flags,RECURSIVELY))
		{
			if(S_ISDIR(InfoFile.st_mode))
				DirectoryStat(FileName);
		}
#endif
	}
	closedir(Dir);
}

/********************************************************
*														*
*	void												*
*	Presentation()										*
*														*
*	Presentazione										*
*														*
********************************************************/
void
Presentation()
{
	printf("\n");
	printf("                    Skandal Backup Program V1.1\n");
	printf("                     Author Pozzoli Alessandro\n");
	printf("                          Copyright 1994\n");
#ifdef AMIGA
	printf("                           Amiga Version\n\n");
#else
	printf("                            Unix Version\n\n");
#endif
	printf("All rights reserved. Not for commercial use.\n");
	printf("Compatibility:  Amiga - Unix - Ms-Dos\n");
	printf("For Infos or Bug Mail pozzoli@ghost.dsi.unimi.it University of Milano\n\n");
}

/********************************************************
*														*
*	void												*
*	Usage()												*
*														*
*	Semplice Manuale									*
*														*
********************************************************/
void
Usage()
{
	printf("Usage : Backup [-<option>] <command) Backup_File length_archive [Dir]\n");
	printf("                                       (a,e,l)       (a,s)\n\n");
	printf(" Command:\n");
	printf("   a  add files \n");
	printf("   e  extract files \n");
	printf("   l  list files \n");
	printf("   s  statistic files occupation\n\n");

	printf(" Option:\n");
	printf("  -n  Create new backup file (not append) (a)\n");
	printf("  -d  delete  files (a,e)\n");
	printf("  -r  recursively directory (a,s) \n");
	printf("  -b  length in byte (a,s) \n");
	printf("  -v  verbose mode off (a,e)\n");
	printf("  -k  disk request off (a,e,l)\n\n");

	CloseAll("");
}

/********************************************************
*														*
*	void												*
*	CheckInput(argc,argv)								*
*														*
*	Contolla Parametri in Ingresso						*
*														*
********************************************************/
void
CheckInput(argc,argv)
int		argc;
char	*argv[];
{
	char	Command[50];
	int		i=0;

	strcpy(Command,argv[1]);				/*Copia opzioni*/

	if(Command[i]=='-')      /* sono delle opzioni */
	{
		i++;
		do
		{
			switch(Command[i])
			{
				case	'n':
								SET_MASK(Backup.Flags,NEW);
								break;
				case	'd':
								SET_MASK(Backup.Flags,DELETE);
								break;
				case	'v':
								SET_MASK(Backup.Flags,VERBOSE);
								break;
				case	'b':
								SET_MASK(Backup.Flags,BYTE);
								break;
				case	'r':
								SET_MASK(Backup.Flags,RECURSIVELY);
								break;
				case	'k':
								SET_MASK(Backup.Flags,DISKREQUEST);
								break;
				default:
								Usage();
								break;
			}
			i++;
		}while(Command[i]!='\0');
		strcpy(Command,argv[2]);				/*Copia comandi*/
		strcpy(Backup.FileName,argv[3]);
		SET_MASK(Backup.Flags,COMMAND);
	}
	else
	{
		strcpy(Command,argv[1]);				/*Copia comandi*/
		strcpy(Backup.FileName,argv[2]);
	}
	if(Command[1]=='\0')
	{	switch(Command[0])
		{
			case	'a':
							SET_MASK(Backup.Flags,ADD);
							break;
			case	'e':
							SET_MASK(Backup.Flags,EXTRACT);
							break;
			case	'l':
							SET_MASK(Backup.Flags,LIST);
							break;
			case	's':
							SET_MASK(Backup.Flags,STATISTIC);
							break;
			default:
							Usage();
							break;
		}
	}
	else
		Usage();

	if(CHECK_MASK(Backup.Flags,COMMAND) && CHECK_MASK(Backup.Flags,STATISTIC))
	{

		if(argc==5)
			strcpy(Backup.Name,argv[4]);
		else
#ifdef AMIGA
			strcpy(Backup.Name,"");
#else
			strcpy(Backup.Name,".");
#endif
		if(!(Backup.Length=atoi(argv[3])))
			Usage();
	}
	else if(CHECK_MASK(Backup.Flags,STATISTIC))
	{

		if(argc==4)
			strcpy(Backup.Name,argv[3]);
		else
#ifdef AMIGA
			strcpy(Backup.Name,"");
#else
			strcpy(Backup.Name,".");
#endif
		if(!(Backup.Length=atoi(argv[2])))
			Usage();
	}
	else if( CHECK_MASK(Backup.Flags,COMMAND) && CHECK_MASK(Backup.Flags,ADD))
	{
		if(argc==6)
			strcpy(Backup.Name,argv[5]);
		else
#ifdef AMIGA
			strcpy(Backup.Name,"");
#else
			strcpy(Backup.Name,".");
#endif
		if(!(Backup.Length=atoi(argv[4])))
			Usage();
	}
    else if(CHECK_MASK(Backup.Flags,ADD))
    {
		if(argc==5)
			strcpy(Backup.Name,argv[4]);
		else
#ifdef AMIGA
			strcpy(Backup.Name,"");
#else
			strcpy(Backup.Name,".");
#endif
    	if(!(Backup.Length=atoi(argv[3])))
		Usage();
	}
    else if(CHECK_MASK(Backup.Flags,COMMAND))
    {
		if(argc==5)
			strcpy(Backup.Name,argv[4]);
		else
#ifdef AMIGA
			strcpy(Backup.Name,"");
#else
			strcpy(Backup.Name,".");
#endif
	}
	else
	{
		if(argc==4)
			strcpy(Backup.Name,argv[3]);
		else
#ifdef AMIGA
			strcpy(Backup.Name,"");
#else
			strcpy(Backup.Name,".");
#endif
	}
	if(!(CHECK_MASK(Backup.Flags,BYTE)))
		Backup.Length*=1024;
}

/********************************************************
*														*
*	void												*
*	main()												*
*														*
*	Programma principale								*
*														*
********************************************************/
main(argc,argv)
int argc;
char **argv;
{
	OpenUp(argc,argv);

	if(CHECK_MASK(Backup.Flags,ADD))
	{
		if(!(CHECK_MASK(Backup.Flags,NEW)))
			FindLastBackupFile(Backup.FileName);
		OpenBackupFile(Backup.FileName);
		BackupDirectory(Backup.Name);
		printf("\n\tBackup Complete\n");
		printf("\t\tNumber of file                 : %8d\n",Backup.Files);
		printf("\t\tTotal byte            	       : %8d\n",Backup.Total);
		printf("\t\tTotal byte backup file 	       : %8d\n",Backup.TotalBack);
		printf("\t\tNumber of backup File          : %8d\n",Backup.FilesBack);
		printf("\t\tSpace left on last backup file : %8d\n",Backup.Length-Backup.AttualLength);
	}
	else if(CHECK_MASK(Backup.Flags,EXTRACT))
	{
		OpenRestoreFile(Backup.FileName);
		RestoreFile();
	}
	else if(CHECK_MASK(Backup.Flags,LIST))
	{
		OpenRestoreFile(Backup.FileName);
		ListBackupFile();
	}
	else if(CHECK_MASK(Backup.Flags,STATISTIC))
	{
		DirectoryStat(Backup.Name);
		if((Backup.AttualLength=Backup.TotalBack%Backup.Length))
			Backup.FilesBack=Backup.TotalBack/Backup.Length+1;
		else
		{
			Backup.FilesBack=Backup.TotalBack/Backup.Length;
			Backup.AttualLength++;
		}


		printf("\n\tStatistic Complete\n");
	    printf("\t\tNumber of File                 : %8d\n",Backup.Files);
		printf("\t\tTotal byte                     : %8d\n",Backup.Total);
		printf("\t\tTotal byte backup file 	       : %8d\n",Backup.TotalBack);
		printf("\t\tNumber of Backup File          : %8d\n",Backup.FilesBack);
		printf("\t\tSpace left on last backup file : %8d\n",Backup.Length-Backup.AttualLength);
	}
	CloseAll("");
}
