home *** CD-ROM | disk | FTP | other *** search
- /*
- ** FO v1.0 by FBJ
- **
- ** (c)Copyright 1991, Campagne Fabien, All Rights Reserved
- **
- ** Campagne Fabien
- ** 805, Rue des Gentianes
- ** 39000 Lons Le saunier
- ** FRANCE
- **
- ** un optimiseur de disk (rapide).
- ** FO doit être linké avec TD.o
- ** pour compiler: cc FO "objects:TD.o -gs"
- **
- ** */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <libraries/dos.h>
- #include <libraries/dosextens.h>
- #include <stdio.h>
- #include <string.h>
- #include "fbj/Blocks.h"
- #include "fbj/ShortBlocks.h"
- #include "fbj/TDprotos.h"
-
-
- /*#define DEBUG 1
- */
- #define ON 1L
- #define OFF 0L
- #define R CMD_READ
- #define W CMD_WRITE
- #define used 0
- #define var Variables
- #define BBM VarAdr->BuffBitMap
- /*#define BootB VarAdr->BuffTrack*/
- #define BT VarAdr->BuffTrack
- #define sourceDrive VarAdr->sourcedrive
- #define destDrive VarAdr->destdrive
- #define dsklist VarAdr->disklist
- #define CLI VarAdr->Cli
- #define err VarAdr->Err
- #define GFree VarAdr->GestFree
- #define DFree VarAdr->DataFree
- #define FLnog VarAdr->FLnoG
- #define drivebusy VarAdr->DriveBusy
- #define FORMAT VarAdr->Format
- #define CHECK VarAdr->Check
-
- extern struct DosLibrary *DOSBase;
-
- struct Variables{
- LONG *BuffBitMap; /* adr du buffer contenant le bloc BitMap */
- WORD BitMap; /* n° du Block BitMap */
- LONG *BuffTrack; /* Buffer de track pour le formattage de la destination */
- LONG *Empty; /* pointeur sur zone contenant datas pour blocs vides */
- BYTE sourcedrive; /* */
- BYTE destdrive; /* */
- LONG TotalBlocks; /* */
- LONG (*TableMem)[]; /* */
- WORD EndTMem; /* indice sur le dernier LONG occupé de TableMem */
- WORD GestFree; /* dernier bloc de Gestion libre */
- WORD DataFree; /* dernier bloc de Data libre */
- LONG *inCHIP; /* Buffer 512L en CHIP pour TD */
- struct DiskList *disklist; /* */
- BYTE Cli; /* if non set, optimize for WB use */
- BYTE FLnoG; /* if set, File List will no longuer be considered as Gestion B */
- BYTE Format; /* if set, the whole disk is formatted */
- BYTE Check; /* if set, The Dos Structure of Source is Checked */
- WORD Err; /* compteur d' erreur */
- BYTE DriveBusy[5];
- };
- struct var *VarAdr;
-
- void RendMem(void);
- void FreeBusy(void);
-
- main(ac,av)
- BYTE *av[];
- WORD ac;
- {
- WORD TotalBlocks,i,j=0,Perr=0;
- LONG k;
- BYTE argn;
- puts("FO v1.0 Fast Optimiser by FBJ.");
- VarAdr=(struct var *)AllocMem(sizeof(struct var),MEMF_CLEAR|MEMF_PUBLIC);
- atexit(RendMem);
-
- WBench(1); /* ( Par défault ) */
- forFDir(0);
- NoFormat(0);
- Check(0);
-
- if (ac<3 )
- {
- if (*av[1]=='?') {help(); exit(0);}
- else puts("? for help");exit(0);
- }
- if (strnicmp(av[1],"df",2)) {puts("1st arg: source drive"); exit(0);}
- if (strnicmp(av[2],"df",2)) {puts("2nd arg: dest drive"); exit(0);}
- sourceDrive=*(av[1]+2)-48;
- destDrive= *(av[2]+2)-48;
- if (sourceDrive<0 || sourceDrive>3) {puts("1st arg: source drive"); exit(0);}
- if (destDrive<0 || destDrive>3) {puts("2nd arg: dest drive"); exit(0);}
-
- argn=3;
- while (ac>=argn && *av[argn]=='-')
- {
- switch (*(av[argn]+1)) {
- case 'w' : WBench(1); break;
- case 'W' : WBench(1); break;
- case 'c' : ComLineInt(1); break;
- case 'n' : if ( !strnicmp(av[argn]+1,"nfo",3) ) NoFormat(1); break;
- case 'N' : if ( !strnicmp(av[argn]+1,"nfo",3) ) NoFormat(1); break;
- case 'F' : if ( !strnicmp(av[argn]+1,"FDir",4) ) forFDir(1); break;
- case 'C' : Check(1); break;
- }
- argn++;
- }
-
- puts("Now insert SOURCE disk and RETURN");
- while ( (getchar()) != 10) ;
-
- DiskBUSY(av[2],1);
- atexit(FreeBusy);
- strncpy(drivebusy,av[2],5);
-
- if (!OpenTD(sourceDrive)) {puts("Source drive Not Available"); exit(0);}
- if (!OpenTD(destDrive)) {puts("Dest drive Not Available"); exit(0);}
- atexit(CloseTD);
- VarAdr->inCHIP=(LONG *)AllocMem(512L,MEMF_CHIP|MEMF_CLEAR|MEMF_PUBLIC);
- VarAdr->BuffBitMap=(LONG *)AllocMem(512L,MEMF_CHIP|MEMF_CLEAR|MEMF_PUBLIC);
- Read_WriteB(R,sourceDrive,BBM,880L); /* charge le Root */
- /* on trouve BitMap */
- VarAdr->BitMap=(WORD)((struct RootB *)(VarAdr->BuffBitMap))->BitMapTable[0];
- #ifdef DEBUG
- printf("n ° du bloc BitMap :%d\n",VarAdr->BitMap);
- #endif
- /* on le charge */
- Read_WriteB(R,sourceDrive,BBM,VarAdr->BitMap);
- /* on réserve le buffer de track et on charge le bootBlock oû il faut */
- BT=(LONG *)AllocMem(11*512L,MEMF_CHIP|MEMF_CLEAR|MEMF_PUBLIC);
- Read_WriteB(R,sourceDrive,BT,0L);
- Read_WriteB(R,sourceDrive,BT+128L,1L);
- #ifdef DEBUG
- printf("Adr du Buff de Track : %p\n",BT);
- #endif
- VarAdr->Empty=(LONG *)AllocMem(512L,MEMF_CLEAR|MEMF_PUBLIC);
- if (VarAdr->Empty==0) Perr++;
- VarAdr->TotalBlocks=HowBlockUsed(BBM);
- #ifdef DEBUG
- printf("Total des Blocks Alloués : %d\n",VarAdr->TotalBlocks);
- #endif
- VarAdr->TableMem=(APTR)AllocMem(VarAdr->TotalBlocks*4+4,MEMF_CLEAR|MEMF_PUBLIC);
- #ifdef DEBUG
- printf("Adr de TableMem : %p\n",&VarAdr->TableMem);
- #endif
- j=0;
- for (i=0;i!=VarAdr->TotalBlocks;i++)
- {
- k=AllocMem(512L,MEMF_CLEAR|MEMF_PUBLIC);
- if (k==0) {Perr=103; break;}
- (*VarAdr->TableMem)[j++]=k;
- }
- (*VarAdr->TableMem)[j]=0L;
- VarAdr->EndTMem=j-1;
-
- if (Perr)
- {
- puts("Désolé, pas assez de mémoire pour optimisation rapide");
- exit(0);
- }
- /* On initialise la strucure DiskList */
- dsklist=(struct SinitB*)AllocMem(sizeof(struct SinitB),MEMF_CLEAR|MEMF_PUBLIC);
- dsklist->dl_Bloc=-9;
- ((struct SinitB*)dsklist)->dl_Type=0;
-
- /* Avec un bloc initial qui ne sert à rien mais est bien pratique */
-
- LoadBinMem();
- MtrOff(sourceDrive);
- if (CHECK)
- {
- puts("Checking Dos Structure of disk");
- CheckDosStruct();
- if (!err) puts("No Error in Dos Structure");
- else {printf("%d ERRORS on disk !! FO Stopped\n",err); exit(0);}
- }
- MtrOff(sourceDrive);
- puts("Now I optimize ...");
- Optimize();
- BitMap();
- ChangeBlocks();
- puts("Writing result to destination disk");
- MemToDisk();
- puts("Fast Optimization done.");
-
- exit(0);
- }
-
- void RendMem()
- {
- LONG M=1;
- WORD i=0;
- if (VarAdr->BuffBitMap)
- {
- FreeMem(BBM,512L);
- BBM=0L;
- }
- if (VarAdr->BuffTrack)
- {
- FreeMem(BT,11*512L);
- BT=0L;
- }
- if (VarAdr->Empty)
- {
- FreeMem(VarAdr->Empty,512L);
- VarAdr->Empty=0;
- }
-
- i=0;
- while (M)
- {
- M=(*VarAdr->TableMem)[i++];
- if (M) FreeMem(M,512L); else break;
- }
- if (VarAdr->TableMem) FreeMem(VarAdr->TableMem,VarAdr->TotalBlocks*4+4);
- if (dsklist) FreeDiskList();
- if (VarAdr->inCHIP) {FreeMem(VarAdr->inCHIP,512L); VarAdr->inCHIP=0;}
- if (VarAdr) {FreeMem(VarAdr,sizeof(struct var)); VarAdr=0;}
-
- }
-
- void FreeBusy()
- {
- DiskBUSY(drivebusy,0);
- }
-
- /* isBlocUsed renvoie 1 si Block libre ou 0 si block occuppé
- il se réfère au BitMap */
-
- isBlocUsed(Bloc)
- WORD Bloc;
- {
- LONG A,B;
- if (Bloc==0 || Bloc==1) return(1); /* Faux car blocks used mais pratique ! */
- A=*(BBM+1+(Bloc-2)/32);
- B=(A>>(((Bloc-2)%32)) & 0x1L);
- return(B);
- }
-
- HowBlockUsed(AdrBM)
- LONG *AdrBM;
- {
- WORD i,TotalBlocks=0;
-
- for (i=2;i<=1760;i++)
- {
- TotalBlocks+=(WORD)!(isBlocUsed(i));
- }
- return(TotalBlocks);
- }
-
- LoadBinMem()
- {
- LONG n,m=0;
- APTR buff1,buff2,inCHIP;
- struct DiskList *dlist;
-
- inCHIP=VarAdr->inCHIP;
- puts("Reading Source and preparing for Fast Optimising");
- for (n=2;n<1760;n++)
- {
- if (isBlocUsed(n)==used)
- {
- buff1=(APTR)(Buffer(m++));
- if (TypeOfMem(buff1)&MEMF_CHIP) buff2=buff1;
- else buff2=inCHIP;
- if (Read_WriteB(R,(LONG)sourceDrive,buff2,n))
- {
- puts("Read Error, can' t optimize");
- exit(0);
- }
- if (buff2==inCHIP) CopyMemQuick(buff2,buff1,512L);
- #ifdef DEBUG
- if (!Buffer(m-1))
- {
- puts("Problème avec LoadBinMem !");
- exit(0);
- }
- #endif
- Organising(buff1,dlist,n);
- }
- if ((n%22)==0)
- {
- printf("CYL %d",n/22);
- putchar(13);
- fflush(stdout);
- }
-
- }
-
- }
-
- /* Cherche et renvoie l' adresse oû ranger le bloc */
- Buffer(m)
- LONG m;
- {
- return((*VarAdr->TableMem)[m]);
- }
-
- Organising(buff1,dlist,n)
- LONG *buff1;
- LONG n;
- struct DiskList *dlist;
-
- {
- switch (*buff1)
- {
- case 2L :
- {
- switch (*(buff1+127))
- {
-
- case 1L: /* RootBlock */
- {
- /* printf("Type : RootB , bloc #%d\n",n);*/
- dlist=(struct DiskList *)Preparing(sizeof(struct SRootB),dsklist);
- dlist->dl_NextB=0;
- dlist->dl_Bloc=n;
- dlist->dl_Bloc2=n;
- dlist->dl_Data=0;
- dlist->dl_Type=3;
- dlist->dl_types.dl_type3.reserved1=0;
- dlist->dl_AdrB=buff1;
- break;
- }
-
- case -3L: /* File Header Block */
- {
- /* printf("Type : File HeaderB , bloc #%d\n",n);*/
- dlist=(struct DiskList *)Preparing(sizeof(struct SFileHderB),dsklist);
- dlist->dl_NextB=0;
- dlist->dl_Bloc=n;
- dlist->dl_Bloc2=0;
- dlist->dl_Type=-1;
- dlist->dl_types.dl_type1.dl_Parent=((struct FileHeaderB*)buff1)->ParentDir;
- dlist->dl_types.dl_type1.dl_NextHash=((struct FileHeaderB*)buff1)->NextHash;
- dlist->dl_types.dl_type1.dl_Extension=((struct FileHeaderB*)buff1)->Extension;
- dlist->dl_AdrB=buff1;
- dlist->dl_Data=isinfo(buff1);
- break;
- }
-
- case 2L: /* User Directory Block */
- {
- /* printf("Type : User DirB , bloc #%d\n",n);*/
- dlist=(struct DiskList *)Preparing(sizeof(struct SUserDirB),dsklist);
- dlist->dl_NextB=0;
- dlist->dl_Bloc=n;
- dlist->dl_Bloc2=0;
- dlist->dl_Type=4;
- dlist->dl_types.dl_type4.dl_Parent=((struct UserDirB*)buff1)->ParentDir;
- dlist->dl_types.dl_type4.dl_NextHash=((struct UserDirB*)buff1)->NextHash;
- dlist->dl_AdrB=buff1;
- dlist->dl_Data=isinfo(buff1);
- break;
- }
-
- default :
- {
- printf("Type : UnknownB1 , bloc #%d\n",n);
- dlist=(struct DiskList *)Preparing(sizeof(struct SUnknownB),dsklist);
- dlist->dl_NextB=0;
- dlist->dl_Bloc=n;
- dlist->dl_Bloc2=n;
- dlist->dl_Data=0;
- dlist->dl_Type=-2;
- dlist->dl_AdrB=buff1;
- break;
- }
- }
- break;
- }
-
- case 16L: if (*(buff1+127)==-3) /* FileList Block */
- {
- /* printf("Type : File ListB , bloc #%d\n",n);*/
- dlist=(struct DiskList *)Preparing(sizeof(struct SFileListB),dsklist);
- dlist->dl_NextB=0;
- dlist->dl_Bloc=n;
- dlist->dl_Bloc2=0;
- dlist->dl_Data=0;
- dlist->dl_Type=13;
- dlist->dl_types.dl_type13.dl_FileHeader=((struct FileListB*)buff1)->ParentFH;
- dlist->dl_types.dl_type13.dl_Extension=((struct FileListB*)buff1)->Extension;
- dlist->dl_AdrB=buff1;
- break;
- }
-
- case 8L: /* Data Block */
- {
- /* printf("Type : DataB , bloc #%d\n",n);*/
- dlist=(struct DiskList *)Preparing(sizeof(struct SDataB),dsklist);
- dlist->dl_NextB=0;
- dlist->dl_Bloc=n;
- dlist->dl_Bloc2=0;
- dlist->dl_Data=0;
- dlist->dl_Type=8;
- dlist->dl_types.dl_type8.dl_FileHeader=((struct DataB*)buff1)->HeaderKey;
- dlist->dl_types.dl_type8.dl_NextData=((struct DataB*)buff1)->NextDataBlock;
- dlist->dl_AdrB=buff1;
- break;
- }
-
- default :
- {
- /* printf("Type : UnknownB2 , bloc #%d\n",n); *//* Par ex le B BitMap */
- if (n==VarAdr->BitMap) break;
- dlist=(struct DiskList *)Preparing(sizeof(struct SUnknownB),dsklist);
- dlist->dl_NextB=0;
- dlist->dl_Bloc=n;
- dlist->dl_Bloc2=n;
- dlist->dl_Data=0;
- dlist->dl_Type=-2;
- dlist->dl_AdrB=buff1;
- break;
- }
- }
- }
-
- Preparing(structsize,adr)
- LONG structsize;
- struct DiskList *adr;
-
- {
- static struct DiskList *Sadr=0;
-
- if (Sadr==0) Sadr=adr; else adr=Sadr;
- if (adr->dl_NextB==0)
- {
- adr->dl_NextB=(struct DiskList *)AllocMem(structsize,MEMF_PUBLIC);
- if (adr->dl_NextB==0)
- {
- puts("Pas de mem pour Preparing()");
- exit(0);
- }
- Sadr=adr->dl_NextB;
- return(adr->dl_NextB);
- }
- else return(Preparing(structsize,adr->dl_NextB));
- }
-
- FreeDiskList()
- {
- struct DiskList *dlist;
- LONG length=0;
- APTR tmp;
-
- dlist=dsklist;
- do
- {
- length=Length(dlist);
- tmp=dlist->dl_NextB;
- if (dlist && length) FreeMem(dlist,length);
- dlist=tmp;
- }
- while (dlist->dl_NextB!=0);
- FreeMem(dlist,Length(dlist));
- dsklist=0;
-
- }
-
- Length(dlist)
- struct DiskList *dlist;
- {
- LONG length;
- switch (dlist->dl_Type)
- {
- case -2L: length=sizeof(struct SUnknownB); break;
- case 13L: length=sizeof(struct SFileListB); break;
- case 8L: length=sizeof(struct SDataB); break;
- case 4L: length=sizeof(struct SUserDirB); break;
- case 3L: length=sizeof(struct SRootB); break;
- case -1L: length=sizeof(struct SFileHderB); break;
- case 0L: length=sizeof(struct SinitB); break;
- default : length=0; puts("err in FreeDiskList"); break;
- }
- return(length);
- }
-
- CheckDosStruct()
- {
- struct DiskList *dlist;
- WORD n;
- struct RootB *adr;
-
- dlist=(APTR)whereB(880);
- if (dlist==0) NotSet(880);
- else
-
-
- { adr=(struct RootB *)dlist->dl_AdrB;
- for (n=0;n<72;n++) /* 72 compris puisque n++ */
- {
- explore(adr->HashTable[n],880);
- }
- }
- }
-
- /* explore: suit une chaine de Hash à partir du bloc header en paramètre */
-
- explore(bloc,parent)
- WORD bloc;
- WORD parent;
- {
- struct DiskList *dlist;
- WORD n,nextbloc;
- struct UserDirB *adr;
-
- if (bloc==0) return(0);
- /*printf("dans explore bloc: %d, parent: %d\n",bloc,parent);*/
- dlist=VarAdr->disklist;
- while (dlist->dl_Bloc!=bloc && dlist!=0) dlist=dlist->dl_NextB;
-
- if (dlist==0) NotSet(bloc,parent);
- else
-
- if (dlist->dl_Type!=-1 && dlist->dl_Type!=4)
- {
- printf ("ERR : Block #%d SHOULD BE Header or UserDir block\n",bloc);
- err++;
- }
-
- if (dlist->dl_types.dl_type4.dl_Parent!=parent)
- {
- printf("ERR : Link Error between block #%d and #%d\n",bloc,parent);
- err++;
- }
-
- if (dlist->dl_Type==-1) CheckHeader(dlist);
- if (dlist->dl_Type==4)
- {
- adr=(struct UserDirB *)dlist->dl_AdrB;
- for (n=0;n<72;n++)
- {
- explore(adr->HashTable[n],bloc);
- }
- }
-
- if (nextbloc=dlist->dl_types.dl_type1.dl_NextHash==0) return(0);
- else explore(nextbloc,parent);
- }
-
- CheckHeader(dlist)
- struct DiskList *dlist;
- {
- WORD bloc,n;
- struct FileHeaderB *adr;
- BYTE errfile=0;
-
- bloc=dlist->dl_Bloc;
- /*printf("dans CheckHeader bloc: %d\n",bloc);*/
- adr=dlist->dl_AdrB;
-
- for (n=0;n<72;n++)
- {
- errfile+=CheckLink(adr->DataTable[n],bloc);
- }
- if (adr->Extension) CheckFList(adr->Extension,bloc);
-
-
- if (errfile) badFile(adr->FileName);
- return(0);
- }
- CheckFList(bloc,fhb)
- WORD bloc,fhb;
- {
- struct SFileListB *dlistFL;
- struct FileListB *adr;
- BYTE errfile=0;
- WORD n;
-
- dlistFL=(APTR)whereB(bloc);
- /* printf("dans CheckFList bloc: %d, pour FHB: %d\n",bloc,fhb);*/
- if (dlistFL==0) NotSet(bloc,fhb);
- else{
- if (dlistFL->dl_Type!=13)
- {
- printf ("ERR : Block #%d SHOULD BE FileList block\n",bloc);
- err++;
- errfile++;
- }
- else
- {
- adr=(struct FileListB *)dlistFL->dl_AdrB;
- if (adr->ParentFH!=fhb)
- {
- printf("ERR : Link Error between block #%d and #%d\n",bloc,fhb);
- err++;
- }
- for (n=0;n<72;n++)
- {
- errfile+=CheckLink(adr->DataTable[n],fhb);
- }
- }
- if (adr->Extension) errfile+=CheckFList(adr->Extension,fhb);
- }
- return(errfile);
- }
-
- CheckLink(dataB,fhB)
- WORD dataB,fhB;
- {
- struct SDataB *dlist;
- BYTE errdata=0;
-
- if (dataB==0) return(0);
- /* printf("dans CheckLink data : %d, fh : %d\n",dataB,fhB);*/
- dlist=(struct SDataB *)VarAdr->disklist;
- while (dlist->dl_Bloc!=dataB && dlist!=0) dlist=dlist->dl_NextB;
-
- if (dlist==0) NotSet(dataB,fhB);
- else
-
- if (dlist->dl_Type!=8)
- {
- printf ("ERR : Block #%d SHOULD BE data block (pointed by FHB #%d)\n",dataB,fhB);
- err++;
- errdata=1;
- }
- else
- if (dlist->dl_type8.dl_FileHeader!=fhB)
- {
- printf("ERR : Link Error between block #%d and #%d\n",fhB,dataB);
- err++;
- errdata=1;
- }
- return(errdata);
- }
-
- badFile(adrName)
- BYTE *adrName;
- {
- BYTE length;
- BYTE buff[30];
-
- length=*adrName;
- adrName++;
- strncpy(buff,adrName,length);
- buff[length]=0;
- printf("File %s contains errors\n",buff);
- }
-
- NotSet(bloc,where)
- WORD bloc,where;
- {
- printf("Block #%d Not Found ! (not unset in BitMap), in %p\n",bloc,where);
- err++;
- }
-
- whereB(bloc)
- WORD bloc;
- {
- struct DiskList *dlist;
-
- dlist=VarAdr->disklist;
- while (dlist->dl_Bloc!=bloc && dlist!=0) dlist=dlist->dl_NextB;
- return(dlist);
- }
- isinfo(buff)
- BYTE *buff;
- {
- BYTE name[30],length,n;
-
-
- length=buff[108*4];
- strncpy(name,buff+108*4+1,length);
- name[length]=0;
- for (n=0; n<length && name[n] != '.';++n);
- if (stricmp(name+n,".info")==0)
- return(1);
- else return(0);
- }
-
- Optimize()
- {
- WORD UDB[100];
- WORD i=1;
-
- UDB[0]=880;
- UDB[1]=0;
- /*printf("UDB[0] : %d\n",UDB[0]);*/
- while (UDB[0])
- {if (!arrange(UDB,&i)) break;}
-
- }
-
- arrange(UDB,i)
- WORD UDB[],*i;
- {
- static WORD gfree=882,dfree=2;
- struct SUserDirB *udbf,*udbp,*fhB;
- struct UserDirB *adrf;
- struct UserDirB *adrp;
- /*struct DiskList *hdb;*/
- struct FileHeaderB *adrh;
- WORD UDBP,n,bloc,parent;
-
- /* printf("in arrange() UDB[0] : %d, i : %d\n",UDB[0],*i);*/
- udbf=(APTR)whereB(UDB[0]);
- if (udbf==0) {NotSet(UDB[0],0); return(0);}
-
- for (n=0;n<*i;n++) UDB[n]=UDB[n+1]; /* On s' occuppe de UDB[0] donc on le retire de la liste */
- UDB[*i]=0;
- (*i)--;
-
- UDBP=udbf->dl_type4.dl_Parent;
-
- if (UDBP) /* null si Root */
- {
- udbp=(APTR)whereB(UDBP);
- if (udbp==0) {NotSet(UDBP,1); return(0);}
- }
-
- adrf=udbf->dl_AdrB;
- /*printf("adrf : %p\n",adrf);*/
-
- if (UDBP) /* Cas du User Dir B */
- {
- adrp=udbp->dl_AdrB;
- parent=adrf->ParentDir=udbp->dl_Bloc2; /* Les Parents sont tjs déplacés avt */
- }
-
- for (n=71;n!=-1;n--)
- {
-
- bloc=adrf->HashTable[n];
- if (bloc)
- {
- adrf->HashTable[n]=gfree;
- do
- {
- fhB=(APTR)whereB(bloc);
- if (fhB==0) {NotSet(bloc,2); break;}
-
- if (fhB->dl_Type==-1)
- {
- gfree=MoveHderB(bloc,gfree,&dfree,UDB,i);
- }
- else
- if (fhB->dl_Type==4)
- {
- gfree=MoveUserDirB(bloc,gfree,parent);
- UDB[(*i)++]=bloc;
- UDB[*i]=0;
- }
-
- adrh=(struct FileHeaderB *)fhB->dl_AdrB;
- bloc=adrh->NextHash;
- adrh->NextHash= (bloc ? gfree : 0);
- /*printf("adrh: %p,bloc: %d\n",adrh,bloc);*/
- }
- while (bloc);
- }
- }
- /*printf("gfree: %d dfree: %d\n",gfree,dfree);*/
- GFree=gfree;
- DFree=dfree;
- return(1);
- }
-
-
-
-
- Inc(datafree)
- WORD *datafree;
- {
- #ifdef DEBUG
- /* printf("in Inc() datafree: %d\n",*datafree);*/
- #endif
- if (*datafree<879) (*datafree)++; /* Ainsi 879 est donné mais pas 880 */
- else
- {
- if (*datafree==879) *datafree=1759;
- else (*datafree)--;
- }
- return(*datafree);
- }
-
- Nextdfree(datafree)
- WORD *datafree;
- {
- if (*datafree<879) return(*datafree+1);
- else
- {
- if ((*datafree+1)==880) return(1759);
- else return(*datafree-1);
- }
- }
-
- /* MoveHderB déplace le Header spécifié du bloc lB au bloc nB.
- nB: nouveau n° de bloc.
- oB: ancien n° de bloc.
- */
-
- MoveHderB(oB,nB,datafree,UDB,i)
- WORD nB,oB,*datafree;
- WORD UDB[],*i;
- {
- struct SFileHderB *dlistB,*fhB;
- struct FileHeaderB *adr;
- struct DiskList *hdb;
- struct FileHeaderB *adrh;
- WORD n,ret,ext,bloc,*nflB;
- WORD gfree;
- LONG AdrD;
- BYTE first;
- #ifdef DEBUG
- printf("in MoveHderB() oB: %d, nB: %d,datafree: %d\n",oB,nB,*datafree);
- #endif
- dlistB=(APTR)whereB(oB);
- if (dlistB==0) NotSet(oB,4);
- else
- {
- if (dlistB->dl_Type!=-1) return(0);
- adr=(struct FileHeaderB *)dlistB->dl_AdrB;
- /* On change le HeaderKey du bloc */
- adr->HeaderKey=nB;
- dlistB->dl_Bloc2=nB;
-
- /* On change tous les DatasB en conséquence */
- gfree=nB+1;
- first=1;
-
- for (n=71;n!=-1;n--)
- {
- if (adr->DataTable[n])
- {
- if ( (dlistB->dl_Data==1) && (CLI==0) ) /* bloc de data ds gestion */
- {
- AdrD=ModifyDataHder(adr->DataTable[n],nB,gfree,adr);
- adr->DataTable[n]=gfree;
- if (first) {adr->FirstDataB=gfree; first=0;}
-
- gfree++;
- if (n) ModifyDataNext(AdrD,gfree);
- else ModifyDataNext(AdrD,gfree+1);
- }
- else
- {
- AdrD=ModifyDataHder(adr->DataTable[n],nB,*datafree,adr);
- adr->DataTable[n]=*datafree;
- if (first) {adr->FirstDataB=*datafree; first=0;}
-
- Inc(datafree);
- if (n) ModifyDataNext(AdrD,*datafree);
- else
- {
- if (FLnog) ModifyDataNext(AdrD,Nextdfree(datafree));
- else ModifyDataNext(AdrD,*datafree);
- }
- }
-
- }
- }
-
- if (adr->Extension)
- {
- if (FLnog)
- {
- nflB=datafree;
- ext=*datafree;
- }
- else
- {
- nflB=&gfree;
- ext=gfree;
- }
- if (CLI) /* pas de .info dans les blocs de gestion */
- {
- ModifyFList(adr->Extension,nB,nflB,datafree,0);
- }
- else
- if (dlistB->dl_Data==1) /* si .info alors ds les blocs de gestion */
- {
- ModifyFList(adr->Extension,nB,nflB,&gfree,1);
- }
- else
- {
- ModifyFList(adr->Extension,nB,nflB,datafree,0);
- }
- adr->Extension=ext;
- }
-
-
- }
- return(gfree);
- }
-
- ModifyDataHder(bloc,nfhB,ndataB,adrfh)
- WORD bloc,nfhB,ndataB;
- LONG adrfh;
- {
- struct SDataB *dlistD;
- struct DataB *adr;
-
- #ifdef DEBUG
- printf("in MofifyDataHder() bloc: %d, nfhB : %d, ndataB: %d\n",bloc,nfhB,ndataB);
- #endif
- dlistD=(APTR)whereB(bloc);
- if (dlistD==0) {NotSet(bloc,adrfh); exit(0);}
- else
- dlistD->dl_Bloc2=ndataB;
- dlistD->dl_type8.dl_FileHeader=nfhB;
- adr=dlistD->dl_AdrB;
- adr->HeaderKey=nfhB;
- return(adr);
- }
-
- ModifyDataNext(adr,ndataNext)
- WORD ndataNext;
- struct DataB *adr;
- {
- if (adr->NextDataBlock) adr->NextDataBlock=ndataNext;
-
- }
-
- /* Renvoie n° du prochain bloc libre */
-
- ModifyFList(bloc,nfhB,nflB,datafree,data)
- WORD bloc,nfhB,*nflB,*datafree,data;
- {
- struct SFileListB *dlistFL;
- struct FileListB *adr;
- LONG *AdrD;
- WORD n,ret=0,ext;
- BYTE first;
- #ifdef DEBUG
- printf("in MofifyFList() bloc: %d, nfhB : %d, nflB: %d,datafree: %d\n",bloc,nfhB,*nflB,(*datafree)+1);
- #endif
- dlistFL=(APTR)whereB(bloc);
- if (dlistFL==0) NotSet(bloc,5);
- else
- {
- /*printf(" Type du bloc: %d\n",dlistFL->dl_Type);*/
- dlistFL->dl_type13.dl_FileHeader=nfhB;
- dlistFL->dl_Bloc2=*nflB;
- adr=(struct FileListB *)dlistFL->dl_AdrB;
- adr->ParentFH=nfhB;
- adr->HeaderKey=*nflB;
- if (FLnog) Inc(nflB); else (*nflB)++;
-
- first=1;
- for (n=71;n!=-1;n--)
- {
- if(adr->DataTable[n])
- {
- AdrD=(APTR)ModifyDataHder(adr->DataTable[n],nfhB,*datafree,bloc);
- adr->DataTable[n]=*datafree;
- if (first) {adr->FirstDataB=*datafree; first=0;}
-
- if (data==0) Inc(datafree); else (*datafree)++;
-
- if (n)
- {
- if (data==0) ModifyDataNext(AdrD,*datafree);
- else ModifyDataNext(AdrD,*datafree+1);
- }
- else
- {
- if (FLnog) ModifyDataNext(AdrD,Nextdfree(datafree));
- else ModifyDataNext(AdrD,*datafree);
- }
- }
- }
-
- ext=*nflB;
- if (adr->Extension)
- {
- ret+=ModifyFList(adr->Extension,nfhB,nflB,datafree,data);
- adr->Extension=ext;
- return(++ret);
- }
-
- return(ext);
- }
- }
-
- MoveUserDirB(oB,nB,parent)
- WORD oB,nB,parent;
- {
- struct SUserDirB *dlist;
- struct UserDirB *adr;
- WORD n;
-
- #ifdef DEBUG
- printf("in MoveUserDir() oB: %d, nB: %d, parent: %d\n",oB,nB,parent);
- #endif
- dlist=(APTR)whereB(oB);
- if (dlist==0) NotSet(oB,6);
- else
- {
- if (dlist->dl_Type==4)
- {
-
- adr=dlist->dl_AdrB;
- dlist->dl_Bloc2=nB;
- adr->HeaderKey=nB;
- for (n=71;n!=-1;n--)
- {
- if (adr->HashTable[n])
- {
- MoveHashFils(adr->HashTable[n],nB);
- }
- }
- return(nB+1);
- } else puts("err in MoveUserDirB");
- }
- }
-
- MoveHashFils(bloc,parent)
- WORD bloc,parent;
- {
- struct DiskList *dlist;
- struct FileHeaderB *adr;
-
- #ifdef DEBUG
- printf("in MoveHashFils() bloc: %d, parent: %d\n",bloc,parent);
- #endif
- dlist=(APTR)whereB(bloc);
- if (dlist==0) {NotSet(bloc,7); return(0);}
-
- if (dlist->dl_Type==-1) adr=dlist->dl_AdrB;
- if (dlist->dl_Type==4) adr=dlist->dl_AdrB;
-
- dlist->dl_types.dl_type4.dl_Parent=parent;
- adr->ParentDir=parent;
- }
-
- ChangeBlocks()
- {
- struct DiskList *dlist;
-
- dlist=(struct DiskList *)VarAdr->disklist;
-
- while (dlist)
- {
- dlist->dl_Bloc=dlist->dl_Bloc2;
- dlist=dlist->dl_NextB;
- }
-
- }
-
- MemToDisk()
- {
- WORD n,bitmap;
- LONG offset,*adrB,*empty,ddrive,A;
- BYTE *BuffT,write,length;
- WORD c,Form;
- struct DiskList *dlist=0;
- struct RootNode *RN;
- struct RootB *adr;
-
- if (sourceDrive==destDrive) {puts("Now insert dest disk and RETURN");
- while ( (c=getchar()) != 10) ;}
-
- MtrOn(destDrive);
- MtrOff(destDrive);
- if (isInserted(destDrive)) {puts("YOU MUST insert DESTINATION disk and RETURN");
- while ( (c=getchar()) != 10) ;
- while (isInserted(destDrive)) fflush(stdout); }
-
- if (isProtected(destDrive)) {puts("UnProtect DESTINATION disk and press RETURN");
- while ( (c=getchar()) != 10) ;
- while (isProtected(destDrive)) fflush(stdout);}
-
-
- offset=2*512L; /* Le boot Block est déja dans le Buffer de Track */
- BuffT=BT;
- /* On met à jour la date de dernière modif de la disquette */
- dlist=(APTR)whereB(880);
- if (dlist==0) NotSet(880,8);
- adr=dlist->dl_AdrB;
- RN=(struct RootNode *)(DOSBase->dl_Root);
- adr->Mday=RN->rn_Time.ds_Days;
- adr->Mmin=RN->rn_Time.ds_Minute;
- adr->Mtick=RN->rn_Time.ds_Tick;
-
- length=adr->DiskName[0];
- adr->DiskName[0]=length+1;
- adr->DiskName[length+1]='.';
-
-
- bitmap=VarAdr->BitMap;
- empty=VarAdr->Empty;
- ddrive=destDrive;
- A=('F'<<24|'B'<<16|'J'<<8|'.');
-
- for (n=0;n<128;n++)
- {
- empty[n]=A;
- }
-
- /*printf("buffer a l' adresse %p\n",empty);*/
- putchar(13);
-
- Form=FORMAT;
- /*printf("Form : %d, VarAdr->Format: %ld\n",Form,VarAdr->Format);*/
- write=Form;
- for (n=2;n<1761;n++)
- {
- if (offset==11*512)
- {
- /*printf("(n-12): %d\n",(n-11)); */
- if (write) CMDonD(ddrive,TD_FORMAT,0,11*512L,BuffT,(n-11)*512L);
- offset=0L;
- if (!Form) write=0;
- }
- if (( (n-22) % 22 )==0)
- {
- printf("CYL n°: %d",n/22);
- putchar(13);
- fflush(stdout);
- }
- if (n==881) {adrB=BBM; write=1;}
- else
- {
- dlist=(APTR)whereB(n);
- if (dlist==0) adrB=empty;
- else
- {
- adrB=dlist->dl_AdrB;
- BuildCheckSum(adrB);
- write=1;
- }
- }
- CopyMemQuick(adrB,BuffT+offset,512L);
- offset+=512L;
- }
- }
-
- BuildCheckSum(Buffer)
- ULONG *Buffer;
- {
- ULONG B;
- WORD n;
-
- Buffer[5]=0;
- n=0;
- B=0;
- while (n<=127)
- {
- B+=Buffer[n];
- n++;
- }
- Buffer[5]=-B;
- }
-
- BitMap()
- {
- struct DiskList *dlist;
- struct RootB *adr;
- WORD n;
- LONG *buffbm,SBM=0;
-
- buffbm=BBM;
- dlist=(APTR)whereB(880);
- if (dlist==0) NotSet(880,9);
-
- adr=dlist->dl_AdrB;
- adr->BitMapTable[0]=881L;
- adr->BMvalid=-1;
-
- /*printf("GFree: %d DFree: %d\n",GFree,DFree);*/
-
- for (n=0;n!=56;n++) buffbm[n]=-1L; /* on nettoye le BitMap */
- for (n=56;n!=128;n++) buffbm[n]=0L;
- if (DFree<880)
- {
- for (n=0;n<DFree;n++) SetBinBM(n,buffbm);
- }
- else
- {
- for (n=0;n!=880;n++) SetBinBM(n,buffbm);
- for (n=DFree+1;n!=1761;n++) SetBinBM(n,buffbm);
-
- }
-
- for (n=880;n!=GFree;n++) SetBinBM(n,buffbm);
-
- buffbm[0]=0L;
- for (n=0;n!=128;n++)
- {
- SBM+=buffbm[n];
- }
- buffbm[0]=-SBM;
-
- }
-
- SetBinBM(bloc,adrbm)
- WORD bloc;
- LONG *adrbm;
- {
- adrbm++;
- adrbm[(bloc-2)/32] &= ~(1<< ( (bloc-2)%32 ));
- }
-
- /* Les options. */
-
- WBench(flag)
- BYTE flag;
- {
- CLI=!flag;
- /* printf("in WBench, CLI set to %d\n",!flag);*/
- }
-
- ComLineInt(flag)
- BYTE flag;
- {
- CLI=flag;
- /* printf("in ComLineInt, CLI set to %d\n",flag);*/
- }
-
- NoFormat(flag)
- BYTE flag;
- {
- VarAdr->Format=!flag;
- /* printf("in NoFormat, Format set to %d\n",VarAdr->Format);*/
- }
-
- forFDir(flag)
- BYTE flag;
- {
- FLnog=flag;
- /* printf("in forFDir, FLnog set to %d\n",flag);*/
- }
-
- Check(flag)
- BYTE flag;
- {
- CHECK=flag;
- }
-
- help()
- {
- puts("FO is FreeWare but contributions are welcomed: ");
- puts("");
- puts("Send any donations to CAMPAGNE Fabien");
- puts(" 805, Rue des Gentianes");
- puts(" 39000 Lons Le Saunier");
- puts(" France");
- puts("");
- puts("Now how to use FO:");
- puts(" 1st argument must be SOURCE drive");
- puts(" 2nd argument must be DESTINATION drive");
- puts(" (They could be the same)");
- puts("Options:");
- puts(" -w : Worbench optimization ( all .info files (ex disk.info) are");
- puts(" near gestion-blocks)");
- puts(" -c : CLI optimization ( .info files are in the area of data-blocks)");
- puts(" -nFo or -nFormat if you use disk already formatted on destination.");
- puts(" -C : Check of the Dos Structure of Source disk before optimization.");
- puts(" -FDir : to use in conjunction with FDir (the Fast Dir by mine)");
- puts(" (File List blocks are moved in data-area)");
- puts("");
- puts(" Enjoy FO. FBJ.");
- }
-
-
-
-
-
-
-
-
-