[comp.sources.amiga] diskwipe

ain@j.cc.purdue.edu (Patrick White) (01/10/88)

Program Name:	diskwipe
Submitted By:	sas.uucp!walker@mcnc.org (Doug Walker)
Summary:	erases all files and directories from a disk.  optionally
		renames the voulme.  Is faster than "delete df0: all".
Poster Boy:  Pat White  (ain@j.cc.purdue.edu)
Untested.

NOTES:
   This source requires Lattic C (it was taking too much time for me to
alter it to compile under Manx), so it is untested.


-- Pat White   (co-moderator comp.sources/binaries.amiga)
UUCP: j.cc.purdue.edu!ain  BITNET: PATWHITE@PURCCVM   PHONE: (317) 743-8421
U.S.  Mail:  320 Brown St. apt. 406,    West Lafayette, IN 47906

========================================


The source compiles under Lattice 4.0, no guarantees for previous versions.
To build it, enter 'execute build' at a CLI prompt.  I had to break the BLINK
command line to get it under 80 characters, so you will need to edit it.The 
script expects a .c file called _main.c, supplied on the Lattice C distribution 
diskettes.  When recompiled with the symbol TINY defined, this results in 
significant space savings.  The executable is 4148 bytes compiled this way.

What is diskwipe?  It is a utility to erase previously formatted DOS
disks, similar to DELETE ALL except it only takes 2 seconds.

This project was brought to you by the Software Distillery, purveyors of 
the finest Amiga Redistributable software.  See the distribution info 
in the file diskwipe.doc.  Enjoy!

   - Doug Walker
     Software Distiller

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	diskwipe.doc
#	build
#	diskwipe.h
#	mydebug.h
#	diskwipe.c
#	execsupport.c
# This archive created: Sat Jan  9 13:37:00 1988
# By:	Patrick White (PUCC Land, USA)
echo shar: extracting diskwipe.doc '(3334 characters)'
cat << \SHAR_EOF > diskwipe.doc
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* |_o_o|\\ Copyright (c) 1987 The Software Distillery.  All Rights Reserved *
* |. o.| ||          Written by Doug Walker                                 *
* | .  | ||          The Software Distillery                                *
* | o  | ||          235 Trillingham Lane                                   *
* |  . |//           Cary, NC 27513                                         *
* ======             BBS:(919)-471-6436                                     *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                              DISKWIPE 1.0

This program, both executable and source, is copyright (c) 1987 The 
Software Distillery.  The program is freely redistributable as long as
the following conditions are met:

1. It is distributed with all files in this archive intact and unchanged.

2. The distributor does so on a not-for-profit basis.  

These distribution rights may be withdrawn by The Software Distillery
at any time if the Distillery feels the distributor is abusing either
of these conditions.

As the author, I request that you send me a copy of any changes you
make to this code before distributing it.  (Address below).

===========================================================================

Have you ever had a disk full of files you wanted to get rid of?  You
probably typed DELETE ALL and listened to the floppy grind away for about
ten minutes doing it.  Well, here's an alternative:  DISKWIPE.

USAGE:  DISKWIPE [MANY] [[DRIVE] <dfn:>] [[NAME] <name>]

MANY           DISKWIPE will work on multiple disks.  It will prompt you 
               after wiping each disk.  To quit, type CTRL-\ at the prompt.

DRIVE <dfn:>   Specifies the name of the floppy drive to use.  The DRIVE
               keyword is optional.  If no drive is specified, DF0: will
               be used.

NAME <name>    Specifies a new name for the disk.  The NAME keyword is
               optional.  If no name was specified,  DISKWIPE will use the 
               existing name.  If the existing name is not valid, the name 
               "dos disk" will be used.  You also have the opportunity to 
               enter a new name when you are prompted to hit RETURN.


EXAMPLES:

DISKWIPE
Wipes all data from drive DF0:.  The disk name will be retained.  You will
be prompted to insert the disk.

DISKWIPE df1: farkle
Wipes all data from drive DF1:.  The name FARKLE will be used.  You will be
prompted.

