home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 13 / AACD13.ISO / AACD / System / Sysmon / src / UnMount.c < prev    next >
C/C++ Source or Header  |  2000-05-30  |  7KB  |  258 lines

  1. /*
  2. **    $RCSfile: UnMount.c,v $
  3. **    $Filename: UnMount.c $
  4. **    $Revision: 0.1 $
  5. **    $Date: 1995/04/29 17:33:51 $
  6. **
  7. **    Try to Shutdown or at least Inhibit DOS-Handlers (version 0.6)
  8. **
  9. **    (C) Copyright 1995-2000 by Etienne Vogt
  10. */
  11.  
  12. #include <exec/alerts.h>
  13. #include <exec/memory.h>
  14. #include <dos/dosextens.h>
  15. #include <dos/dostags.h>
  16. #include <workbench/startup.h>
  17. #define __USE_SYSBASE
  18. #include <proto/exec.h>
  19. #include <proto/dos.h>
  20. #include <clib/alib_protos.h>
  21. #include <string.h>
  22.  
  23. struct ExecBase *SysBase;
  24. struct DosLibrary *DOSBase;
  25. static struct WBStartup *wbmsg;
  26. static struct RDArgs *myrda;
  27.  
  28. static UBYTE version[] = "$VER: UnMount 0.6 (8.1.00)";
  29. static UBYTE template[] = "DEVICE,INHIBIT/S,RETRY/K/N,ALL/S,FREENODE/S";
  30.  
  31. #define DBUFSIZE    16
  32. #define DNAMSIZE    24
  33.  
  34. struct devBuffer
  35. {    struct devBuffer *dbf_Link;
  36.     UBYTE    dbf_Name[DBUFSIZE][DNAMSIZE];
  37. };
  38.  
  39. #define    OPT_DEVICE    0
  40. #define OPT_INHIBIT    1
  41. #define    OPT_RETRY    2
  42. #define OPT_ALL        3
  43. #define OPT_FREENODE    4
  44. #define OPTMAX        5
  45.  
  46. ULONG __saveds main(void);
  47. static void cleanexit(ULONG rc);
  48. static int unmount(STRPTR device, int inhibit, int retry, BOOL verbose);
  49. static struct devBuffer *getdevices(int *nodes);
  50. static void freedbufs(struct devBuffer *dbufs);
  51. static void killdevices(struct devBuffer *dbuf, int numdevs, int inhibit, int retry, int freenode);
  52. static void freeNode(STRPTR device);
  53.  
  54. ULONG __saveds main(void)    /* No startup code */
  55. {
  56.   struct Process *myproc;
  57.   LONG opts[OPTMAX];
  58.   ULONG rc = 0;
  59.  
  60.   SysBase = *(struct ExecBase **)4;
  61.   DOSBase = NULL;
  62.   wbmsg = NULL;
  63.   myrda = NULL;
  64.  
  65.   myproc = (struct Process *)FindTask(NULL);
  66.   if ((DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",36)) == NULL)
  67.   { Alert(AT_Recovery|AG_OpenLib|AO_DOSLib);
  68.     return 100;
  69.   }
  70.  
  71.   if (!(myproc->pr_CLI))        /* If started from WB, exit cleanly */
  72.   { WaitPort(&(myproc->pr_MsgPort));
  73.     wbmsg = (struct WBStartup *)GetMsg(&(myproc->pr_MsgPort));
  74.     cleanexit(20);
  75.   }
  76.   else
  77.   { APTR oldwinptr;
  78.     int retrycount = 10, error;
  79.  
  80.     memset((char *)opts, 0, sizeof(opts));
  81.     if ((myrda = ReadArgs(template, opts, NULL)) == NULL)
  82.     { PrintFault(IoErr(),"UnMount");
  83.       cleanexit(20);
  84.     }
  85.  
  86.     if (opts[OPT_RETRY]) retrycount = *((LONG *)opts[OPT_RETRY]);
  87.  
  88.     oldwinptr = myproc->pr_WindowPtr;        /* Disable DOS Requesters    */
  89.     myproc->pr_WindowPtr = (APTR)(-1L);
  90.  
  91.     if (opts[OPT_DEVICE])
  92.     { struct DosList *dol;
  93.       char buffer[DNAMSIZE];
  94.       STRPTR colon;
  95.  
  96.       dol = LockDosList(LDF_DEVICES | LDF_READ);
  97.       strncpy(buffer, (STRPTR)opts[OPT_DEVICE], sizeof(buffer));
  98.       if (colon = (UBYTE *)strchr(buffer,':')) *colon = (UBYTE)0;
  99.       else buffer[DNAMSIZE-1] = (UBYTE)0;
  100.       if (dol = FindDosEntry(dol, buffer, LDF_DEVICES))
  101.       { UnLockDosList(LDF_DEVICES | LDF_READ);
  102.     if (error = unmount((STRPTR)opts[OPT_DEVICE], opts[OPT_INHIBIT], retrycount, TRUE))
  103.     { PrintFault(error, "UnMount");
  104.       rc = 10;
  105.     }
  106.     else if (opts[OPT_FREENODE]) freeNode((STRPTR)opts[OPT_DEVICE]);
  107.       }
  108.       else
  109.       { UnLockDosList(LDF_DEVICES | LDF_READ);
  110.     PrintFault(ERROR_DEVICE_NOT_MOUNTED, "UnMount");
  111.     rc = 20;
  112.       }
  113.  
  114.     }
  115.     else if (opts[OPT_ALL])
  116.     { struct devBuffer *dbuf;
  117.       int numdevs;
  118.  
  119.       if (dbuf = getdevices(&numdevs)) killdevices(dbuf, numdevs, opts[OPT_INHIBIT], retrycount, opts[OPT_FREENODE]);
  120.       else
  121.       { PrintFault(ERROR_NO_FREE_STORE, "UnMount");
  122.     rc = 20;
  123.       }
  124.     }
  125.     else
  126.     { PrintFault(ERROR_REQUIRED_ARG_MISSING, "UnMount");
  127.       rc = 20;
  128.     }
  129.  
  130.     myproc->pr_WindowPtr = oldwinptr;
  131.   }
  132.   cleanexit(rc);
  133. }
  134.  
  135. static void cleanexit(ULONG rc)
  136. {
  137.   if (myrda) FreeArgs(myrda);
  138.   if (DOSBase) CloseLibrary((struct Library *)DOSBase);
  139.   if (wbmsg)
  140.   { Forbid();
  141.     ReplyMsg((struct Message *)wbmsg);
  142.   }
  143.   Exit(rc);
  144. }
  145.  
  146. static int unmount(STRPTR device, int inhibit, int retry, BOOL verbose)
  147. { struct DevProc *dvp;
  148.   int count = 0, rc = 0;
  149.  
  150.   if (!strchr(device,':')) return ERROR_INVALID_COMPONENT_NAME;
  151.   if (dvp = GetDeviceProc(device, NULL))
  152.   { if (DoPkt0(dvp->dvp_Port, ACTION_DIE) == DOSFALSE)
  153.     { rc = IoErr();
  154.       if (IsFileSystem(device) && inhibit)
  155.       { if (verbose) Printf("UnMount : Couldn't kill device %s, Trying to inhibit...\n", device);
  156.     do
  157.     { if (Inhibit(device, DOSTRUE)) break;
  158.       else if ((rc = IoErr()) == ERROR_ACTION_NOT_KNOWN) count = retry;
  159.       else Delay(TICKS_PER_SECOND);
  160.         } while (++count < retry);
  161.     if (count < retry) rc = 0;
  162.       }
  163.     }
  164.     FreeDeviceProc(dvp);
  165.   }
  166.   else rc = IoErr();
  167.   return rc;
  168. }
  169.  
  170. static struct devBuffer *getdevices(int *nodes)
  171. { struct devBuffer *dbuf;
  172.  
  173.   if (dbuf = AllocVec(sizeof(struct devBuffer), MEMF_PUBLIC | MEMF_CLEAR))
  174.   { struct DosList *dol;
  175.     struct devBuffer *db = dbuf;
  176.     int i = 0;
  177.  
  178.     dol = LockDosList(LDF_DEVICES | LDF_READ);
  179.     *nodes = 0;
  180.     while (dol = NextDosEntry(dol, LDF_DEVICES))
  181.     { UBYTE namlen;
  182.       UBYTE *namptr;
  183.  
  184.       if (dol->dol_Task == NULL) continue;
  185.       namptr = BADDR(dol->dol_Name);
  186.       namlen = (namptr[0] < DNAMSIZE - 1 ? namptr[0] : DNAMSIZE - 2);
  187.       strncpy(db->dbf_Name[i], namptr + 1, namlen);
  188.       db->dbf_Name[i][namlen] = ':';
  189.       db->dbf_Name[i][namlen+1] = '\0';
  190.       if (strcmp(db->dbf_Name[i], "RAM:") == 0) continue;
  191.       (*nodes)++;
  192.  
  193.       if (++i == DBUFSIZE)
  194.       { struct devBuffer *db1;
  195.  
  196.     if (db1 = AllocVec(sizeof(struct devBuffer), MEMF_PUBLIC | MEMF_CLEAR))
  197.     { db->dbf_Link = db1;
  198.       db = db1;
  199.       i = 0;
  200.     }
  201.     else
  202.     { UnLockDosList(LDF_DEVICES | LDF_READ);
  203.       freedbufs(dbuf);
  204.       return NULL;
  205.     }
  206.       }
  207.     }
  208.     UnLockDosList(LDF_DEVICES | LDF_READ);
  209.   }
  210.   return dbuf;
  211. }
  212.  
  213. static void freedbufs(struct devBuffer *dbufs)
  214. { struct devBuffer *nextdb;
  215.  
  216.   do
  217.   { nextdb = dbufs->dbf_Link;
  218.     FreeVec(dbufs);
  219.   } while (dbufs = nextdb);
  220. }
  221.  
  222. static void killdevices(struct devBuffer *dbuf, int numdevs, int inhibit, int retry, int freenode)
  223. { struct devBuffer *db = dbuf;
  224.   STRPTR devname;
  225.   int j, i, error;
  226.  
  227.   for (j = 0, i = 0 ; j < numdevs ; j++)
  228.   { devname = db->dbf_Name[i];
  229.     if (IsFileSystem(devname))
  230.     { Printf("Unmounting device %s\n", db->dbf_Name[i]);
  231.       if (error = unmount(devname, inhibit, retry, FALSE)) PrintFault(error, "UnMount");
  232.       else if (freenode) freeNode(devname);
  233.     }
  234.  
  235.     if (++i == DBUFSIZE)
  236.     { db = db->dbf_Link;
  237.       i = 0;
  238.     }
  239.   }
  240.   freedbufs(dbuf);
  241. }
  242.  
  243. static void freeNode(STRPTR device)
  244. { struct DosList *dol;
  245.   char buffer[DNAMSIZE];
  246.   STRPTR colon;
  247.  
  248.   dol = LockDosList(LDF_DEVICES | LDF_WRITE);
  249.   strncpy(buffer, device, sizeof(buffer));
  250.   if (colon = (UBYTE *)strchr(buffer,':')) *colon = (UBYTE)0;
  251.   else buffer[DNAMSIZE-1] = (UBYTE)0;
  252.   if (dol = FindDosEntry(dol, buffer, LDF_DEVICES))
  253.   { RemDosEntry(dol);
  254.     FreeDosEntry(dol);
  255.   }
  256.   UnLockDosList(LDF_DEVICES | LDF_WRITE);
  257. }
  258.