blob: 47e33f4339359e9a20429a3d096505b57cc0baeb [file] [log] [blame]
/*
* dmnt.c - SCO OpenServer mount support functions for lsof
*/
/*
* Copyright 1995 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 1995 Purdue Research Foundation.\nAll rights reserved.\n";
static char *rcsid = "$Id: dmnt.c,v 1.8 2005/08/08 19:54:32 abe Exp $";
#endif
#include "lsof.h"
/*
* Local static definitions
*/
static struct mounts *Lmi = (struct mounts *)NULL; /* local mount info */
static int Lmist = 0; /* Lmi status */
/*
* readmnt() - read mount table
*/
struct mounts *
readmnt()
{
int br, fd;
int bx = sizeof(struct mnttab);
char *cp;
char dvnm[MAXPATHLEN], fsnm[MAXPATHLEN];
MALLOC_S dvnml, fsnml;
MALLOC_S len;
char *ln = (char *)NULL;
struct mnttab m;
struct mounts *mtp;
struct stat sb;
if (Lmi || Lmist)
return(Lmi);
/*
* Open access to the mount table.
*/
if ((fd = open(MNTTAB, O_RDONLY, 0)) < 0) {
(void) fprintf(stderr, "%s: can't open %s\n", Pn, MNTTAB);
Exit(1);
}
/*
* Read the first mount table entry.
*/
br = read(fd, (char *)&m, bx);
dvnml = fsnml = 0;
/*
* Process the next complete mount table entry.
*/
while (br == bx) {
if (!dvnml) {
/*
* Start the device and file system name assemblies.
*/
dvnml = strlen(m.mt_dev);
if (dvnml >= MAXPATHLEN)
dvnml = MAXPATHLEN - 1;
(void) strncpy(dvnm, m.mt_dev, dvnml);
dvnm[dvnml] = '\0';
fsnml = strlen(m.mt_filsys);
if (fsnml >= MAXPATHLEN)
fsnml = MAXPATHLEN - 1;
(void) strncpy(fsnm, m.mt_filsys, fsnml);
fsnm[fsnml] = '\0';
}
while ((br = read(fd, (char *)&m, bx)) == bx
&& strcmp(m.mt_filsys, "nothing") == 0
&& strcmp(m.mt_dev, "nowhere") == 0) {
/*
* Add the "nothing/nowhere" extensions to the assemblies.
*/
len = strlen(&m.mt_dev[8]);
if (len >= (MAXPATHLEN - dvnml))
len = MAXPATHLEN - dvnml - 1;
if (len) {
(void) strncpy(&dvnm[dvnml], &m.mt_dev[8], len);
dvnml += len;
dvnm[dvnml] = '\0';
}
len = strlen(&m.mt_filsys[8]);
if (len >= (MAXPATHLEN - fsnml))
len = MAXPATHLEN - fsnml - 1;
if (len) {
(void) strncpy(&fsnm[fsnml], &m.mt_filsys[8], len);
fsnml += len;
fsnm[fsnml] = '\0';
}
}
/*
* Skip automount place markers.
*/
if ((cp = strrchr(dvnm, ':')) && strncmp(cp, ":(pid", 5) == 0) {
dvnml = fsnml = 0;
continue;
}
/*
* Interpolate a possible symbolic directory link.
*/
if (ln) {
(void) free((FREE_P *)ln);
ln = (char *)NULL;
}
if (!(ln = Readlink(fsnm))) {
if (!Fwarn){
(void) fprintf(stderr,
" Output information may be incomplete.\n");
}
dvnml = fsnml = 0;
continue;
}
if (*ln != '/')
continue;
if (ln == fsnm) {
/*
* Allocate space for a copy of the file system name.
*/
if (!(ln = mkstrcpy(fsnm, (MALLOC_S *)NULL))) {
no_space_for_mount:
(void) fprintf(stderr, "%s: no space for mount at ", Pn);
safestrprt(fsnm, stderr, 0);
(void) fprintf(stderr, " (");
safestrprt(dvnm, stderr, 0);
(void) fprintf(stderr, ")\n");
Exit(1);
}
}
/*
* Stat() the directory.
*/
if (statsafely(ln, &sb)) {
if (!Fwarn) {
(void) fprintf(stderr,
"%s: WARNING: can't stat() file system: ", Pn);
safestrprt(fsnm, stderr, 1);
(void) fprintf(stderr,
" Output information may be incomplete.\n");
}
dvnml = fsnml = 0;
continue;
}
/*
* Allocate and fill a local mount structure.
*/
if (!(mtp = (struct mounts *)malloc(sizeof(struct mounts))))
goto no_space_for_mount;
mtp->dir = ln;
ln = (char *)NULL;
mtp->next = Lmi;
mtp->dev = sb.st_dev;
mtp->rdev = sb.st_rdev;
mtp->inode = (INODETYPE)sb.st_ino;
mtp->mode = sb.st_mode;
/*
* Interpolate a possible file system (mounted-on) device name link
*/
if (!(cp = mkstrcpy(dvnm, (MALLOC_S *)NULL)))
goto no_space_for_mount;
mtp->fsname = cp;
ln = Readlink(cp);
/*
* Stat() the file system (mounted-on) name and add file system
* information to the local mount table entry.
*/
if (statsafely(ln, &sb))
sb.st_mode = 0;
mtp->fsnmres = ln;
ln = (char *)NULL;
mtp->fs_mode = sb.st_mode;
Lmi = mtp;
dvnml = fsnml = 0;
}
(void) close(fd);
/*
* Clean up and return the local mount information table address.
*/
if (ln)
(void) free((FREE_P *)ln);
Lmist = 1;
return(Lmi);
}