DISKWIPE MANY df0:
Wipes all data from drive df0:.  You will be prompted before the first disk
and after each disk.  You can type in a name for each disk at the prompt
or just hit return to use the old name.  CTRL-\ quits.


BUGS:
There is a problem with running diskwipe while DOS is validating the floppy.
An invalid disk structure may be generated if this occurs.  To be safe, 
wait until the disk light goes out completely before issuing the DISKWIPE
command.

FUTURE PLANS:
A replacement FORMAT command that accepts WIPE as an option.

SUPPORT, SUGGESTIONS, CONTRIBUTIONS:
Please state what version of the program you have when writing.
This is version 1.0.

Doug Walker
405 B3 Gooseneck Drive
Cary, NC 27513

or

The Software Distillery
235 Trillingham Lane
Cary, NC 27513
BBS: (919)471-6436
SHAR_EOF
if test 3334 -ne "`wc -c diskwipe.doc`"
then
echo shar: error transmitting diskwipe.doc '(should have been 3334 characters)'
fi
echo shar: extracting build '(266 characters)'
cat << \SHAR_EOF > build
#NOTE: I have split the BLINK command line - you must rejoin it!
lc -dTINY=1 -d_exit=XCEXIT -v -dexit=XCEXIT -cufs -M _main diskwipe execsup
blink lib:c.o _main.o diskwipe.o execsup.o to diskwipe map diskwipe.map 
hsflx verbose sc sd nd lib lib:lc.lib lib:amiga.lib
SHAR_EOF
if test 266 -ne "`wc -c build`"
then
echo shar: error transmitting build '(should have been 266 characters)'
fi
echo shar: extracting diskwipe.h '(2249 characters)'
cat << \SHAR_EOF > diskwipe.h
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* |_o_o|\\ Copyright (c) 1987 The Software Distillery.  All Rights Reserved *
* |. o.| ||          Written by Doug Walker                                 *
* | .  | ||          The Software Distillery                                *
* | o  | ||          235 Trillingham Lane                                   *
* |  . |//           Cary, NC 27513                                         *
* ======             BBS:(919)-471-6436                                     *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#include "exec/types.h"
#include "exec/memory.h"
#include "exec/types.h"
#include "exec/nodes.h"
#include "exec/ports.h"
#include "libraries/dosextens.h"
#include "devices/trackdisk.h"
#include "string.h"
#include <stdlib.h>
#if 0
#include <proto/dos.h>
#include <proto/exec.h>
#endif
#ifdef MYDEBUG
#include "stdio.h"
#endif

struct MsgPort *NewPort(void);
void DisposePort(struct MsgPort *);
struct IOExtTD *CreateIOExtTD(struct MsgPort *);
#define DeleteIOExtTD(xxx) FreeMem((char *)xxx, sizeof(struct IOExtTD))
void testbreak(void);
void inhibit(LONG);
void iopanic(void);
void panic(int);
void GetName(char *);
long checksum(long *);
void makeroot(long *, char *);
void DosTerm(void);
void DosInit(int);
void enditall(void);
void TDIO(UWORD);
void TDInit(void);
void TDTerm(void);
void TDMotOff(void);
char toupper(char);

#ifndef min
#define min(a,b) ((a)<(b) ? (a) : (b))
#endif

#define TDREQ(field) g.diskreq->iotd_Req.field
#define ETDREQ(field) g.diskreq->field

#define NUMCYLS  80
#define NUMHEADS  2
#define MYIOSIZE TD_SECTOR

#define PUTTERM(msg) Write(g.outfile, globmsg[msg], (long)globlen[msg]);

#ifndef EXTERN
#define EXTERN extern
#endif

#define DW_FILLED 0x00000001
#define DW_MANY   0x00000002
#define DW_NOTDOS 0x00000004
#define DW_QUIET  0x00000008
#define DW_PANIC  0x00000010
#define DW_PANIC2 0x00000020
#define DW_TDOPEN 0x00000040

