/*
 * dfile.c -- Darwin file processing functions for libproc-based lsof
 */


/*
 * Portions Copyright 2005-2007 Apple Inc.  All rights reserved.
 *
 * Copyright 2005 Purdue Research Foundation, West Lafayette, Indiana
 * 47907.  All rights reserved.
 *
 * Written by Allan Nathanson, Apple Inc., and Victor A. Abell, Purdue
 * University.
 *
 * 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 Apple Inc. 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, Apple
 *    Inc. 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 2005-2007 Apple Inc. and Purdue Research Foundation.\nAll rights reserved.\n";
static char *rcsid = "$Id: dfile.c,v 1.7 2011/08/07 22:52:30 abe Exp $";
#endif


#include "lsof.h"


/*
 * enter_file_info() -- enter file information
 */

void
enter_file_info(pfi)
	struct proc_fileinfo *pfi;	/* pointer to process file info */
{
	int f;
/*
 * Construct access code
 */
	f = pfi->fi_openflags & (FREAD | FWRITE);
	if (f == FREAD)
	    Lf->access = 'r';
	else if (f == FWRITE)
	    Lf->access = 'w';
	else if (f == (FREAD | FWRITE))
	    Lf->access = 'u';
/*
 * Save the offset / size
 */
	Lf->off = (SZOFFTYPE)pfi->fi_offset;
	if (Foffset)
	    Lf->off_def = 1;
/*
 * Save file structure information as requested.
 */
	if (Fsv & FSV_FG) {
	    Lf->ffg = (long)pfi->fi_openflags;
	    Lf->fsv |= FSV_FG;
	}
}


/*
 * enter_vnode_info() -- enter vnode information
 */

void
enter_vnode_info(vip)
	struct vnode_info_path *vip;	/* pointer to vnode info with path */
{
	char buf[32], *cp;
	dev_t dev = 0;
	int devs = 0;
	struct mounts *mp;
/*
 * Derive file type.
 */
	switch ((int)(vip->vip_vi.vi_stat.vst_mode & S_IFMT)) {
	case S_IFIFO:
	    cp = "FIFO";
	    Ntype = N_FIFO;
	    break;
	case S_IFCHR:
	    cp = "CHR";
	    Ntype = N_CHR;
	    break;
	case S_IFDIR:
	    cp = "DIR";
	    Ntype = N_REGLR;
	    break;
	case S_IFBLK:
	    cp = "BLK";
	    Ntype = N_BLK;
	    break;
	case S_IFREG:
	    cp = "REG";
	    Ntype = N_REGLR;
	    break;
	default:
	    (void) snpf(buf, sizeof(buf), "%04o",
		(((vip->vip_vi.vi_stat.vst_mode & S_IFMT) >> 12) & 0xfff));
	    cp = buf;
	    Ntype = N_REGLR;
	}
	if (!Lf->type[0])
	    (void) snpf(Lf->type, sizeof(Lf->type), "%s", cp);
	Lf->ntype = Ntype;
/*
 * Save device number and path
 */
	switch (Ntype) {
	case N_FIFO:
	    break;
	case N_CHR:
	case N_BLK:
	    Lf->rdev = vip->vip_vi.vi_stat.vst_rdev;
	    Lf->rdev_def = 1;
	    /* fall through */
	default:
	    Lf->dev = dev = vip->vip_vi.vi_stat.vst_dev;
	    Lf->dev_def = devs = 1;
	}
/*
 * Save path name.
 */
	vip->vip_path[sizeof(vip->vip_path) - 1] = '\0';
	if (vip->vip_path[0] != '\0') {
	    Lf->V_path = mkstrcpy(vip->vip_path, (MALLOC_S *)NULL);
	}
/*
 * Save node number.
 */
	Lf->inode = (INODETYPE)vip->vip_vi.vi_stat.vst_ino;
	Lf->inp_ty = 1;
/*
 * Save link count, as requested.
 */
	if (Fnlink) {
	    Lf->nlink = vip->vip_vi.vi_stat.vst_nlink;
	    Lf->nlink_def = 1;
	    if (Nlink && (Lf->nlink < Nlink))
		Lf->sf |= SELNLINK;
	}
/*
 * If a device number is defined, locate file system and save its identity.
 */
	if (devs) {
	    for (mp = readmnt(); mp; mp = mp->next) {
		if (dev == mp->dev) {
		    Lf->fsdir = mp->dir;
		    Lf->fsdev = mp->fsname;
		    if (mp->is_nfs && Fnfs)
			Lf->sf |= SELNFS;
		    break;
		}
	    }
	}
/*
 * Save the file size.
 */
	switch (Ntype) {
	case N_CHR:
	case N_FIFO:
	    Lf->off_def = 1;
	    break;
	default:
	    Lf->sz = (SZOFFTYPE)vip->vip_vi.vi_stat.vst_size;
	    Lf->sz_def = 1;
	}
/*
 * Test for specified file.
 */
	if (Sfile && is_file_named(NULL,
				   ((Ntype == N_CHR) || (Ntype == N_BLK) ? 1
									 : 0)))
	{
	    Lf->sf |= SELNM;
	}
/*
 * Enter name characters.
 */
	if (!Lf->nm && Namech[0])
	    enter_nm(Namech);
}


