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