struct MYGLOBAL
{
   int flags;
   int errnum;
   struct MsgPort *diskport, *replyport;
   struct MsgPort *dosport;
   struct Message *msg;
   struct DosPacket *packet;
   struct IOExtTD *diskreq;
   int tdunit;
   BPTR outfile;
};

EXTERN struct MYGLOBAL g;
SHAR_EOF
if test 2249 -ne "`wc -c diskwipe.h`"
then
echo shar: error transmitting diskwipe.h '(should have been 2249 characters)'
fi
echo shar: extracting mydebug.h '(1851 characters)'
cat << \SHAR_EOF > mydebug.h
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* |_o_o|\\ Copyright (c) 1987 The Software Distillery.  All Rights Reserved *
* |. o.| ||          Written by Doug Walker                                 *
* | .  | ||          The Software Distillery                                *
* | o  | ||          235 Trillingham Lane                                   *
* |  . |//           Cary, NC 27511                                         *
* ======             BBS:(919)-471-6436                                     *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#ifndef EXTERN
#define EXTERN extern
#endif

#if 0
#define MYDEBUG 1
#endif

#ifndef DEBUGGRP
#define DEBUGGRP 0
#endif

#define BUG(lvl, args) BUGGRP(DEBUGGRP, lvl, args)
#define BUGGETC(lvl)   BUGGGETC(DEBUGGRP, lvl)
#define BUG0(lvl, args) BUGGRP(0, lvl, args)
#define BUGGTC0(lvl)   BUGGGETC(0, lvl)
#define BUG1(lvl, args) BUGGRP(1, lvl, args)
#define BUGGTC1(lvl)   BUGGGETC(1, lvl)
#define BUG2(lvl, args) BUGGRP(2, lvl, args)
#define BUGGTC2(lvl)   BUGGGETC(2, lvl)
#define BUG3(lvl, args) BUGGRP(3, lvl, args)
#define BUGGTC3(lvl)   BUGGGETC(3, lvl)
#define BUG4(lvl, args) BUGGRP(4, lvl, args)
#define BUGGTC4(lvl)   BUGGGETC(4, lvl)
#define BUG5(lvl, args) BUGGRP(5, lvl, args)
#define BUGGTC5(lvl)   BUGGGETC(5, lvl)

#ifdef MYDEBUG

void dump(char *, int);

#define MAXDEBUG 10
EXTERN int debug[MAXDEBUG];

#define BUGTEST(lvl) (lvl<=debug[DEBUGGRP])

#define BUGGRP(grp, lvl, args) {if(lvl<=debug[grp])\
                                   {printf args ; fflush(stdout);}}
#define BUGGGETC(grp, lvl) {if(lvl<=debug[grp])\
                       {printf("Hit return to continue: ");(void)getchar();}}

#else

#define BUGTEST(grp) (0)
#define BUGGRP(grp, lvl, args) {}
#define BUGGGETC(grp, lvl) {}

#endif MYDEBUG
SHAR_EOF
if test 1851 -ne "`wc -c mydebug.h`"
then
echo shar: error transmitting mydebug.h '(should have been 1851 characters)'
fi
echo shar: extracting diskwipe.c '(10889 characters)'
cat << \SHAR_EOF > diskwipe.c
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* |_o_o|\\ Copyright (c) 1987 The Software Distillery.  All Rights Reserved *
* |. o.| ||          Written by Doug Walker                                 *
* | .  | ||          The Software Distillery                                *
* | o  | ||          235 Trillingham Lane                                   *
* |  . |//           Cary, NC 27513                                         *
* ======             BBS:(919)-471-6436                                     *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#define EXTERN

#include "mydebug.h"
#include "diskwipe.h"

#define MSG_COPYRIGHT 0
#define MSG_DESTROY   1
#define MSG_INSERT    2
#define MSG_USAGE     3
#define MSG_CTRLBK    4
#define MSG_KEEP      5
#define MSG_USE       6

