xref: /onnv-gate/usr/src/cmd/rexd/where.c (revision 0)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  *
22*0Sstevel@tonic-gate  * Copyright 2001 Sun Microsystems, Inc.  All rights reserved.
23*0Sstevel@tonic-gate  * Use is subject to license terms.
24*0Sstevel@tonic-gate  */
25*0Sstevel@tonic-gate 
26*0Sstevel@tonic-gate /*
27*0Sstevel@tonic-gate  * where.c - get full pathname including host:
28*0Sstevel@tonic-gate  */
29*0Sstevel@tonic-gate 
30*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
31*0Sstevel@tonic-gate 
32*0Sstevel@tonic-gate 
33*0Sstevel@tonic-gate #include <netdb.h>
34*0Sstevel@tonic-gate #include <stdio.h>
35*0Sstevel@tonic-gate #include <stdlib.h>
36*0Sstevel@tonic-gate #include <string.h>
37*0Sstevel@tonic-gate #include <unistd.h>
38*0Sstevel@tonic-gate #include <fcntl.h>
39*0Sstevel@tonic-gate #include <errno.h>
40*0Sstevel@tonic-gate #include <string.h>
41*0Sstevel@tonic-gate 
42*0Sstevel@tonic-gate #include <sys/mntent.h>
43*0Sstevel@tonic-gate 
44*0Sstevel@tonic-gate #include <sys/mnttab.h>
45*0Sstevel@tonic-gate #include <sys/param.h>
46*0Sstevel@tonic-gate #include <sys/stat.h>
47*0Sstevel@tonic-gate 
48*0Sstevel@tonic-gate #include "sharetab.h"
49*0Sstevel@tonic-gate 
50*0Sstevel@tonic-gate extern	FILE	*setmntent();
51*0Sstevel@tonic-gate 
52*0Sstevel@tonic-gate FILE *setsharetab();
53*0Sstevel@tonic-gate void endsharetab();
54*0Sstevel@tonic-gate 
55*0Sstevel@tonic-gate 
56*0Sstevel@tonic-gate 
57*0Sstevel@tonic-gate extern	int	Debug;
58*0Sstevel@tonic-gate 
59*0Sstevel@tonic-gate /*
60*0Sstevel@tonic-gate  * where(pn, host, fsname, within)
61*0Sstevel@tonic-gate  *
62*0Sstevel@tonic-gate  * pn is the pathname we are looking for,
63*0Sstevel@tonic-gate  * host gets the name of the host owning the file system,
64*0Sstevel@tonic-gate  * fsname gets the file system name on the host,
65*0Sstevel@tonic-gate  * within gets whatever is left from the pathname
66*0Sstevel@tonic-gate  *
67*0Sstevel@tonic-gate  * Returns: 0 if ERROR, 1 if OK
68*0Sstevel@tonic-gate  */
69*0Sstevel@tonic-gate int
70*0Sstevel@tonic-gate where(pn, host, fsname, within)
71*0Sstevel@tonic-gate char *pn;
72*0Sstevel@tonic-gate char *host;
73*0Sstevel@tonic-gate char *fsname;
74*0Sstevel@tonic-gate char *within;
75*0Sstevel@tonic-gate {
76*0Sstevel@tonic-gate 	struct stat sb;
77*0Sstevel@tonic-gate 	char curdir[MAXPATHLEN];
78*0Sstevel@tonic-gate 	char qualpn[MAXPATHLEN];
79*0Sstevel@tonic-gate 	char *p;
80*0Sstevel@tonic-gate 
81*0Sstevel@tonic-gate 	if (Debug)
82*0Sstevel@tonic-gate 	    printf("where: pn %s\n", pn);
83*0Sstevel@tonic-gate 
84*0Sstevel@tonic-gate 	if (stat(pn, &sb) < 0) {
85*0Sstevel@tonic-gate 		char *errstr;
86*0Sstevel@tonic-gate 
87*0Sstevel@tonic-gate 		if ((errstr = strerror(errno)) == NULL)
88*0Sstevel@tonic-gate 			errstr = "unknown error";
89*0Sstevel@tonic-gate 
90*0Sstevel@tonic-gate 		if (Debug)
91*0Sstevel@tonic-gate 		    printf("where: stat failed");
92*0Sstevel@tonic-gate 		strcpy(within, errstr);
93*0Sstevel@tonic-gate 		return (0);
94*0Sstevel@tonic-gate 	}
95*0Sstevel@tonic-gate 	/*
96*0Sstevel@tonic-gate 	 * first get the working directory,
97*0Sstevel@tonic-gate 	 */
98*0Sstevel@tonic-gate 	if (getcwd(curdir, MAXPATHLEN) == NULL) {
99*0Sstevel@tonic-gate 		sprintf(within, "Unable to get working directory (%s)",
100*0Sstevel@tonic-gate 			curdir);
101*0Sstevel@tonic-gate 		return (0);
102*0Sstevel@tonic-gate 	}
103*0Sstevel@tonic-gate 	if (chdir(pn) == 0) {
104*0Sstevel@tonic-gate 		getcwd(qualpn, MAXPATHLEN);
105*0Sstevel@tonic-gate 		chdir(curdir);
106*0Sstevel@tonic-gate 	} else {
107*0Sstevel@tonic-gate 		if (p = strrchr(pn, '/')) {
108*0Sstevel@tonic-gate 			*p = 0;
109*0Sstevel@tonic-gate 			chdir(pn);
110*0Sstevel@tonic-gate 			(void) getcwd(qualpn, MAXPATHLEN);
111*0Sstevel@tonic-gate 			chdir(curdir);
112*0Sstevel@tonic-gate 			strcat(qualpn, "/");
113*0Sstevel@tonic-gate 			strcat(qualpn, p+1);
114*0Sstevel@tonic-gate 		} else {
115*0Sstevel@tonic-gate 			strcpy(qualpn, curdir);
116*0Sstevel@tonic-gate 			strcat(qualpn, "/");
117*0Sstevel@tonic-gate 			strcat(qualpn, pn);
118*0Sstevel@tonic-gate 		}
119*0Sstevel@tonic-gate 	}
120*0Sstevel@tonic-gate 	return (findmount(qualpn, host, fsname, within));
121*0Sstevel@tonic-gate }
122*0Sstevel@tonic-gate 
123*0Sstevel@tonic-gate /*
124*0Sstevel@tonic-gate  * findmount(qualpn, host, fsname, within)
125*0Sstevel@tonic-gate  *
126*0Sstevel@tonic-gate  * Searches the mount table to find the appropriate file system
127*0Sstevel@tonic-gate  * for a given absolute path name.
128*0Sstevel@tonic-gate  * host gets the name of the host owning the file system,
129*0Sstevel@tonic-gate  * fsname gets the file system name on the host,
130*0Sstevel@tonic-gate  * within gets whatever is left from the pathname
131*0Sstevel@tonic-gate  *
132*0Sstevel@tonic-gate  * Returns: 0 on failure, 1 on success.
133*0Sstevel@tonic-gate  */
134*0Sstevel@tonic-gate int
135*0Sstevel@tonic-gate findmount(qualpn, host, fsname, within)
136*0Sstevel@tonic-gate char *qualpn;
137*0Sstevel@tonic-gate char *host;
138*0Sstevel@tonic-gate char *fsname;
139*0Sstevel@tonic-gate char *within;
140*0Sstevel@tonic-gate {
141*0Sstevel@tonic-gate 	FILE	*mfp;
142*0Sstevel@tonic-gate 	char	bestname[MAXPATHLEN];
143*0Sstevel@tonic-gate 	int	bestlen = 0,
144*0Sstevel@tonic-gate 	bestnfs = 0;
145*0Sstevel@tonic-gate 	struct	share *exp;
146*0Sstevel@tonic-gate 	struct	mnttab		mp,
147*0Sstevel@tonic-gate 	*mnt;
148*0Sstevel@tonic-gate 	char	*endhost;	/* points past the colon in name */
149*0Sstevel@tonic-gate 	int	i,
150*0Sstevel@tonic-gate 	len;
151*0Sstevel@tonic-gate 
152*0Sstevel@tonic-gate 	if (Debug)
153*0Sstevel@tonic-gate 		printf("findmount: qualpn %s\n", qualpn);
154*0Sstevel@tonic-gate 
155*0Sstevel@tonic-gate 	for (i = 0; i < 10; i++) {
156*0Sstevel@tonic-gate 		mfp = setmntent("/etc/mnttab", "r");
157*0Sstevel@tonic-gate 		if (mfp != NULL)
158*0Sstevel@tonic-gate 			break;
159*0Sstevel@tonic-gate 		sleep(1);
160*0Sstevel@tonic-gate 	}
161*0Sstevel@tonic-gate 
162*0Sstevel@tonic-gate 	if (mfp == NULL) {
163*0Sstevel@tonic-gate 		sprintf(within, "mount table problem");
164*0Sstevel@tonic-gate 		return (0);
165*0Sstevel@tonic-gate 	}
166*0Sstevel@tonic-gate 
167*0Sstevel@tonic-gate 	bestname[0] = '\0';
168*0Sstevel@tonic-gate 	while ((getmntent(mfp, &mp)) == 0) {
169*0Sstevel@tonic-gate 		if (strcmp(mp.mnt_fstype, "nfs") != 0)
170*0Sstevel@tonic-gate 			/*
171*0Sstevel@tonic-gate 			 * If it is not nfs filesystem type, skip the
172*0Sstevel@tonic-gate 			 * entry
173*0Sstevel@tonic-gate 			 */
174*0Sstevel@tonic-gate 			continue;
175*0Sstevel@tonic-gate 
176*0Sstevel@tonic-gate 		len = preflen(qualpn, mp.mnt_mountp);
177*0Sstevel@tonic-gate 
178*0Sstevel@tonic-gate 		if (Debug)
179*0Sstevel@tonic-gate 			printf("preflen: %d %s %s", len, qualpn, mp.mnt_mountp);
180*0Sstevel@tonic-gate 
181*0Sstevel@tonic-gate 		if (qualpn[len] != '/' && qualpn[len] != '\0' && len > 1)
182*0Sstevel@tonic-gate 			/*
183*0Sstevel@tonic-gate 			 * If the last matching character is neither / nor
184*0Sstevel@tonic-gate 			 * the end of the pathname, not a real match
185*0Sstevel@tonic-gate 			 * (except for matching root, len==1)
186*0Sstevel@tonic-gate 			 */
187*0Sstevel@tonic-gate 			continue;
188*0Sstevel@tonic-gate 
189*0Sstevel@tonic-gate 		if (len > bestlen) {
190*0Sstevel@tonic-gate 			bestlen = len;
191*0Sstevel@tonic-gate 			strncpy(bestname, mp.mnt_special, sizeof (bestname));
192*0Sstevel@tonic-gate 		}
193*0Sstevel@tonic-gate 		if (Debug)
194*0Sstevel@tonic-gate 			printf(" %s\n", bestname);
195*0Sstevel@tonic-gate 	}
196*0Sstevel@tonic-gate 
197*0Sstevel@tonic-gate 	endmntent(mfp);
198*0Sstevel@tonic-gate 
199*0Sstevel@tonic-gate 	endhost = strchr(bestname, ':');
200*0Sstevel@tonic-gate 
201*0Sstevel@tonic-gate 	/*
202*0Sstevel@tonic-gate 	 * If the file system was of type NFS, then there should already
203*0Sstevel@tonic-gate 	 * be a host name, otherwise, use ours.
204*0Sstevel@tonic-gate 	 */
205*0Sstevel@tonic-gate 	if (endhost) {
206*0Sstevel@tonic-gate 		*endhost++ = 0;
207*0Sstevel@tonic-gate 		strncpy(host, bestname, MAXHOSTNAMELEN);
208*0Sstevel@tonic-gate 		strncpy(fsname, endhost, MAXPATHLEN);
209*0Sstevel@tonic-gate 
210*0Sstevel@tonic-gate 		/*
211*0Sstevel@tonic-gate 		 * special case to keep the "/" when we match root
212*0Sstevel@tonic-gate 		 */
213*0Sstevel@tonic-gate 		if (bestlen == 1)
214*0Sstevel@tonic-gate 			bestlen = 0;
215*0Sstevel@tonic-gate 	} else {
216*0Sstevel@tonic-gate 		gethostname(host, MAXHOSTNAMELEN);
217*0Sstevel@tonic-gate 
218*0Sstevel@tonic-gate 		/*
219*0Sstevel@tonic-gate 		 *	If this is our file system, try for an even longer
220*0Sstevel@tonic-gate 		 *	match from /etc/xtab.
221*0Sstevel@tonic-gate 		 */
222*0Sstevel@tonic-gate 		if (mfp = setsharetab()) {
223*0Sstevel@tonic-gate 			while (getshare(mfp, &exp) > 0)
224*0Sstevel@tonic-gate 				if (len = preflen(qualpn, exp->sh_path))
225*0Sstevel@tonic-gate 					if (len > bestlen) {
226*0Sstevel@tonic-gate 						bestlen = len;
227*0Sstevel@tonic-gate 						strncpy(bestname, exp->sh_path,
228*0Sstevel@tonic-gate 							sizeof (bestname));
229*0Sstevel@tonic-gate 					}
230*0Sstevel@tonic-gate 			endsharetab(mfp);
231*0Sstevel@tonic-gate 		}
232*0Sstevel@tonic-gate 		strncpy(fsname, qualpn, bestlen);
233*0Sstevel@tonic-gate 		fsname[bestlen] = 0;
234*0Sstevel@tonic-gate 	}
235*0Sstevel@tonic-gate 	strncpy(within, qualpn + bestlen, MAXPATHLEN);
236*0Sstevel@tonic-gate 
237*0Sstevel@tonic-gate 	if (Debug)
238*0Sstevel@tonic-gate 		printf("findmount: qualpn %s\nhost %s\nfsname %s\nwithin %s\n",
239*0Sstevel@tonic-gate 			qualpn, host, fsname, within);
240*0Sstevel@tonic-gate 	return (1);
241*0Sstevel@tonic-gate }
242*0Sstevel@tonic-gate 
243*0Sstevel@tonic-gate /*
244*0Sstevel@tonic-gate  * Returns: length of second argument if it is a prefix of the
245*0Sstevel@tonic-gate  * first argument, otherwise zero.
246*0Sstevel@tonic-gate  */
247*0Sstevel@tonic-gate int
248*0Sstevel@tonic-gate preflen(str, pref)
249*0Sstevel@tonic-gate char	*str, *pref;
250*0Sstevel@tonic-gate {
251*0Sstevel@tonic-gate 	int len;
252*0Sstevel@tonic-gate 
253*0Sstevel@tonic-gate 	len = strlen(pref);
254*0Sstevel@tonic-gate 	if (strncmp(str, pref, len) == 0)
255*0Sstevel@tonic-gate 		return (len);
256*0Sstevel@tonic-gate 	return (0);
257*0Sstevel@tonic-gate }
258*0Sstevel@tonic-gate 
259*0Sstevel@tonic-gate FILE
260*0Sstevel@tonic-gate *setsharetab()
261*0Sstevel@tonic-gate {
262*0Sstevel@tonic-gate 	FILE	*f;
263*0Sstevel@tonic-gate 	int	fd;
264*0Sstevel@tonic-gate 
265*0Sstevel@tonic-gate 	/*
266*0Sstevel@tonic-gate 	 * Create the tab file if it does not exist already
267*0Sstevel@tonic-gate 	 */
268*0Sstevel@tonic-gate 	if (access(SHARETAB, F_OK) < 0)	{
269*0Sstevel@tonic-gate 		fd = open(SHARETAB, O_CREAT, 0644);
270*0Sstevel@tonic-gate 		close(fd);
271*0Sstevel@tonic-gate 	}
272*0Sstevel@tonic-gate 	if (access(SHARETAB, W_OK) == 0) {
273*0Sstevel@tonic-gate 		f = fopen(SHARETAB, "r+");
274*0Sstevel@tonic-gate 	} else {
275*0Sstevel@tonic-gate 		f = fopen(SHARETAB, "r");
276*0Sstevel@tonic-gate 	}
277*0Sstevel@tonic-gate 	if (f == NULL) {
278*0Sstevel@tonic-gate 		return (NULL);
279*0Sstevel@tonic-gate 	}
280*0Sstevel@tonic-gate 	if (lockf(fileno(f), F_LOCK, 0L) < 0) {
281*0Sstevel@tonic-gate 		(void) fclose(f);
282*0Sstevel@tonic-gate 		return (NULL);
283*0Sstevel@tonic-gate 	}
284*0Sstevel@tonic-gate 	return (f);
285*0Sstevel@tonic-gate }
286*0Sstevel@tonic-gate 
287*0Sstevel@tonic-gate 
288*0Sstevel@tonic-gate void
289*0Sstevel@tonic-gate endsharetab(f)
290*0Sstevel@tonic-gate FILE	*f;
291*0Sstevel@tonic-gate {
292*0Sstevel@tonic-gate 	(void) fclose(f);
293*0Sstevel@tonic-gate }
294