home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 4 / FreshFish_May-June1994.bin / bbs / mar94 / util / misc / flush.lha / Flush / Flush.c < prev    next >
C/C++ Source or Header  |  1994-01-13  |  16KB  |  820 lines

  1.  
  2. #define VERSION "1.2"
  3.  
  4. /*********************************************************************
  5.  
  6.  * Flush        Flushes all unused libraries, devices and fonts.
  7.  *              Note that some libraries and devices refuse to
  8.  *              flush themselves.
  9.  *
  10.  *
  11.  * Options:
  12.  *
  13.  *      -d    ; only flush devices
  14.  *      -f    ; only flush fonts
  15.  *      -l    ; only flush libraries
  16.  *      -r    ; report only; don't flush
  17.  *      -v    ; be verbose; print names of all removed objects
  18.  *      -oOBJ ; remove OBJ , must have a suffix of
  19.  *                         .library, .device, or .font(x,y)
  20.  *      -h    ; this message
  21.  *
  22.  *
  23.  * Runs under AmigaDOS 2.04+
  24.  *
  25.  *
  26.  *****  Written by Gary Duncan
  27.  *
  28.  *      Bug reports etc via e-mail to gduncan@philips.oz.au) , or mail to
  29.  *
  30.  *Work: Gary Duncan
  31.  *      Philips PTS
  32.  *      23 Lakeside Dr
  33.  *      Tally-Ho Technology Park
  34.  *      Burwood East Vic 3151
  35.  *      Australia
  36.  *
  37.  *Home: Gary Duncan
  38.  *      57 Melbourne Hill Rd
  39.  *      Warrandyte
  40.  *      Vic 3113
  41.  *      Australia
  42.  *
  43.  *Thanks to these beta-testers for testing early versions:-
  44.  *
  45.  *      Benbuck Nason (bigben@netcom.com)
  46.  *      Torsten Nielsen (torsten@diku.dk)
  47.  *      Darren Reid and others (shockwave@jupiter.sun.csd.unb.ca)
  48.  *
  49.  *
  50.  *****  Freely distributable for non-commercial purposes.
  51.  *      Please keep this header intact.
  52.  *
  53.  *      Use this program at your own risk.
  54.  *
  55.  *
  56.  *      Compiles under SAS 6.3
  57.  *
  58.  *      Formatted with 'indent -gnu' ; a big time-saving program.
  59.  *
  60.  *****************************************************************/
  61.  
  62. #include "flush.h"
  63.  
  64. extern struct GfxBase *GfxBase;
  65.  
  66.  
  67. /*
  68.  * string for AmigaDOS Version Command
  69.  */
  70. char A_vers[] = "\0$VER: Flush\t" VERSION " (13.1.94)";
  71.  
  72.  
  73. /*
  74.  * lib/device array ; one entry per lib/device list containing
  75.  * name and open count.
  76.  */
  77.  
  78. static S_LIB *pre_flush;
  79. static S_LIB *post_flush;
  80.  
  81. static int pre_cnt = 0;
  82. static int post_cnt = 0;
  83.  
  84. char *remove_it;
  85.  
  86. int r_count = 0;
  87.  
  88. ULONG s_total;
  89. ULONG s_fast;
  90. ULONG s_chipx;
  91.  
  92. ULONG e_total;
  93. ULONG e_fast;
  94. ULONG e_chipx;
  95.  
  96. ULONG r_total;
  97. ULONG r_fast;
  98. ULONG r_chipx;
  99.  
  100. BOOL v_flag = FALSE;
  101. BOOL r_flag = FALSE;
  102. BOOL o_flag = FALSE;
  103. BOOL d_flag = FALSE;
  104. BOOL f_flag = FALSE;
  105. BOOL l_flag = FALSE;
  106.  
  107. /*
  108.  **********************************************************
  109.  */
  110.  
  111. main (int argc, char **argv)
  112.  
  113. {
  114.   ULONG t, c, f;
  115.  
  116.   /*
  117.    * check options
  118.    */
  119.  
  120.   scan_args (argc, argv);
  121.  
  122.   /*
  123.    * get buffers to hold List items
  124.    */
  125.  
  126.   GetItemsBuf (&pre_flush, &post_flush);
  127.  
  128.   /*
  129.    * kluge to get printf() to get its 16K malloc'd buffer now
  130.    * so that it won't confuse memory usage reporting later
  131.    */
  132.  
  133.   printf ("\r");
  134.   fflush (stdout);
  135.  
  136.   /*
  137.    * get memory at start
  138.    */
  139.   memm (&s_fast, &s_chipx);
  140.  
  141.   /*
  142.    * check if its just one removal
  143.    */
  144.   if (o_flag)
  145.     {
  146.       rem_obj (remove_it);
  147.     }
  148.   else
  149.     {
  150.       /*
  151.        * flush fonts before libs, as attempting to flush
  152.        * diskfont.library seems to flush them automatically
  153.        * and we want font flushing shown.
  154.        */
  155.       if (f_flag == TRUE)
  156.     {
  157.       FlushFonts (r_flag);
  158.     }
  159.       else if (l_flag == TRUE)
  160.     {
  161.       FlushLibraries (r_flag);
  162.     }
  163.       else if (d_flag == TRUE)
  164.     {
  165.       FlushDevices (r_flag);
  166.     }
  167.       else
  168.     {
  169.       FlushFonts (r_flag);
  170.       FlushLibraries (r_flag);
  171.       FlushDevices (r_flag);
  172.     }
  173.     }
  174.   /*
  175.    * get memory at end
  176.    */
  177.   memm (&e_fast, &e_chipx);
  178.  
  179.   c = (e_chipx - s_chipx) / 1024;
  180.   f = (e_fast - s_fast) / 1024;
  181.   t = c + f;
  182.  
  183.   if (r_flag == FALSE)
  184.     {
  185.       printf ("Memory regained (KB) : total = %ld, [chip = %ld, fast = %ld]\n",
  186.           t, c, f);
  187.     }
  188. }
  189.  
  190. /*
  191.  **********************************************************
  192.  */
  193.  
  194. void
  195. FlushLibraries (BOOL flag)
  196. {
  197.   LIBRARY *l_ptr;
  198.   NODE *node;
  199.   int lib_cnt = 0;
  200.   int open_cnt = 0;
  201.   int j;
  202.   int cc = 0;
  203.   BOOL flushed_flag;
  204.  
  205.  
  206.   pre_cnt = 0;
  207.   post_cnt = 0;
  208.  
  209.   /*
  210.    * iterate through lib list until all flushable libs flushed;
  211.    * need to do this because some libs use other libs, i.e do
  212.    * a flush themselves
  213.    *
  214.    * - if "report" option, just pass through once
  215.    *
  216.    */
  217.  
  218.   while (TRUE)
  219.     {
  220.       Forbid ();
  221.       for (flushed_flag = FALSE, node = SysBase->LibList.lh_Head;
  222.        node->ln_Succ; node = node->ln_Succ)
  223.     {
  224.       char *l_name;
  225.       ++cc;
  226.       l_ptr = (LIBRARY *) node;
  227.       l_name = node->ln_Name;
  228.  
  229.       open_cnt = l_ptr->lib_OpenCnt;
  230.  
  231.       /*
  232.        * if flushable, record if not already in table
  233.        */
  234.       if (
  235.            (open_cnt == 0)
  236.            &&
  237.            (!check_flushed (pre_cnt, pre_flush, l_name))
  238.         )
  239.  
  240.         {
  241.           /*
  242.            * hold open count, lib name
  243.            */
  244.           pre_flush[pre_cnt].o_cnt = open_cnt;
  245.           pre_flush[pre_cnt].confeds.vr.ver = l_ptr->lib_Version;
  246.           pre_flush[pre_cnt].confeds.vr.rev = l_ptr->lib_Revision;
  247.  
  248.           strncpy (pre_flush[pre_cnt].name, l_name, S_BUFLEN - 1);
  249.           /*
  250.            * don't flush diskfont.library if fonts shouldn't be
  251.            * flushed
  252.            */
  253.           if (r_flag == FALSE)
  254.         {
  255.           if (!(l_flag && (strcmp (l_name, "diskfont.library") == 0)))
  256.             RemLibrary (l_ptr);
  257.         }
  258.           flushed_flag = TRUE;
  259.           ++pre_cnt;
  260.         }
  261.     }
  262.       Permit ();
  263.  
  264.       if (lib_cnt == 0)
  265.     lib_cnt = cc;        /* hold first pass lib count */
  266.       /*
  267.        * if no flushable libs this time, exit loop
  268.        */
  269.       if ((flushed_flag == FALSE) || (r_flag == TRUE))
  270.     break;
  271.     }
  272.   /*
  273.    * see if report only
  274.    */
  275.   if (r_flag == TRUE)
  276.     {
  277.       for (j = 0; j < pre_cnt; ++j)
  278.     {
  279.       char *l_name = pre_flush[j].name;
  280.  
  281.       printf ("\tFlushable Library      :  %-27s(%d.%d)\n", l_name,
  282.           pre_flush[j].confeds.vr.ver,
  283.           pre_flush[j].confeds.vr.rev);
  284.     }
  285.       return;
  286.     }
  287.  
  288.   /*
  289.    * now see what's been flushed
  290.    */
  291.   if (pre_cnt)
  292.     {
  293.       Forbid ();
  294.       for (node = SysBase->LibList.lh_Head; node->ln_Succ;
  295.        node = node->ln_Succ)
  296.     {
  297.       l_ptr = (LIBRARY *) node;
  298.       if (l_ptr->lib_OpenCnt == 0)
  299.         {
  300.           /*
  301.            * hold open count, lib name
  302.            */
  303.           post_flush[post_cnt].o_cnt = l_ptr->lib_OpenCnt;
  304.           post_flush[post_cnt].confeds.vr.ver = l_ptr->lib_Version;
  305.           post_flush[post_cnt].confeds.vr.rev = l_ptr->lib_Revision;
  306.           strncpy (post_flush[post_cnt].name, node->ln_Name, S_BUFLEN - 1);
  307.  
  308.           ++post_cnt;
  309.         }
  310.     }
  311.       Permit ();
  312.     }
  313.   /*
  314.    * report on flushed libraries
  315.    */
  316.  
  317.   printf ("Libraries: total = %2d , flushable = %2d, flushed = %2d\n",
  318.       lib_cnt, pre_cnt, pre_cnt - post_cnt);
  319.   /*
  320.    * now see how many libraries flushed themselves
  321.    */
  322.  
  323.   if (pre_cnt && v_flag)
  324.     {
  325.       for (j = 0; j < pre_cnt; ++j)
  326.     {
  327.       char *l_name = pre_flush[j].name;
  328.  
  329.       if (!check_flushed (post_cnt, post_flush, l_name))
  330.         printf ("\tFlushed         :  %-27s(%d.%d)\n", l_name,
  331.             pre_flush[j].confeds.vr.ver,
  332.             pre_flush[j].confeds.vr.rev);
  333.     }
  334.       /*
  335.        * now see how many libraries did not flush themselves
  336.        */
  337.  
  338.       for (j = 0; j < post_cnt; ++j)
  339.     {
  340.       char *l_name = post_flush[j].name;
  341.  
  342.       printf ("\tNot Flushed     :  %-27s(%d.%d)\n", l_name,
  343.           post_flush[j].confeds.vr.ver,
  344.           post_flush[j].confeds.vr.rev);
  345.     }
  346.  
  347.       printf ("\n");
  348.     }
  349.   return;
  350. }
  351.  
  352. /*
  353.  **********************************************************
  354.  */
  355.  
  356. void
  357. FlushDevices (BOOL flag)
  358. {
  359.   LIBRARY *l_ptr;
  360.   NODE *node;
  361.   int dev_cnt = 0;
  362.   int j;
  363.  
  364.   pre_cnt = 0;
  365.   post_cnt = 0;
  366.  
  367.   Forbid ();
  368.   for (node = SysBase->DeviceList.lh_Head; node->ln_Succ;
  369.        node = node->ln_Succ)
  370.     {
  371.       l_ptr = (LIBRARY *) node;
  372.  
  373.       ++dev_cnt;
  374.       /*
  375.        * record all flushable (  open count  = 0 )
  376.        */
  377.  
  378.       if (l_ptr->lib_OpenCnt == 0)
  379.     {
  380.       /*
  381.        * hold open count, lib name
  382.        */
  383.       pre_flush[pre_cnt].o_cnt = l_ptr->lib_OpenCnt;
  384.       pre_flush[pre_cnt].confeds.vr.ver = l_ptr->lib_Version;
  385.       pre_flush[pre_cnt].confeds.vr.rev = l_ptr->lib_Revision;
  386.       strncpy (pre_flush[pre_cnt].name, node->ln_Name, S_BUFLEN);
  387.  
  388.       ++pre_cnt;
  389.  
  390.       if (r_flag == FALSE)
  391.         {
  392.           RemDevice ((DEVICE *) l_ptr);
  393.         }
  394.     }
  395.     }
  396.   Permit ();
  397.  
  398.   /*
  399.    * see if report only
  400.    */
  401.   if (r_flag == TRUE)
  402.     {
  403.       for (j = 0; j < pre_cnt; ++j)
  404.     {
  405.       char *l_name = pre_flush[j].name;
  406.  
  407.       printf ("\tFlushable Device       :  %-27s(%d.%d)\n", l_name,
  408.           pre_flush[j].confeds.vr.ver,
  409.           pre_flush[j].confeds.vr.rev);
  410.     }
  411.       return;
  412.