17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*39e7390aSna195498 * Common Development and Distribution License (the "License"). 6*39e7390aSna195498 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 21965005c8Schin 22965005c8Schin /* 23*39e7390aSna195498 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24965005c8Schin * Use is subject to license terms. 25965005c8Schin */ 26965005c8Schin 277c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 287c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate 31965005c8Schin #pragma ident "%Z%%M% %I% %E% SMI" 327c478bd9Sstevel@tonic-gate /* 337c478bd9Sstevel@tonic-gate * UNIX shell 347c478bd9Sstevel@tonic-gate */ 357c478bd9Sstevel@tonic-gate 367c478bd9Sstevel@tonic-gate #include "mac.h" 377c478bd9Sstevel@tonic-gate #include <errno.h> 387c478bd9Sstevel@tonic-gate #include <sys/types.h> 397c478bd9Sstevel@tonic-gate #include <sys/stat.h> 407c478bd9Sstevel@tonic-gate #include <limits.h> 41*39e7390aSna195498 #include "defs.h" 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate #define DOT '.' 447c478bd9Sstevel@tonic-gate #define NULL 0 457c478bd9Sstevel@tonic-gate #define SLASH '/' 467c478bd9Sstevel@tonic-gate #define PARTLY 2 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate static void rmslash(); 497c478bd9Sstevel@tonic-gate #ifdef __STDC__ 507c478bd9Sstevel@tonic-gate extern const char longpwd[]; 517c478bd9Sstevel@tonic-gate #else 527c478bd9Sstevel@tonic-gate extern char longpwd[]; 537c478bd9Sstevel@tonic-gate #endif 547c478bd9Sstevel@tonic-gate extern char *getcwd(); 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate unsigned char cwdname[PATH_MAX+1]; 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate static int didpwd = FALSE; 597c478bd9Sstevel@tonic-gate 60965005c8Schin void 61965005c8Schin cwd(unsigned char *dir) 627c478bd9Sstevel@tonic-gate { 63965005c8Schin unsigned char *pcwd; 64965005c8Schin unsigned char *pdir; 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate /* First remove extra /'s */ 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate rmslash(dir); 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate /* Now remove any .'s */ 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate pdir = dir; 737c478bd9Sstevel@tonic-gate if(*dir == SLASH) 747c478bd9Sstevel@tonic-gate pdir++; 757c478bd9Sstevel@tonic-gate while(*pdir) /* remove /./ by itself */ 767c478bd9Sstevel@tonic-gate { 777c478bd9Sstevel@tonic-gate if((*pdir==DOT) && (*(pdir+1)==SLASH)) 787c478bd9Sstevel@tonic-gate { 797c478bd9Sstevel@tonic-gate movstr(pdir+2, pdir); 807c478bd9Sstevel@tonic-gate continue; 817c478bd9Sstevel@tonic-gate } 827c478bd9Sstevel@tonic-gate pdir++; 837c478bd9Sstevel@tonic-gate while ((*pdir) && (*pdir != SLASH)) 847c478bd9Sstevel@tonic-gate pdir++; 857c478bd9Sstevel@tonic-gate if (*pdir) 867c478bd9Sstevel@tonic-gate pdir++; 877c478bd9Sstevel@tonic-gate } 887c478bd9Sstevel@tonic-gate /* take care of trailing /. */ 897c478bd9Sstevel@tonic-gate if(*(--pdir)==DOT && pdir > dir && *(--pdir)==SLASH) { 907c478bd9Sstevel@tonic-gate if(pdir > dir) { 917c478bd9Sstevel@tonic-gate *pdir = NULL; 927c478bd9Sstevel@tonic-gate } else { 937c478bd9Sstevel@tonic-gate *(pdir+1) = NULL; 947c478bd9Sstevel@tonic-gate } 957c478bd9Sstevel@tonic-gate 967c478bd9Sstevel@tonic-gate } 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate /* Remove extra /'s */ 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate rmslash(dir); 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate /* Now that the dir is canonicalized, process it */ 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate if(*dir==DOT && *(dir+1)==NULL) 1057c478bd9Sstevel@tonic-gate { 1067c478bd9Sstevel@tonic-gate return; 1077c478bd9Sstevel@tonic-gate } 1087c478bd9Sstevel@tonic-gate 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate if(*dir==SLASH) 1117c478bd9Sstevel@tonic-gate { 1127c478bd9Sstevel@tonic-gate /* Absolute path */ 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate pcwd = cwdname; 1157c478bd9Sstevel@tonic-gate *pcwd++ = *dir++; 1167c478bd9Sstevel@tonic-gate didpwd = PARTLY; 1177c478bd9Sstevel@tonic-gate } 1187c478bd9Sstevel@tonic-gate else 1197c478bd9Sstevel@tonic-gate { 1207c478bd9Sstevel@tonic-gate /* Relative path */ 1217c478bd9Sstevel@tonic-gate 1227c478bd9Sstevel@tonic-gate if (didpwd == FALSE) 1237c478bd9Sstevel@tonic-gate return; 1247c478bd9Sstevel@tonic-gate didpwd = PARTLY; 1257c478bd9Sstevel@tonic-gate pcwd = cwdname + length(cwdname) - 1; 1267c478bd9Sstevel@tonic-gate if(pcwd != cwdname+1) 1277c478bd9Sstevel@tonic-gate *pcwd++ = SLASH; 1287c478bd9Sstevel@tonic-gate } 1297c478bd9Sstevel@tonic-gate while(*dir) 1307c478bd9Sstevel@tonic-gate { 1317c478bd9Sstevel@tonic-gate if(*dir==DOT && 1327c478bd9Sstevel@tonic-gate *(dir+1)==DOT && 1337c478bd9Sstevel@tonic-gate (*(dir+2)==SLASH || *(dir+2)==NULL)) 1347c478bd9Sstevel@tonic-gate { 1357c478bd9Sstevel@tonic-gate /* Parent directory, so backup one */ 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate if( pcwd > cwdname+2 ) 1387c478bd9Sstevel@tonic-gate --pcwd; 1397c478bd9Sstevel@tonic-gate while(*(--pcwd) != SLASH) 1407c478bd9Sstevel@tonic-gate ; 1417c478bd9Sstevel@tonic-gate pcwd++; 1427c478bd9Sstevel@tonic-gate dir += 2; 1437c478bd9Sstevel@tonic-gate if(*dir==SLASH) 1447c478bd9Sstevel@tonic-gate { 1457c478bd9Sstevel@tonic-gate dir++; 1467c478bd9Sstevel@tonic-gate } 1477c478bd9Sstevel@tonic-gate continue; 1487c478bd9Sstevel@tonic-gate } 1497c478bd9Sstevel@tonic-gate if (pcwd >= &cwdname[PATH_MAX+1]) 1507c478bd9Sstevel@tonic-gate { 1517c478bd9Sstevel@tonic-gate didpwd=FALSE; 1527c478bd9Sstevel@tonic-gate return; 1537c478bd9Sstevel@tonic-gate } 1547c478bd9Sstevel@tonic-gate *pcwd++ = *dir++; 1557c478bd9Sstevel@tonic-gate while((*dir) && (*dir != SLASH)) 1567c478bd9Sstevel@tonic-gate { 1577c478bd9Sstevel@tonic-gate if (pcwd >= &cwdname[PATH_MAX+1]) 1587c478bd9Sstevel@tonic-gate { 1597c478bd9Sstevel@tonic-gate didpwd=FALSE; 1607c478bd9Sstevel@tonic-gate return; 1617c478bd9Sstevel@tonic-gate } 1627c478bd9Sstevel@tonic-gate *pcwd++ = *dir++; 1637c478bd9Sstevel@tonic-gate } 1647c478bd9Sstevel@tonic-gate if (*dir) 1657c478bd9Sstevel@tonic-gate { 1667c478bd9Sstevel@tonic-gate if (pcwd >= &cwdname[PATH_MAX+1]) 1677c478bd9Sstevel@tonic-gate { 1687c478bd9Sstevel@tonic-gate didpwd=FALSE; 1697c478bd9Sstevel@tonic-gate return; 1707c478bd9Sstevel@tonic-gate } 1717c478bd9Sstevel@tonic-gate *pcwd++ = *dir++; 1727c478bd9Sstevel@tonic-gate } 1737c478bd9Sstevel@tonic-gate } 1747c478bd9Sstevel@tonic-gate if (pcwd >= &cwdname[PATH_MAX+1]) 1757c478bd9Sstevel@tonic-gate { 1767c478bd9Sstevel@tonic-gate didpwd=FALSE; 1777c478bd9Sstevel@tonic-gate return; 1787c478bd9Sstevel@tonic-gate } 1797c478bd9Sstevel@tonic-gate *pcwd = NULL; 1807c478bd9Sstevel@tonic-gate 1817c478bd9Sstevel@tonic-gate --pcwd; 1827c478bd9Sstevel@tonic-gate if(pcwd>cwdname && *pcwd==SLASH) 1837c478bd9Sstevel@tonic-gate { 1847c478bd9Sstevel@tonic-gate /* Remove trailing / */ 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate *pcwd = NULL; 1877c478bd9Sstevel@tonic-gate } 1887c478bd9Sstevel@tonic-gate return; 1897c478bd9Sstevel@tonic-gate } 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate void 1927c478bd9Sstevel@tonic-gate cwd2() 1937c478bd9Sstevel@tonic-gate { 1947c478bd9Sstevel@tonic-gate struct stat stat1, stat2; 1957c478bd9Sstevel@tonic-gate unsigned char *pcwd; 1967c478bd9Sstevel@tonic-gate /* check if there are any symbolic links in pathname */ 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate if(didpwd == FALSE) 1997c478bd9Sstevel@tonic-gate return; 2007c478bd9Sstevel@tonic-gate pcwd = cwdname + 1; 2017c478bd9Sstevel@tonic-gate if(didpwd == PARTLY) { 2027c478bd9Sstevel@tonic-gate while (*pcwd) 2037c478bd9Sstevel@tonic-gate { 2047c478bd9Sstevel@tonic-gate char c; 2057c478bd9Sstevel@tonic-gate while((c = *pcwd++) != SLASH && c != '\0'); 2067c478bd9Sstevel@tonic-gate *--pcwd = '\0'; 2077c478bd9Sstevel@tonic-gate if (lstat((char *)cwdname, &stat1) == -1 2087c478bd9Sstevel@tonic-gate || (stat1.st_mode & S_IFMT) == S_IFLNK) { 2097c478bd9Sstevel@tonic-gate didpwd = FALSE; 2107c478bd9Sstevel@tonic-gate *pcwd = c; 2117c478bd9Sstevel@tonic-gate return; 2127c478bd9Sstevel@tonic-gate } 2137c478bd9Sstevel@tonic-gate *pcwd = c; 2147c478bd9Sstevel@tonic-gate if(c) 2157c478bd9Sstevel@tonic-gate pcwd++; 2167c478bd9Sstevel@tonic-gate } 2177c478bd9Sstevel@tonic-gate didpwd = TRUE; 2187c478bd9Sstevel@tonic-gate } else 2197c478bd9Sstevel@tonic-gate if (stat((char *)cwdname, &stat1) == -1) { 2207c478bd9Sstevel@tonic-gate didpwd = FALSE; 2217c478bd9Sstevel@tonic-gate return; 2227c478bd9Sstevel@tonic-gate } 2237c478bd9Sstevel@tonic-gate /* 2247c478bd9Sstevel@tonic-gate * check if ino's and dev's match; pathname could 2257c478bd9Sstevel@tonic-gate * consist of symbolic links with ".." 2267c478bd9Sstevel@tonic-gate */ 2277c478bd9Sstevel@tonic-gate 2287c478bd9Sstevel@tonic-gate if (stat(".", &stat2) == -1 2297c478bd9Sstevel@tonic-gate || stat1.st_dev != stat2.st_dev 2307c478bd9Sstevel@tonic-gate || stat1.st_ino != stat2.st_ino) 2317c478bd9Sstevel@tonic-gate didpwd = FALSE; 2327c478bd9Sstevel@tonic-gate return; 2337c478bd9Sstevel@tonic-gate } 2347c478bd9Sstevel@tonic-gate 2357c478bd9Sstevel@tonic-gate unsigned char * 2367c478bd9Sstevel@tonic-gate cwdget() 2377c478bd9Sstevel@tonic-gate { 2387c478bd9Sstevel@tonic-gate cwd2(); 2397c478bd9Sstevel@tonic-gate if (didpwd == FALSE) { 240*39e7390aSna195498 if (getcwd((char *)cwdname, PATH_MAX+1) == NULL) 2417c478bd9Sstevel@tonic-gate *cwdname = 0; 2427c478bd9Sstevel@tonic-gate didpwd = TRUE; 2437c478bd9Sstevel@tonic-gate } 2447c478bd9Sstevel@tonic-gate return (cwdname); 2457c478bd9Sstevel@tonic-gate } 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gate /* 2487c478bd9Sstevel@tonic-gate * Print the current working directory. 2497c478bd9Sstevel@tonic-gate */ 2507c478bd9Sstevel@tonic-gate 251965005c8Schin void 252965005c8Schin cwdprint(void) 2537c478bd9Sstevel@tonic-gate { 254965005c8Schin unsigned char *cp; 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate cwd2(); 2577c478bd9Sstevel@tonic-gate if (didpwd == FALSE) { 258*39e7390aSna195498 if (getcwd((char *)cwdname, PATH_MAX+1) == NULL) { 2597c478bd9Sstevel@tonic-gate if (errno && errno != ERANGE) 260*39e7390aSna195498 error(badpwd); 2617c478bd9Sstevel@tonic-gate else 2627c478bd9Sstevel@tonic-gate error(longpwd); 2637c478bd9Sstevel@tonic-gate } 2647c478bd9Sstevel@tonic-gate didpwd = TRUE; 2657c478bd9Sstevel@tonic-gate } 2667c478bd9Sstevel@tonic-gate 2677c478bd9Sstevel@tonic-gate for (cp = cwdname; *cp; cp++) { 2687c478bd9Sstevel@tonic-gate prc_buff(*cp); 2697c478bd9Sstevel@tonic-gate } 2707c478bd9Sstevel@tonic-gate 2717c478bd9Sstevel@tonic-gate prc_buff(NL); 2727c478bd9Sstevel@tonic-gate return; 2737c478bd9Sstevel@tonic-gate } 2747c478bd9Sstevel@tonic-gate 2757c478bd9Sstevel@tonic-gate /* 2767c478bd9Sstevel@tonic-gate * This routine will remove repeated slashes from string. 2777c478bd9Sstevel@tonic-gate */ 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate static void 2807c478bd9Sstevel@tonic-gate rmslash(string) 2817c478bd9Sstevel@tonic-gate unsigned char *string; 2827c478bd9Sstevel@tonic-gate { 283965005c8Schin unsigned char *pstring; 2847c478bd9Sstevel@tonic-gate 2857c478bd9Sstevel@tonic-gate pstring = string; 2867c478bd9Sstevel@tonic-gate while(*pstring) 2877c478bd9Sstevel@tonic-gate { 2887c478bd9Sstevel@tonic-gate if(*pstring==SLASH && *(pstring+1)==SLASH) 2897c478bd9Sstevel@tonic-gate { 2907c478bd9Sstevel@tonic-gate /* Remove repeated SLASH's */ 2917c478bd9Sstevel@tonic-gate 2927c478bd9Sstevel@tonic-gate movstr(pstring+1, pstring); 2937c478bd9Sstevel@tonic-gate continue; 2947c478bd9Sstevel@tonic-gate } 2957c478bd9Sstevel@tonic-gate pstring++; 2967c478bd9Sstevel@tonic-gate } 2977c478bd9Sstevel@tonic-gate 2987c478bd9Sstevel@tonic-gate --pstring; 2997c478bd9Sstevel@tonic-gate if(pstring>string && *pstring==SLASH) 3007c478bd9Sstevel@tonic-gate { 3017c478bd9Sstevel@tonic-gate /* Remove trailing / */ 3027c478bd9Sstevel@tonic-gate 3037c478bd9Sstevel@tonic-gate *pstring = NULL; 3047c478bd9Sstevel@tonic-gate } 3057c478bd9Sstevel@tonic-gate return; 3067c478bd9Sstevel@tonic-gate } 307