/*
 * ddev.c - Darwin device support functions for /dev/kmem-based lsof
 */


/*
 * Copyright 1994 Purdue Research Foundation, West Lafayette, Indiana
 * 47907.  All rights reserved.
 *
 * Written by Victor A. Abell
 *
 * This software is not subject to any license of the American Telephone
 * and Telegraph Company or the Regents of the University of California.
 *
 * Permission is granted to anyone to use this software for any purpose on
 * any computer system, and to alter it and redistribute it freely, subject
 * to the following restrictions:
 *
 * 1. Neither the authors nor Purdue University are responsible for any
 *    consequences of the use of this software.
 *
 * 2. The origin of this software must not be misrepresented, either by
 *    explicit claim or by omission.  Credit to the authors and Purdue
 *    University must appear in documentation and sources.
 *
 * 3. Altered versions must be plainly marked as such, and must not be
 *    misrepresented as being the original software.
 *
 * 4. This notice may not be removed or altered.
 */

#ifndef lint
static char copyright[] =
"@(#) Copyright 1994 Purdue Research Foundation.\nAll rights reserved.\n";
static char *rcsid = "$Id: ddev.c,v 1.5 2006/03/27 23:24:50 abe Exp $";
#endif


#include "lsof.h"


/*
 * Local definitions
 */

#if	defined(DVCH_DEVPATH)
#define	DDEV_DEVPATH	DVCH_DEVPATH
#else	/* !defined(DVCH_DEVPATH) */
#define	DDEV_DEVPATH	"/dev"
#endif	/* defined(DVCH_DEVPATH) */

#if	defined(USE_STAT)
#define	STATFN	stat
#else	/* !defined(USE_STAT) */
#define	STATFN	lstat
#endif	/* defined(USE_STAT) */


/*
 * Local static variables.
 */

static dev_t *ADev = (dev_t *) NULL;	/* device numbers besides DevDev found
					 * inside DDEV_DEVPATH */
static int ADevA = 0;			/* entries allocated to ADev[] */
static int ADevU = 0;			/* entries used in ADev[] */


/*
 * Local function prototypes
 */

_PROTOTYPE(static int rmdupdev,(struct l_dev ***dp, int n, char *nm));
_PROTOTYPE(static void saveADev,(struct stat *s));


#if	defined(HASSPECDEVD)
/*
 * HASSPECDEVD() -- process stat(2) result to see if the device number is
 *		    inside DDEV_DEVPATH "/"
 *
 * exit: s->st_dev changed to DevDev, as required
 */

void
HASSPECDEVD(p, s)
	char *p;			/* file path */
	struct stat *s;			/* stat(2) result for file */
{
	int i;

	switch (s->st_mode & S_IFMT) {
	case S_IFCHR:
	case S_IFBLK:
	    if (s->st_dev == DevDev)
		return;
	    (void) readdev(0);
	    if (!ADev)
		return;
	    for (i = 0; i < ADevU; i++) {
		if (s->st_dev == ADev[i]) {
		    s->st_dev = DevDev;
		    return;
		}
	    }
	}
}
#endif	/* defined(HASSPECDEVD) */


/*
 * readdev() - read device names, modes and types
 */

