/*
 * dmnt.c -- Linux mount support functions for /proc-based lsof
 */


/*
 * Copyright 1997 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 1997 Purdue Research Foundation.\nAll rights reserved.\n";
static char *rcsid = "$Id: dmnt.c,v 1.18 2011/09/07 19:07:45 abe Exp $";
#endif


#include "lsof.h"


/*
 * Local definitions
 */

#if	defined(HASMNTSUP)
#define	HASHMNT	128			/* mount supplement hash bucket count
					 * !!!MUST BE A POWER OF 2!!! */
#endif	/* defined(HASMNTSUP) */


/*
 * Local function prototypes
 */

_PROTOTYPE(static char *cvtoe,(char *os));

#if	defined(HASMNTSUP)
_PROTOTYPE(static int getmntdev,(char *dn, struct stat *s, int *ss));
_PROTOTYPE(static int hash_mnt,(char *dn));
#endif	/* defined(HASMNTSUP) */


/*
 * Local structure definitions.
 */

#if	defined(HASMNTSUP)
typedef struct mntsup {
	char *dn;			/* directory name */
	dev_t dev;			/* device number */
	int ln;				/* line on which defined */
	struct mntsup *next;		/* next entry */
} mntsup_t;
#endif	/* defined(HASMNTSUP) */


/*
 * Local static definitions
 */

static struct mounts *Lmi = (struct mounts *)NULL;	/* local mount info */
static int Lmist = 0;					/* Lmi status */
static mntsup_t **MSHash = (mntsup_t **)NULL;		/* mount supplement
							 * hash buckets */


/*
 * cvtoe() -- convert octal-escaped characters in string
 */

static char *
cvtoe(os)
	char *os;			/* original string */
{
	int c, cl, cx, ol, ox, tx;
	char *cs;
	int tc;
/*
 * Allocate space for a copy of the string in which octal-escaped characters
 * can be replaced by the octal value -- e.g., \040 with ' '.  Leave room for
 * a '\0' terminator.
 */
	if (!(ol = (int)strlen(os)))
	   return((char *)NULL);
	if (!(cs = (char *)malloc(ol + 1))) {
	    (void) fprintf(stderr,
		"%s: can't allocate %d bytes for octal-escaping.\n",
		Pn, ol + 1);
	    Exit(1);
	}
/*
 * Copy the string, replacing octal-escaped characters as they are found.
 */
	for (cx = ox = 0, cl = ol; ox < ol; ox++) {
	    if (((c = (int)os[ox]) == (int)'\\') && ((ox + 3) < ol)) {

	    /*
	     * The beginning of an octal-escaped character has been found.
	     *
	     * Convert the octal value to a character value.
	     */
		for (tc = 0, tx = 1; os[ox + tx] && (tx < 4); tx++) {
		    if (((int)os[ox + tx] < (int)'0')
		    ||  ((int)os[ox + tx] > (int)'7'))
		    {

		    /*
		     * The escape isn't followed by octets, so ignore the
		     * escape and just copy it.
		     */
			break;
		    }
		    tc <<= 3;
		    tc += (int)(os[ox + tx] - '0');
		}
		if (tx == 4) {

		/*
		 * If three octets (plus the escape) were assembled, use their
		 * character-forming result.
		 *
		 * Otherwise copy the escape and what follows it until another
		 * escape is found.
		 */
		    ox += 3;
		    c = (tc & 0xff);
		}
	    }
	    if (cx >= cl) {

	    /*
	     * Expand the copy string, as required.  Leave room for a '\0'
	     * terminator.
	     */
		cl += 64;		/* (Make an arbitrary increase.) */
		if (!(cs = (char *)realloc(cs, cl + 1))) {
		    (void) fprintf(stderr,
			"%s: can't realloc %d bytes for octal-escaping.\n",
			Pn, cl + 1);
		    Exit(1);
		}
	    }
	/*
	 * Copy the character.
	 */
	    cs[cx++] = (char)c;
	}
/*
 * Terminate the copy and return its pointer.
 */
	cs[cx] = '\0';
	return(cs);
}


#if	defined(HASMNTSUP)
/*
 * getmntdev() - get mount device from mount supplement
 */

