/* ************************************************************************* *
   xfsm - (C) Copyright 1993-1999 Robert Gasch (Robert_Gasch@peoplesoft.com)
	  http://www.peoplesoft.com/peoplepages/g/robert_gasch/src/

   Permission to use, copy, modify and distribute this software for any 
   purpose and without fee is hereby granted, provided that this copyright
   notice appear in all copies as well as supporting documentation. All
   work developed as a consequence of the use of this program should duly
   acknowledge such use.

   No representations are made about the suitability of this software for
   any purpose. This software is provided "as is" without express or implied 
   warranty.

   See the GNU General Public Licence for more information.
 * ************************************************************************* */


#include "xfsm.h"
#ifdef ULTRIX
/* *** This defines the gt_names string which means that we have to *** */
/* ***        include it here to avoid multiple definitions         *** */
#include <sys/fs_types.h>
#endif


extern Display			*mydisplay;
extern char*			myname;
extern char*			title;
extern XrmDatabase		resourceDB;
extern WinType			main_win,
				fs_win[MAXFS],
				detail_win;
extern unsigned long		fg, bg,
				warncols[];
extern XSizeHints		szhint;
extern int 			show_use,
				upd_interval,
				NFS,
				detail_share_color,
				minimize,
				menu_border,
				show_biggest,
				fs_border,
				percent,
				absolute,
				available,
				bell,
				popup,
				fs_level[],
				fs_warn[],
				verbose,
				sort,
				gray,
				override_ignore,
				rootdf,
				idx[],
				root;
extern double			b_blocks,
				b_bsize,
				b_disk;
extern unsigned long		turns;
extern float			fs_perc[],
				res_space,
				warnvals[],
				warn_val;
extern StringInfo		strinfo[];
extern struct statfs 		stats[];




static MyString ignore_names[MAXFS],	/* *** file systems to be ignored *** */
		select_names[MAXFS],	/* *** file systems to be selected*** */
#ifndef SCO
		ignore_type[MAXFS],	/* *** FS types to ignore *** */
		only_type,		/* *** show only this type *** */
#endif /* !SCO */
		ignore_pattern[MAXFS],	/* *** FSN patterns to be ignored *** */
		select_pattern[MAXFS];	/* *** FSN patterns to be selected*** */
static int	lname,
		ignore_n_count=0,
		ignore_p_count=0,
		select_n_count=0,
		select_p_count=0,
#ifndef SCO
		ignore_t_count=0,
		only_t=FALSE,
#endif /* !SCO */
		percent_width,
		old_detail_letter_x=0;
#ifdef AIX
static char	vmount_buf[BUFFERSIZE];
#endif




/* ************************************************************************ */
/* ************** set the window's width in relative mode ***************** */
/* ************************************************************************ */
void fix_fs_win_width (i)
int i;
{
	double  bsize=stats[i].f_bsize;

#ifdef SCO
	bsize=512;
#endif
	if (!absolute)
		{
		fs_win[i].width=(int)(fs_win[i].width*
			(((double)stats[i].f_blocks)*bsize)/b_disk);
		if (fs_win[i].width < 1) 
			fs_win[i].width=1;
		}
}