/*
 * err2nm() -- convert errno to a message in Namech
 */

void
err2nm(pfx)
	char *pfx;			/* Namech message prefix */
{
	char *sfx;

	switch (errno) {
	case EBADF:

	/*
	 * The file descriptor is no longer available.
	 */
	    sfx = "FD unavailable";
	    break;
	case ESRCH:

	/*
	 * The process is no longer available.
	 */
	    sfx = "process unavailable";
	    break;
	default:

	/*
	 * All other errors are reported with strerror() information.
	 */
	    sfx = strerror(errno);
	}
	(void) snpf(Namech, Namechl, "%s: %s", pfx, sfx);
	enter_nm(Namech);
}


/*
 * print_nm() -- print Name column
 */
void
print_nm(lf)
	struct lfile *lf;
{
	printname(0);
	putchar('\n');
}


/*
 * print_v_path() -- print vnode's path
 */

int
print_v_path(lf)
	struct lfile *lf;
{
	if (lf->V_path) {
	    safestrprt(lf->V_path, stdout, 0);
	    return(1);
	}
	return(0);
}


/*
 * process_atalk() -- process an Apple Talk file
 */

void
process_atalk(pid, fd)
	int pid;			/* PID */
	int32_t fd;			/* FD */
{
	(void) snpf(Lf->type, sizeof(Lf->type), "ATALK");
	return;
}


/*
 * process_fsevents() -- process a file system events file
 */

void
process_fsevents(pid, fd)
	int pid;			/* PID */
	int32_t fd;			/* FD */
{
	(void) snpf(Lf->type, sizeof(Lf->type), "FSEVENTS");
}


/*
 * process_kqueue() -- process a kernel queue file
 */

void
process_kqueue(pid, fd)
	int pid;			/* PID */
	int32_t fd;			/* FD */
{
	struct kqueue_fdinfo kq;
	int nb;
/*
 * Get the kernel queue file information.
 */
	(void) snpf(Lf->type, sizeof(Lf->type), "KQUEUE");
	nb = proc_pidfdinfo(pid, fd, PROC_PIDFDKQUEUEINFO, &kq, sizeof(kq));
	if (nb <= 0) {
	    (void) err2nm("kqueue");
	    return;
	} else if (nb < sizeof(kq)) {
	    (void) fprintf(stderr,
		"%s: PID %d, FD %d; proc_pidfdinfo(PROC_PIDFDKQUEUEINFO);\n",
		Pn, pid, fd);
	    (void) fprintf(stderr,
		"      too few bytes; expected %ld, got %d\n",
		sizeof(kq), nb);
	    Exit(1);
	}
/*
 * Enter the kernel queue file information.
 */
	enter_file_info(&kq.pfi);
/*
 * Enter queue counts as NAME column information.
 */
	(void) snpf(Namech, Namechl,
	    "count=%" SZOFFPSPEC "u, state=%#x",
	    (SZOFFTYPE)kq.kqueueinfo.kq_stat.vst_size,
	    kq.kqueueinfo.kq_state);
	enter_nm(Namech);
}


