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