home *** CD-ROM | disk | FTP | other *** search
- /*
- * deadalloc.c Dead track allocator.
- * (c)Tim MacKenzie .
- *
- * This program is freely redistributable. It may be modified, hacked and
- * mutilated as long as this is not for profit, this message must also
- * remain with it.
- *
- * Begun: 17/6/90
- * History:
- * v1.0: Allocates dead blocks only.
- * v1.1: Creates file with dead blocks in it.
- * v1.2: Checks every block instead of just the first on a track
- * v1.21: Repaired some bugs in 1.2.
- * v1.22: Doesnt include blocks 0 and 1 in file list.
- * v1.23: Now doesn't write new bitmap if reallocating blocks.
- */
-
- #define REV "v1.23"
- #define DATE "13/8/90"
-
- #include <devices/trackdisk.h>
- /* This should include lots of things with it (I hope) */
- #include <exec/memory.h>
- #include <stdio.h>
- #include <ctype.h>
- #include <proto/exec.h>
- #include <proto/dos.h>
- /* Works with DICE */
- /* Need open_lib's with Aztec or Lattice */
-
- struct Task *my_task;
- struct MsgPort port;
- struct IOStdReq req;
- UBYTE *m_data; /* Sector buffer */
- char drive=1; /* Which drive to access */
- char error_list[160];
- long bitblock;
- char n_opt;
- char doubly_alloc=0;
- /* This flag gets set if a track is already allocated and is dead */
-
- struct file_head {
- long type;
- long key;
- long num_block;
- long dat_size;
- long first;
- long sum;
- long blocks[72];
- long res[2];
- long prot;
- long size;
- char comment[92];
- long date[3];
- char name[64];
- long hash;
- long parent;
- long extens;
- long sec;
- } head;
-
- close_all()
- {/* Closes anything that was opened in open_all()
- */
- printf("\x9b\x20\x70\x9b0;31\x6d");
- /* Back to normal */
- read_track(0);
- FreeMem(m_data,512);
- CloseDevice(&req);
- RemPort(&port);
- exit(0);
- }
-
- chkabort()
- {/* Dont let anyone take control away from me!*/
- }
-
- open_all()
- {/* This opens the trackdisk device and assoc stuff.
- */
- m_data=AllocMem(512,MEMF_CHIP);
- if (!m_data) {
- printf("Cant get 512 bytes (What is happening to my world?)\n");
- exit();
- }
- my_task=FindTask(0L); /* Find my task! */
- port.mp_SigTask=my_task;
- AddPort(&port);
- if(OpenDevice(TD_NAME,(long)drive,&req,0L)) {
- printf("Couldn't open %s. exiting.\n",TD_NAME);
- exit();
- }
- req.io_Message.mn_ReplyPort=&port;
- req.io_Command=CMD_READ;
- req.io_Data=m_data;
- req.io_Length=TD_SECTOR;
- }
-
-
- read_track(track)
- int track;
- {/* Reads the track specified into the buffer.
- */
- int error;
- req.io_Command=CMD_READ;
- req.io_Length=TD_SECTOR;
- req.io_Offset= track *512;
- req.io_Data=m_data;
- error=DoIO(&req);
- req.io_Command=TD_MOTOR;
- req.io_Length=0;
- DoIO(&req); /* Turn motor off */
- return(error);
- }
-
- write_track(track)
- long track;
- {/* Writes the track specified into the buffer.
- */
- long error;
- req.io_Command=CMD_WRITE;
- req.io_Length=TD_SECTOR;
- req.io_Offset= track *512;
- req.io_Data=m_data;
- error=DoIO(&req);
- req.io_Command=TD_MOTOR;
- req.io_Length=0;
- DoIO(&req); /* Turn motor off */
- return(error);
- }
-
- display_err(err)
- int err;
- {/* Displays the error number and interpretation.
- */
- static char *msgs[]={
- "Not Specified",
- "No sector header",
- "Bad Sector Preamble",
- "Bad Sector ID",
- "Bad Header sum",
- "Bad Sector sum",
- "Too Few Sectors",
- "Bad Sector Header",
- "Write Protected",
- "Disk Changed",
- "Seek error",
- "No Memory",
- "Bad Unit Number",
- "Bad Drive Type",
- "Drive in use",
- "Post Reset"
- };
- printf("Error %ld: %s\n",err,msgs[err-20]);
- }
-
- check_disk()
- {/* This routine checks the disk for errors and fills up the error_list array
- */
- long i;
- long err;
- int count;
- req.io_Command=CMD_READ;
- req.io_Length=512;
- count=0;
- printf("\x9b\x30\x20\x70");
- for (i=0;i<160;i++) {
- long j;
- printf("Track %d.\n",i);
- printf("\x9b\x41");
- for (j=0;j<11;j++) {
- req.io_Offset=(i*11 +j)*512;
- err=DoIO(&req);
- if (err) {
- printf("Track %d: ",i);
- display_err(err);
- error_list[i]=1;
- count++;
- break;
- }
- }
- }
- printf("\x9b\x20\x70");
- printf("Check complete. %d errors.\n",count);
- req.io_Command=TD_MOTOR;
- req.io_Length=0;
- DoIO(&req);
- return(count);
- }
-
- warn(bit)
- int bit;
- {
- ULONG *dat;
- ULONG block;
- long err;
- printf("Warning: block %d is allocated\n",bit);
- doubly_alloc=1;
- }
-
-
- dead_alloc()
- {/* This is the bit that allocates the dead blocks.
- */
- int i,j;
- ULONG sum;
- long bit,err;
- err=read_track(bitblock);
- if (err) {
- display_err(err);
- printf("The bitmap block has an error... quitting \n");
- return;
- }
- for (i=0;i<160;i++) {
- if (error_list[i]) {
- for (j=0;j<11;j++) {
- bit=32+ i*11 +j -2;
- if (bit>=32) {
- if (!(((ULONG *)m_data)[bit/32] & (1<<(bit%32)))) warn(bit);
- ((ULONG *)m_data)[bit/32] = (((ULONG *)m_data)[bit/32]) & ~((ULONG)1 << (bit%32));
- }
- }
- }
- }
- fix_bit_sum(m_data);
- do {
- err=write_track(bitblock);
- if (err) {
- char c;
- printf("Error writing bitblock: ");
- display_err(err);
- printf("Retry? ");
- fflush(stdout);
- scanf("%c",&c);
- if (!(c=='y' || c=='Y')) err=0;
- }
- } while (err);
- }
-
- fix_bit_sum(dat)
- ULONG *dat;
- {
- ULONG sum,i;
- sum=0;
- for (i=1;i<128;i++)
- sum= sum+((ULONG *)dat)[i];
- ((ULONG *)dat)[0] = -sum;
- }
-
- fix_block_sum(dat)
- ULONG *dat;
- {
- ULONG sum,i;
- sum=0;
- for (i=0;i<128;i++)
- if (i!=5)
- sum= sum+((ULONG *)dat)[i];
- ((ULONG *)dat)[5] = -sum;
- }
-
- long
- find_free()
- {/* Finds a free block, allocates it and returns it's address.
- */
- long i,j,i1,j1;
- long err;
- err=read_track(bitblock);
- if (err) return(0);
- for (i1=880;i1<1760;i1++) {
- j1=1760-i1;
- i=i1+30;
- j=j1+30;
- if (((ULONG *)m_data)[i/32] & (1 << (i%32))) {
- ((ULONG *)m_data)[i/32] = (((ULONG *)m_data)[i/32]) & ~((ULONG)1 << (i%32));
- fix_bit_sum(m_data);
- write_track(bitblock);
- return(i1);
- }
- else if ((((ULONG *)m_data)[j/32] & (1 << (j%32))&&j>31)) {
- ((ULONG *)m_data)[j/32] = (((ULONG *)m_data)[j/32]) & ~((ULONG)1 << (j%32));
- fix_bit_sum(m_data);
- write_track(bitblock);
- return(j1);
- }
- }
- }
-
- dead_file(count)
- long count;
- {/* This creates the file "...dead" in the root directory of the disk
- * with the dead blocks in it.
- */
- long upto,err,which,howmany,next,i;
- int lower;
- if (error_list[0]==1) lower=2;
- else lower=0;
- if(!(which=find_free())) {
- printf("Error allocating block for ...Dead file\n");
- return;
- }
- head.type=2;
- head.key=which;
- head.prot=0x007;
- strcpy(head.comment,"\x21 File for holding dead tracks in.");
- strcpy(head.name,"\7...Dead");
- head.parent=880;
- head.sec=-3;
- for (upto=0,howmany=0;upto<1760 && howmany<72;upto++)
- if (error_list[upto/11] && upto>=2) {
- head.blocks[71-howmany]=upto;
- howmany++;
- }
- head.num_block=howmany-lower;
- head.size=(count*11-lower)*488;
- head.first=head.blocks[71];
- read_track(880);
- head.hash=((ULONG *)m_data)[61];
- ((ULONG *)m_data)[61]=which;
- /* ^^ 61 is the hash value for ...Dead . If you change
- * the name then you have to change the hash value.
- */
- fix_block_sum(m_data);
- write_track(880);
- next=0;
- if (howmany==72) {
- if(!(next=find_free())) {
- printf("Error allocating block for ...Dead file\n");
- return;
- }
- head.extens=next;
- }
- for (i=0;i<128;i++)
- ((ULONG *)m_data)[i]=((ULONG *)&head)[i];
- fix_block_sum(m_data);
- write_track(which);
- /* Here make extension blocks if number of blocks > 72 */
- while (upto<1760) {
- long next_ext;
- next_ext=0;
- head.type=0x10;
- for (howmany=0;upto<1760 && howmany<72;upto++)
- if (error_list[upto/11]) {
- head.blocks[71-howmany]=upto;
- howmany++;
- }
- for (i=howmany;i<72;i++)
- head.blocks[71-i]=0;
- head.num_block=howmany;
- head.hash=0;
- for (i=0;i<92;i++) head.comment[i]=0;
- for (i=0;i<64;i++) head.name[i]=0;
- head.prot=0;
- head.size=0;
- head.parent=which;
- head.key=next;
- head.first=0;
- head.extens=0;
- if (howmany==72) {
- next_ext=find_free();
- head.extens=next_ext;
- }
- for (i=0;i<128;i++)
- ((ULONG *)m_data)[i]=((ULONG *)&head)[i];
- fix_block_sum(m_data);
- write_track(next);
- next=next_ext;
- }
- }
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- BPTR in;
- int i,count;
- int err,nofile;
- nofile=0;
- printf("\x9b33;4mDead track allocator %s.\x9b0;33m ) Tim MacKenzie %s.\x9b31m\n",REV,DATE);
- for (i=1;i<argc;i++) {
- if (argv[i][0]!='-' && argv[i][0]!='d') {
- printf("Usage: %s [-m] [-n] [df?:] \n",argv[0]);
- printf(" -m : Modify bitmap only. Dont add file\n");
- printf(" -n : Allow reallocation of blocks\n");
- printf(" df?: Set drive number (default is drive 1)\n");
- exit(1);
- }
- if (argv[i][1]=='m') {nofile=1; continue;}
- if (argv[i][1]=='n') {n_opt=1; continue;}
- if (argv[i][1]=='f') {
- drive=argv[i][2]-'0';
- if (drive <0 || drive >4) {
- argv[i][0]='0';
- i--;
- continue;
- }
- continue;
- }
- }
- if (!nofile) {
- char name[12];
- strcpy(name,"df1:...Dead");
- name[2]='0'+drive;
- in = Open(name,MODE_OLDFILE);
- if (in) {
- printf("File \"...Dead\" already exists on drive df%1d:.\n",drive);
- printf("Change it's protection and delete it. Then retry\n");
- Close(in);
- exit();
- }
- }
- open_all();
- err=read_track(880);
- if(err) {
- display_err(err);
- printf("Error reading root block. Quitting.\n");
- close_all();
- }
- bitblock=((long *)m_data)[79];
- printf("Volume: %s. Bitmap on %d.\n",&m_data[(108<<2)+1],bitblock);
- count=check_disk();
- if (count) {
- dead_alloc();
- if (!n_opt && doubly_alloc) {
- printf("Some dead tracks are allocated to existing files.\n");
- printf("Delete offending file/s or use -n option (dangerous!)\n");
- close_all();
- }
- if (!nofile)
- dead_file(count);
- printf("Now remove the disk and reinsert it before using.\n");
- }
- close_all();
- }
-