home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 13
/
AACD13.ISO
/
AACD
/
System
/
Sysmon
/
src
/
UnMount.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-05-30
|
7KB
|
258 lines
/*
** $RCSfile: UnMount.c,v $
** $Filename: UnMount.c $
** $Revision: 0.1 $
** $Date: 1995/04/29 17:33:51 $
**
** Try to Shutdown or at least Inhibit DOS-Handlers (version 0.6)
**
** (C) Copyright 1995-2000 by Etienne Vogt
*/
#include <exec/alerts.h>
#include <exec/memory.h>
#include <dos/dosextens.h>
#include <dos/dostags.h>
#include <workbench/startup.h>
#define __USE_SYSBASE
#include <proto/exec.h>
#include <proto/dos.h>
#include <clib/alib_protos.h>
#include <string.h>
struct ExecBase *SysBase;
struct DosLibrary *DOSBase;
static struct WBStartup *wbmsg;
static struct RDArgs *myrda;
static UBYTE version[] = "$VER: UnMount 0.6 (8.1.00)";
static UBYTE template[] = "DEVICE,INHIBIT/S,RETRY/K/N,ALL/S,FREENODE/S";
#define DBUFSIZE 16
#define DNAMSIZE 24
struct devBuffer
{ struct devBuffer *dbf_Link;
UBYTE dbf_Name[DBUFSIZE][DNAMSIZE];
};
#define OPT_DEVICE 0
#define OPT_INHIBIT 1
#define OPT_RETRY 2
#define OPT_ALL 3
#define OPT_FREENODE 4
#define OPTMAX 5
ULONG __saveds main(void);
static void cleanexit(ULONG rc);
static int unmount(STRPTR device, int inhibit, int retry, BOOL verbose);
static struct devBuffer *getdevices(int *nodes);
static void freedbufs(struct devBuffer *dbufs);
static void killdevices(struct devBuffer *dbuf, int numdevs, int inhibit, int retry, int freenode);
static void freeNode(STRPTR device);
ULONG __saveds main(void) /* No startup code */
{
struct Process *myproc;
LONG opts[OPTMAX];
ULONG rc = 0;
SysBase = *(struct ExecBase **)4;
DOSBase = NULL;
wbmsg = NULL;
myrda = NULL;
myproc = (struct Process *)FindTask(NULL);
if ((DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",36)) == NULL)
{ Alert(AT_Recovery|AG_OpenLib|AO_DOSLib);
return 100;
}
if (!(myproc->pr_CLI)) /* If started from WB, exit cleanly */
{ WaitPort(&(myproc->pr_MsgPort));
wbmsg = (struct WBStartup *)GetMsg(&(myproc->pr_MsgPort));
cleanexit(20);
}
else
{ APTR oldwinptr;
int retrycount = 10, error;
memset((char *)opts, 0, sizeof(opts));
if ((myrda = ReadArgs(template, opts, NULL)) == NULL)
{ PrintFault(IoErr(),"UnMount");
cleanexit(20);
}
if (opts[OPT_RETRY]) retrycount = *((LONG *)opts[OPT_RETRY]);
oldwinptr = myproc->pr_WindowPtr; /* Disable DOS Requesters */
myproc->pr_WindowPtr = (APTR)(-1L);
if (opts[OPT_DEVICE])
{ struct DosList *dol;
char buffer[DNAMSIZE];
STRPTR colon;
dol = LockDosList(LDF_DEVICES | LDF_READ);
strncpy(buffer, (STRPTR)opts[OPT_DEVICE], sizeof(buffer));
if (colon = (UBYTE *)strchr(buffer,':')) *colon = (UBYTE)0;
else buffer[DNAMSIZE-1] = (UBYTE)0;
if (dol = FindDosEntry(dol, buffer, LDF_DEVICES))
{ UnLockDosList(LDF_DEVICES | LDF_READ);
if (error = unmount((STRPTR)opts[OPT_DEVICE], opts[OPT_INHIBIT], retrycount, TRUE))
{ PrintFault(error, "UnMount");
rc = 10;
}
else if (opts[OPT_FREENODE]) freeNode((STRPTR)opts[OPT_DEVICE]);
}
else
{ UnLockDosList(LDF_DEVICES | LDF_READ);
PrintFault(ERROR_DEVICE_NOT_MOUNTED, "UnMount");
rc = 20;
}
}
else if (opts[OPT_ALL])
{ struct devBuffer *dbuf;
int numdevs;
if (dbuf = getdevices(&numdevs)) killdevices(dbuf, numdevs, opts[OPT_INHIBIT], retrycount, opts[OPT_FREENODE]);
else
{ PrintFault(ERROR_NO_FREE_STORE, "UnMount");
rc = 20;
}
}
else
{ PrintFault(ERROR_REQUIRED_ARG_MISSING, "UnMount");
rc = 20;
}
myproc->pr_WindowPtr = oldwinptr;
}
cleanexit(rc);
}
static void cleanexit(ULONG rc)
{
if (myrda) FreeArgs(myrda);
if (DOSBase) CloseLibrary((struct Library *)DOSBase);
if (wbmsg)
{ Forbid();
ReplyMsg((struct Message *)wbmsg);
}
Exit(rc);
}
static int unmount(STRPTR device, int inhibit, int retry, BOOL verbose)
{ struct DevProc *dvp;
int count = 0, rc = 0;
if (!strchr(device,':')) return ERROR_INVALID_COMPONENT_NAME;
if (dvp = GetDeviceProc(device, NULL))
{ if (DoPkt0(dvp->dvp_Port, ACTION_DIE) == DOSFALSE)
{ rc = IoErr();
if (IsFileSystem(device) && inhibit)
{ if (verbose) Printf("UnMount : Couldn't kill device %s, Trying to inhibit...\n", device);
do
{ if (Inhibit(device, DOSTRUE)) break;
else if ((rc = IoErr()) == ERROR_ACTION_NOT_KNOWN) count = retry;
else Delay(TICKS_PER_SECOND);
} while (++count < retry);
if (count < retry) rc = 0;
}
}
FreeDeviceProc(dvp);
}
else rc = IoErr();
return rc;
}
static struct devBuffer *getdevices(int *nodes)
{ struct devBuffer *dbuf;
if (dbuf = AllocVec(sizeof(struct devBuffer), MEMF_PUBLIC | MEMF_CLEAR))
{ struct DosList *dol;
struct devBuffer *db = dbuf;
int i = 0;
dol = LockDosList(LDF_DEVICES | LDF_READ);
*nodes = 0;
while (dol = NextDosEntry(dol, LDF_DEVICES))
{ UBYTE namlen;
UBYTE *namptr;
if (dol->dol_Task == NULL) continue;
namptr = BADDR(dol->dol_Name);
namlen = (namptr[0] < DNAMSIZE - 1 ? namptr[0] : DNAMSIZE - 2);
strncpy(db->dbf_Name[i], namptr + 1, namlen);
db->dbf_Name[i][namlen] = ':';
db->dbf_Name[i][namlen+1] = '\0';
if (strcmp(db->dbf_Name[i], "RAM:") == 0) continue;
(*nodes)++;
if (++i == DBUFSIZE)
{ struct devBuffer *db1;
if (db1 = AllocVec(sizeof(struct devBuffer), MEMF_PUBLIC | MEMF_CLEAR))
{ db->dbf_Link = db1;
db = db1;
i = 0;
}
else
{ UnLockDosList(LDF_DEVICES | LDF_READ);
freedbufs(dbuf);
return NULL;
}
}
}
UnLockDosList(LDF_DEVICES | LDF_READ);
}
return dbuf;
}
static void freedbufs(struct devBuffer *dbufs)
{ struct devBuffer *nextdb;
do
{ nextdb = dbufs->dbf_Link;
FreeVec(dbufs);
} while (dbufs = nextdb);
}
static void killdevices(struct devBuffer *dbuf, int numdevs, int inhibit, int retry, int freenode)
{ struct devBuffer *db = dbuf;
STRPTR devname;
int j, i, error;
for (j = 0, i = 0 ; j < numdevs ; j++)
{ devname = db->dbf_Name[i];
if (IsFileSystem(devname))
{ Printf("Unmounting device %s\n", db->dbf_Name[i]);
if (error = unmount(devname, inhibit, retry, FALSE)) PrintFault(error, "UnMount");
else if (freenode) freeNode(devname);
}
if (++i == DBUFSIZE)
{ db = db->dbf_Link;
i = 0;
}
}
freedbufs(dbuf);
}
static void freeNode(STRPTR device)
{ struct DosList *dol;
char buffer[DNAMSIZE];
STRPTR colon;
dol = LockDosList(LDF_DEVICES | LDF_WRITE);
strncpy(buffer, device, sizeof(buffer));
if (colon = (UBYTE *)strchr(buffer,':')) *colon = (UBYTE)0;
else buffer[DNAMSIZE-1] = (UBYTE)0;
if (dol = FindDosEntry(dol, buffer, LDF_DEVICES))
{ RemDosEntry(dol);
FreeDosEntry(dol);
}
UnLockDosList(LDF_DEVICES | LDF_WRITE);
}