home *** CD-ROM | disk | FTP | other *** search
- /*
- unmount.c --- unmount filesystems.
-
- (c) Copyright 1995 SHW Wabnitz
- Written by Bernhard Fastenrath (fasten@shw.com)
-
- This file may be distributed under the terms
- of the GNU General Public License.
- */
-
- #include "halt_library.h"
-
- static void
- FreeList (List *list)
- {
- Node *node, *next;
-
- for (next = node = list -> lh_Head; next -> ln_Succ; node = next)
- {
- next = node -> ln_Succ;
- if (node -> ln_Name)
- FreeMem (node -> ln_Name, node -> ln_Pri);
- FreeMem (node, sizeof (Node));
- }
- }
-
- static int
- PingPong (MsgPort *from, MsgPort *to, StandardPacket *sp,
- ULONG action, ULONG arg)
- {
- sp -> sp_Msg.mn_Node.ln_Name = (char *) &sp -> sp_Pkt;
- sp -> sp_Pkt.dp_Link = &sp -> sp_Msg;
- sp -> sp_Pkt.dp_Port = from;
- sp -> sp_Pkt.dp_Type = action;
- sp -> sp_Pkt.dp_Arg1 = arg;
- PutMsg (to, &sp -> sp_Msg);
- do
- WaitPort (from);
- while (!GetMsg (from));
- return 1;
- }
-
- static int
- SendToHandler (MsgPort *mp, ULONG ptype, char *handler, ULONG arg)
- {
- DevProc *dp = NULL;
- StandardPacket sp;
- int ret = 0;
-
- dp = GetDeviceProc (handler, dp);
- if (dp)
- {
- PingPong (mp, dp -> dvp_Port, &sp, ACTION_IS_FILESYSTEM, 0);
- if (sp.sp_Pkt.dp_Res1 == DOSTRUE)
- {
- PingPong (mp, dp -> dvp_Port, &sp, ptype, arg);
- ret = 1;
- }
- else
- ret = -1;
- }
- FreeDeviceProc (dp);
- return ret;
- }
-
- static int
- SendToAll (MsgPort *mp, ULONG ptype, ULONG arg)
- {
- List list;
- Node *node;
- DosInfo *di;
- DeviceNode *dn;
- int len, out_of_mem = 0;
- char *name;
- BPTR *pdn;
- int ret;
-
- NewList (&list);
- Forbid ();
- di = BADDR (((RootNode *) DOSBase -> dl_Root) -> rn_Info);
- for (pdn = &di -> di_DevInfo; dn = (DeviceNode *) BADDR (*pdn);
- pdn = &dn -> dn_Next)
- {
- if (dn -> dn_Type == DLT_DEVICE)
- {
- if (node = (Node *) AllocMem (sizeof (Node), MEMF_CLEAR))
- {
- name = BADDR (dn -> dn_Name);
- len = (int) name[0];
- if (node -> ln_Name = AllocMem (len + 2, 0))
- {
- CopyMem (name+1, node -> ln_Name, len);
- node -> ln_Name[len] = ':';
- node -> ln_Name[len+1] = '\0';
- node -> ln_Pri = len + 2;
- AddTail (&list, node);
- }
- else
- {
- out_of_mem = 1;
- FreeMem (node, sizeof (Node));
- break;
- }
- }
- else
- {
- out_of_mem = 1;
- break;
- }
- }
- }
- Permit ();
-
- if (out_of_mem)
- {
- FreeList (&list);
- return 0;
- }
-
- len = 0;
- for (node = list.lh_Head; node -> ln_Succ; node = node -> ln_Succ)
- ret = SendToHandler (mp, ptype, node -> ln_Name, arg);
- FreeList (&list);
- return 1;
- }
-
- /*** public functions ***/
-
- int
- unmount (MsgPort *mp, char *filesystem)
- {
- ULONG arg = DOSTRUE, ptype = ACTION_INHIBIT;
- int free_port = 0, ret;
-
- if (!mp)
- {
- if (!(mp = CreatePort (NULL, 0)))
- return 0;
- free_port = 1;
- }
- if (filesystem)
- {
- ret = SendToHandler (mp, ptype, filesystem, arg);
- }
- else
- {
- ret = SendToAll (mp, ptype, arg);
- }
- if (free_port)
- DeletePort (mp);
- return ret;
- }
-
-