/* *********************************************************************** */
/* ******************** write out the detailed info ********************** */
/* *********************************************************************** */
void write_detail (i)
int i;
{
	int 	c=3, 
		longest,
		rhs,
		lhs = XTextWidth(detail_win.font_info, "Blocks Available ",
			sizeof ("Blocks Available ")),
		dflt_rhs = XTextWidth(detail_win.font_info,DETAIL_LETTER_STRING,
			sizeof (DETAIL_LETTER_STRING));
	char 	s[30]; 
	long	bsize=stats[i].f_bsize, 
		blocks=stats[i].f_blocks,
#ifndef SCO
		bavail=stats[i].f_bavail,
#endif
		bfree=stats[i].f_bfree,
		calc_bsize=bsize;
#ifdef ULTRIX
		/* *** ULTRIX always returns the number of 1K blocks *** */
		calc_bsize=1024;
#endif /* ULTRIX */
#ifdef SCO
		/* *** SCO always returns the number of 512 byte blocks *** */
		calc_bsize=512;
#endif /* SCO */
#ifdef FreeBSD
		/* *** FreeBSD has fsize which is the physical block size *** */
		/* *** and bsize which is the optimal transfer block size *** */
		/* *** and which depends on the filesystem parameter.     *** */
		calc_bsize=stats[i].f_bsize;
#endif /* FreeBSD */

	/* *** take the longer of the two 'problematic' strings *** */
	if (strlen (MntOpt) > strlen (DevName))
		rhs = XTextWidth(detail_win.font_info, MntOpt,
			longest = strlen (MntOpt));
	else
		rhs = XTextWidth(detail_win.font_info, DevName,
			longest = strlen (DevName));
	/* *** resize the detail window accordingly *** */
	if (longest > DETAIL_LETTER_X)
	   {
	    if (longest != old_detail_letter_x) 
		{
		detail_win.width = rhs + lhs + OFF_X*2;
		szhint.min_width = detail_win.width;
                szhint.max_width = detail_win.width;
		szhint.min_height = szhint.max_height = detail_win.height;
		szhint.flags = PMinSize | PMaxSize | PSize;
		XSetNormalHints (mydisplay, detail_win.win, &szhint);
		XResizeWindow (mydisplay, detail_win.win, 
			detail_win.width, DETAIL_Y);
		} 
	   }
	else 
	if (detail_win.width > dflt_rhs + lhs + OFF_X*2)
		/* *** window os too big - shrink it *** */
		{
		detail_win.width = dflt_rhs + lhs + OFF_X;
		szhint.min_width = detail_win.width;
		szhint.max_width = detail_win.width;
		szhint.min_height = szhint.max_height = detail_win.height;
		szhint.flags = PMinSize | PMaxSize | PSize;
		XSetNormalHints (mydisplay, detail_win.win, &szhint);
		XResizeWindow (mydisplay, detail_win.win, 
			detail_win.width, DETAIL_Y);
		}
	old_detail_letter_x = longest;

	XClearWindow (mydisplay, detail_win.win);
	/* *** write the detailed info *** */
	XDrawImageString (mydisplay, detail_win.win, detail_win.gc, 
		((detail_win.width / 2) - (XTextWidth(detail_win.font_info,
		FsName, strlen(FsName)) / 2)), OFF_Y+MENU_HEIGHT(detail_win), 
		FsName, strlen(FsName));
	XDrawImageString (mydisplay, detail_win.win, detail_win.gc, 
		OFF_X, OFF_Y+MENU_HEIGHT(detail_win)*c, "Device Name", 
		strlen ("Device Name"));
	sprintf (s, "%s", DevName);
	XDrawImageString (mydisplay, detail_win.win, detail_win.gc, 
		OFF_X+lhs, OFF_Y+MENU_HEIGHT(detail_win)*c++, s, strlen(s));

	XDrawImageString (mydisplay, detail_win.win, detail_win.gc, 
		OFF_X, OFF_Y+MENU_HEIGHT(detail_win)*c, "Total Size", 
		strlen ("Total Size"));
	if (blocks == -1 || calc_bsize == -1)
		sprintf (s, "Undefined");
	else
		sprintf (s, "%.2f MB", (double)
		/* *** use this computational order to avoid overflows *** */
			((double)(calc_bsize)/(double)(MB))*(double)(blocks));
	XDrawImageString (mydisplay, detail_win.win, detail_win.gc, 
		OFF_X+lhs, OFF_Y+MENU_HEIGHT(detail_win)*c++, s, strlen (s));

	XDrawImageString (mydisplay, detail_win.win, detail_win.gc, 
		OFF_X, OFF_Y+MENU_HEIGHT(detail_win)*c, "Space Free", 
		strlen ("Space Free"));
	if (bfree == -1 || calc_bsize == -1)
		sprintf (s, "Undefined");
	else
		sprintf (s, "%.2f MB", (double)
		/* *** use this computational order to avoid overflows *** */
			((double)(calc_bsize)/(double)(MB))*(double)(bfree));
	XDrawImageString (mydisplay, detail_win.win, detail_win.gc, 
		OFF_X+lhs, OFF_Y+MENU_HEIGHT(detail_win)*c++, s, strlen (s));

#ifndef SCO
	XDrawImageString (mydisplay, detail_win.win, detail_win.gc, 
		OFF_X, OFF_Y+MENU_HEIGHT(detail_win)*c, "Space Available", 
		strlen ("Space Available"));
	if (bavail == -1 || calc_bsize == -1)
		sprintf (s, "Undefined");
	else
		sprintf (s, "%.2f MB", (double)
		/* *** use this computational order to avoid overflows *** */
			((double)(calc_bsize)/(double)(MB))*(double)(bavail));
	XDrawImageString (mydisplay, detail_win.win, detail_win.gc, 
		OFF_X+lhs, OFF_Y+MENU_HEIGHT(detail_win)*c++, s, strlen (s));
#endif

#ifndef OSF1 
# ifndef SCO
	XDrawImageString (mydisplay, detail_win.win, detail_win.gc,
		OFF_X, OFF_Y+MENU_HEIGHT(detail_win)*c, "Mount Type",
		strlen ("Mount Type"));
	sprintf (s, "%s", MntTyp);
	XDrawImageString (mydisplay, detail_win.win, detail_win.gc,
		OFF_X+lhs, OFF_Y+MENU_HEIGHT(detail_win)*c++, s, strlen (s));
# endif /* !SCO */
	
	XDrawImageString (mydisplay, detail_win.win, detail_win.gc,
		OFF_X, OFF_Y+MENU_HEIGHT(detail_win)*c, "Mount Options",
		strlen ("Mount Options"));
	sprintf (s, "%s", MntOpt);
	XDrawImageString (mydisplay, detail_win.win, detail_win.gc,
		OFF_X+lhs, OFF_Y+MENU_HEIGHT(detail_win)*c++, s, strlen (s));
#endif /* !OSF1 */

	XDrawImageString (mydisplay, detail_win.win, detail_win.gc, 
		OFF_X, OFF_Y+MENU_HEIGHT(detail_win)*c, "Block Size", 
		strlen ("Block Size"));
#ifdef FreeBSD
	sprintf (s, "%ld", calc_bsize);
#else
	sprintf (s, "%ld", bsize);
#endif /* FreeBSD */
	CHECKNA;
	XDrawImageString (mydisplay, detail_win.win, detail_win.gc, 
		OFF_X+lhs, OFF_Y+MENU_HEIGHT(detail_win)*c++, s, strlen (s));

	XDrawImageString (mydisplay, detail_win.win, detail_win.gc, 
		OFF_X, OFF_Y+MENU_HEIGHT(detail_win)*c, "Blocks", 
		strlen ("Blocks"));
	sprintf (s, "%ld", blocks);
	CHECKNA;
	XDrawImageString (mydisplay, detail_win.win, detail_win.gc, 
		OFF_X+lhs, OFF_Y+MENU_HEIGHT(detail_win)*c++, s, strlen (s));

	XDrawImageString (mydisplay, detail_win.win, detail_win.gc, 
		OFF_X, OFF_Y+MENU_HEIGHT(detail_win)*c, "Blocks Free",
		strlen ("Blocks Free"));
	sprintf (s, "%ld", bfree);
	CHECKNA;
	XDrawImageString (mydisplay, detail_win.win, detail_win.gc, 
		OFF_X+lhs, OFF_Y+MENU_HEIGHT(detail_win)*c++, s, strlen (s));

#ifndef SCO
	XDrawImageString (mydisplay, detail_win.win, detail_win.gc, 
		OFF_X, OFF_Y+MENU_HEIGHT(detail_win)*c, "Blocks Available",
		strlen ("Blocks Available"));
	sprintf (s, "%ld", bavail);
	CHECKNA;
	XDrawImageString (mydisplay, detail_win.win, detail_win.gc, 
		OFF_X+lhs, OFF_Y+MENU_HEIGHT(detail_win)*c++, s, strlen (s));
#endif

	XDrawImageString (mydisplay, detail_win.win, detail_win.gc, 
		OFF_X, OFF_Y+MENU_HEIGHT(detail_win)*c, 
#ifdef ULTRIX
		"Gnodes", strlen ("Gnodes"));
#else
		"File Inodes", strlen ("File Inodes"));
#endif

#ifdef SGI
	sprintf (s, "%lld", stats[i].f_files);
#else
	sprintf (s, "%d", stats[i].f_files);
#endif
	CHECKNA;
	XDrawImageString (mydisplay, detail_win.win, detail_win.gc, 
		OFF_X+lhs, OFF_Y+MENU_HEIGHT(detail_win)*c++, s, strlen (s));

	XDrawImageString (mydisplay, detail_win.win, detail_win.gc, 
		OFF_X, OFF_Y+MENU_HEIGHT(detail_win)*c, 
#ifdef ULTRIX
		"Free Gnodes", strlen ("Free Gnodes"));
#else
		"Free Inodes", strlen ("Free Inodes"));
#endif

#ifdef SGI
	sprintf (s, "%lld", stats[i].f_ffree);
#else
	sprintf (s, "%d", stats[i].f_ffree);
#endif
	CHECKNA;
	XDrawImageString (mydisplay, detail_win.win, detail_win.gc, 
		OFF_X+lhs, OFF_Y+MENU_HEIGHT(detail_win)*c++, s, strlen (s));

#if defined (SVR4) || defined (SOLARIS) || defined (AUX) || defined (SGI) || \
    defined (DGUX)
	XDrawImageString (mydisplay, detail_win.win, detail_win.gc, 
		OFF_X, OFF_Y+MENU_HEIGHT(detail_win)*c, "Inodes Available",
		strlen ("Inodes Available"));
# ifdef AUX
	sprintf (s, "%ld", stats[i].f_bavail);
# else
#  ifdef SGI
	sprintf (s, "%lld", stats[i].f_favail);
#  else
	sprintf (s, "%ld", stats[i].f_favail);
# endif /* SGI */
# endif /* AUX */
	CHECKNA;
	XDrawImageString (mydisplay, detail_win.win, detail_win.gc, 
		OFF_X+lhs, OFF_Y+MENU_HEIGHT(detail_win)*c++, s, strlen (s));
#endif /* SVR4 || SOLARIS || AUX || SGI || DGUX */
}



