home *** CD-ROM | disk | FTP | other *** search
-
- #define VERSION "1.2"
-
- /*********************************************************************
-
- * Flush Flushes all unused libraries, devices and fonts.
- * Note that some libraries and devices refuse to
- * flush themselves.
- *
- *
- * Options:
- *
- * -d ; only flush devices
- * -f ; only flush fonts
- * -l ; only flush libraries
- * -r ; report only; don't flush
- * -v ; be verbose; print names of all removed objects
- * -oOBJ ; remove OBJ , must have a suffix of
- * .library, .device, or .font(x,y)
- * -h ; this message
- *
- *
- * Runs under AmigaDOS 2.04+
- *
- *
- ***** Written by Gary Duncan
- *
- * Bug reports etc via e-mail to gduncan@philips.oz.au) , or mail to
- *
- *Work: Gary Duncan
- * Philips PTS
- * 23 Lakeside Dr
- * Tally-Ho Technology Park
- * Burwood East Vic 3151
- * Australia
- *
- *Home: Gary Duncan
- * 57 Melbourne Hill Rd
- * Warrandyte
- * Vic 3113
- * Australia
- *
- *Thanks to these beta-testers for testing early versions:-
- *
- * Benbuck Nason (bigben@netcom.com)
- * Torsten Nielsen (torsten@diku.dk)
- * Darren Reid and others (shockwave@jupiter.sun.csd.unb.ca)
- *
- *
- ***** Freely distributable for non-commercial purposes.
- * Please keep this header intact.
- *
- * Use this program at your own risk.
- *
- *
- * Compiles under SAS 6.3
- *
- * Formatted with 'indent -gnu' ; a big time-saving program.
- *
- *****************************************************************/
-
- #include "flush.h"
-
- extern struct GfxBase *GfxBase;
-
-
- /*
- * string for AmigaDOS Version Command
- */
- char A_vers[] = "\0$VER: Flush\t" VERSION " (13.1.94)";
-
-
- /*
- * lib/device array ; one entry per lib/device list containing
- * name and open count.
- */
-
- static S_LIB *pre_flush;
- static S_LIB *post_flush;
-
- static int pre_cnt = 0;
- static int post_cnt = 0;
-
- char *remove_it;
-
- int r_count = 0;
-
- ULONG s_total;
- ULONG s_fast;
- ULONG s_chipx;
-
- ULONG e_total;
- ULONG e_fast;
- ULONG e_chipx;
-
- ULONG r_total;
- ULONG r_fast;
- ULONG r_chipx;
-
- BOOL v_flag = FALSE;
- BOOL r_flag = FALSE;
- BOOL o_flag = FALSE;
- BOOL d_flag = FALSE;
- BOOL f_flag = FALSE;
- BOOL l_flag = FALSE;
-
- /*
- **********************************************************
- */
-
- main (int argc, char **argv)
-
- {
- ULONG t, c, f;
-
- /*
- * check options
- */
-
- scan_args (argc, argv);
-
- /*
- * get buffers to hold List items
- */
-
- GetItemsBuf (&pre_flush, &post_flush);
-
- /*
- * kluge to get printf() to get its 16K malloc'd buffer now
- * so that it won't confuse memory usage reporting later
- */
-
- printf ("\r");
- fflush (stdout);
-
- /*
- * get memory at start
- */
- memm (&s_fast, &s_chipx);
-
- /*
- * check if its just one removal
- */
- if (o_flag)
- {
- rem_obj (remove_it);
- }
- else
- {
- /*
- * flush fonts before libs, as attempting to flush
- * diskfont.library seems to flush them automatically
- * and we want font flushing shown.
- */
- if (f_flag == TRUE)
- {
- FlushFonts (r_flag);
- }
- else if (l_flag == TRUE)
- {
- FlushLibraries (r_flag);
- }
- else if (d_flag == TRUE)
- {
- FlushDevices (r_flag);
- }
- else
- {
- FlushFonts (r_flag);
- FlushLibraries (r_flag);
- FlushDevices (r_flag);
- }
- }
- /*
- * get memory at end
- */
- memm (&e_fast, &e_chipx);
-
- c = (e_chipx - s_chipx) / 1024;
- f = (e_fast - s_fast) / 1024;
- t = c + f;
-
- if (r_flag == FALSE)
- {
- printf ("Memory regained (KB) : total = %ld, [chip = %ld, fast = %ld]\n",
- t, c, f);
- }
- }
-
- /*
- **********************************************************
- */
-
- void
- FlushLibraries (BOOL flag)
- {
- LIBRARY *l_ptr;
- NODE *node;
- int lib_cnt = 0;
- int open_cnt = 0;
- int j;
- int cc = 0;
- BOOL flushed_flag;
-
-
- pre_cnt = 0;
- post_cnt = 0;
-
- /*
- * iterate through lib list until all flushable libs flushed;
- * need to do this because some libs use other libs, i.e do
- * a flush themselves
- *
- * - if "report" option, just pass through once
- *
- */
-
- while (TRUE)
- {
- Forbid ();
- for (flushed_flag = FALSE, node = SysBase->LibList.lh_Head;
- node->ln_Succ; node = node->ln_Succ)
- {
- char *l_name;
- ++cc;
- l_ptr = (LIBRARY *) node;
- l_name = node->ln_Name;
-
- open_cnt = l_ptr->lib_OpenCnt;
-
- /*
- * if flushable, record if not already in table
- */
- if (
- (open_cnt == 0)
- &&
- (!check_flushed (pre_cnt, pre_flush, l_name))
- )
-
- {
- /*
- * hold open count, lib name
- */
- pre_flush[pre_cnt].o_cnt = open_cnt;
- pre_flush[pre_cnt].confeds.vr.ver = l_ptr->lib_Version;
- pre_flush[pre_cnt].confeds.vr.rev = l_ptr->lib_Revision;
-
- strncpy (pre_flush[pre_cnt].name, l_name, S_BUFLEN - 1);
- /*
- * don't flush diskfont.library if fonts shouldn't be
- * flushed
- */
- if (r_flag == FALSE)
- {
- if (!(l_flag && (strcmp (l_name, "diskfont.library") == 0)))
- RemLibrary (l_ptr);
- }
- flushed_flag = TRUE;
- ++pre_cnt;
- }
- }
- Permit ();
-
- if (lib_cnt == 0)
- lib_cnt = cc; /* hold first pass lib count */
- /*
- * if no flushable libs this time, exit loop
- */
- if ((flushed_flag == FALSE) || (r_flag == TRUE))
- break;
- }
- /*
- * see if report only
- */
- if (r_flag == TRUE)
- {
- for (j = 0; j < pre_cnt; ++j)
- {
- char *l_name = pre_flush[j].name;
-
- printf ("\tFlushable Library : %-27s(%d.%d)\n", l_name,
- pre_flush[j].confeds.vr.ver,
- pre_flush[j].confeds.vr.rev);
- }
- return;
- }
-
- /*
- * now see what's been flushed
- */
- if (pre_cnt)
- {
- Forbid ();
- for (node = SysBase->LibList.lh_Head; node->ln_Succ;
- node = node->ln_Succ)
- {
- l_ptr = (LIBRARY *) node;
- if (l_ptr->lib_OpenCnt == 0)
- {
- /*
- * hold open count, lib name
- */
- post_flush[post_cnt].o_cnt = l_ptr->lib_OpenCnt;
- post_flush[post_cnt].confeds.vr.ver = l_ptr->lib_Version;
- post_flush[post_cnt].confeds.vr.rev = l_ptr->lib_Revision;
- strncpy (post_flush[post_cnt].name, node->ln_Name, S_BUFLEN - 1);
-
- ++post_cnt;
- }
- }
- Permit ();
- }
- /*
- * report on flushed libraries
- */
-
- printf ("Libraries: total = %2d , flushable = %2d, flushed = %2d\n",
- lib_cnt, pre_cnt, pre_cnt - post_cnt);
- /*
- * now see how many libraries flushed themselves
- */
-
- if (pre_cnt && v_flag)
- {
- for (j = 0; j < pre_cnt; ++j)
- {
- char *l_name = pre_flush[j].name;
-
- if (!check_flushed (post_cnt, post_flush, l_name))
- printf ("\tFlushed : %-27s(%d.%d)\n", l_name,
- pre_flush[j].confeds.vr.ver,
- pre_flush[j].confeds.vr.rev);
- }
- /*
- * now see how many libraries did not flush themselves
- */
-
- for (j = 0; j < post_cnt; ++j)
- {
- char *l_name = post_flush[j].name;
-
- printf ("\tNot Flushed : %-27s(%d.%d)\n", l_name,
- post_flush[j].confeds.vr.ver,
- post_flush[j].confeds.vr.rev);
- }
-
- printf ("\n");
- }
- return;
- }
-
- /*
- **********************************************************
- */
-
- void
- FlushDevices (BOOL flag)
- {
- LIBRARY *l_ptr;
- NODE *node;
- int dev_cnt = 0;
- int j;
-
- pre_cnt = 0;
- post_cnt = 0;
-
- Forbid ();
- for (node = SysBase->DeviceList.lh_Head; node->ln_Succ;
- node = node->ln_Succ)
- {
- l_ptr = (LIBRARY *) node;
-
- ++dev_cnt;
- /*
- * record all flushable ( open count = 0 )
- */
-
- if (l_ptr->lib_OpenCnt == 0)
- {
- /*
- * hold open count, lib name
- */
- pre_flush[pre_cnt].o_cnt = l_ptr->lib_OpenCnt;
- pre_flush[pre_cnt].confeds.vr.ver = l_ptr->lib_Version;
- pre_flush[pre_cnt].confeds.vr.rev = l_ptr->lib_Revision;
- strncpy (pre_flush[pre_cnt].name, node->ln_Name, S_BUFLEN);
-
- ++pre_cnt;
-
- if (r_flag == FALSE)
- {
- RemDevice ((DEVICE *) l_ptr);
- }
- }
- }
- Permit ();
-
- /*
- * see if report only
- */
- if (r_flag == TRUE)
- {
- for (j = 0; j < pre_cnt; ++j)
- {
- char *l_name = pre_flush[j].name;
-
- printf ("\tFlushable Device : %-27s(%d.%d)\n", l_name,
- pre_flush[j].confeds.vr.ver,
- pre_flush[j].confeds.vr.rev);
- }
- return;
- }
- /*
- * now see what's been flushed
- */
- if (pre_cnt)
- {
- Forbid ();
- for (node = SysBase->DeviceList.lh_Head; node->ln_Succ;
- node = node->ln_Succ)
- {
- l_ptr = (LIBRARY *) node;
- if (l_ptr->lib_OpenCnt == 0)
- {
- /*
- * hold open count, lib name
- */
- post_flush[post_cnt].o_cnt = l_ptr->lib_OpenCnt;
- post_flush[post_cnt].confeds.vr.ver = l_ptr->lib_Version;
- post_flush[post_cnt].confeds.vr.rev = l_ptr->lib_Revision;
- strncpy (post_flush[post_cnt].name, node->ln_Name, S_BUFLEN);
-
- ++post_cnt;
- }
- }
- Permit ();
- }
- /*
- * report
- */
- printf ("Devices : total = %2d , flushable = %2d, flushed = %2d\n",
- dev_cnt, pre_cnt, pre_cnt - post_cnt);
-
- /*
- * now see how many devices flushed themselves
- */
- if (pre_cnt && v_flag)
- {
- for (j = 0; j < pre_cnt; ++j)
- {
- char *l_name = pre_flush[j].name;
-
- if (!check_flushed (post_cnt, post_flush, l_name))
- printf ("\tFlushed : %-27s(%d.%d)\n", l_name,
- pre_flush[j].confeds.vr.ver,
- pre_flush[j].confeds.vr.rev);
- }
- /*
- * now see how many devices did not flush themselves
- */
-
- for (j = 0; j < post_cnt; ++j)
- {
- char *l_name = post_flush[j].name;
-
- printf ("\tNot Flushed : %-27s(%d.%d)\n", l_name,
- post_flush[j].confeds.vr.ver,
- post_flush[j].confeds.vr.rev);
- }
- printf ("\n");
- }
- return;
- }
-
- /*
- **********************************************************
- */
-
- void
- FlushFonts (BOOL flag)
- {
- TEXTFONT *tf;
- NODE *node;
- int font_cnt = 0;
- int o_cnt;
- int j;
-
- pre_cnt = 0;
-
- /*
- * now record fonts, and flush those flushable
- */
-
- Forbid ();
- for (node = GfxBase->TextFonts.lh_Head; node->ln_Succ;
- node = node->ln_Succ)
- {
- tf = (TEXTFONT *) node;
-
- ++font_cnt;
-
- o_cnt = tf->tf_Accessors;
-
- if ((o_cnt == 0) && (tf->tf_Flags & FPF_DISKFONT))
- {
- /*
- * flushable ; hold font name
- */
- pre_flush[pre_cnt].o_cnt = o_cnt;
- pre_flush[pre_cnt].confeds.fonts.font_x = tf->tf_XSize;
- pre_flush[pre_cnt].confeds.fonts.font_y = tf->tf_YSize;
- strncpy (pre_flush[pre_cnt].name, node->ln_Name, S_BUFLEN - 1);
-
- ++pre_cnt;
-
- /*
- * then flush it
- */
- if (r_flag == FALSE)
- {
- RemFont (tf);
- Remove (node);
- }
- }
- }
- Permit ();
-
- /*
- * see if report only
- */
- if (r_flag == TRUE)
- {
- for (j = 0; j < pre_cnt; ++j)
- {
- char *l_name = pre_flush[j].name;
-
- printf ("\tFlushable Font : %-27s(X=%2d,Y=%2d)\n", l_name,
- pre_flush[j].confeds.fonts.font_x,
- pre_flush[j].confeds.fonts.font_y);
- }
-
- return;
- }
- /*
- * see what's been flushed
- */
-
- /*
- * force font flushing (lib won't be flushed)
- */
- rem_obj ("diskfont.library");
-
- post_cnt = 0;
-
- Forbid ();
- for (node = GfxBase->TextFonts.lh_Head; node->ln_Succ;
- node = node->ln_Succ)
- {
- tf = (TEXTFONT *) node;
-
- o_cnt = tf->tf_Accessors;
-
- if ((o_cnt == 0) && (tf->tf_Flags & FPF_DISKFONT))
- {
- /*
- * hold open count, font name
- */
- post_flush[post_cnt].o_cnt = o_cnt;
- post_flush[post_cnt].confeds.fonts.font_x = tf->tf_XSize;
- post_flush[post_cnt].confeds.fonts.font_y = tf->tf_YSize;
- strncpy (post_flush[post_cnt].name, node->ln_Name, S_BUFLEN - 1);
-
- ++post_cnt;
- }
- }
- Permit ();
-
- printf ("Fonts : total = %2d , flushable = %2d, flushed = %2d\n",
- font_cnt, pre_cnt, pre_cnt - post_cnt);
-
- if (pre_cnt && v_flag)
- {
- /*
- * now see how many fonts were flushed
- */
- for (j = 0; j < pre_cnt; ++j)
- {
- char *l_name = pre_flush[j].name;
-
- if (!check_flushed (post_cnt, post_flush, l_name))
- {
- printf ("\tFlushed : %-27s(X=%2d,Y=%2d)\n", l_name,
- pre_flush[j].confeds.fonts.font_x,
- pre_flush[j].confeds.fonts.font_y);
- }
- }
- /*
- * now see how many fonts were not flushed
- */
-
- for (j = 0; j < post_cnt; ++j)
- {
- char *l_name = post_flush[j].name;
-
- printf ("\tNot Flushed : %-27s(X=%2d,Y=%2d)\n", l_name,
- post_flush[j].confeds.fonts.font_x,
- post_flush[j].confeds.fonts.font_y);
- }
- printf ("\n");
- }
-
- return;
- }
-
- /*
- **********************************************************
- */
-
- int
- GetListCount (LIST * list)
- {
- int count = 0;
- NODE *node;
-
- Forbid ();
-
- for (node = list->lh_Head; node->ln_Succ; node = node->ln_Succ)
- count++;
-
- Permit ();
-
- return count;
- }
-
-
- /*
- **********************************************************
- */
-
- void
- memm (ULONG * fast, ULONG * chipx)
- {
- *fast = AvailMem (MEMF_FAST);
- *chipx = AvailMem (MEMF_CHIP);
- }
-
-
- /*
- **********************************************************
- */
-
- BOOL
- check_flushed (int count, S_LIB * s_ptr, char *n_ptr)
- {
- int j;
-
- for (j = 0; j < count; ++j)
- {
- if (strcmp (s_ptr[j].name, n_ptr) == 0)
- return TRUE;
- }
- return FALSE;
- }
-
- /*
- **********************************************************
- */
-
- void
- GetItemsBuf (S_LIB ** pre, S_LIB ** post)
- {
- ULONG bf, bl, bd;
- ULONG v;
-
- bf = GetListCount (&GfxBase->TextFonts);
- bl = GetListCount (&SysBase->LibList);
- bd = GetListCount (&SysBase->DeviceList);
-
- v = max (bf, bl);
- v = max (v, bd);
-
- /*
- * increase the entry count a bit for safety
- */
-
- v += 10;
-
-
- if ((*pre = malloc (v * sizeof (S_LIB))) == NULL)
- {
- fprintf (stderr, "Can't malloc pre-buffer\n");
- exit (1);
- }
- if ((*post = malloc (v * sizeof (S_LIB))) == NULL)
- {
- fprintf (stderr, "Can't malloc post-buffer\n");
- exit (1);
- }
- }
-
- /*
- **********************************************************
- */
-
- void
- usage ()
- {
-
- printf (
- "Flush: flushes unused libraries, devices, fonts from RAM\n\
- Version %s [%s] written by gduncan@philips.oz.au\n\n\
- usage: flush [-d] [-f] [-l] [-v] [-r] [-h] [-oOBJ]\n\
- -d ; only flush devices\n\
- -f ; only flush fonts\n\
- -l ; only flush libraries\n\
- -r ; report only; don't flush\n\
- -v ; be verbose; print names of all removed objects\n\
- -oOBJ ; remove OBJ , must have a suffix of .library or .device\n\
- -h ; this message\n",
-
- VERSION, __DATE__);
-
- }
-
- /***************************************************************************
-
-
- Function : scan_args
-
- Purpose: scans and validates command line
-
- Entry :
-
-
- Returns :
-
-
-
- ****************************************************************************/
-
-
-
- void
- scan_args (int argc, char **argv)
-
- {
- char *ptr;
- char arch;
-
- while (--argc)
- {
- ptr = *++argv;
-
- arch = *++ptr;
- switch (arch)
- {
-
- case 'h':
- usage ();
- exit (1);
-
- case 'd':
- d_flag = TRUE;
- break;
-
- case 'f':
- f_flag = TRUE;
- break;
-
- case 'l':
- l_flag = TRUE;
- break;
-
- case 'v':
- v_flag = TRUE;
- break;
-
- case 'r':
- r_flag = TRUE;
- break;
-
- case 'o':
- o_flag = TRUE;
- remove_it = ++ptr;
- break;
-
- default:
- fprintf (stderr, "unknown option\n"); /* bad option */
- exit (1);
- }
- }
- }
-
- /*
- **********************************************************
- */
-
- void
- rem_obj (char *ptr)
- {
- char *z;
- NODE *lp;
-
- if ((z = strstr (ptr, ".library")) != NULL)
- {
- if ((lp = (NODE *) FindName ((LIST *) SysBase->LibList.lh_Head, ptr)))
- RemLibrary ((LIBRARY *) lp);
- }
- else if ((z = strstr (ptr, ".device")) != NULL)
- {
- if ((lp = (NODE *) FindName ((LIST *) SysBase->DeviceList.lh_Head, ptr)))
- RemDevice ((DEVICE *) lp);
- }
- else
- fprintf (stderr, "not a .device or .library\n");
-
- }
-
- /**/
-