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 2004 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#pragma ident	"%Z%%M%	%I%	%E% SMI"
28
29#include <stdlib.h>
30#include <sys/types.h>
31#include <stdio.h>
32#include <sys/mnttab.h>
33#include <sys/mntent.h>
34#include <sys/stat.h>
35#include <sys/time.h>
36#include <string.h>
37#include <fcntl.h>
38
39#include "statcommon.h"
40#include "dsr.h"
41
42static time_t mtime;
43mnt_t *nfs;
44static mnt_t *ufs;
45
46static void build_mnt_list(FILE *);
47
48mnt_t *
49lookup_mntent_byname(char *nm)
50{
51	mnt_t *rv = 0;
52	mnt_t *minfo;
53	uint_t did_nfs;
54
55
56	if (nm) {
57		minfo = ufs;
58		did_nfs = 0;
59		while (minfo) {
60			if (strcmp(nm, minfo->device_name)) {
61				if (minfo->next != 0)
62					minfo = minfo->next;
63				else if (did_nfs == 0) {
64					minfo = nfs;
65					did_nfs = 1;
66				}
67				else
68					minfo = 0;
69			} else {
70				rv = minfo;
71				break;
72			}
73		}
74	}
75	return (rv);
76}
77
78void
79do_mnttab(void)
80{
81	struct stat 	buf;
82	FILE 		*mpt;
83	struct flock    lb;
84
85	if (stat(MNTTAB, &buf) == 0) {
86		if (buf.st_mtime != mtime) {
87			/*
88			 * File has changed. Get the new file.
89			 */
90			if ((mpt = fopen(MNTTAB, "r"))) {
91				lb.l_type = F_RDLCK;
92				lb.l_whence = 0;
93				lb.l_start = 0;
94				lb.l_len = 0;
95				(void) fcntl(fileno(mpt), F_SETLKW, &lb);
96				build_mnt_list(mpt);
97				mtime = buf.st_mtime;
98				/*
99				 * Lock goes away when we close the file.
100				 */
101				(void) fclose(mpt);
102			}
103		}
104	}
105}
106
107static void
108build_mnt_list(FILE *mpt)
109{
110	mnt_t *item;
111	mnt_t **which;
112	mnt_t *tmp;
113	int  found;
114	struct extmnttab mnt;
115
116	if (mpt) {
117		while (nfs) {
118			free(nfs->device_name);
119			free(nfs->mount_point);
120			free(nfs->devinfo);
121			tmp = nfs;
122			nfs = nfs->next;
123			free(tmp);
124		}
125		while (ufs) {
126			free(ufs->device_name);
127			free(ufs->mount_point);
128			free(ufs->devinfo);
129			tmp = ufs;
130			ufs = ufs->next;
131			free(tmp);
132		}
133		(void) memset(&mnt, 0, sizeof (struct extmnttab));
134
135		resetmnttab(mpt);
136		while ((found = getextmntent(mpt, &mnt,
137			sizeof (struct extmnttab))) != -1) {
138			if (found == 0) {
139				if (strcmp(mnt.mnt_fstype, MNTTYPE_UFS) == 0)
140					which = &ufs;
141				else if (strcmp(mnt.mnt_fstype,
142				    MNTTYPE_NFS) == 0)
143					which = &nfs;
144				else
145					which = 0;
146				if (which) {
147					item = safe_alloc(sizeof (mnt_t));
148					item->device_name =
149						safe_strdup(mnt.mnt_special);
150					item->mount_point =
151						safe_strdup(mnt.mnt_mountp);
152					item->devinfo =
153						safe_strdup(mnt.mnt_mntopts);
154					item->minor = mnt.mnt_minor;
155					item->next = *which;
156					*which = item;
157				}
158			}
159		}
160	}
161}
162