/* ************************************************************************ */
/* ************ get_fs get the file systems which are mounted ************* */
/* ************************************************************************ */
void get_fs ()
{
	int		x,y, removed, min, t, fs_returned=0;
#if defined (SVR4) || defined (SOLARIS) || defined (SCO) || \
    defined (SUNOS) || defined (LINUX) || defined (HPUX) || \
    defined (CONVEXOS) || defined (MACH) || defined (DYNIX) || \
    defined (AUX) || defined (SGI)|| defined (DGUX)
	FILE		*fp;
#endif
#ifdef ULTRIX
	int		which_fs=0;
#endif
#ifdef AIX
	int		i=0, retcode;
#endif
#ifdef SCO
	MyString	buffer;
#endif

/* *** The struct names here are overloaded in main.h. The reason   *** */
/* *** we still have porting exceptions here are that the functions *** */
/* *** we call have different parameter types we have to adhere to. *** */
#if defined (SUNOS) || defined (LINUX) || defined (DYNIX) || \
    defined (HPUX) || defined (AIX) || defined (CONVEXOS) || \
    defined (AUX) || defined (SGI) || defined (DGUX)
	struct mntent 	*mnt_info;
# else
# if defined (SVR4) || defined (SOLARIS) || defined (ULTRIX) || defined (MACH) 
	struct mntent 	mnt_info;
#  else
#  if defined (OSF1) || defined (FreeBSD) || defined (BSDI)
	struct statfs	*mnt_info;
	int		i, nstatfs;
#  endif /* OSF1 || FreeBSD || BSDI */
# endif /* SVR4 || SOLARIS || ULTRIX || MACH || DGUX */
#endif /* SUNOS || LINUX || DYNIX || HPUX || AIX || CONVEXOS || AUX || SGI */


	NFS=0;
	/* *** here we open the file containing FS info     *** */
	/* *** AIX && ULTRIX do not have to do this as we   *** */
	/* *** acces the mount data directly though memory  *** */
#if defined (SUNOS) || defined (LINUX) || defined (HPUX) || \
    defined (CONVEXOS) || defined (MACH) || defined (DYNIX) || \
    defined (AUX) || defined (SGI) || defined (DGUX)
	if ((fp=setmntent(MOUNT_FILE,"r"))==NULL)
		{
		perror("Can't open setmntent ... Exiting");
		exit(1);
		}
# else
# if defined (SVR4) || defined (SOLARIS)
	if ((fp=fopen(MOUNT_FILE,"r"))==NULL)
		{
		perror("Can't open /etc/mnttab ... Exiting");
		exit(1);
		}
#  else
#  ifdef OSF1
	nstatfs = getfsstat((struct statfs *)0, 0, MNT_NOWAIT);
	if (nstatfs < 0)
		{
		perror("Can't getfsstat(0) ... Exiting");
		exit(1);
		}
	mnt_info = (struct statfs *)malloc(nstatfs * sizeof (struct statfs));
	if (mnt_info == (struct statfs *)0)
		{
		perror("Can't malloc() ... Exiting");
		exit(1);
		}
	nstatfs = getfsstat(mnt_info,nstatfs*sizeof(struct statfs),MNT_NOWAIT);
	if (nstatfs < 0)
		{
		perror("Can't getfsstat() ... Exiting");
		exit(1);
		}
#   else
#   if defined (FreeBSD) || defined (BSDI)
	nstatfs = getmntinfo(&mnt_info,MNT_NOWAIT);
	if (nstatfs < 0)
		{
		perror("Can't getmntinfo() ... Exiting");
		exit(1);
		}
#    else
#    ifdef SCO
	/* *** execute command *** */
	if ((fp = popen ("/etc/mount", "r")) == NULL)
		{
		perror ("Can't do popen to /etc/mount command ... Exiting\n");
		exit (1);
		};
#    endif /* SCO */
#   endif /* FreeBSD || BSDI */
#  endif /* OSF1 */
# endif /* SVR4 || SOLARIS */
#endif /* SUNOS || LINUX || HPUX || CONVEXOS || MACH || DYNIX || AUX || SGI ||
	  DGUX */


	/* *** read the contents of the file *** */
#if defined (SUNOS) || defined (LINUX) || defined (HPUX) || \
    defined (CONVEXOS) || defined (MACH) || defined(DYNIX) || \
    defined (AUX) || defined (SGI) || defined (DGUX)
	while ((mnt_info=getmntent(fp)) && NFS < MAXFS)
# else
# if defined (SVR4) || defined (SOLARIS)
	while (!(getmntent (fp, &mnt_info)) && NFS < MAXFS)
#  else
#  if defined (OSF1) || defined (FreeBSD) || defined(BSDI)
	i=0;
	while (i < nstatfs && NFS < MAXFS)
#   else
#   ifdef AIX
	/* *** this is clumsy, but it get's things done    *** */
	/* *** correctly in the existing program structure *** */
	retcode=mntctl(MCTL_QUERY, sizeof(vmount_buf), vmount_buf);
	if (retcode==0)
		{
		fprintf (stderr, "Buffer too small; needs to be %d long\n\
Please change the definition of BUFFERSIZE in main.h to an appropriate value\n",
			*((int *) vmount_buf));
		exit(1);
		}
	/* *** assign the first strcture and start the loop *** */
	mnt_info=(struct vmount *)vmount_buf;
	while (i<retcode && NFS < MAXFS)
#    else
#    ifdef ULTRIX
	while (getmnt (&which_fs, &mnt_info, sizeof (struct mntent), 
			 NOSTAT_MANY, "no_path") > 0)
#     else
#     ifdef SCO
	while ((fgets (buffer, STRLENGTH , fp)) != NULL)
#     endif /* SCO */
#    endif /* ULTRIX */
#   endif /* AIX */
#  endif /* OSF1 || FreeBSD || BSDI */
# endif /* SVR4 || SOLARIS */
#endif /* SUNOS || LINUX || HPUX || CONVEXOS || MACH || AUX || SGI || DGUX */


		{
		/* *** here the actual while loop starts *** */
#if defined (SUNOS) || defined (LINUX) || defined (DYNIX) || \
    defined (HPUX) || defined (CONVEXOS) || defined (MACH) || \
    defined (AUX) || defined (SGI) || defined (DGUX)
		strcpy (strinfo[NFS].fs_name, mnt_info->mnt_dir);
		strcpy (strinfo[NFS].dev_name, mnt_info->mnt_fsname);
		strcpy (strinfo[NFS].mnt_typ, mnt_info->mnt_type);
		strcpy (strinfo[NFS].mnt_opt, mnt_info->mnt_opts);
# else
# if defined (SVR4) || defined (SOLARIS)
		strcpy (strinfo[NFS].fs_name, mnt_info.mnt_dir);
		strcpy (strinfo[NFS].dev_name, mnt_info.mnt_fsname);
		strcpy (strinfo[NFS].mnt_typ, mnt_info.mnt_type);
		strcpy (strinfo[NFS].mnt_opt, mnt_info.mnt_opts);
#  else
#  if defined (OSF1) || defined (FreeBSD) || defined (BSDI)
		strcpy (strinfo[NFS].fs_name, mnt_info[i].f_mntonname);
		strcpy (strinfo[NFS].dev_name, mnt_info[i].f_mntfromname);
		i++;
#   else
#   ifdef AIX
		strcpy (strinfo[NFS].fs_name, vmt2dataptr(mnt_info,VMT_STUB));
		strcpy (strinfo[NFS].dev_name,vmt2dataptr(mnt_info,VMT_OBJECT));
		/* *** of course IBM had to make things difficult *** */
		switch (mnt_info -> vmt_gfstype)
			{
			case MNT_AIX: strcpy (strinfo[NFS].mnt_typ, "aix");
					break;
			case MNT_NFS: strcpy (strinfo[NFS].mnt_typ, "nfs");
					break;
			case MNT_JFS: strcpy (strinfo[NFS].mnt_typ, "jfs");
					break;
			case MNT_CDROM: strcpy (strinfo[NFS].mnt_typ, "cdrom");
					break;
			default: strcpy (strinfo[NFS].mnt_typ, "user defined");
					break;
			}
		strcpy (strinfo[NFS].mnt_opt, "");
		if (mnt_info -> vmt_flags & MNT_READONLY)
			strcat (strinfo[NFS].mnt_opt, "ro, ");
		if (mnt_info -> vmt_flags & MNT_REMOVABLE)
			strcat (strinfo[NFS].mnt_opt, "removable, ");
		if (mnt_info -> vmt_flags & MNT_DEVICE)
			strcat (strinfo[NFS].mnt_opt, "device, ");
		if (mnt_info -> vmt_flags & MNT_REMOTE)
			strcat (strinfo[NFS].mnt_opt, "remote, ");
		if (mnt_info -> vmt_flags & MNT_UNMOUNTING)
			strcat (strinfo[NFS].mnt_opt, "unmounting, ");
		if (mnt_info -> vmt_flags & MNT_SYSV_MOUNT)
			strcat (strinfo[NFS].mnt_opt, "sysv mount, ");
		if (mnt_info -> vmt_flags & MNT_NOSUID)
			strcat (strinfo[NFS].mnt_opt, "no suid, ");
		if (mnt_info -> vmt_flags & MNT_NODEV)
			strcat (strinfo[NFS].mnt_opt, "no device access, ");
		/* *** safety in case none of the above apply *** */
		if (!strcmp (strinfo[NFS].mnt_opt, ""))
			strcpy (strinfo[NFS].mnt_opt, "rw");
		/* *** remove trailing comma *** */
		if (strinfo[NFS].mnt_opt[strlen(strinfo[NFS].mnt_opt)-2] == ',')
		    strinfo[NFS].mnt_opt[strlen(strinfo[NFS].mnt_opt)-2] = '\0';
		i++;
		mnt_info=(struct vmount *)((char *) 
			mnt_info+mnt_info->vmt_length);
#    else
#    ifdef ULTRIX
		strcpy (strinfo[NFS].fs_name, mnt_info.mnt_dir);
		strcpy (strinfo[NFS].dev_name, mnt_info.mnt_fsname);
		strcpy (strinfo[NFS].mnt_typ, gt_names[mnt_info.mnt_type]);
		/* *** IBM & ULTRIX developers should go bowling together *** */
		/* ***      then again, it almost looks like they have    *** */
		strcpy (strinfo[NFS].mnt_opt, "");
		if (mnt_info.mnt_opts & M_RONLY)
			strcat (strinfo[NFS].mnt_opt, "ro, ");
		if (mnt_info.mnt_opts & M_QUOTA)
			strcat (strinfo[NFS].mnt_opt, "quota, ");
		if (mnt_info.mnt_opts & M_LOCAL)
			strcat (strinfo[NFS].mnt_opt, "local, ");
		if (mnt_info.mnt_opts & M_NOSUID)
			strcat (strinfo[NFS].mnt_opt, "nosuid, "); 
		if (mnt_info.mnt_opts & M_NODEV)
			strcat (strinfo[NFS].mnt_opt, "nodev, ");
		if (mnt_info.mnt_opts & M_FORCE)
			strcat (strinfo[NFS].mnt_opt, "force, ");
		if (mnt_info.mnt_opts & M_SYNC)
			strcat (strinfo[NFS].mnt_opt, "sync ,");
		if (mnt_info.mnt_opts & M_NOCACHE)
			strcat (strinfo[NFS].mnt_opt, "nocache, ");
		if (mnt_info.mnt_opts & M_EXPORTED)
			strcat (strinfo[NFS].mnt_opt, "exported, " );
		if (mnt_info.mnt_opts & M_EXRONLY)
			strcat (strinfo[NFS].mnt_opt, "exported ro, ");
		if (mnt_info.mnt_opts & M_NOEXEC)
			strcat (strinfo[NFS].mnt_opt, "noexec, ");
		/* *** safety in case none of the above apply *** */
		if (!strcmp (strinfo[NFS].mnt_opt, ""))
			strcpy (strinfo[NFS].mnt_opt, "rw");
		/* *** remove trailing comma *** */
		if (strinfo[NFS].mnt_opt[strlen (strinfo[NFS].mnt_opt)-2]==',')
			strinfo[NFS].mnt_opt[
				strlen (strinfo[NFS].mnt_opt)-2] = '\0';
#     else
#     ifdef SCO
		sscanf (buffer, "%s%*s%s%s", strinfo[NFS].fs_name, 
			strinfo[NFS].dev_name, strinfo[NFS].mnt_opt);
#     endif /* SCO */
#    endif /* ULTRIX */
#   endif /* AIX */
#  endif /* OSF1 */
# endif /* SVR4 || SOLARIS */
#endif /* SUNOS || LINUX || DYNIX || HPUX || ULTRIX || CONVEXOS || MACH || 
          AUX || SGI || DGUX */


		/* *** see if this is one of the file *** */
		/* *** systems that we want to remove *** */
		removed=FALSE;
#if !defined (MACH) && !defined (AIX) && !defined (OSF1) && \
    !defined (SCO) && !defined (FreeBSD) && !defined (BSDI)
		/* *** AIX does not need it as we use mntctl         *** */
		/* *** OSF1 neither as it uses getfsstat             *** */
# ifdef ULTRIX
		if (mnt_info.mnt_type == fs_ignore)
			removed=TRUE;
# else
#  if defined (SOLARIS) || defined (SVR4) 
		if (strstr(mnt_info.mnt_opts, fs_ignore))
			removed=TRUE;
#  else
#   if defined (SGI)
		if (strstr(mnt_info->mnt_opts, fs_ignore))
			removed=TRUE;
#   else  
#    if defined (DGUX)
		if (hasmntopt(mnt_info,fs_ignore) != NULL)
			removed=TRUE;
#     else
		/* *** generic comparison *** */
		if (!override_ignore)
			if (!strcmp(mnt_info->mnt_type, fs_ignore))
				{
				removed=TRUE;
				if (verbose && !turns)
					printf ("%s marked MNTTYPE_IGNORE ... overriding ignore ...",
						strinfo[NFS].fs_name);
				}

#    endif /* DGUX */
#   endif /* SGI */
#  endif /* SOLARIS || SVR4 */
# endif /* ULTRIX */
#endif /* !MACH && !AIX && !OSF1 && !SCO && !FreeBSD && !BSDI */

		/* *** see if the user has any options which affect *** */
		/* *** which file systems we show *** */
#ifndef SCO
		if (only_t)
			if (strcmp (strinfo[NFS].mnt_typ, only_type))
				removed=TRUE;
#endif /* !SCO */
		if (!removed)
		   for (x=0; x<ignore_n_count; x++)
			/* *** we found a match *** */
			if (!strcmp (strinfo[NFS].fs_name, ignore_names[x]))
				{
				removed=TRUE;
				x=ignore_n_count;
				}
		if (!removed)
		   for (x=0; x<ignore_p_count; x++)
			/* *** we found a match *** */
			if(strstr(strinfo[NFS].fs_name,ignore_pattern[x])!=NULL)
				{
				removed=TRUE;
				x=ignore_p_count;
				}
#ifndef SCO
		if (!removed)
		   for (x=0; x<ignore_t_count; x++)
			/* *** we found a match *** */
			if (!strcmp (strinfo[NFS].mnt_typ, ignore_type[x]))
				{
				removed=TRUE;
				x=ignore_t_count;
				}
#endif /* !SCO */

		/* *** FS was not targeted by -d, -D, -it or -ot option *** */
		if (!removed && (select_n_count > 0))
			{
			removed=TRUE;
			for (x=0; x<select_n_count; x++)
				/* *** we found a match *** */
				if (!strcmp (strinfo[NFS].fs_name, 
				    	     select_names[x]))
					{
					removed=FALSE;
					x=select_n_count;
					}
			}
		if (!removed && (select_p_count > 0))
			{
			removed=TRUE;
			for (x=0; x<select_p_count; x++)
				/* *** we found a match *** */
				if (strstr (strinfo[NFS].fs_name,
					    select_pattern[x])!=NULL)
					{
					removed=FALSE;
					x=select_p_count;
					}
			}
				
		if (!removed)
			NFS++;
		fs_returned++;
		/* *** end of while loop *** */
		}

	/* ***         close the file           *** */
	/* *** ULTRIX: didn't open a file so    *** */
	/* *** we also don't have to close it   *** */
	/* *** AIX and OSF1: Same as AIX        *** */
	/* *** although we free the buffer      *** */
#if defined (SUNOS) || defined (LINUX) || defined (HPUX) || \
    defined (CONVEXOS) || defined (MACH) || defined (AUX) || defined (SGI) || \
    defined (DGUX) 
	endmntent(fp);
# else
# if defined (SVR4) || defined (SOLARIS) || defined (SCO)
	fclose (fp);
#  else
#  ifdef AIX
	free (vmount_buf);
#   else
#   ifdef OSF1
	free (mnt_info);
#   endif /* OSF1 */
#  endif /* AIX */
# endif /* SVR4 || SOLARIS */
#endif /* SUNOS || LINUX || HPUX || CONVEXOS || MACH || DYNIX || AUX || SGI || 
	  DGUX */

	if (NFS==MAXFS)
		{
		printf ("Maximum number of file systems (%d) exceeded...",
			MAXFS);
		printf ("Ignoring Rest\n");
		}
	/* *** did we get any valid file sytems back *** */
	if (NFS < 1)
		{
		if (fs_returned > 0)
			fprintf (stderr, 
				"Mount returned %d file systems\nAfter \
processing command line none are left ... exiting\n", fs_returned);
		else
			fprintf (stderr, 
				"Mount returned no valid file systems ... \
Exiting\n");
		exit (1);
		}
			
	if (sort)
		/* *** perform simple selection sort *** */
		for (x=0; x<NFS; x++)
			{
			min=x;
			for (y=x+1; y<NFS; y++)
				if ((strcmp (strinfo[idx[min]].fs_name, 
					     strinfo[idx[y]].fs_name)) > 0)
					min=y;
			if (min != x)
				{
				printf ("switching %d, %d\n", min, x);
				t=idx[min];
				idx[min]=idx[x];
				idx[x]=t;
				}
			}
}



