/*
** SetTDRetry v37.1
** 
** Compiled under SAS/C 6.50
**
*/

#define __USE_SYSBASE

#include <exec/types.h>
#include <exec/execbase.h>
#include <dos/dosextens.h>
#include <dos/rdargs.h>
#include <devices/trackdisk.h>

#include <string.h>

#include <proto/dos.h>
#include <proto/exec.h>

#define DOSLIB "dos.library"
#define DOSVER 36L

#define ThisProcess ((struct Process *)(SysBase->ThisTask))
#define Result2(x) ThisProcess->pr_Result2 = x

#define OPT_UNITS 0
#define OPT_RETRY 1
#define OPT_QUIET 2
#define OPT_COUNT 3

#define TEMPLATE "UNITS=U/A/N/M,RETRYCOUNT=RC/N/K,QUIET=Q/S"

#define MSG_FAILED "SetTDRetry failed"

#define RETRY_DEFAULT 10

const char *vertag = "$VER: SetTDRetry 37.1 (23.4.94) ©1994 S. Koszewski";

// prototypes

int PatchUnit(struct ExecBase *SysBase, struct DosLibrary *DOSBase,
              long unit, long quiet, long cnt);
int command(void);

// program

int command(void)
  {
  struct ExecBase *SysBase = (*((struct ExecBase **)4));
  struct DosLibrary *DOSBase;
  long opts[OPT_COUNT],i,rc = RETURN_FAIL,*units,quiet,cnt;
  struct RDArgs *rdargs;
  
  if(DOSBase = (struct DosLibrary *)OpenLibrary(DOSLIB,DOSVER))
    {
    for(i=0;i<OPT_COUNT;i++) opts[i]=0L;
    rdargs = ReadArgs(TEMPLATE,opts,NULL);
    if(rdargs)
      {
      quiet=opts[OPT_QUIET];
      
      cnt = opts[OPT_RETRY] ? *((long *)opts[OPT_RETRY]) : RETRY_DEFAULT;
        
      if(opts[OPT_UNITS] && cnt>0 && cnt<=100)
        {
        units=(long *)opts[OPT_UNITS];
        while(i = *units++) PatchUnit(SysBase,DOSBase,*((long *)i),quiet,cnt);
        rc = RETURN_OK;
        }
      else rc = RETURN_WARN;
        
      FreeArgs(rdargs);
      }
    else
      PrintFault(IoErr(),MSG_FAILED);
    
    CloseLibrary((struct Library *)DOSBase);
    }
  else
    Result2(ERROR_INVALID_RESIDENT_LIBRARY);
  
  return rc;
  }

int PatchUnit(struct ExecBase *SysBase, struct DosLibrary *DOSBase,
              long unit, long quiet, long cnt)
  {
  struct MsgPort *myport;
  struct IORequest *ioreq;
  long rc = RETURN_FAIL;
  
  if(!quiet) VPrintf("Patching trackdisk.device unit #%ld", (APTR)&unit);
  
  if(myport = CreateMsgPort())
    {
    if(ioreq = CreateIORequest(myport,sizeof(struct IORequest)))
      {
      if(!OpenDevice(TD_NAME, unit, ioreq, 0L))
        {
        ((struct TDU_PublicUnit *)ioreq->io_Unit)->tdu_RetryCnt = (UBYTE)cnt;
        rc = RETURN_OK;
        CloseDevice(ioreq);
        }
      DeleteIORequest(ioreq);
      }
    DeleteMsgPort(myport);
    }
  
  if(!quiet) PutStr(rc==RETURN_OK?" - Ok.\n":" - Failed.\n");
  
  return rc;
  }
