home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
500-599
/
ff537.lzh
/
FO
/
FO.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-26
|
27KB
|
1,278 lines
/*
** 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.");
}