/* *********************************************************************** */
/* ********************** get the file system stats ********************** */
/* *********************************************************************** */
void get_fs_stat()
{
	static time_t	last_mod_time=0;
	int 		i, j, t, x, old_lname=lname, updated=FALSE, shortcut=TRUE;
	double		blocks,
			bfree,
#ifndef SCO
			bavail,
#endif
			bsize,
			orig_blocks;
	struct stat	stat_info;

#if !defined (AIX) && !defined (ULTRIX) && !defined (OSF1) && \
	!defined (FreeBSD) && !defined (BSDI)
	/* *** This does not work under AIX as just about everything  *** */
	/* *** is stored in the ODM datbase. Some *&$%*&*$&% design!  *** */
	/* *** ULTRIX and OSF1 on the other hand seem to keep it all  *** */
	/* ***    in memory. See my comment about the AIX design.     *** */
	/* *** Anyhow, here we check if MOUNT_FILE has been modified. *** */
	/* ***  If not, no file systems have been (dis)mounted and    *** */
	/* ***   we don't have to call get_fs(). This is much cheaper *** */
	/* ***        than calling get_fs() everytime we update.      *** */
	if (!(stat (MOUNT_FILE, &stat_info)))
		{
		if (stat_info.st_mtime > last_mod_time)
			{
			last_mod_time = stat_info.st_mtime;
			b_blocks=0;
			b_bsize=0;
			b_disk=0;
			lname=0;
			updated=TRUE;
			/* *** get mounted file systems *** */
			get_fs ();
			}
		}
	else
		{
		fprintf(stderr,"Can't get stat of %s ... Exiting\n", MOUNT_FILE);
		exit (1);
		}
#else
	/* *** get mounted file systems unconditionally *** */
	/* *** we can't check with stat() to save time *** */
	lname=0;
	updated=TRUE;
	shortcut=FALSE;
	get_fs ();
#endif /* !AIX && !ULTRIX && !OSF1 && !FreeBSD && !BSDI */

	if (!turns)
		{
		updated=TRUE;
		lname=0;
		}

 	/* *** read file system status *** */
	for (i=0; i<NFS; i++)
		{
#if defined (SUNOS) || defined (LINUX) || defined (AIX) || defined (HPUX) || \
    defined (ULTRIX) || defined (CONVEXOS) || defined (MACH) || \
    defined (OSF1) || defined (FreeBSD) || defined (AUX) 
#undef statfs
		t=statfs (FsName, &stats[i]);
# else
# if defined (SVR4) || defined (SOLARIS) || defined (SGI) || defined (DGUX)
		t=statvfs (FsName, &stats[i]);
#  else
#  if defined (DYNIX) || defined (SCO)
		t=statfs (FsName, &stats[i], sizeof(struct statfs), 0);
#  endif /* DYNIX || SCO */
# endif /* SVR4 || SOLARIS || SGI || DGUX */
#endif /* SUNOS || LINUX || AIX || HPUX || ULTRIX || CONVEXOS || MACH || \
          OSF1 || FreeBSD || AUX || BSDI */

	/* *** see if the return code is an error *** */
	if (t == -1)
		{
		fs_perc[i]=NOGOOD;
		fprintf (stderr, "Can't get superblock describing %s ...\n",
			FsName);
		}
	else
		{
#ifdef DEBUG
		printf ("Got status on %s\n", FsName);
#endif

		blocks=stats[i].f_blocks;
		bfree=stats[i].f_bfree;
#ifdef SCO
		bsize=512;
#else
		bsize=stats[i].f_bsize;
#endif
#ifndef SCO
		bavail=stats[i].f_bavail;
#endif

		/* *** find largest file system and block size *** */
		if (blocks > b_blocks)
			b_blocks=blocks;

		if (bsize > b_bsize)
			b_bsize=bsize;

		if (bsize*blocks > b_disk)
			b_disk=bsize*blocks;

		/* *** find largest file system name if we called get_fs *** */
		if (minimize == MNL) 
			{
			int l = XTextWidth(main_win.font_info, FsName, 
				strlen(FsName)+4);

			if (l > lname)
				lname = l;
			}

		/* *** throw out file systems of size 0 *** */
		if (blocks == 0)
			{
			if (verbose && turns && shortcut)
			 printf ("File system %s is of size 0 - ignoring it!\n",
				FsName);
			for (x=i; x<NFS; x++)
				{
				strcpy (strinfo[x].fs_name,
					strinfo[x+1].fs_name);
				strcpy (strinfo[x].dev_name, 
					strinfo[x+1].dev_name);
#ifndef SCO
				strcpy (strinfo[x].mnt_typ, 
					strinfo[x+1].mnt_typ);
#endif /* SCO */
				strcpy (strinfo[x].mnt_opt, 
					strinfo[x+1].mnt_opt);
				stats[x]=stats[x+1];
				}
			i--;
			NFS--;
			}
		else
			{
			/* *** figure out percentage of free blocks *** */
			if (root)
			   {
	   		   if (show_use)
				{
				if (rootdf)
	   				fs_perc[i]=(float) ((blocks-bfree)/(blocks-bfree+bavail));
				else
	   				fs_perc[i]=(float) ((blocks-bfree)/blocks);
#ifdef DEBUG
	   			printf ("A: Total: %f \t Free: %f == %2f%%\n", 
					blocks, bfree, fs_perc[i]);
#endif
				}
	   		   else
				{
				if (rootdf)
	   				fs_perc[i]=(float) (bfree/(blocks-bfree+bavail));
				else
	   				fs_perc[i]=(float) (bfree/blocks);
#ifdef DEBUG
	   			printf ("B: Total: %f \t Free: %f == %2f%%\n", 
					blocks, bfree, fs_perc[i]);
#endif
				}
			   }
#ifndef SCO
			/* *** SCO doesn't know bavail - can't use this *** */
			else
			   {
			   /* *** account for the reserved     *** */
			   /* *** space and decrease the       *** */
			   /* *** number of blocks accordingly *** */
			   orig_blocks=blocks;
			   blocks *= (1-res_space);
	   		   if (show_use)
				{
				/* *** msdos doesn't know reserved space *** */
				if (strstr (strinfo[i].mnt_typ, "msdos"))
					fs_perc[i]=(float)((orig_blocks-bavail)/
						orig_blocks);
				else
					fs_perc[i]=(float) 
						((blocks-bavail)/blocks);
# ifdef DEBUG
	   			printf ("C: Total: %f \t Avail: %f == %.2f%%\n", 
					blocks, bavail, fs_perc[i]);
# endif
				} 
	   		  else
				{
				/* *** msdos doesn't know reserved space *** */
				if (strstr (strinfo[i].mnt_typ, "msdos"))
	   				fs_perc[i]=(float) (bavail/orig_blocks);
				else
	   				fs_perc[i]=(float) (bavail/blocks);
# ifdef DEBUG
	   			printf ("D: Total: %f \t Avail: %f == %.2f%%\n", 
					blocks, bavail, fs_perc[i]);
# endif
				}
			   }
#endif /* !SCO */
			}
		}
	}
	/* *** No file systems left *** */
	if (NFS < 1)
		{
		fprintf(stderr,"No File systems left ... Exiting\n");
		exit (0);
		}

	/* *** Update bar levels *** */
	for (i=0; i<NFS; i++) 
		{
		for (j=3; j>=0; j--) 
			{
			if (warnvals[j] > -1 && fs_perc[i] >= warnvals[j]) 
				{
#ifdef DEBUG
				printf("LEVEL: fs_perc[%d] = %f\n",i,fs_perc[i]);
				printf("LEVEL: old level   = %d\n",fs_level[i]);
				printf("LEVEL: new level   = %d\n",j);
#endif
                   		if (fs_level[i] < j) 
					{
#ifdef DEBUG
					printf("LEVEL: warning set for %d\n",i);
#endif
					fs_warn[i] = TRUE;
					}
				fs_level[i] = j;
				break;
                		}
			}
		}


	/* *** calculate the new main window width *** */
	if ((!minimize || minimize == MNL) && updated && old_lname != lname) 
		{
		main_win.width = OFF_X + OFF_X + lname + percent_width;

		if (main_win.width < MIN_WIN_X)
			main_win.width=MIN_WIN_X;
		if (turns)
			{
			XResizeWindow (mydisplay, main_win.win, main_win.width,
				main_win.height);
			fix_menu_pos (main_win.width);
			}
		for (i=0; i<NFS; i++)
			{
			fs_win[i].width=main_win.width-OFF_X*2;
			/* *** don't do this the first time *** */
			if (turns)
				fix_fs_win_width (i);
			if (turns)
				{
				XResizeWindow (mydisplay, fs_win[i].win, 
					fs_win[i].width, fs_win[i].height);
				if (fs_perc[i]!=NOGOOD)
					redraw_fs_win (i);
				}
			}
		}
	turns++;
}