#define MSG_SYS       7
#define MSG_NOMEM     7
#define MSGGETSERR    8
#define MSG_WPROT     8
#define MSG_NODISK    9
#define MSG_BADUNIT  10
#define MSG_INUSE     7
#define MSG_DISKERR  12

char globlen[] =
{
   58, 59, 50, 56, 21, 15, 20, 12, 24, 17, 14, 16,
#ifdef MYDEBUG
   26
#endif
};

char *globmsg[] =
{
   "DISKWIPE 1.0 - Copyright (c) 1987 The Software Distillery\n",
#define DESTROY_SPOT      36
   "\n***** WARNING: All data in drive DF0: will be lost! *****\n",
   "Insert disk and enter new name or press RETURN to ",
   "Usage: diskwipe [MANY] [[DRIVE] <dfn:>] [[NAME] <name>]\n",
   "Press CTRL-\\ to quit\n",
   "keep old name: ",
   "use specified name: ",
   "Fatal error\n",
   "Disk is write protected\n",
   "No disk in drive\n",
   "No such drive\n",
   "Drive in use\n",
#ifdef MYDEBUG
#define DISKERR_SPOT 22
   "Trackdisk error, code    \n"
#endif
   };

void inhibit(arg1)
LONG arg1;
{
   BUG(1, ("inhibit: Entry\n"))
   g.msg->mn_ReplyPort = g.packet->dp_Port = g.replyport;
   g.msg->mn_Node.ln_Name = (char *)g.packet;
   g.msg->mn_Node.ln_Type = NT_MESSAGE;
/*   msg->mn_Length =  0; */

   g.packet->dp_Link = g.msg;
   g.packet->dp_Type = ACTION_INHIBIT;
   g.packet->dp_Arg1 = arg1;
   PutMsg(g.dosport, g.msg);
   WaitPort(g.replyport); 
   (void)GetMsg(g.replyport);
   BUG(1, ("inhibit: Exit, res1 %ld res2 %ld\n", g.packet->dp_Res1, g.packet->dp_Res2))
}

void iopanic()
{
#ifdef MYDEBUG
   short code;
#endif
   register int iomsg;
BUG(1, ("iopanic: Entry, io_Error = %d\n", TDREQ(io_Error)))
   switch(TDREQ(io_Error))
   {
      case TDERR_WriteProt:    iomsg = MSG_WPROT;   break;  /* 28 */
      case TDERR_DiskChanged:  iomsg = MSG_NODISK;  break;  /* 29 */
      case TDERR_BadUnitNum:                                /* 32 */
      case TDERR_BadDriveType: iomsg = MSG_BADUNIT; break;  /* 33 */
      case TDERR_DriveInUse:   iomsg = MSG_INUSE;   break;  /* 34 */
      default:
#ifdef MYDEBUG
         code = (TDREQ(io_Error)) & 255;
BUG(100, ("iopanic: code is %d\n", (unsigned int)code))
         globmsg[MSG_DISKERR][DISKERR_SPOT] = '0' + (short)(code/(short)100);
         code %= (short)100;
BUG(100, ("iopanic: code is %d\n", (unsigned int)code))
         globmsg[MSG_DISKERR][DISKERR_SPOT+1] = '0' + (short)(code/(short)10);
         code %= (short)10;
BUG(100, ("iopanic: code is %d\n", (unsigned int)code))
         globmsg[MSG_DISKERR][DISKERR_SPOT+2] = '0' + code;
         iomsg = MSG_DISKERR;
         break;
#else
     iomsg = MSG_SYS;
#endif
   }
   panic(iomsg);
}

void panic(msgnum)
int msgnum;
{
   BUG(1, ("panic: Entry\n"))
   g.errnum++;

   if(msgnum>=MSGGETSERR) Write(g.outfile, "ERROR: ", 7L);
   PUTTERM(msgnum);

   enditall();
}

