/* * dmnt.c - SCO UnixWare mount support functions for lsof */ /* * Copyright 1996 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 1996 Purdue Research Foundation.\nAll rights reserved.\n"; static char *rcsid = "$Id: dmnt.c,v 1.7 2005/08/13 16:21:41 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() { char *dn = (char *)NULL; char *ln; struct mnttab me; FILE *mfp; struct mounts *mtp; char *opt, *opte; struct stat sb; #if defined(HASPROCFS) int procfs = 0; #endif if (Lmi || Lmist) return(Lmi); /* * Open access to the mount table and read mount table entries. */ if (!(mfp = fopen(MNTTAB, "r"))) { (void) fprintf(stderr, "%s: can't access %s\n", Pn, MNTTAB); return(0); } while (!getmntent(mfp, &me)) { /* * Skip loop-back mounts, since they are aliases for legitimate file * systems and there is no way to determine that a vnode refers to a * loop-back alias. * * Also skip file systems of type MNTTYPE_IGNORE or with the option * MNTOPT_IGNORE, since they are auto-mounted file systems whose * real entries (if they are mounted) will be separately identified * by getmntent(). */ if (!strcmp(me.mnt_fstype, MNTTYPE_LO) || !strcmp(me.mnt_fstype, MNTTYPE_IGNORE)) continue; /* * Interpolate a possible symbolic directory link. */ if (dn) (void) free((FREE_P *)dn); if (!(dn = mkstrcpy(me.mnt_mountp, (MALLOC_S *)NULL))) { no_space_for_mount: (void) fprintf(stderr, "%s: no space for mount at ",Pn); safestrprt(me.mnt_special, stderr, 0); (void) fprintf(stderr, " ("); safestrprt(me.mnt_mountp, stderr, 0); (void) fprintf(stderr, ")\n"); Exit(1); } 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; /* * Stat() the directory. */ if (statsafely(dn, &sb)) { if (!Fwarn) { (void) fprintf(stderr, "%s: can't stat()", Pn); #if defined(HASFSTYPE) putc(' ', stderr); safestrprt(me.mnt_fstype, stderr, 0); #endif /* defined(HASFSTYPE) */ (void) fprintf(stderr, " file system "); safestrprt(me.mnt_mountp, stderr, 1); (void) fprintf(stderr, " Output information may be incomplete.\n"); } if (!(opt = strstr(me.mnt_mntopts, "dev="))) { (void) memset(&sb, 0, sizeof(sb)); if (!(opte = x2dev(opt + 4, &sb.st_dev))) { sb.st_mode = S_IFDIR | 0777; #if defined(HASFSTYPE) (void) strncpy(sb.st_fstype, me.mnt_fstype, sizeof(sb.st_fstype)); sb.st_fstype[sizeof(sb.st_fstype) - 1 ] = '\0'; #endif /* HASFSTYPE */ if (!Fwarn) { (void) fprintf(stderr, " assuming \"%.*s\" from %s\n", (opte - opt), opt, MNTTAB); } } else opt = (char *)NULL; } if (!opt) continue; } /* * Allocate and fill a local mount structure. */ if (!(mtp = (struct mounts *)malloc(sizeof(struct mounts)))) goto no_space_for_mount; #if defined(HASFSTYPE) if (!(mtp->fstype = mkstrcpy(sb.st_fstype, (MALLOC_S *)NULL))) goto no_space_for_mount; #endif /* HASFSTYPE */ mtp->dir = dn; dn = (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; #if defined(HASPROCFS) # if defined(HASFSTYPE) if (!strcmp(sb.st_fstype, HASPROCFS)) # else /* !defined*HASFSTYPE) */ if (!strcmp(me.mnt_special, "/proc")) # endif /* defined(HASFSTYPE) */ { /* * Save information on exactly one procfs file system. */ if (procfs) Mtprocfs = (struct mounts *)NULL; else { procfs = 1; Mtprocfs = mtp; } } #endif /* defined(HASPROCFS) */ /* * Interpolate a possible file system (mounted-on device) name link. */ if (!(dn = mkstrcpy(me.mnt_special, (MALLOC_S *)NULL))) goto no_space_for_mount; mtp->fsname = dn; ln = Readlink(dn); dn = (char *)NULL; /* * Stat() the file system (mounted-on) name and add file system * information to the local mounts structure. */ if (!ln || statsafely(ln, &sb)) sb.st_mode = 0; mtp->fsnmres = ln; mtp->fs_mode = sb.st_mode; Lmi = mtp; } (void) fclose(mfp); /* * Clean up and return local mount info table address. */ if (dn) (void) free((FREE_P *)dn); Lmist = 1; return(Lmi); }