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