void GetName(diskname)
char *diskname;
{
   int i;
   char *tmpchar;
BUG(1, ("GetName: Entry\n"))
#ifdef NOTDOS
   if(!(g.flags & DW_NOTDOS))
   {
#endif
      TDREQ(io_Length) = MYIOSIZE;
      TDIO(CMD_READ);
BUG(100, ("Getname: TDIO done\n"))
      tmpchar = (char *)(TDREQ(io_Data));
      if(tmpchar[3] != 2 || tmpchar[511] != 1) goto DEFNAME;
      memcpy(diskname, tmpchar+433, i=min(30, (int)tmpchar[432]));
      diskname[i] = '\0';
BUG(100, ("GetName: %d chars in name\n", i))
BUG(1, ("GetName: Exit, name is '%s'\n", diskname))
      return;
#ifdef NOTDOS
   }
#endif

DEFNAME:
BUG(10, ("GetName: Root block not initialized, using default\n"))
         strcpy(diskname, "Dos disk");
BUG(1, ("GetName: Exit, name is '%s'\n", diskname))
}

long checksum(block)
long *block;
{
   long sum;
   int i;

   for(i=0, sum = 0L; i<128; i++) sum += block[i];

   BUG(100, ("checksum: returning %ld\n", -sum))
   return(-sum);
}

void makeroot(buffer, diskname)
long *buffer;
char *diskname;
{
   int i;
   memset((char *)buffer, 0, TD_SECTOR);
   buffer[0]   = 2L;   /* Type                        */
   buffer[3]   = 72L;  /* Hashtable size              */
   buffer[79]  = 881L; /* Block to contain the bitmap */
   *(((char *)buffer)+432) = i = strlen(diskname);
   memcpy(((char *)buffer)+433, diskname, i);
   DateStamp(buffer+121);  /* Volume creation date      */
   DateStamp(buffer+105);  /* Volume last modified date */
   buffer[127] = 1L;       /* Secondary type for root   */
   buffer[5] = checksum(buffer);
}

void DosTerm()
{
BUG(1, ("DosTerm: enter\n"))
   if(g.replyport)
   {
BUG(10, ("DosTerm: Disposing of replyport\n"))
      inhibit(0L);
      DisposePort(g.replyport);
      g.replyport = (struct MsgPort *)NULL;
   }
   if(g.msg)    FreeMem((char *)g.msg, sizeof(struct Message));
   if(g.packet) FreeMem((char *)g.packet, sizeof(struct DosPacket));
   g.msg = (struct Message *)(g.packet = (struct DosPacket *)NULL);
BUG(1, ("DosTerm: exit	\n"))
}

void DosInit(device)
int device;
{
   char devname[5];
BUG(1, ("DosInit: Entry\n"))

   strcpy(devname, "df0:");
   devname[2] = '0' + device;

   if( !(g.msg = (struct Message *)AllocMem(sizeof(struct Message), 
                    			  MEMF_PUBLIC|MEMF_CLEAR))      ||
       !(g.packet = (struct DosPacket *)AllocMem(sizeof(struct DosPacket), 
        			   	  MEMF_PUBLIC|MEMF_CLEAR)) ||
       !(g.replyport = NewPort())
     )
      panic(MSG_NOMEM);

   g.dosport = (struct MsgPort *)DeviceProc(devname);
   inhibit(1);
}

void enditall()
{
BUG(1, ("Enditall: Entry\n"))
   TDTerm();
BUG(100, ("Enditall: TDTerm done\n"))
   DosTerm();
BUG(100, ("Enditall: DosTerm done\n"))
   Write(g.outfile, "\n", 1);
   XCEXIT(0);
}

void testbreak()
{
   if (SetSignal(0,0) & (SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D))
   {
      Write(g.outfile, "***Break", 8);
      enditall();
   }
}

