| /* |
| * 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); |
| } |