blob: d02acd45d59ef0f9f213a1255da29bed9ee0242f [file] [log] [blame]
/*
* dmnt.c - /dev/kmem-based HP-UX mount support functions for 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: dmnt.c,v 1.8 2005/08/08 19:50:23 abe Exp $";
#endif
#if defined(HPUXKERNBITS) && HPUXKERNBITS>=64
#define _TIME_T
typedef int time_t;
#endif /* defined(HPUXKERNBITS) && HPUXKERNBITS>=64 */
#include "lsof.h"
/*
* Local static definitions
*/
static struct mounts *Lmi = (struct mounts *)NULL; /* local mount info */
/*
* completevfs() - complete local vfs structure
*/
void
#if HPUXV>=800
completevfs(vfs, dev, v)
struct l_vfs *vfs; /* local vfs structure pointer */
dev_t *dev; /* device */
struct vfs *v; /* kernel vfs structure */
#else /* HPUXV<800 */
completevfs(vfs, dev)
struct l_vfs *vfs; /* local vfs structure pointer */
dev_t *dev; /* device */
#endif /* HPUXV>=800 */
{
struct mounts *mp;
/*
* If only Internet socket files are selected, don't bother completing the
* local vfs structure.
*/
if (Selinet)
return;
#if HPUXV>=800
/*
* On HP-UX 8 and above, first search the local mount table for a match on
* the file system name from the vfs structure.
*/
if (v) {
for (mp = readmnt(); mp; mp = mp->next) {
if (strcmp(mp->fsname, v->vfs_name) == 0) {
vfs->dev = mp->dev;
vfs->dir = mp->dir;
vfs->fsname = mp->fsname;
# if defined(HASFSINO)
vfs->fs_ino = mp->inode;
# endif /* defined(HASFSINO) */
return;
}
}
}
#endif /* HPUXV>=800 */
/*
* Search for a match on device number.
*/
for (mp = readmnt(); mp; mp = mp->next) {
if (mp->dev == *dev) {
vfs->dev = mp->dev;
vfs->dir = mp->dir;
vfs->fsname = mp->fsname;
#if defined(HASFSINO)
vfs->fs_ino = mp->inode;
#endif /* defined(HASFSINO) */
return;
}
}
#if HPUXV>=800
/*
* If the file system name and device number searches fail, use the
* vfs structure name, if there is one. Determine the device number
* with statsafely().
*/
if (v && v->vfs_name[0]) {
struct stat sb;
if (!(vfs->dir = mkstrcpy(v->vfs_name, (MALLOC_S *)NULL))) {
(void) fprintf(stderr, "%s: no space for vfs name: ", Pn);
safestrprt(v->vfs_name, stderr, 1);
Exit(1);
}
if (statsafely(v->vfs_name, &sb) == 0)
vfs->dev = sb.st_dev;
else
vfs->dev = (dev_t)0;
# if defined(HASFSINO)
vfs->fs_ino = (INODETYPE)0;
# endif /* defined(HASFSINO) */
}
#endif /* HPUXV>=800 */
}
/*
* readvfs() - read vfs structure
*/
struct l_vfs *
readvfs(lv)
struct vnode *lv; /* local vnode */
{
struct mount m;
struct mntinfo mi;
int ms;
dev_t td;
struct vfs v;
struct l_vfs *vp;
if (!lv->v_vfsp)
return((struct l_vfs *)NULL);
for (vp = Lvfs; vp; vp = vp->next) {
if ((KA_T)lv->v_vfsp == vp->addr)
return(vp);
}
if ((vp = (struct l_vfs *)malloc(sizeof(struct l_vfs))) == NULL) {
(void) fprintf(stderr, "%s: PID %d, no space for vfs\n",
Pn, Lp->pid);
Exit(1);
}
vp->dev = 0;
vp->dir = (char *)NULL;
vp->fsname = (char *)NULL;
#if defined(HASFSINO)
vp->fs_ino = 0;
#endif /* defined(HASFSINO) */
if (lv->v_vfsp && kread((KA_T)lv->v_vfsp, (char *)&v, sizeof(v))) {
(void) free((FREE_P *)vp);
return((struct l_vfs *)NULL);
}
/*
* Complete the mount information.
*/
if (Ntype == N_NFS) {
/*
* The device number for an NFS file is found by following the vfs
* private data pointer to an mntinfo structure.
*/
if (v.vfs_data
&& kread((KA_T)v.vfs_data, (char *)&mi, sizeof(mi)) == 0) {
#if HPUXV<1020
td = (dev_t)makedev(255, (int)mi.mi_mntno);
#else /* HPUXV>=1020 */
td = mi.mi_mntno;
#endif /* HPUXV<1020 */
#if HPUXV>=800
(void) completevfs(vp, &td, (struct vfs *)NULL);
#else /* HPUXV<800 */
(void) completevfs(vp, &td);
#endif /* HPUXV>=800 */
}
} else {
if (v.vfs_data) {
if (kread((KA_T)v.vfs_data, (char *)&m, sizeof(m)) == 0)
ms = 1;
else
ms = 0;
}
#if defined(HAS_AFS)
/*
* Fake the device number for an AFS device.
*/
else if (Ntype == N_AFS) {
m.m_dev = AFSDEV;
ms = 1;
}
#endif /* defined(HAS_AFS) */
else
ms = 0;
if (ms)
#if HPUXV>=800
# if HPUXV<1000
(void) completevfs(vp, (dev_t *)&m.m_dev, &v);
# else /* HPUXV>=1000 */
(void) completevfs(vp, v.vfs_dev ? (dev_t *)&v.vfs_dev
: (dev_t *)&m.m_dev,
&v);
# endif /* HPUXV<1000 */
#else /* HPUXV<800 */
(void) completevfs(vp, (dev_t *)&m.m_dev);
#endif /* HPUXV>=800 */
}
/*
* Complete local vfs structure and link to the others.
*/
vp->next = Lvfs;
vp->addr = (KA_T)lv->v_vfsp;
Lvfs = vp;
return(vp);
}