home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d5xx / d558 / disdf.lha / DisDF / DisDF.c < prev    next >
C/C++ Source or Header  |  1991-10-28  |  11KB  |  473 lines

  1.  
  2. /* DisDF.c V1.1    Disables DF0-DF3                                       */
  3. /* Patrick F. Misteli 22.7.91                                             */
  4. /* see DisDF.doc and 'usage' below                                        */
  5.  
  6. #define ND 4                                         /* max floppy drives */
  7. #define NN 100                                   /* max tasknodes to scan */
  8. #define DISABLEDP -123                       /* priority of disabled task */
  9. #define BUSYPRI   -122
  10.  
  11. #include <exec/types.h>
  12. #include <exec/exec.h>
  13. #include <exec/execbase.h>
  14. #include <exec/memory.h>
  15. #include <exec/tasks.h>
  16. #include <stdio.h>
  17.  
  18. #include <devices/trackdisk.h>
  19. #include <exec/devices.h>
  20. #include <exec/io.h>
  21.  
  22. #include <dos.h>                           /* LATTICE is defined in dos.h */
  23.       /* manx 3.4b doesn't have dos.h so add one with AZTEC defined in it */
  24.  
  25. #ifdef LATTICE
  26. #include <proto/exec.h>
  27.  
  28. #else
  29. #ifdef AZTEC
  30. struct IORequest *CreateExtIO();
  31. struct MsgPort *CreatePort();
  32. #include <functions.h>
  33.  
  34. #else
  35. #define OTHER_COMPILER 1
  36. struct IORequest *CreateExtIO();
  37. struct MsgPort *CreatePort();
  38. struct Task *DeviceProc();
  39. struct Task *FindTask();
  40. long SetTaskPri();
  41. long Signal();
  42. char *AllocMem();
  43. struct Task *CreateTask();
  44. #endif
  45. #endif
  46.  
  47. extern struct ExecBase *SysBase;
  48.  
  49. char extioerrmsg[]  = "DisDF CreateExtIO() error";
  50. char creatportmsg[] = "DisDF CreatePort() error";
  51. char nofloppymsg[]  = "DisDF no floppy drive found";
  52. char notmountmsg[]  = "DisDF DFi not mounted";
  53. char missingdmsg[]  = "DisDF DFi device process missing";
  54. char missingtmsg[]  = "DisDF DFi trackdisk.device task missing";
  55. char missingfmsg[]  = "DisDF DFi File Process task missing";
  56. char memerrormsg[]  = "DisDF not enough memory";
  57. char statusokmsg[]  = "DisDF DFi trackdisk oxx File System oxx";
  58. char statusermsg[]  = "DisDF DFi error";
  59. char busytaskmsg[]  = "DisDF BusyLoop-122 running";
  60.  
  61. char *usagemsg[] =
  62. {
  63.  "\nDisDF V1.0 toggles floppy drives' trackdisk.device tasks off or on\n",
  64.  "usage : DisDF [0] [1] [2] [3] [-d|e] [-f] [-h]",
  65.  "         #  drive number if not all DF0: to DF3:",
  66.  "        -c  change priorities and start busyloop task",
  67.  "        -d  disable instead of toggle",
  68.  "        -e  enable  instead of toggle",
  69.  "        -f  disable floppy drives' File System tasks also",
  70.  "        -h  help message to stdout",
  71.  "        -s  status message to stdout only, tasks not changed",
  72.  "        -v  verbose",
  73.  NULL
  74. };
  75.  
  76. char trackdisk[]  = TD_NAME;                        /* "trackdisk.device" */
  77. char filesystem[] = "File System";
  78. char dfstr[] = "DF0:";
  79. char busyname[] = "BusyLoop-122";
  80.  
  81. struct Task *me;
  82. struct Node *fnode[ ND ], *tnode[ ND ];
  83. struct Task *busytask;
  84. int drive[ ND ], statusonly, chicken;
  85. long previouspri;
  86.  
  87. main( argc, argv )
  88. int argc;
  89. char *argv[];
  90. {
  91.  register int i;
  92.  register struct Node *np;
  93.  register int j, k;
  94.  struct Node *anode[ NN ];
  95.  int all, en, ds, fs, verbose;
  96.  unsigned failval;
  97.  struct MsgPort *diskport;
  98.  struct IOExtTD *ioexttd;
  99.  
  100.  failval = 0;
  101.  all = TRUE;
  102.  en = ds = fs = verbose = statusonly = chicken = FALSE;
  103.  for ( i = 0; i < ND; i++ )
  104.  {
  105.   drive[i] = FALSE;
  106.   tnode[i] = NULL;
  107.   fnode[i] = NULL;
  108.  }
  109.  
  110.  if ( argc > 1 )
  111.  {
  112.   for ( i = 1; i < argc; i++ )
  113.   {
  114.    switch ( *argv[i] )
  115.    {
  116.     case '-':
  117.      if ( argv[ i ][ 2 ] )
  118.            usageexit();
  119.      switch( argv[ i ][ 1 ])
  120.      {
  121.       case 'c':
  122.        chicken = TRUE;
  123.       break;
  124.       case 'd':
  125.        if ( en )
  126.         usageexit();
  127.        ds = TRUE;
  128.       break;
  129.       case 'e':
  130.        if ( ds )
  131.         usageexit();
  132.        en = TRUE;
  133.       break;
  134.       case 'f':
  135.        fs = TRUE;
  136.       break;
  137.       case 's':
  138.        statusonly = TRUE;
  139.       break;
  140.       case 'v':
  141.        verbose = TRUE;
  142.       break;
  143.       default :
  144.        usageexit();
  145.       break;
  146.      }
  147.     break;
  148.     case '0' :
  149.     case '1' :
  150.     case '2' :
  151.     case '3' :
  152.      if ( argv[i][1] != 0 )
  153.       usageexit();
  154.      drive[ *argv[i] - 48 ] = TRUE;
  155.      all = FALSE;
  156.     break;
  157.     default:
  158.      usageexit();
  159.     break;
  160.    } /* switch   */
  161.   } /* for i    */
  162.  } /* argc > 1 */
  163.  
  164.  if ( all )
  165.   drive[0] = drive[1] = drive[2] = drive[3] = TRUE;
  166.  
  167.  me = FindTask( 0L );
  168.  previouspri = SetTaskPri( me, -1L ); /* allow most other tasks to finish */
  169.  Forbid();                        /* before grabbing the CPU until exit() */
  170.  
  171.               /* find out which drives are mounted by trying to open them */
  172.  diskport = CreatePort( 0, 0 );
  173.  if( diskport == NULL )
  174.  {
  175.   puts( creatportmsg );
  176.   permexit( 11 );
  177.  }
  178.  ioexttd = (struct IOExtTD *)CreateExtIO( diskport,
  179.                                             (long)sizeof(struct IOExtTD ) );
  180.  if( ioexttd == 0 )
  181.  {
  182.   puts( extioerrmsg );
  183.   DeletePort( diskport );
  184.   permexit( 12 );
  185.  }
  186.  for ( i = 0; i < ND; i++ )
  187.  {
  188.   if ( drive[i] )
  189.    if ( !OpenDevice( trackdisk, (long)i, (struct IORequest *)ioexttd, 0L ) )
  190.    {                          /* get pointer to its trackdisk.device task */
  191.     tnode[i] =
  192.            (struct Node *)ioexttd->iotd_Req.io_Unit->unit_MsgPort.mp_SigTask;
  193.     CloseDevice( (struct IORequest *)ioexttd );
  194.    }
  195.  }
  196.  DeleteExtIO( (struct IORequest *)ioexttd, sizeof( struct IOExtTD ) );
  197.  DeletePort( diskport );
  198.  
  199.  if ( all )                    /* check that at least one drive was found */
  200.  {
  201.   for ( i = 0; i < ND; i++ )
  202.    if ( tnode[i] )
  203.     break;
  204.   if ( i >= ND )
  205.   {
  206.    puts( nofloppymsg );
  207.    permexit( 13 );
  208.   }
  209.  }
  210.  else
  211.  {
  212.   for ( i = 0; i < ND; i++ )     /* check for drives specified in command */
  213.    if ( !tnode[i] )
  214.     if ( drive[i] )
  215.     {
  216.      notmountmsg[8] = 48 + i;
  217.      puts( notmountmsg );   
  218.     }
  219.  }
  220.  
  221.  for ( i = 0; i < ND; i++ ) /* find each mounted drive's File System task */
  222.  {
  223.   if ( tnode[i] )
  224.   {
  225.    dfstr[2] = 48 + i;
  226.    fnode[i] = (struct Node *)DeviceProc( dfstr );
  227.    if ( fnode[i] )
  228.     fnode[i] = (struct Node *)( (long)fnode[i] - sizeof(struct Task) );
  229.    else
  230.    {
  231.     tnode[i] = NULL;
  232.     missingdmsg[8] = 48 + i;
  233.     puts( missingdmsg );
  234.     failval += 1 << (i + 4);
  235.    }
  236.   }
  237.  }
  238.             /* ensure that the tasks found above are in exec's task lists */
  239.  for ( i = 0; i < NN; i++ )
  240.   anode[i] = NULL;
  241.  i = 0;
  242.  Disable();
  243.  for ( np = (struct Node *)SysBase->TaskReady.lh_Head; i < NN, np->ln_Succ;
  244.                                                           np = np->ln_Succ )
  245.   anode[i++] = np;
  246.  for ( np = (struct Node *)SysBase->TaskWait.lh_Head;  i < NN, np->ln_Succ;
  247.                                                           np = np->ln_Succ )
  248.   anode[i++] = np;
  249.  Enable();
  250.  for ( i = 0; i < ND; i++ )
  251.  {
  252.   if ( tnode[i] )
  253.   {
  254.    for ( j = 0; j < NN; j++ )
  255.     if ( tnode[i] == anode[j] )
  256.      break;
  257.    if ( j >= NN )          /* if the task is not there, ignore this drive */
  258.    {
  259.     tnode[i] = NULL;
  260.     fnode[i] = NULL;
  261.     missingtmsg[8] = 48 + i;
  262.     puts( missingtmsg );
  263.     failval += 1 << (i + 8);
  264.    }
  265.   }
  266.   if ( fnode[i] )
  267.   {
  268.    for ( j = 0; j < NN; j++ )
  269.     if ( fnode[i] == anode[j] )
  270.      break;
  271.    if ( j >= NN )
  272.    {
  273.     tnode[i] = NULL;
  274.     fnode[i] = NULL;
  275.     missingfmsg[8] = 48 + i;
  276.     puts( missingfmsg );
  277.     failval += 1 << (i + 12);
  278.    }
  279.   }
  280.  }
  281.  
  282.  if ( statusonly )
  283.  {
  284.   typestatus();
  285.   permexit( 0 );
  286.  }
  287.  
  288.  if ( !chicken )
  289.  {
  290.   Disable();           /* remove tasks found above from exec's task lists */
  291.   for ( i = 0; i < ND; i++ )
  292.    if( tnode[i] )
  293.    {
  294.     Remove( tnode[i] );
  295.     Remove( fnode[i] );
  296.    }
  297.   Enable();
  298.  }
  299.  
  300.  for ( i = j = 0; i < ND; i++ )                        /* modify priority */
  301.  {
  302.   if ( tnode[i] )
  303.   {
  304.    if ( en || ( ( tnode[i]->ln_Pri == DISABLEDP ) && !ds )  )
  305.    {
  306.     modtask( tnode[i], 5 );
  307.     modtask( fnode[i], 10 );
  308.    }
  309.    else
  310.    {
  311.     modtask( tnode[i], DISABLEDP );
  312.     if ( fs )
  313.      modtask( fnode[i], DISABLEDP );
  314.     else
  315.      modtask( fnode[i], 10 );
  316.    }
  317.   }
  318.  }
  319.  
  320.  if ( !chicken )
  321.  {
  322.   Disable();                   /* put modified tasks back in exec's lists */
  323.   for ( i = 0; i < ND; i++ )
  324.    if( tnode[i] )
  325.    {
  326.     if ( tnode[i]->ln_Pri == DISABLEDP )
  327.     {
  328.      AddTail( &SysBase->TaskWait, tnode[i] );
  329.      AddTail( &SysBase->TaskWait, fnode[i] );
  330.     }
  331.     else
  332.     {
  333.      AddTail( &SysBase->TaskReady, tnode[i] );
  334.      AddTail( &SysBase->TaskReady, fnode[i] );
  335.     }
  336.    }
  337.   Enable();
  338.  }
  339.  
  340.  if ( busytask = FindTask( busyname ) )          /* maybe remove busytask */
  341.  {
  342.   for ( i = j = k = 0; i < ND; i++ )
  343.    if ( tnode[i] )
  344.     if ( tnode[i]->ln_Pri == DISABLEDP )
  345.     {
  346.      j++;
  347.      if ( ((struct Task*)tnode[i])->tc_State != TS_REMOVED )
  348.       k++;
  349.     }
  350.     else         /* previously removed tasks in the wait list need a nudge */
  351.     {
  352.      Signal( (struct Task *)tnode[i],
  353.                                     ((struct Task *)tnode[i])->tc_SigAlloc );
  354.      Signal( (struct Task *)fnode[i],
  355.                                     ((struct Task *)fnode[i])->tc_SigAlloc );
  356.     }
  357.   if ( !j || ( !chicken && k ) )
  358.    rembusytask();
  359.  }
  360.  else                                               /* maybe add busytask */
  361.  {
  362.   if ( chicken )
  363.    for ( i = 0; i < ND; i++ )
  364.     if ( tnode[i] )
  365.      if ( tnode[i]->ln_Pri == DISABLEDP )
  366.       break;;
  367.   if ( i <  ND )
  368.    addbusytask();
  369.  }
  370.  if ( verbose )
  371.   typestatus();
  372.  permexit( failval );
  373. } /* main */
  374.  
  375. usageexit()
  376. {
  377.  register int i;
  378.  for ( i = 0; usagemsg[i][0]; i++ )
  379.   puts( usagemsg[i] );
  380.  exit( 10 );
  381. }
  382.  
  383. modtask( task, pri )                  /* modifies task state and priority */
  384. struct Task *task;
  385. int pri;
  386. {
  387.  task->tc_State = TS_WAIT;
  388.  if ( ( ((struct Node *)task)->ln_Pri = pri ) == DISABLEDP )
  389.   if ( !chicken )
  390.    task->tc_State = TS_REMOVED;
  391. }
  392.  
  393. typestatus()
  394. {
  395.  register int i;
  396.  for ( i = 0; i < ND; i++ )
  397.  {
  398.   if ( !drive[i] )
  399.    continue;
  400.   if ( tnode[i] )
  401.   {
  402.    statusokmsg[8]  = i + 48;
  403.    if ( tnode[i]->ln_Pri == DISABLEDP )
  404.    {
  405.     statusokmsg[21] = 'f';
  406.     statusokmsg[22] = 'f';
  407.    }
  408.    else
  409.    {
  410.     statusokmsg[21] = 'n';
  411.     statusokmsg[22] = ' ';
  412.    }
  413.    if ( fnode[i]->ln_Pri == DISABLEDP )
  414.    {
  415.     statusokmsg[37] = 'f';
  416.     statusokmsg[38] = 'f';
  417.    }
  418.    else
  419.    {
  420.     statusokmsg[37] = 'n';
  421.     statusokmsg[38] = ' ';
  422.    }
  423.    puts( statusokmsg );
  424.   }
  425.   else
  426.    if ( !statusonly )
  427.    {
  428.     statusermsg[8] = i + 48;
  429.     puts( statusermsg );
  430.    }
  431.  } /* for i */
  432.  if ( FindTask( busyname ) )
  433.   puts( busytaskmsg );
  434. } /* typestatus */
  435.  
  436. permexit( exitval )                 /* all exits after Forbid() come here */
  437. unsigned exitval;
  438. {
  439.  SetTaskPri( me, previouspri );    /* otherwise the CLI or WB stays at -1 */
  440.  Permit();               /* SetTaskPri() reschedules Forbidden tasks ?... */
  441.  exit( exitval );
  442. }
  443.  
  444. addbusytask()                  /* starts a busyloop task at priority -122 */
  445. {
  446.  char *busycode;
  447.  if ( !( busycode = AllocMem( 32L, MEMF_CLEAR ) ) )
  448.  {
  449.   puts( memerrormsg );
  450.   permexit( 14 );
  451.  }
  452.  busycode[0] = 0x60; busycode[1] = 0xfe;                   /* kk:  BRA kk */
  453.  CopyMemQuick( busyname, busycode + 2, 12L );
  454.  if ( !( busytask =
  455.                CreateTask( busycode + 2, (long)BUSYPRI, busycode, 128L ) ) )
  456.  {
  457.   FreeMem( busycode, 32L );
  458.   puts( memerrormsg );
  459.   permexit( 14 );
  460.  }
  461.  busytask->tc_UserData = (APTR)busycode;
  462. }
  463.  
  464. rembusytask()
  465. {
  466.  char *busycode;
  467.  busycode = (char *)busytask->tc_UserData;
  468.  DeleteTask( busytask );
  469.  FreeMem( busycode, 32L );
  470. }
  471.  
  472. /* fin DisDF.c */
  473.