8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / sh / pwd.c
blob631434454d4711d0663bc3dad4d3a2beff335d82
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright 2015 PALO, Richard.
27 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
31 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
32 /* All Rights Reserved */
36 * UNIX shell
39 #include "mac.h"
40 #include <errno.h>
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #include <limits.h>
44 #include "defs.h"
46 #define DOT '.'
47 #define NULLCHAR '\0'
48 #define SLASH '/'
49 #define PARTLY 2
51 static void rmslash(unsigned char *string);
52 #ifdef __STDC__
53 extern const char longpwd[];
54 #else
55 extern char longpwd[];
56 #endif
57 extern char *getcwd();
59 unsigned char cwdname[PATH_MAX+1];
61 static int didpwd = FALSE;
63 void
64 cwd(unsigned char *dir)
66 unsigned char *pcwd;
67 unsigned char *pdir;
69 /* First remove extra /'s */
71 rmslash(dir);
73 /* Now remove any .'s */
75 pdir = dir;
76 if (*dir == SLASH)
77 pdir++;
78 while (*pdir) { /* remove /./ by itself */
79 if ((*pdir == DOT) && (*(pdir+1) == SLASH)) {
80 movstr(pdir+2, pdir);
81 continue;
83 pdir++;
84 while ((*pdir) && (*pdir != SLASH))
85 pdir++;
86 if (*pdir)
87 pdir++;
89 /* take care of trailing /. */
90 if (*(--pdir) == DOT && pdir > dir && *(--pdir) == SLASH) {
91 if (pdir > dir) {
92 *pdir = NULLCHAR;
93 } else {
94 *(pdir+1) = NULLCHAR;
99 /* Remove extra /'s */
101 rmslash(dir);
103 /* Now that the dir is canonicalized, process it */
105 if (*dir == DOT && *(dir+1) == NULLCHAR) {
106 return;
110 if (*dir == SLASH) {
111 /* Absolute path */
113 pcwd = cwdname;
114 *pcwd++ = *dir++;
115 didpwd = PARTLY;
117 else
119 /* Relative path */
121 if (didpwd == FALSE)
122 return;
123 didpwd = PARTLY;
124 pcwd = cwdname + length(cwdname) - 1;
125 if (pcwd != cwdname+1)
126 *pcwd++ = SLASH;
128 while (*dir) {
129 if (*dir == DOT &&
130 *(dir+1) == DOT &&
131 (*(dir+2) == SLASH || *(dir+2) == NULLCHAR)) {
132 /* Parent directory, so backup one */
134 if (pcwd > cwdname+2)
135 --pcwd;
136 while (*(--pcwd) != SLASH)
138 pcwd++;
139 dir += 2;
140 if (*dir == SLASH) {
141 dir++;
143 continue;
145 if (pcwd >= &cwdname[PATH_MAX+1]) {
146 didpwd = FALSE;
147 return;
149 *pcwd++ = *dir++;
150 while ((*dir) && (*dir != SLASH)) {
151 if (pcwd >= &cwdname[PATH_MAX+1]) {
152 didpwd = FALSE;
153 return;
155 *pcwd++ = *dir++;
157 if (*dir) {
158 if (pcwd >= &cwdname[PATH_MAX+1]) {
159 didpwd = FALSE;
160 return;
162 *pcwd++ = *dir++;
165 if (pcwd >= &cwdname[PATH_MAX+1]) {
166 didpwd = FALSE;
167 return;
169 *pcwd = NULLCHAR;
171 --pcwd;
172 if (pcwd > cwdname && *pcwd == SLASH) {
173 /* Remove trailing / */
175 *pcwd = NULLCHAR;
179 void
180 cwd2()
182 struct stat stat1, stat2;
183 unsigned char *pcwd;
184 /* check if there are any symbolic links in pathname */
186 if (didpwd == FALSE)
187 return;
188 pcwd = cwdname + 1;
189 if (didpwd == PARTLY) {
190 while (*pcwd) {
191 char c;
192 do {
193 c = *pcwd++;
194 } while (c != SLASH && c != NULLCHAR);
195 *--pcwd = NULLCHAR;
196 if (lstat((char *)cwdname, &stat1) == -1 ||
197 (stat1.st_mode & S_IFMT) == S_IFLNK) {
198 didpwd = FALSE;
199 *pcwd = c;
200 return;
202 *pcwd = c;
203 if (c)
204 pcwd++;
206 didpwd = TRUE;
207 } else
208 if (stat((char *)cwdname, &stat1) == -1) {
209 didpwd = FALSE;
210 return;
213 * check if ino's and dev's match; pathname could
214 * consist of symbolic links with ".."
217 if (stat(".", &stat2) == -1 ||
218 stat1.st_dev != stat2.st_dev ||
219 stat1.st_ino != stat2.st_ino)
220 didpwd = FALSE;
223 unsigned char *
224 cwdget()
226 cwd2();
227 if (didpwd == FALSE) {
228 if (getcwd((char *)cwdname, PATH_MAX+1) == NULL)
229 *cwdname = NULLCHAR;
230 didpwd = TRUE;
232 return (cwdname);
236 * Print the current working directory.
239 void
240 cwdprint(void)
242 unsigned char *cp;
244 cwd2();
245 if (didpwd == FALSE) {
246 if (getcwd((char *)cwdname, PATH_MAX+1) == NULL) {
247 if (errno && errno != ERANGE)
248 error(badpwd);
249 else
250 error(longpwd);
252 didpwd = TRUE;
255 for (cp = cwdname; *cp; cp++) {
256 prc_buff(*cp);
259 prc_buff(NL);
263 * This routine will remove repeated slashes from string.
266 static void
267 rmslash(unsigned char *string)
269 unsigned char *pstring;
271 pstring = string;
272 while (*pstring) {
273 if (*pstring == SLASH && *(pstring+1) == SLASH) {
274 /* Remove repeated SLASH's */
276 movstr(pstring+1, pstring);
277 continue;
279 pstring++;
282 --pstring;
283 if (pstring > string && *pstring == SLASH) {
284 /* Remove trailing / */
286 *pstring = NULLCHAR;