1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22/* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Copyright 2006 Ricardo Correia. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28/* Copyright (c) 1988 AT&T */ 29/* All Rights Reserved */ 30 31#include <stdio.h> 32#include <string.h> 33#include <mntent.h> 34#include <sys/errno.h> 35#include <sys/mnttab.h> 36 37#include <sys/types.h> 38#include <sys/sysmacros.h> 39#include <sys/stat.h> 40#include <unistd.h> 41 42#define BUFSIZE (MNT_LINE_MAX + 2) 43 44__thread char buf[BUFSIZE]; 45 46#define DIFF(xx) ( \ 47 (mrefp->xx != NULL) && \ 48 (mgetp->xx == NULL || strcmp(mrefp->xx, mgetp->xx) != 0)) 49 50int 51getmntany(FILE *fp, struct mnttab *mgetp, struct mnttab *mrefp) 52{ 53 int ret; 54 55 while ( 56 ((ret = _sol_getmntent(fp, mgetp)) == 0) && ( 57 DIFF(mnt_special) || DIFF(mnt_mountp) || 58 DIFF(mnt_fstype) || DIFF(mnt_mntopts))) { } 59 60 return (ret); 61} 62 63int 64_sol_getmntent(FILE *fp, struct mnttab *mgetp) 65{ 66 struct mntent mntbuf; 67 struct mntent *ret; 68 69 ret = getmntent_r(fp, &mntbuf, buf, BUFSIZE); 70 71 if (ret != NULL) { 72 mgetp->mnt_special = mntbuf.mnt_fsname; 73 mgetp->mnt_mountp = mntbuf.mnt_dir; 74 mgetp->mnt_fstype = mntbuf.mnt_type; 75 mgetp->mnt_mntopts = mntbuf.mnt_opts; 76 return (0); 77 } 78 79 if (feof(fp)) 80 return (-1); 81 82 return (MNT_TOOLONG); 83} 84 85static int 86getextmntent_impl(FILE *fp, struct extmnttab *mp, int len) 87{ 88 int ret; 89 struct stat64 st; 90 91 ret = _sol_getmntent(fp, (struct mnttab *)mp); 92 if (ret == 0) { 93 if (stat64(mp->mnt_mountp, &st) != 0) { 94 mp->mnt_major = 0; 95 mp->mnt_minor = 0; 96 return (ret); 97 } 98 mp->mnt_major = major(st.st_dev); 99 mp->mnt_minor = minor(st.st_dev); 100 } 101 102 return (ret); 103} 104 105int 106getextmntent(const char *path, struct extmnttab *entry, struct stat64 *statbuf) 107{ 108 struct stat64 st; 109 FILE *fp; 110 int match; 111 112 if (strlen(path) >= MAXPATHLEN) { 113 (void) fprintf(stderr, "invalid object; pathname too long\n"); 114 return (-1); 115 } 116 117 /* 118 * Search for the path in /proc/self/mounts. Rather than looking for the 119 * specific path, which can be fooled by non-standard paths (i.e. ".." 120 * or "//"), we stat() the path and search for the corresponding 121 * (major,minor) device pair. 122 */ 123 if (stat64(path, statbuf) != 0) { 124 (void) fprintf(stderr, "cannot open '%s': %s\n", 125 path, strerror(errno)); 126 return (-1); 127 } 128 129 130#ifdef HAVE_SETMNTENT 131 if ((fp = setmntent(MNTTAB, "re")) == NULL) { 132#else 133 if ((fp = fopen(MNTTAB, "re")) == NULL) { 134#endif 135 (void) fprintf(stderr, "cannot open %s\n", MNTTAB); 136 return (-1); 137 } 138 139 /* 140 * Search for the given (major,minor) pair in the mount table. 141 */ 142 143 match = 0; 144 while (getextmntent_impl(fp, entry, sizeof (*entry)) == 0) { 145 if (makedev(entry->mnt_major, entry->mnt_minor) == 146 statbuf->st_dev) { 147 match = 1; 148 break; 149 } 150 } 151 (void) fclose(fp); 152 153 if (!match) { 154 (void) fprintf(stderr, "cannot find mountpoint for '%s'\n", 155 path); 156 return (-1); 157 } 158 159 if (stat64(entry->mnt_mountp, &st) != 0) { 160 entry->mnt_major = 0; 161 entry->mnt_minor = 0; 162 return (-1); 163 } 164 165 return (0); 166} 167