static int
getmntdev(dn, s, ss)
	char *dn;			/* mount point directory name */
	struct stat *s;			/* stat(2) buffer receptor */
	int *ss;			/* stat(2) status result -- i.e., SB_*
					 * values */
{
	static int err = 0;
	int h;
	mntsup_t *mp, *mpn;
	static char *vbuf = (char *)NULL;
	static size_t vsz = (size_t)0;

	if (err)
	    return(0);
	if (!MSHash) {

	/*
	 * No mount supplement hash buckets have been allocated, so read the
	 * mount supplement file and create hash buckets for its entries.
	 */
	    char buf[(MAXPATHLEN*2) + 1], *dp, path[(MAXPATHLEN*2) + 1];
	    dev_t dev;
	    FILE *fs;
	    int ln = 0;
	    size_t sz;

	    if ((MntSup != 2) || !MntSupP)
		return(0);
	    if (!is_readable(MntSupP, 1)) {

	    /*
	     * The mount supplement file isn't readable.
	     */
		err = 1;
		return(0);
	    }
	    if (!(fs = open_proc_stream(MntSupP, "r", &vbuf, &vsz, 0))) {

	    /*
	     * The mount supplement file can't be opened for reading.
	     */
		if (!Fwarn)
		    (void) fprintf(stderr, "%s: can't open(%s): %s\n",
			Pn, MntSupP, strerror(errno));
		err = 1;
		return(0);
	    }
	    buf[sizeof(buf) - 1] = '\0';
	/*
	 * Read the mount supplement file.
	 */
	    while (fgets(buf, sizeof(buf) - 1, fs)) {
		ln++;
		if ((dp = strchr(buf, '\n')))
		    *dp = '\0';
		if (buf[0] != '/') {

		/*
		 * The mount supplement line doesn't begin with the absolute
		 * path character '/'.
		 */
		    if (!Fwarn)
			(void) fprintf(stderr,
			    "%s: %s line %d: no path: \"%s\"\n",
			    Pn, MntSupP, ln, buf);
		    err = 1;
		    continue;
		}
		if (!(dp = strchr(buf, ' ')) || strncmp(dp + 1, "0x", 2)) {

		/*
		 * The path on the mount supplement line isn't followed by
		 * " 0x".
		 */
		    if (!Fwarn)
			(void) fprintf(stderr,
			    "%s: %s line %d: no device: \"%s\"\n",
			    Pn, MntSupP, ln, buf);
		    err = 1;
		    continue;
		}
		sz = (size_t)(dp - buf);
		(void) strncpy(path, buf, sz);
		path[sz] = '\0';
	    /*
	     * Assemble the hexadecimal device number of the mount supplement
	     * line.
	     */
		for (dev = 0, dp += 3; *dp; dp++) {
		    if (!isxdigit((int)*dp))
			break;
		    if (isdigit((int)*dp))
			dev = (dev << 4) + (int)*dp - (int)'0';
		    else
			dev = (dev << 4) + (int)tolower(*dp) - (int)'a' + 10;
		}
		if (*dp) {

		/*
		 * The device number couldn't be assembled.
		 */
		    if (!Fwarn)
			(void) fprintf(stderr,
			    "%s: %s line %d: illegal device: \"%s\"\n",
			    Pn, MntSupP, ln, buf);
		    err = 1;
		    continue;
		}
	    /*
	     * Search the mount supplement hash buckets.  (Allocate them as
	     * required.)
	     */
		if (!MSHash) {
		    if (!(MSHash = (mntsup_t **)calloc(HASHMNT,
						       sizeof(mntsup_t *)))
		    ) {
			(void) fprintf(stderr,
			    "%s: no space for mount supplement hash buckets\n",
			    Pn);
			Exit(1);
		    }
		}
		h = hash_mnt(path);
		for (mp = MSHash[h]; mp; mp = mp->next) {
		    if (!strcmp(mp->dn, path))
			break;
		}
		if (mp) {

		/*
		 * A path match was located.  If the device number is the
		 * same, skip this mount supplement line.  Otherwise, issue
		 * a warning.
		 */
		    if (mp->dev != dev) {
			(void) fprintf(stderr,
			    "%s: %s line %d path duplicate of %d: \"%s\"\n",
			    Pn, MntSupP, ln, mp->ln, buf);
			err = 1;
		    }
		    continue;
		}
	    /*
	     * Allocate and fill a new mount supplement hash entry.
	     */
		if (!(mpn = (mntsup_t *)malloc(sizeof(mntsup_t)))) {
		    (void) fprintf(stderr,
			"%s: no space for mount supplement entry: %d \"%s\"\n",
			Pn, ln, buf);
		    Exit(1);
		}
		if (!(mpn->dn = (char *)malloc(sz + 1))) {
		    (void) fprintf(stderr,
			"%s: no space for mount supplement path: %d \"%s\"\n",
			Pn, ln, buf);
		    Exit(1);
		}
		(void) strcpy(mpn->dn, path);
		mpn->dev = dev;
		mpn->ln = ln;
		mpn->next = MSHash[h];
		MSHash[h] = mpn;
	    }
	    if (ferror(fs)) {
		if (!Fwarn)
		    (void) fprintf(stderr, "%s: error reading %s\n",
			Pn, MntSupP);
		err = 1;
	    }
	    (void) fclose(fs);
	    if (err) {
		if (MSHash) {
		    for (h = 0; h < HASHMNT; h++) {
			for (mp = MSHash[h]; mp; mp = mpn) {
			    mpn = mp->next;
			    if (mp->dn)
				(void) free((MALLOC_P *)mp->dn);
			    (void) free((MALLOC_P *)mp);
			}
		    }
		    (void) free((MALLOC_P *)MSHash);
		    MSHash = (mntsup_t **)NULL;
		}
		return(0);
	    }
	}
/*
 * If no errors have been detected reading the mount supplement file, search
 * its hash biuckets for the supplied directory path.
 */
	if (err)
	    return(0);
	h = hash_mnt(dn);
	for (mp = MSHash[h]; mp; mp = mp->next) {
	    if (!strcmp(dn, mp->dn)) {
		memset((void *)s, 0, sizeof(struct stat));
		s->st_dev = mp->dev;
		*ss |= SB_DEV;
		return(1);
	    }
	}
	return(0);
}