void
readdev(skip)
	int skip;			/* skip device cache read if 1 --
					 * ignored since device cache not
					 * used */
{
	DIR *dfp;
	int dnamlen;
	struct dirent *dp;
	char *fp = (char *)NULL;
	char *path = (char *)NULL;
	int i = 0;
	int j = 0;
	MALLOC_S pl, sz;
	struct stat sb;
/*
 * Read device names but once.
 */
	if (Sdev)
	    return;
/*
 * Prepare to scan DDEV_DEVPATH.
 */
	Dstkn = Dstkx = 0;
	Dstk = (char **)NULL;
	(void) stkdir(DDEV_DEVPATH);
/*
 * Unstack the next directory.
 */
	while (--Dstkx >= 0) {
	    if (!(dfp = OpenDir(Dstk[Dstkx]))) {

# if	defined(WARNDEVACCESS)
		if (!Fwarn) {
		    (void) fprintf(stderr, "%s: WARNING: can't open: ", Pn);
		    safestrprt(Dstk[Dstkx], stderr, 1);
		}
# endif	/* defined(WARNDEVACCESS) */

		(void) free((FREE_P *)Dstk[Dstkx]);
		Dstk[Dstkx] = (char *)NULL;
		continue;
	    }
	    if (path) {
		(void) free((FREE_P *)path);
		path = (char *)NULL;
	    }
	    if (!(path = mkstrcat(Dstk[Dstkx], -1, "/", 1, (char *)NULL, -1,
				  &pl)))
	    {
		(void) fprintf(stderr, "%s: no space for: ", Pn);
		safestrprt(Dstk[Dstkx], stderr, 1);
		Exit(1);
	    }
	    (void) free((FREE_P *)Dstk[Dstkx]);
	    Dstk[Dstkx] = (char *)NULL;
	/*
	 * Scan the directory.
	 */
	    for (dp = ReadDir(dfp); dp; dp = ReadDir(dfp)) {
		if (dp->d_ino == 0 || dp->d_name[0] == '.')
		    continue;
	    /*
	     * Form the full path name and get its status.
	     */
		dnamlen = (int)dp->d_namlen;
		if (fp) {
		    (void) free((FREE_P *)fp);
		    fp = (char *)NULL;
		}
		if (!(fp = mkstrcat(path, pl, dp->d_name, dnamlen,
				    (char *)NULL, -1, (MALLOC_S *)NULL)))
		{
		    (void) fprintf(stderr, "%s: no space for: ", Pn);
		    safestrprt(path, stderr, 0);
		    safestrprtn(dp->d_name, dnamlen, stderr, 1);
		    Exit(1);
		}
		if (STATFN(fp, &sb) != 0) {
		    if (errno == ENOENT)	/* a sym link to nowhere? */
			continue;

# if	defined(WARNDEVACCESS)
		    if (!Fwarn) {
			int errno_save = errno;

			(void) fprintf(stderr, "%s: can't stat ", Pn);
			safestrprt(fp, stderr, 0);
			(void) fprintf(stderr, ": %s\n", strerror(errno_save));
		    }
# endif	/* defined(WARNDEVACCESS) */

		    continue;
		}
	    /*
	     * If it's a subdirectory, stack its name for later
	     * processing.
	     */
		if ((sb.st_mode & S_IFMT) == S_IFDIR) {

		/*
		 * Skip /dev/fd.
		 */
		    if (strcmp(fp, "/dev/fd"))
			(void) stkdir(fp);
		    continue;
		}
		if ((sb.st_mode & S_IFMT) == S_IFLNK) {

		/*
		 * Ignore symbolic links.
		 */
		    continue;
		}
		if ((sb.st_mode & S_IFMT) == S_IFCHR) {

		/*
		 * Save character device information in Devtp[].
		 */
		    if (i >= Ndev) {
			Ndev += DEVINCR;
			if (!Devtp)
			    Devtp = (struct l_dev *)malloc(
				    (MALLOC_S)(sizeof(struct l_dev)*Ndev));
			else
			    Devtp = (struct l_dev *)realloc((MALLOC_P *)Devtp,
				    (MALLOC_S)(sizeof(struct l_dev)*Ndev));
			if (!Devtp) {
			    (void) fprintf(stderr,
				"%s: no space for character device\n", Pn);
			    Exit(1);
			}
		    }
		    Devtp[i].rdev = sb.st_rdev;
		    Devtp[i].inode = (INODETYPE)sb.st_ino;
		    if (!(Devtp[i].name = mkstrcpy(fp, (MALLOC_S *)NULL))) {
			(void) fprintf(stderr,
			    "%s: no space for device name: ", Pn);
			safestrprt(fp, stderr, 1);
			Exit(1);
		    }
		    Devtp[i].v = 0;
		    i++;
		}

# if	defined(HASBLKDEV)
		if ((sb.st_mode & S_IFMT) == S_IFBLK) {

		/*
		 * Save block device information in BDevtp[].
		 */
		    if (j >= BNdev) {
			BNdev += DEVINCR;
			if (!BDevtp)
			    BDevtp = (struct l_dev *)malloc(
				     (MALLOC_S)(sizeof(struct l_dev)*BNdev));
			else
			    BDevtp = (struct l_dev *)realloc((MALLOC_P *)BDevtp,
				     (MALLOC_S)(sizeof(struct l_dev)*BNdev));
			if (!BDevtp) {
			    (void) fprintf(stderr,
				"%s: no space for block device\n", Pn);
			    Exit(1);
			}
		    }
		    BDevtp[j].name = fp;
		    fp = (char *)NULL;
		    BDevtp[j].inode = (INODETYPE)sb.st_ino;
		    BDevtp[j].rdev = sb.st_rdev;
		    BDevtp[j].v = 0;
		    j++;
		}
# endif	/* defined(HASBLKDEV) */

	    /*
	     * Save a possible new st_dev number within DDEV_DEVPATH.
	     */
		if (sb.st_dev != DevDev)
		    (void) saveADev(&sb);
	    }
	    (void) CloseDir(dfp);
	}
/*
 * Free any unneeded space that was allocated.
 */
	if (ADev && (ADevU < ADevA)) {

	/*
	 * Reduce space allocated to additional DDEV_DEVPATH device numbers.
	 */
	    if (!ADevU) {

	    /*
	     * If no space was used, free the entire allocation.
	     */
		(void) free((FREE_P *)ADev);
		ADev = (dev_t *)NULL;
		ADevA = 0;
	    } else {

	    /*
	     * Reduce the allocation to what was used.
	     */
		sz = (MALLOC_S)(ADevU * sizeof(dev_t));
		if (!(ADev = (dev_t *)realloc((MALLOC_P *)ADev, sz))) {
		    (void) fprintf(stderr, "%s: can't reduce ADev[]\n", Pn);
		    Exit(1);
		}
	    }
	}
	if (!Dstk) {
	    (void) free((FREE_P *)Dstk);
	    Dstk = (char **)NULL;
	}
	if (fp)
	    (void) free((FREE_P *)fp);
	if (path)
	    (void) free((FREE_P *)path);

# if	defined(HASBLKDEV)
/*
 * Reduce the BDevtp[] (optional) and Devtp[] tables to their minimum
 * sizes; allocate and build sort pointer lists; and sort the tables by
 * device number.
 */
	if (BNdev) {
	    if (BNdev > j) {
		BNdev = j;
		BDevtp = (struct l_dev *)realloc((MALLOC_P *)BDevtp,
			 (MALLOC_S)(sizeof(struct l_dev) * BNdev));
	    }
	    if (!(BSdev = (struct l_dev **)malloc(
			  (MALLOC_S)(sizeof(struct l_dev *) * BNdev))))
	    {
		(void) fprintf(stderr,
		    "%s: no space for block device sort pointers\n", Pn);
		Exit(1);
	    }
	    for (j = 0; j < BNdev; j++) {
		BSdev[j] = &BDevtp[j];
	    }
	    (void) qsort((QSORT_P *)BSdev, (size_t)BNdev,
		(size_t)sizeof(struct l_dev *), compdev);
	    BNdev = rmdupdev(&BSdev, BNdev, "block");
	}
	
#  if	!defined(NOWARNBLKDEV)
	else {
	    if (!Fwarn)
		(void) fprintf(stderr,
		    "%s: WARNING: no block devices found\n", Pn);
	}
#  endif	/* !defined(NOWARNBLKDEV) */
# endif	/* defined(HASBLKDEV) */

	if (Ndev) {
	    if (Ndev > i) {
		Ndev = i;
		Devtp = (struct l_dev *)realloc((MALLOC_P *)Devtp,
			(MALLOC_S)(sizeof(struct l_dev) * Ndev));
	    }
	    if (!(Sdev = (struct l_dev **)malloc(
			 (MALLOC_S)(sizeof(struct l_dev *) * Ndev))))
	    {
		(void) fprintf(stderr,
		    "%s: no space for character device sort pointers\n", Pn);
		Exit(1);
	    }
	    for (i = 0; i < Ndev; i++) {
		Sdev[i] = &Devtp[i];
	    }
	    (void) qsort((QSORT_P *)Sdev, (size_t)Ndev,
		(size_t)sizeof(struct l_dev *), compdev);
	    Ndev = rmdupdev(&Sdev, Ndev, "char");
	} else {
	    (void) fprintf(stderr, "%s: no character devices found\n", Pn);
	    Exit(1);
	}
}