/* ***************************************************************** */
/* ****************** Process the program arguments **************** */
/* ***************************************************************** */
void process_databases (argc, argv, commandlineDB)
int argc;
char **argv;
XrmDatabase commandlineDB;
{
	char name[MAXPATHLEN];
	char msg[255];
	int i;

	strcpy (msg, "");
	/* *** Load the local app-defaults file. *** */
	if (getenv ("XAPPLRESDIR"))
		{
		strcpy(name, getenv ("XAPPLRESDIR"));
		strcat(name, "/");
		strcat(name, CLASS_NAME);
		resourceDB = XrmGetFileDatabase(name);
		if (resourceDB)
			sprintf (msg, 
				"Read Resource definitions in %s ...", name);
		}
		

	/* *** check if we really found something *** */
	/* *** if not, check in APP_DEFAULTS_DIR *** */
	if (!resourceDB) 
		{
		strcpy(name, APP_DEFAULTS_DIR);
		strcat(name, "/");
		strcat(name, CLASS_NAME);
		resourceDB = XrmGetFileDatabase(name);
		if (resourceDB)
			sprintf(msg, "Read Resource definitions in %s ...",
				name);
		}

	/* *** Load in any definitions supplied in the X server. *** */
	if (XResourceManagerString(mydisplay) != NULL)
		XrmMergeDatabases(XrmGetStringDatabase(XResourceManagerString
			(mydisplay)), &resourceDB);

	/* *** Merge in the command line arguments. *** */
	XrmMergeDatabases(commandlineDB, &resourceDB);

	/* *** See if the help flag was set. *** */
	if (getBoolResource(resourceDB, catlist(myname, ".help", (char*)NULL),
		"Xfsm.Help", False))
			do_help();

	/* *** See if the verbose flag was set. *** */
	if ((verbose = getBoolResource(resourceDB,
		catlist(myname, ".verbose", (char*) NULL), 
		"Xfsm.Verbose", False))) 
		{
		PRINT_COPYRIGHT;
		puts ("-v flag caught - verbose mode enabled...");
		if (resourceDB && strlen (msg))
			puts (msg);
		}

	/* *** this one has to go befor the -fg evaluation   *** */
	/* *** as otherwise the default supplied to the      *** */
	/* *** evaluation function will override our setting *** */
	if (!(gray = getBoolResource(resourceDB,
		catlist(myname, ".gray", (char*) NULL), "Xfsm.Gray", True)))
		if (verbose) 
			puts("-b flag caught - will draw bars black.");

	/* *** assign foreground and backgound colors *** */
 	fg = getColorResource(resourceDB, catlist(myname, 
		".foreground", (char*) NULL), "Xfsm.Foreground",
		BlackPixel (mydisplay, DefaultScreen (mydisplay))); 
	if (fg != BlackPixel (mydisplay, DefaultScreen (mydisplay)))
		{
		if (verbose)
			printf ("-fg flag caught - foreground set and \
gray fill disabled.\n");
		gray=FALSE;
		}

	bg = getColorResource(resourceDB, catlist(myname, 
		".background", (char*) NULL), "Xfsm.Background",
		WhitePixel (mydisplay, DefaultScreen (mydisplay)));
	if (bg != WhitePixel (mydisplay, DefaultScreen (mydisplay)))
		if (verbose) 
			printf ("-bg flag caught - background set\n");

#ifndef SCO
	if ((root = getBoolResource(resourceDB, 
		catlist(myname, ".root", (char*) NULL), "Xfsm.Root", False))) 
		{
		if (verbose)
			puts("-r flag caught - will give statistics for root.");
		}

	if ((rootdf = getBoolResource(resourceDB, 
		catlist(myname, ".rootdf", (char*) NULL), "Xfsm.Rootdf", False))) 
		{
		if (verbose)
			puts("-rootdf flag caught - will calculate df % values with root mode.");
		}
#endif

	if ((minimize = getIntResource(resourceDB,
		catlist(myname, ".minimize", (char*) NULL), 
		"Xfsm.Minimize", False)))
		{
		if (verbose)
			{
			if (minimize == MNL)
				puts("-mnl flag caught - will minimize \
window with regard to FS name length.");
			else
				puts("-m flag caught - will minimize \
window size.");
			}
		}

	if ((menu_border = getBoolResource(resourceDB,
		catlist(myname, ".menuborder", (char*)NULL),
		"Xfsm.Menuborder", False)))
		if (verbose)
			puts("-mb flag caught - will draw menu border.");

	if ((fs_border = getBoolResource(resourceDB,
		catlist(myname, ".fs_border", (char*)NULL),
		"Xfsm.Fs_border", True)));
	else
		if (verbose)
			puts("-fsb flag caught - will not draw file system \
border.");

	if (!(percent = getBoolResource(resourceDB,
		catlist(myname, ".percent", (char*) NULL),
		"Xfsm.Percent", True)))
		{
		available=FALSE;
		if (verbose) 
			puts("-p flag caught - will turn percent display off.");
		}

	if ((available = getBoolResource(resourceDB,
		catlist(myname, ".available", (char*) NULL),
		"Xfsm.Available", False))) 
			{
			percent=FALSE;
			if (verbose)
				puts("-A flag caught - will show available \
space in MBs");
			}

	if ((override_ignore = getBoolResource(resourceDB,
		catlist(myname, ".override_ignore", (char*) NULL), 
		"Xfsm.OverrideIgnore", False)))
		if (verbose)
			puts("-oi flag caught - will keep file systems \
marked 'ignore'.");

	if ((absolute = getBoolResource(resourceDB,
		catlist(myname, ".absolute", (char*) NULL), 
		"Xfsm.Absolute", False)))
		if (verbose)
			puts("-a flag caught - will display sizes relative \
to absolute FS size.");

	if (!(show_use = getBoolResource(resourceDB,
		catlist(myname, ".used", (char*) NULL), "Xfsm.Used", True)))
		if (verbose)
			puts("-f flag caught - will show space free rather \
than space used.");

	if ((show_biggest = getBoolResource(resourceDB,
		catlist(myname, ".showbiggest", (char*) NULL), 
		"Xfsm.ShowBiggest", False)))
		if (verbose)
			puts("-sb flag caught - will show biggest file \
system size.");

	if ((bell = getBoolResource(resourceDB,
		catlist(myname, ".bell", (char*) NULL), "Xfsm.Bell", False)))
		if (verbose)
			puts("-e flag caught - will extend warning to \
include a beep.");

	if ((sort = getBoolResource(resourceDB,
		catlist(myname, ".sort", (char*) NULL), 
		"Xfsm.Sort", False))) 
		if (verbose)
			puts ("-sort flag caught - will sort by name ...");

	if ((detail_share_color = getBoolResource(resourceDB,
		catlist(myname, ".detailWin.share", (char*) NULL),
		"Xfsm.detailWin.Share", False)))
		if (verbose)
		puts ("Detail window will have the same color as the \
file system it is displaying.");

	
	if ((res_space = (float) getIntResource(resourceDB,
		catlist(myname, ".reserved_space", (char*)NULL),
		"Xfsm.Reserved_space", RES_SPACE_DFLT)) != RES_SPACE_DFLT) 
		{
		if (res_space < 0 || res_space > 100)
			{
			printf("Illegal value specified for resreved space ... \
resetting to default (%d%%)\n", RES_SPACE_DFLT);
			res_space=10;
			}
		else
			if (verbose)
				printf ("-rs flag caught - setting reserved \
space level to %f %%.\n", res_space);
		}
	res_space /= 100.0;

	if ((popup = getBoolResource(resourceDB,
                catlist(myname, ".popup", (char*) NULL),
                "Xfsm.Popup", False)))
                if (verbose)
			printf ("-pu flag caught - setting popup\n");

	if ((warn_val = (float) getIntResource(resourceDB,
		catlist(myname, ".warnval", (char*)NULL),
		"Xfsm.Warnval", 0)) != 0.0) 
		{
		if (warn_val < 1.0 || warn_val > 99.0) 
			{
			puts("Illegal value supplied for warning threshold ... \
resetting.");
			warn_val = 0.0;
			} 
		else
			{
			if (verbose)
				printf ("-w flag caught - setting warning \
threshold to %f %%.\n", warn_val);
			warn_val /= 100.0;
			}
		}
	if ((warnvals[1] = (float) getIntResource(resourceDB,
		catlist(myname, ".warn1val", (char*)NULL),
		"Xfsm.Warn1val", -1)) != -1) 
		{
		if (warnvals[1] < 0 || warnvals[1] > 100)
			{
			fprintf (stderr, 
				"Illegal warning level 1 (%f) specifed ...\
exiting\n", warnvals[1]);
			exit (1);
			}
		else
			{
			if (verbose) 
				printf ("-wl1 flag caught and gray fill disabled \n\t- setting warning \
level 1 to %f %%.\n", warnvals[1]);
			gray=FALSE;
			warnvals[1] /= 100;
			}
		}
	if ((warnvals[2] = (float) getIntResource(resourceDB,
		catlist(myname, ".warn2val", (char*)NULL),
		"Xfsm.Warn2val", -1)) != -1) 
		{
		if (warnvals[2] <= warnvals[1] || warnvals[2] > 100)
			{
			fprintf (stderr, 
				"Illegal warning level 2 (%f) specifed ...\
exiting\n", warnvals[2]);
			exit (1);
			}
		else
			{
			if (verbose) 
				printf ("-wl2 flag caught and gray fill disabled \n\t- setting warning \
level 2 to %f %%.\n", warnvals[2]);
			gray=FALSE;
			warnvals[2] /= 100;
			}
		}
	if ((warnvals[3] = (float) getIntResource(resourceDB,
		catlist(myname, ".warn3val", (char*)NULL),
		"Xfsm.Warn3val", -1)) != -1) 
		{
		if (warnvals[3] <= warnvals[2] || warnvals[3] > 100)
			{
			fprintf (stderr, 
				"Illegal warning level 3 (%f) specifed ...\
exiting\n", warnvals[3]);
			exit (1);
			}
		else
			{
			if (verbose) 
				printf ("-wl3 flag caught and gray fill disabled \n\t- setting warning \
level 3 to %f %%.\n", warnvals[3]);
			gray=FALSE;
			warnvals[3] /= 100;
			}
		}

	 if ((warncols[0] = getColorResource(resourceDB, catlist(myname, 
		".warn0col", (char*)NULL), "Xfsm.Warn0col", fg)) != fg) 
		{
		if (verbose)
			printf ("-wl0c flag caught & gray fill disabled - default color \
set to %d ...\n", (int)warncols[0]);
		gray=FALSE;
                }

	if ((warncols[1] = getColorResource(resourceDB, catlist(myname, 
		".warn1col", (char*)NULL), "Xfsm.Warn1col", warncols[0])) != warncols[0]) 
		{
		if (verbose)
			printf ("-wl1c flag caught - warning level 1 color \
set to %d ...\n", (int)warncols[1]);
		}
	if ((warncols[2] = getColorResource(resourceDB, catlist(myname, 
		".warn2col",(char*)NULL),"Xfsm.Warn2col",warncols[1]))!=warncols[1]) 
		{
		if (verbose)
			printf ("-wl2c flag caught - warning level 2 color \
set to %d ...\n", (int)warncols[2]);
		}
	if ((warncols[3] = getColorResource(resourceDB, catlist(myname, 
		".warn3col",(char*)NULL),"Xfsm.Warn3col",warncols[2]))!=warncols[2]) 
		{
		if (verbose)
			printf ("-wl3c flag caught - warning level 3 color \
set to %d ...\n", (int)warncols[3]);
		}

	if ((upd_interval = getIntResource(resourceDB,
		catlist(myname, ".updInterval", (char*)NULL),
		"Xfsm.UpdInterval", 60)) != 60) 
		{
		if (upd_interval < 1) 
			{
			fprintf (stderr, "Supplied interval (%d) too small \
(minimum = 1).\n", upd_interval);
			exit (1);
			}
		if (verbose)
			printf ("-i flag caught - update interval changed \
to %d sec.\n", upd_interval);
		}

	for (i = 1; i < argc; i++)
#ifndef SCO
	   if (!strcmp (argv[i], "-ot"))
		{
		if (!only_t)
			{
			if (ignore_t_count)
				{
				fprintf (stderr, "-it and -ot conflict ... \
will ignore any -it settings\n");
				ignore_t_count=0;
				}
			strcpy (only_type, argv[i+1]);
			only_t=TRUE;
			i++;
			}
		else
			fprintf (stderr, 
				"-ot flag already set ... will ignore %s\n",
				argv[i+1]);
		}
	   else
#endif /* !SCO */
	   if (!strcmp (argv[i], "-d"))
		/* *** does it begin with an "-" *** */
		while (i < (argc - 1) && argv[i + 1][0] != '-') 
			{
			if (ignore_n_count < MAXFS) 
				{
				if (verbose)
				    printf ("Will ignore %s ...\n", argv[i+1]);
				strcpy (ignore_names[ignore_n_count++], 
					argv[i + 1]);
				} 
			else
				fprintf (stderr,
					"Exceeded number of ignore file \
systems ... %s ignored.\n", argv[i+1]);
			i++;
			}
	   else 
 	   if (!strcmp (argv[i], "-D"))
		/* *** does it begin with an "-" *** */
		while (i < (argc - 1) && argv[i + 1][0] != '-') 
			{
			/* *** check all file systems for arg *** */
			if (ignore_p_count < MAXFS) 
				{
				if (verbose)
					printf ("Will ignore patterns \
matching %s ...\n", argv[i + 1]);
				strcpy (ignore_pattern[ignore_p_count++], 
					argv[i + 1]);
				} 
			else
				fprintf (stderr,
					"Exceeded number of ignore patterns \
... %s ignored\n", argv[i + 1]);
			i++;
			} 
	else
	if (!strcmp (argv[i], "-s"))
		/* *** does it begin with an "-" *** */
		while (i < (argc - 1) && argv[i + 1][0] != '-')
			{
			if (select_n_count < MAXFS)
				{
				if (verbose)
				    printf ("Will select %s ...\n", argv[i+1]);
				strcpy (select_names[select_n_count++],
					argv[i + 1]);
				}
			else
				fprintf (stderr,
					"Exceeded number of selected file \
systems ... %s ignored.\n", argv[i+1]);
			i++;
			}
	else
	if (!strcmp (argv[i], "-S"))
		/* *** does it begin with an "-" *** */
		while (i < (argc - 1) && argv[i + 1][0] != '-')
			{
			/* *** check all file systems for arg *** */
			if (select_p_count < MAXFS)
				{
				if (verbose)
					printf ("Will select patterns \
matching %s ...\n", argv[i + 1]);
				strcpy (select_pattern[select_p_count++],
					argv[i + 1]);
				}
			else
				fprintf (stderr,
					"Exceeded number of select patterns \
... %s ignored\n", argv[i + 1]);
			i++;
			}
#ifndef SCO
	else
	if (!strcmp (argv[i], "-it"))
		{
		/* *** does it begin with an "-" *** */
		while (i < (argc - 1) && argv[i + 1][0] != '-')
			{
			if (only_t)
				{
				fprintf (stderr, "-it and -ot conflict ... \
will ignore any -it settings\n");
				break;
				}
			/* *** check all file systems for arg *** */
			if (ignore_t_count < MAXFS)
				{
				if (verbose)
					printf ("Will ignore types %s ...\n", 
						argv[i + 1]);
				strcpy (ignore_type[ignore_t_count++],
					argv[i + 1]);
				}
			else
				fprintf (stderr,
					"Exceeded number of ignore patterns \
... %s ignored\n", argv[i + 1]);
			i++;
			}
		}
#endif /* !SCO */

	   else
	   printf ("Argument %s not recognized as an option ... ignored\n",
		argv[i]);

}