/*
 * process_pipe() -- process pipe file
 */

static void
process_pipe_common(pi)
	struct pipe_fdinfo *pi;
{
	char dev_ch[32], *ep;
        size_t sz;

	(void) snpf(Lf->type, sizeof(Lf->type), "PIPE");
/*
 * Enter the pipe handle as the device.
 */
	(void) snpf(dev_ch, sizeof(dev_ch), "%s",
	    print_kptr((KA_T)pi->pipeinfo.pipe_handle, (char *)NULL, 0));
	enter_dev_ch(dev_ch);
/*
 * Enable offset or size reporting.
 */
	if (Foffset)
	    Lf->off_def = 1;
	else {
	    Lf->sz = (SZOFFTYPE)pi->pipeinfo.pipe_stat.vst_blksize;
	    Lf->sz_def = 1;
	}
/*
 * If there is a peer handle, enter it in as NAME column information.
 */
	if (pi->pipeinfo.pipe_peerhandle) {
	    (void) snpf(Namech, Namechl, "->%s",
		print_kptr((KA_T)pi->pipeinfo.pipe_peerhandle, (char *)NULL, 0));
	    enter_nm(Namech);
	} else
	    Namech[0] = '\0';
/*
 * If the pipe has a count, add it to the NAME column.
 */
	if (pi->pipeinfo.pipe_stat.vst_size) {
	    ep = endnm(&sz);
	    (void) snpf(ep, sz, ", cnt=%" SZOFFPSPEC "u",
		(SZOFFTYPE)pi->pipeinfo.pipe_stat.vst_size);
	}
}
	
	
void
process_pipe(pid, fd)
	int pid;			/* PID */
	int32_t fd;			/* FD */
{
	int nb;
	struct pipe_fdinfo pi;
/*
 * Get pipe file information.
 */
	nb = proc_pidfdinfo(pid, fd, PROC_PIDFDPIPEINFO, &pi, sizeof(pi));
	if (nb <= 0) {
	    (void) err2nm("pipe");
	    return;
	} else if (nb < sizeof(pi)) {
	    (void) fprintf(stderr,
		"%s: PID %d, FD %d; proc_pidfdinfo(PROC_PIDFDPIPEINFO);\n",
		Pn, pid, fd);
	    (void) fprintf(stderr,
		"      too few bytes; expected %ld, got %d\n",
	       sizeof(pi), nb);
	    Exit(1);
	}

	process_pipe_common(&pi);
}


/*
 * process_psem() -- process a POSIX semaphore file
 */

void
process_psem(pid, fd)
	int pid;			/* PID */
	int32_t fd;			/* FD */
{
	int nb;
	struct psem_fdinfo ps;
/*
 * Get the sempaphore file information.
 */
	(void) snpf(Lf->type, sizeof(Lf->type), "PSXSEM");
	nb = proc_pidfdinfo(pid, fd, PROC_PIDFDPSEMINFO, &ps, sizeof(ps));
	if (nb <= 0) {
	    (void) err2nm("semaphore");
	    return;
	} else if (nb < sizeof(ps)) {
	    (void) fprintf(stderr,
		"%s: PID %d, FD %d; proc_pidfdinfo(PROC_PIDFDPSEMINFO);\n",
		Pn, pid, fd);
	    (void) fprintf(stderr,
		"      too few bytes; expected %ld, got %d\n",
		sizeof(ps), nb);
	    Exit(1);
	}
/*
 * Enter the semaphore file information.
 */
	enter_file_info(&ps.pfi);
/*
 * If there is a semaphore file name, enter it.
 */
	if (ps.pseminfo.psem_name[0]) {
	    ps.pseminfo.psem_name[sizeof(ps.pseminfo.psem_name) - 1] = '\0';
	    (void) snpf(Namech, Namechl, "%s", ps.pseminfo.psem_name);
	    enter_nm(Namech);
	}
/*
 * Unless file size has been specifically requested, enable the printing of
 * file offset.
 */
	if (!Fsize)
	    Lf->off_def = 1;
}


