1/* 2 * dmnt.c -- Darwin mount support functions for libproc-based lsof 3 */ 4 5 6/* 7 * Portions Copyright 2005 Apple Computer, Inc. All rights reserved. 8 * 9 * Copyright 2005 Purdue Research Foundation, West Lafayette, Indiana 10 * 47907. All rights reserved. 11 * 12 * Written by Allan Nathanson, Apple Computer, Inc., and Victor A. 13 * Abell, Purdue University. 14 * 15 * This software is not subject to any license of the American Telephone 16 * and Telegraph Company or the Regents of the University of California. 17 * 18 * Permission is granted to anyone to use this software for any purpose on 19 * any computer system, and to alter it and redistribute it freely, subject 20 * to the following restrictions: 21 * 22 * 1. Neither the authors, nor Apple Computer, Inc. nor Purdue University 23 * are responsible for any consequences of the use of this software. 24 * 25 * 2. The origin of this software must not be misrepresented, either 26 * by explicit claim or by omission. Credit to the authors, Apple 27 * Computer, Inc. and Purdue University must appear in documentation 28 * and sources. 29 * 30 * 3. Altered versions must be plainly marked as such, and must not be 31 * misrepresented as being the original software. 32 * 33 * 4. This notice may not be removed or altered. 34 */ 35 36 37#ifndef lint 38static char copyright[] = 39"@(#) Copyright 2005 Apple Computer, Inc. and Purdue Research Foundation.\nAll rights reserved.\n"; 40static char *rcsid = "$Id: dmnt.c,v 1.6 2012/04/10 16:41:04 abe Exp $"; 41#endif 42 43 44#include "lsof.h" 45 46 47/* 48 * Local static information 49 */ 50 51static struct mounts *Lmi = (struct mounts *)NULL; /* local mount info */ 52static int Lmist = 0; /* Lmi status */ 53 54/* 55 * readmnt() -- read mount table 56 */ 57 58struct mounts * 59readmnt() 60{ 61#if defined(DIR_MNTSTATUS_TRIGGER) 62 struct { 63 uint32_t length; 64 uint32_t mount_flags; 65 } ab; 66 struct attrlist al; 67#endif /* defined(DIR_MNTSTATUS_TRIGGER) */ 68 char *dn = (char *)NULL; 69 char *ln; 70 struct statfs *mb = (struct statfs *)NULL; 71 struct mounts *mtp; 72 int n; 73 struct stat sb; 74 75 if (Lmi || Lmist) 76 return(Lmi); 77/* 78 * Access mount information. 79 */ 80 if ((n = getmntinfo(&mb, MNT_NOWAIT)) <= 0) { 81 (void) fprintf(stderr, "%s: no mount information\n", Pn); 82 return(0); 83 } 84/* 85 * Read mount information. 86 */ 87 for (; n; n--, mb++) { 88 89 if (!mb->f_type) 90 continue; 91 /* 92 * Avoid file systems that are not appropriate paths to 93 * user data (e.g. automount maps, triggers). 94 */ 95#if defined(DIR_MNTSTATUS_TRIGGER) 96 (void) bzero((char *)&al, sizeof(al)); 97 al.bitmapcount = ATTR_BIT_MAP_COUNT; 98 al.dirattr = ATTR_DIR_MOUNTSTATUS; 99 if (getattrlist(mb->f_mntonname, &al, &ab, sizeof(ab), 0) == 0) { 100 if (ab.mount_flags & DIR_MNTSTATUS_TRIGGER) 101 continue; // if mount trigger 102 } 103#else /* !defined(DIR_MNTSTATUS_TRIGGER) */ 104 if (mb->f_flags & MNT_AUTOMOUNTED) { 105 if (!strncmp(mb->f_mntfromname, "map ", 4) 106 || !strcmp(mb->f_mntfromname, "trigger")) 107 continue; 108 } 109#endif /* defined(DIR_MNTSTATUS_TRIGGER) */ 110 111 /* 112 * Interpolate a possible symbolic directory link. 113 */ 114 if (dn) 115 (void) free((FREE_P *)dn); 116 if (!(dn = mkstrcpy(mb->f_mntonname, (MALLOC_S *)NULL))) { 117 118no_space_for_mount: 119 120 (void) fprintf(stderr, "%s: no space for mount at ", Pn); 121 safestrprt(mb->f_mntonname, stderr, 0); 122 (void) fprintf(stderr, " ("); 123 safestrprt(mb->f_mntfromname, stderr, 0); 124 (void) fprintf(stderr, ")\n"); 125 Exit(1); 126 } 127 if (!(ln = Readlink(dn))) { 128 if (!Fwarn) { 129 (void) fprintf(stderr, 130 " Output information may be incomplete.\n"); 131 } 132 continue; 133 } 134 if (ln != dn) { 135 (void) free((FREE_P *)dn); 136 dn = ln; 137 } 138 if (*dn != '/') 139 continue; 140 /* 141 * Stat() the directory. 142 */ 143 if (statsafely(dn, &sb)) { 144 if (!Fwarn) { 145 (void) fprintf(stderr, "%s: WARNING: can't stat() ", Pn); 146 147 safestrprt(mb->f_fstypename, stderr, 0); 148 149 (void) fprintf(stderr, " file system "); 150 safestrprt(mb->f_mntonname, stderr, 1); 151 (void) fprintf(stderr, 152 " Output information may be incomplete.\n"); 153 } 154 (void) bzero((char *)&sb, sizeof(sb)); 155 sb.st_dev = (dev_t)mb->f_fsid.val[0]; 156 sb.st_mode = S_IFDIR | 0777; 157 if (!Fwarn) { 158 (void) fprintf(stderr, 159 " assuming \"dev=%x\" from mount table\n", 160 sb.st_dev); 161 } 162 } 163 /* 164 * Allocate and fill a local mount structure. 165 */ 166 if (!(mtp = (struct mounts *)malloc(sizeof(struct mounts)))) 167 goto no_space_for_mount; 168 mtp->dir = dn; 169 dn = (char *)NULL; 170 mtp->next = Lmi; 171 mtp->dev = sb.st_dev; 172 mtp->rdev = sb.st_rdev; 173 mtp->inode = (INODETYPE)sb.st_ino; 174 mtp->mode = sb.st_mode; 175 mtp->is_nfs = strcasecmp(mb->f_fstypename, "nfs") ? 0 : 1; 176 /* 177 * Interpolate a possible file system (mounted-on) device name link. 178 */ 179 if (!(dn = mkstrcpy(mb->f_mntfromname, (MALLOC_S *)NULL))) 180 goto no_space_for_mount; 181 mtp->fsname = dn; 182 ln = Readlink(dn); 183 dn = (char *)NULL; 184 /* 185 * Stat() the file system (mounted-on) name and add file system 186 * information to the local mount table entry. 187 */ 188 if (!ln || statsafely(ln, &sb)) 189 sb.st_mode = 0; 190 mtp->fsnmres = ln; 191 mtp->fs_mode = sb.st_mode; 192 Lmi = mtp; 193 } 194/* 195 * Clean up and return the local mount info table address. 196 */ 197 if (dn) 198 (void) free((FREE_P *)dn); 199 Lmist = 1; 200 return(Lmi); 201} 202