/*
 * hash_mnt() - hash mount point
 */

static int
hash_mnt(dn)
	char *dn;			/* mount point directory name */
{
	register int i, h;
	size_t l;

	if (!(l = strlen(dn)))
	    return(0);
	if (l == 1)
	    return((int)*dn & (HASHMNT - 1));
	for (i = h = 0; i < (int)(l - 1); i++) {
	    h ^= ((int)dn[i] * (int)dn[i+1]) << ((i*3)%13);
	}
	return(h & (HASHMNT - 1));
}
#endif	/* defined(HASMNTSUP) */


/*
 * readmnt() - read mount table
 */

struct mounts *
readmnt()
{
	char buf[MAXPATHLEN], *cp, **fp;
	char *dn = (char *)NULL;
	int ds;
	char *fp0 = (char *)NULL;
	char *fp1 = (char *)NULL;
	int fr, ignrdl, ignstat;
	char *ln;
	struct mounts *mp;
	FILE *ms;
	int nfs;
	struct stat sb;
	static char *vbuf = (char *)NULL;
	static size_t vsz = (size_t)0;

	if (Lmi || Lmist)
	    return(Lmi);
/*
 * Open access to /proc/mounts, assigning a page size buffer to its stream.
 */
	(void) snpf(buf, sizeof(buf), "%s/mounts", PROCFS);
	ms = open_proc_stream(buf, "r", &vbuf, &vsz, 1);
/*
 * Read mount table entries.
 */
	while (fgets(buf, sizeof(buf), ms)) {
	    if (get_fields(buf, (char *)NULL, &fp, (int *)NULL, 0) < 3
	    ||  !fp[0] || !fp[1] || !fp[2])
		continue;
	/*
	 * Convert octal-escaped characters in the device name and mounted-on
	 * path name.
	 */
	    if (fp0) {
		(void) free((FREE_P *)fp0);
		fp0 = (char *)NULL;
	    }
	    if (fp1) {
		(void) free((FREE_P *)fp1);
		fp1 = (char *)NULL;
	    }
	    if (!(fp0 = cvtoe(fp[0])) || !(fp1 = cvtoe(fp[1])))
		continue;
	/*
	 * Ignore an entry with a colon in the device name, followed by
	 * "(pid*" -- it's probably an automounter entry.
	 *
	 * Ignore autofs, pipefs, and sockfs entries.
	 */
	    if ((cp = strchr(fp0, ':')) && !strncasecmp(++cp, "(pid", 4))
		continue;
	    if (!strcasecmp(fp[2], "autofs") || !strcasecmp(fp[2], "pipefs")
	    ||  !strcasecmp(fp[2], "sockfs"))
		continue;
	/*
	 * Interpolate a possible symbolic directory link.
	 */
	    if (dn)
		(void) free((FREE_P *)dn);
	    dn = fp1;
	    fp1 = (char *)NULL;

#if	defined(HASEOPT)
	if (Efsysl) {

	/*
	 * If there is an -e file system list, check it to decide if a stat()
	 * and Readlink() on this one should be performed.
	 */
	    efsys_list_t *ep;

	    for (ignrdl = ignstat = 0, ep = Efsysl; ep; ep = ep->next) {
		if (!strcmp(dn, ep->path)) {
		    ignrdl = ep->rdlnk;
		    ignstat = 1;
		    break;
		}
	    }
	} else

#endif	/* defined(HASEOPT */

	    ignrdl = ignstat = 0;

	/*
	 * Avoid Readlink() when requested.
	 */
	    if (!ignrdl) {
		if (!(ln = Readlink(dn))) {
		    if (!Fwarn) {
			(void) fprintf(stderr,
			"      Output information may be incomplete.\n");
		    }
			continue;
		}
		if (ln != dn) {
		    (void) free((FREE_P *)dn);
		    dn = ln;
		}
	    }
	    if (*dn != '/')
		continue;
	/*
	 * Detect an NFS mount point.
	 */
	    if (!(nfs = strcasecmp(fp[2], "nfs")) && !HasNFS)
		HasNFS = 1;
	/*
	 * Skip duplicate directories.
	 */
	    for (mp = Lmi; mp; mp = mp->next) {
		if (!strcmp(dn, mp->dir))
		    break;
	    }
	    if (mp)
		continue;
	/*
	 * Stat() the directory.
	 */
	    if (ignstat)
		fr = 1;
	    else {
		if ((fr = statsafely(dn, &sb))) {
		    if (!Fwarn) {
			(void) fprintf(stderr, "%s: WARNING: can't stat() ",
			    Pn);
			safestrprt(fp[2], stderr, 0);
			(void) fprintf(stderr, " file system ");
			safestrprt(dn, stderr, 1);
			(void) fprintf(stderr,
			    "      Output information may be incomplete.\n");
		    }
		} else
		    ds = SB_ALL;
	    }

#if	defined(HASMNTSUP)
	    if (fr) {

	    /*
	     * If the stat() failed or wasn't called, check the mount
	     * supplement table, if possible.
	     */
		if ((MntSup == 2) && MntSupP) {
		    ds = 0;
		    if (getmntdev(dn, &sb, &ds) || !(ds & SB_DEV)) {
			(void) fprintf(stderr,
			    "%s: assuming dev=%#lx for %s from %s\n",
			    Pn, (long)sb.st_dev, dn, MntSupP);
			}
		} else {
		    if (!ignstat)
			continue;
		   ds = 0;		/* No stat() was allowed. */
		}
	    }
#else	/* !defined(HASMNTSUP) */
	    if (fr) {
		if (!ignstat)
		    continue;
		ds = 0;			/* No stat() was allowed. */
	    }
#endif	/* defined(HASMNTSUP) */

	/*
	 * Allocate and fill a local mount structure.
	 */
	    if (!(mp = (struct mounts *)malloc(sizeof(struct mounts)))) {
		(void) fprintf(stderr,
		    "%s: can't allocate mounts struct for: ", Pn);
		safestrprt(dn, stderr, 1);
		Exit(1);
	    }
	    mp->dir = dn;
	    dn = (char *)NULL;
	    mp->next = Lmi;
	    mp->dev = ((mp->ds = ds) & SB_DEV) ? sb.st_dev : 0;
	    mp->rdev = (ds & SB_RDEV) ? sb.st_rdev : 0;
	    mp->inode = (INODETYPE)((ds & SB_INO) ? sb.st_ino : 0);
	    mp->mode = (ds & SB_MODE) ? sb.st_mode : 0;
	    if (!nfs) {
		mp->ty = N_NFS;
		if (HasNFS < 2)
		    HasNFS = 2;
	    } else
		mp->ty = N_REGLR;

#if	defined(HASMNTSUP)
	/*
	 * If support for the mount supplement file is defined and if the
	 * +m option was supplied, print mount supplement information.
	 */
	    if (MntSup == 1) {
		if (mp->dev)
		    (void) printf("%s %#lx\n", mp->dir, (long)mp->dev);
		else
		    (void) printf("%s 0x0\n", mp->dir);
	    }
#endif	/* defined(HASMNTSUP) */

	/*
	 * Save mounted-on directory name.
	 */
	    dn = fp0;
	    fp0 = (char *)NULL;
	    mp->fsname = dn;
	/*
	 * Interpolate a possible file system (mounted-on) device name link.
	 *
	 * Avoid Readlink() when requested.
	 */
	    if (ignrdl || (*dn != '/')) {
		if (!(ln = mkstrcpy(dn, (MALLOC_S *)NULL))) {
		    (void) fprintf(stderr,
			"%s: can't allocate space for: ", Pn);
		    safestrprt(dn, stderr, 1);
		    Exit(1);
		}
		ignstat = 1;
	    } else
		ln = Readlink(dn);
	    dn = (char *)NULL;
	/*
	 * Stat() the file system (mounted-on) name and add file system
	 * information to the local mount table entry.
	 */
	    if (ignstat || !ln || statsafely(ln, &sb))
		sb.st_mode = 0;
	    mp->fsnmres = ln;
	    mp->fs_mode = sb.st_mode;
	    Lmi = mp;
	}
/*
 * Clean up and return the local mount info table address.
 */
	(void) fclose(ms);
	if (dn)
	    (void) free((FREE_P *)dn);
	if (fp0)
	    (void) free((FREE_P *)fp0);
	if (fp1)
	    (void) free((FREE_P *)fp1);
	Lmist = 1;
	return(Lmi);
}