/*
 * process_pshm() -- process POSIX shared memory file
 */

static void
process_pshm_common(ps)
	struct pshm_fdinfo *ps;
{
	(void) snpf(Lf->type, sizeof(Lf->type), "PSXSHM");
/*
 * Enter the POSIX shared memory file information.
 */
	enter_file_info(&ps->pfi);
/*
 * If the POSIX shared memory file has a path name, enter it; otherwise, if it
 * has a mapping address, enter that.
 */
	if (ps->pshminfo.pshm_name[0]) {
	    ps->pshminfo.pshm_name[sizeof(ps->pshminfo.pshm_name) - 1] = '\0';
	    (void) snpf(Namech, Namechl, "%s", ps->pshminfo.pshm_name);
	    enter_nm(Namech);
	} else if (ps->pshminfo.pshm_mappaddr) {
	    (void) snpf(Namech, Namechl, "obj=%s",
		print_kptr((KA_T)ps->pshminfo.pshm_mappaddr, (char *)NULL, 0));
	    enter_nm(Namech);
	}
/*
 * Enable offset or size reporting.
 */
	if (Foffset)
	    Lf->off_def = 1;
	else {
	    Lf->sz = (SZOFFTYPE)ps->pshminfo.pshm_stat.vst_size;
	    Lf->sz_def = 1;
	}
}


void
process_pshm(pid, fd)
	int pid;			/* PID */
	int32_t fd;			/* FD */
{
	int nb;
	struct pshm_fdinfo ps;
/*
 * Get the POSIX shared memory file information.
 */
	nb = proc_pidfdinfo(pid, fd, PROC_PIDFDPSHMINFO, &ps, sizeof(ps));
	if (nb <= 0) {
	    (void) err2nm("POSIX shared memory");
	    return;
	} else if (nb < sizeof(ps)) {
	    (void) fprintf(stderr,
		"%s: PID %d, FD %d; proc_pidfdinfo(PROC_PIDFDPSHMINFO);\n",
		Pn, pid, fd);
	    (void) fprintf(stderr,
		"      too few bytes; expected %ld, got %d\n",
		sizeof(ps), nb);
	    Exit(1);
	}

	process_pshm_common(&ps);
}


/*
 * process_vnode() -- process a vnode file
 */

static void
process_vnode_common(vi)
	struct vnode_fdinfowithpath *vi;
{
/*
 * Enter the file and vnode information.
 */
	enter_file_info(&vi->pfi);
	enter_vnode_info(&vi->pvip);
}


void
process_vnode(pid, fd)
	int pid;			/* PID */
	int32_t fd;			/* FD */
{
	int nb;
	struct vnode_fdinfowithpath vi;

	nb = proc_pidfdinfo(pid, fd, PROC_PIDFDVNODEPATHINFO, &vi, sizeof(vi));
	if (nb <= 0) {
	    if (errno == ENOENT) {

	    /*
	     * The file descriptor's vnode may have been revoked.  This is a
	     * bit of a hack, since an ENOENT error might not always mean the
	     * descriptor's vnode has been revoked.  As the libproc API
	     * matures, this code may need to be revisited.
	     */
		enter_nm("(revoked)");
	    } else
		(void) err2nm("vnode");
	    return;
	} else if (nb < sizeof(vi)) {
	    (void) fprintf(stderr,
		"%s: PID %d, FD %d: proc_pidfdinfo(PROC_PIDFDVNODEPATHINFO);\n",
		Pn, pid, fd);
	    (void) fprintf(stderr,
		"      too few bytes; expected %ld, got %d\n",
		sizeof(vi), nb);
	    Exit(1);
	}

	process_vnode_common(&vi);
}
