home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
back2roots/padua
/
padua.7z
/
padua
/
disk
/
RDBFlags-1.3.lha
/
RDBFlags.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-04-07
|
8KB
|
282 lines
/*
* modify RDB flags
*
* Copyright ⌐ 1994 by Andreas M. Kirchwitz
* Seesener Stra▀e 69
* D-10709 Berlin, Germany
* UUCP/Internet: amk@zikzak.in-berlin.de
*
* Thanks to Ralph Babel (author of "The Amiga Guru Book")
* and Matthias Scheler (owner of a copy of "The Amiga Guru Book").
*/
#define __USE_SYSBASE
#include <exec/types.h>
#include <exec/alerts.h>
#include <exec/memory.h>
#include <devices/trackdisk.h>
#include <devices/hardblocks.h>
#include <dos/dosextens.h>
#include <dos/rdargs.h>
#include <proto/exec.h>
#include <proto/dos.h>
extern struct ExecBase *__far AbsExecBase;
/* defines */
#define PROGRAMNAME_MAX 32
#define DEFAULT_DEVICE "scsi.device"
#define DEFAULT_UNIT 0
#define DEFAULT_SECTORSIZE TD_SECTOR
#define DEFAULT_FLAGS 0
#define RDBFLAGS_TEMPLATE "Device/K,Unit/N,SectorSize/N,LastDisk/S,NoLastDisk/S,LastLun/S,NoLastLun/S,LastTarget/S,NoLastTarget/S,Reselect/S,NoReselect/S,Sync/S,NoSync/S"
struct Args
{
char *device;
LONG *pUnit;
LONG *pSectorSize;
LONG lastDisk;
LONG noLastDisk;
LONG lastLun;
LONG noLastLun;
LONG lastTarget;
LONG noLastTarget;
LONG reselection;
LONG noReselection;
LONG synchronous;
LONG noSynchronous;
LONG defaultUnit;
LONG defaultSectorSize;
};
/* globals */
static const char version[] = "$VER: RDBFlags 1.3 " __AMIGADATE__;
LONG main(void)
{
LONG result;
struct ExecBase *SysBase;
struct Library *DOSBase;
struct Process *pr;
struct Message *mn;
struct RDArgs *rda;
struct MsgPort *mp;
struct IOStdReq *io;
struct RigidDiskBlock *rdb;
char *name;
char *device;
ULONG unit;
ULONG sectorSize, i;
ULONG sector;
ULONG flags;
LONG *p, sum;
struct Args args;
struct DriveGeometry DG;
char programName[PROGRAMNAME_MAX];
SysBase = AbsExecBase;
pr = (struct Process *) FindTask(NULL);
result = RETURN_FAIL;
if (pr->pr_CLI != NULL)
{
if ((DOSBase = OpenLibrary(DOSNAME, 37)) != NULL)
{
if (!GetProgramName(name = programName, PROGRAMNAME_MAX))
name = "RDBFlags";
args.device = DEFAULT_DEVICE;
args.pUnit = &args.defaultUnit;
args.pSectorSize = &args.defaultSectorSize;
args.lastDisk = FALSE;
args.noLastDisk = FALSE;
args.lastLun = FALSE;
args.noLastLun = FALSE;
args.lastTarget = FALSE;
args.noLastTarget = FALSE;
args.reselection = FALSE;
args.noReselection = FALSE;
args.synchronous = FALSE;
args.noSynchronous = FALSE;
args.defaultUnit = DEFAULT_UNIT;
args.defaultSectorSize = DEFAULT_SECTORSIZE;
if (rda = ReadArgs(RDBFLAGS_TEMPLATE, (LONG *) &args, NULL))
{
device = args.device;
unit = *args.pUnit;
result = RETURN_ERROR;
if ((mp = CreateMsgPort()) != NULL)
{
if ((io = CreateIORequest(mp, sizeof(struct IOStdReq))) != NULL)
{
if (OpenDevice(device, unit, (struct IORequest *) io, DEFAULT_FLAGS) == 0)
{
Printf("device \"%s\", unit %lu\n", device, unit);
io->io_Command = TD_GETGEOMETRY;
io->io_Length = sizeof(struct DriveGeometry);
io->io_Data = &DG;
if (DoIO((struct IORequest *) io) != 0) {
Printf("%s: error %ld while reading drive geometry.\n", name, (LONG) io->io_Error);
Printf("%s: (use option \"SectorSize\" to override default sector size)\n", name);
DG.dg_SectorSize = *args.pSectorSize;
DG.dg_BufMemType = MEMF_CHIP;
}
else if (args.pSectorSize != &args.defaultSectorSize) {
DG.dg_SectorSize = *args.pSectorSize;
DG.dg_BufMemType = MEMF_CHIP;
}
sectorSize = DG.dg_SectorSize;
Printf("sector size is %lu bytes\n", sectorSize);
if (sectorSize >= sizeof(struct RigidDiskBlock))
{
if (rdb = AllocMem(sectorSize, DG.dg_BufMemType))
{
for (sector = 0; sector < RDB_LOCATION_LIMIT; ++sector)
{
io->io_Command = CMD_READ;
io->io_Length = sectorSize;
io->io_Data = rdb;
io->io_Offset = sector * sectorSize;
if (DoIO((struct IORequest *) io) == 0
&& rdb->rdb_ID == IDNAME_RIGIDDISK
&& rdb->rdb_SummedLongs * sizeof(LONG) <= sectorSize)
{
for (sum = 0, p = (LONG *) rdb, i = rdb->rdb_SummedLongs; i != 0; --i)
sum += *p++;
if (sum == 0 && rdb->rdb_BlockBytes == sectorSize)
break;
}
}
if (sector != RDB_LOCATION_LIMIT)
{
Printf("found RDB at sector %lu\n", sector);
Printf("drive %-.8s %-.16s %-.4s\n", rdb->rdb_DiskVendor, rdb->rdb_DiskProduct, rdb->rdb_DiskRevision);
flags = rdb->rdb_Flags;
if ( args.lastDisk && args.noLastDisk
|| args.lastLun && args.noLastLun
|| args.lastTarget && args.noLastTarget
|| args.reselection && args.noReselection
|| args.synchronous && args.noSynchronous )
{
Printf("%s: contradictory options, won't alter RDB.\n", name);
}
else
{
if (args.lastDisk) flags |= RDBFF_LAST;
if (args.noLastDisk) flags &= ~RDBFF_LAST;
if (args.lastLun) flags |= RDBFF_LASTLUN;
if (args.noLastLun) flags &= ~RDBFF_LASTLUN;
if (args.lastTarget) flags |= RDBFF_LASTTID;
if (args.noLastTarget) flags &= ~RDBFF_LASTTID;
if (args.reselection) flags &= ~RDBFF_NORESELECT;
if (args.noReselection) flags |= RDBFF_NORESELECT;
if (args.synchronous) flags |= RDBFF_SYNCH;
if (args.noSynchronous) flags &= ~RDBFF_SYNCH;
}
Printf("\n last disk: %s\n", flags & RDBFF_LAST ? "yes" : "no");
Printf(" last lun: %s\n", flags & RDBFF_LASTLUN ? "yes" : "no");
Printf(" last target: %s\n", flags & RDBFF_LASTTID ? "yes" : "no");
Printf(" reselection: %s\n", flags & RDBFF_NORESELECT ? "no" : "yes");
Printf(" synchronous: %s\n\n", flags & RDBFF_SYNCH ? "yes" : "no");
result = RETURN_OK;
if (flags != rdb->rdb_Flags)
{
rdb->rdb_Flags = flags;
rdb->rdb_ChkSum = 0;
for (sum = 0, p = (LONG *) rdb, i = rdb->rdb_SummedLongs; i != 0; --i)
sum -= *p++;
rdb->rdb_ChkSum = sum;
Printf("RDB modified, saving to disk!\n");
io->io_Command = CMD_WRITE;
io->io_Length = sectorSize;
io->io_Data = rdb;
io->io_Offset = sector * sectorSize;
if (DoIO((struct IORequest *) io) == 0)
{
io->io_Command = CMD_UPDATE;
(void) DoIO((struct IORequest *) io);
}
if (io->io_Error != 0)
{
result = RETURN_ERROR;
io->io_Command = CMD_CLEAR;
(void) DoIO((struct IORequest *) io);
Printf("%s: error %ld while writing RDB.\n", name, (LONG) io->io_Error);
}
}
}
else
Printf("%s: no RDB found.\n", name);
io->io_Command = TD_MOTOR;
io->io_Length = 0;
(void) DoIO((struct IORequest *) io);
FreeMem(rdb, sectorSize);
}
else
PrintFault(ERROR_NO_FREE_STORE, name);
}
else
Printf("%s: sector size %lu too small for RDB.\n", name, sectorSize);
CloseDevice((struct IORequest *) io);
}
else
Printf("%s: error %ld opening \"%s\", unit %lu.\n", name, (LONG) io->io_Error, device, unit);
DeleteMsgPort(mp);
}
DeleteIORequest(io);
}
FreeArgs(rda);
}
else
PrintFault(IoErr(), name);
CloseLibrary(DOSBase);
}
else
Alert(AT_Recovery | AG_OpenLib | AO_DOSLib);
}
else
{
(void) WaitPort(&pr->pr_MsgPort);
mn = GetMsg(&pr->pr_MsgPort);
Forbid();
ReplyMsg(mn);
}
return result;
}