void main(argc, argv)
int argc;
char *argv[];
{
   char diskname[31];
   char *tmpchar, *usename;
   int nameflag, nexttok, i;

#ifdef MYDEBUG
   int j;
   for(i=0; i<MAXDEBUG; i++) debug[i] = 0;
#endif

   if(argc == 0) XCEXIT(5);

   memset((char *)&g, 0, sizeof(struct MYGLOBAL));

#ifdef MYDEBUG
   if(argc>1 && argv[1][0] == '-' && toupper(argv[1][1]) == 'D')
   {
      if(argv[1][2] == '*') i = -1;
      else (void)stcd_i(argv[1]+2, &i);
      if(i >= MAXDEBUG) i = 0;
      (void)stcd_i(argv[2], &j);
      if(i>= 0)
      {
         debug[i] = j;
         printf("Debugging group %d initialized at level %d\n",i,j);
      }
      else
      {
         for(i=0; i<MAXDEBUG; i++) debug[i] = j;
         printf("All debugging initialized at level %d\n", j);
      }
      argc-=2, argv+=2;
   }
#endif
   BUG(1, ("main: Entry\n"))

   g.outfile = Output();

   usename = diskname;
   nameflag = FALSE;
   for(nexttok=0; argc > 1; argc--, argv++)
   {
      if(argv[1][0] == '?')
      {
         PUTTERM(MSG_COPYRIGHT);
         panic(MSG_USAGE);
      }
      else if(!nexttok && !stricmp(argv[1], "MANY"))
         g.flags |= DW_MANY;
#ifdef NOTDOS
      else if(!nexttok && !stricmp(argv[1], "NOTDOS"))
         g.flags |= DW_NOTDOS;
#endif
      else if(nexttok == 1 || (!nexttok && 
           (toupper(argv[1][0]) == 'D' && toupper(argv[1][1]) == 'F' &&
            (i = argv[1][2] - '0')>=0 && i < 4
          )))
      {
         g.tdunit = i;
         nexttok = 0;
      }
      else if(!nexttok && !stricmp(argv[1], "DRIVE"))
         nexttok = 1;
      else if(!nexttok && !stricmp(argv[1], "NAME"))
         nexttok = 2;
      else if(!nameflag)
      {
         usename = argv[1];
         nameflag = TRUE;
         nexttok = 0;
      }
      else
         panic(MSG_USAGE);
   }

   TDInit();

   DosInit(g.tdunit);

   if(!(TDREQ(io_Data) = (APTR)AllocMem(MYIOSIZE, MEMF_CHIP|MEMF_CLEAR)))
      panic(MSG_NOMEM);

   globmsg[MSG_DESTROY][DESTROY_SPOT] = '0' + g.tdunit;
   PUTTERM(MSG_DESTROY)
   if(g.flags & DW_MANY) PUTTERM(MSG_CTRLBK)

   diskname[30] = '\0';
   do
   {
      TDMotOff();
      PUTTERM(MSG_INSERT)
      PUTTERM(nameflag ? MSG_USE : MSG_KEEP)
      if(!Read(Input(), diskname, 30)) break;
      testbreak();
      if(diskname[0] != '\n' && (tmpchar=strchr(diskname, '\n')) )
      {
         *tmpchar = '\0';
         usename = diskname;
         nameflag = FALSE;
      }
      else if(!nameflag)
         GetName(diskname);

      TDREQ(io_Length)  = MYIOSIZE;

#ifdef NOTDOS
      if(g.flags & DW_NOTDOS)
      {
         strcpy((char *)TDREQ(io_Data), "DOS");
         TDREQ(io_Offset) = 0;
         TDIO(CMD_WRITE);
         TDREQ(io_Offset) = 880*TD_SECTOR;
      }
#endif

      makeroot((long *)TDREQ(io_Data), usename);
      TDIO(CMD_WRITE);
   }
   while(g.flags & DW_MANY);

   enditall();   
}

void TDIO(command)
UWORD command;
{
   BUG(1, ("TDIO: Entry, command %d\n", command))
   TDREQ(io_Command) = command;
   DoIO((struct IORequest *)g.diskreq);
   if(TDREQ(io_Error)) iopanic();
   BUG(1, ("TDIO: Exit\n"))
}