void do_help ()
{
	printf ("\n\
                        X   X  FFFFF  SSSSS  M     M\n\
                         X X   F      S      M M M M\n\
                          X    FFFFF  SSSSS  M  M  M\n\
                         X X   F          S  M     M\n\
                        X   X  F      SSSSS  M     M\n\
\n\
displays a list of bar graphs for the file systems of the host you are on.\n\
Clicking on a file system gives you detailed information - clicking in the\n\
detail window or clicking in it again closes the detail window. Use %c or the\n\
right mouse button to toggle between absolute and relative display modes.\n\
The following options are supported:\n",
TOGGLE_KEY);

printf ("\n\
        +rv                     reverse video (use to override xrdb entry)\n\
        +synchronous            syncronous mode (use to override xrdb entry)\n\
        -?                      help\n\
	-A			show available space in MBs\n\
        -a                      absolute display mode\n\
        -background <arg>       backgound color \n\
        -b                      black bars (disable gray fill)\n\
        -bg <arg>               same as -background\n\
        -bordercolor <arg>      border color\n\
	-d <arg1 ... argn>	ignore these file systems\n\
	-D <arg1 ... argn>	ignore file systems matching these patterns\n\
	-detailgeometry         Geometry of detail window. Only X and Y are\n\
					honored\n\
	-e 			extend warning to include bell\n\
	-f			show free space rather than space used\n\
	-fg			same as -foreground\n\
        -font <arg>             font\n\
        -foreground <arg>       forground color (also file system bar color)\n\
        -geometry <arg>         geometry (will override extreme window sizes\n\
                                        to apply reasonable settings)\n\
        -help                   help\n\
        -i <arg>                interval at which stats are updated\n\
					default = 60s\n\
	-iconic                 iconic\n");
#ifndef SCO
printf ("\
	-it <arg1 ... argn>	ignore file systems of this type\n");
#endif /* !SCO */
printf ("\
        -m                      minimize window size\n\
        -mb                     draw menu borders\n\
        -mnl                    minimize window size so that the longest file\n\
                                        system name fits\n\
        -name <arg>             run xfsm under this name\n");
#ifndef SCO
printf ("\
	-ot <arg>		show only file systems of this type\n");
#endif /* !SCO */
printf ("\
	-oi			-oi (override ignore) to keep file systems\n\
					which are marked 'ignore'\n\
	-p                      don't display percentages\n");
#ifndef SCO
printf ("\
        -r                      display space with respect to root\n\
	-rootdf			calculate df %% when running in root (-r) mode\n");
#endif /* !SCO */
printf ("\
	-rs <arg>		specify the amount of space reserved for root\n\
					default = %d%% \n\
        -rv                     reverse video\n\
	-s <arg1 ... argn>	select only these file systems\n\
	-S <arg1 ... argn>	select only file systems matching these patterns\n\
	-sb			show biggest file system size in lower right\n\
	-sort			sort file systems according to name\n\
        -synchronous            synchronous mode\n\
	-t 			tile to show in main window\n\
        -v                      verbose\n\
        -w <arg>                display warning pix when usage reaches <arg>%%\n\
	-wl0			default color for file systems\n\
	-wl1			first warning level\n\
	-wl1c			first warning level color\n\
	-wl2			second warning level\n\
	-wl2c			second warning level color\n\
	-wl3			third warning level\n\
	-wl3c			third warning level color\n\
        -xrm                    set an entry in the resource database for\n\
                                        this execution only\n\
        help                    get this description\n", RES_SPACE_DFLT);


	PRINT_KNOWN_BUGS;
	PRINT_COPYRIGHT;
	exit (0);
}



syntax highlighted by Code2HTML, v. 0.9.1