/*
 * rmdupdev() - remove duplicate (major/minor/inode) devices
 */

static int
rmdupdev(dp, n, nm)
	struct l_dev ***dp;	/* device table pointers address */
	int n;			/* number of pointers */
	char *nm;		/* device table name for error message */
{
	int i, j, k;
	struct l_dev **p;

	for (i = j = 0, p = *dp; i < n ;) {
	    for (k = i + 1; k < n; k++) {
		if (p[i]->rdev != p[k]->rdev || p[i]->inode != p[k]->inode)
		    break;
	    }
	    if (i != j)
		p[j] = p[i];
	    j++;
	    i = k;
	}
	if (n == j)
	    return(n);
	if (!(*dp = (struct l_dev **)realloc((MALLOC_P *)*dp,
		    (MALLOC_S)(j * sizeof(struct l_dev *)))))
	{
	    (void) fprintf(stderr, "%s: can't realloc %s device pointers\n",
		Pn, nm);
	    Exit(1);
	}
	return(j);
}


/*
 * saveADev() - save additional device number appearing inside DDEV_DEVPATH
 */

static void
saveADev(s)
	struct stat *s;			/* stat(2) buffer for file */
{
	int i;
	MALLOC_S sz;
/*
 * Process VCHR files.
 *
 * Optionally process VBLK files.
 */

#if	defined(HASBLKDEV)
	if (((s->st_mode & S_IFMT) != S_IFBLK)
	&&  ((s->st_mode & S_IFMT) != S_IFCHR))
#else	/* !defined(HASBLKDEV) */
	if ((s->st_mode & S_IFCHR) != S_IFCHR)
#endif	/* defined(HASBLKDEV) */

		return;
/*
 * See if this is a new VBLK or VCHR st_dev value for ADev[].
 */
	for (i = 0; i < ADevU; i++) {
	    if (s->st_dev == ADev[i])
		return;
	}
/*
 * This is a new device number to add to ADev[].
 */
	if (ADevU >= ADevA) {
	    ADevA += 16;
	    sz = (MALLOC_S)(ADevA * sizeof(dev_t));
	    if (ADev)
		ADev = (dev_t *)realloc((MALLOC_P *)ADev, sz);
	    else
		ADev = (dev_t *)malloc(sz);
	    if (!ADev) {
		(void) fprintf(stderr, "%s: no space for ADev[]\n", Pn);
		Exit(1);
	    }
	}
	ADev[ADevU++] = s->st_dev;
}