void TDInit()
{
   BUG(1, ("TDInit: Entry\n"))

   if(!(g.diskport = NewPort()) || !(g.diskreq = CreateIOExtTD(g.diskport)))
      panic(MSG_SYS);

   ETDREQ(iotd_Count) = (unsigned long)0xffffffff;
   TDREQ(io_Offset) = 880*TD_SECTOR;

   BUG(10, ("TDInit: Port created, diskreq allocated\n"))

   if(OpenDevice(TD_NAME, g.tdunit, (struct IORequest *)g.diskreq, 0))
      iopanic();

   g.flags |= DW_TDOPEN;

   BUG(1, ("TDInit: Exit\n"))
}

void TDTerm()
{
   BUG(1, ("TDTerm: Entry\n"))

   if(g.flags & DW_TDOPEN)
   {
      if(TDREQ(io_Data))
      {
BUG(100, ("Enditall: freeing io_Data\n"))
         FreeMem((char *)TDREQ(io_Data), MYIOSIZE);
         TDREQ(io_Data) = NULL;
      }
      if(g.errnum<2) TDMotOff();

      CloseDevice((struct IORequest *)g.diskreq);
BUG(10, ("TDTerm: Device closed\n"))

      DeleteIOExtTD(g.diskreq);
BUG(10, ("TDTerm: Diskreq freed\n"))

      g.diskreq = (struct IOExtTD *)NULL;
   }

   if(g.diskport)
   {
      DisposePort(g.diskport);
      g.diskport = (struct MsgPort *)NULL;
BUG(10, ("TDTerm: port deleted\n"))
   }

BUG(1, ("TDTerm: Exit\n"))
}

void TDMotOff()
{
BUG(1, ("TDMotOff: Entry\n"))
   TDREQ(io_Length) = 0;
   if(!TDREQ(io_Error))
   {
BUG(10, ("TDMotOff: Clearing track buffer\n"))
      TDIO((UWORD)ETD_UPDATE);
      TDIO((UWORD)ETD_CLEAR);
   }

   TDIO((UWORD)ETD_MOTOR);
BUG(1, ("TDMotOff: Exit\n"))
}

void MemCleanup(){}
SHAR_EOF
if test 10889 -ne "`wc -c diskwipe.c`"
then
echo shar: error transmitting diskwipe.c '(should have been 10889 characters)'
fi
echo shar: extracting execsupport.c '(1083 characters)'
cat << \SHAR_EOF > execsupport.c
#include "diskwipe.h"

struct MsgPort *NewPort()
{
   UBYTE sigbit;
   struct MsgPort *port;

   if ((sigbit = AllocSignal(-1)) == -1)
      return(NULL);

   if ((port = (struct MsgPort *)
               AllocMem((ULONG)sizeof(struct MsgPort),
                        MEMF_CLEAR|MEMF_PUBLIC)) == NULL)
      {
      FreeSignal(sigbit);
      return(NULL);
      }

   port->mp_Node.ln_Type = NT_MSGPORT;
   port->mp_Flags        = PA_SIGNAL;
   port->mp_SigBit       = sigbit;
   port->mp_SigTask      = FindTask(0);
   NewList(&(port->mp_MsgList));
   return(port);
}

void DisposePort(port)
struct MsgPort *port;
{
   FreeSignal(port->mp_SigBit);
   FreeMem((char *)port, (ULONG)sizeof(*port));
}

struct IOExtTD *CreateIOExtTD(mp)
struct MsgPort *mp;
   {
   struct IOExtTD *ioext;
   if ((ioext = (struct IOExtTD *)
                AllocMem(sizeof(struct IOExtTD),
                         MEMF_CLEAR|MEMF_PUBLIC)) != NULL)
      {
      ioext->iotd_Req.io_Message.mn_Node.ln_Type = NT_MESSAGE;
      ioext->iotd_Req.io_Message.mn_ReplyPort = mp;
      }
   return(ioext);
   }
SHAR_EOF
if test 1083 -ne "`wc -c execsupport.c`"
then
echo shar: error transmitting execsupport.c '(should have been 1083 characters)'
fi
#	End of shell archive
exit 0