remove OSF1 support
[oweals/cde.git] / cde / programs / dtksh / ksh93 / src / cmd / ksh93 / bltins / cd_pwd.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: cd_pwd.c /main/3 1995/11/01 16:27:31 rswiston $ */
24 /***************************************************************
25 *                                                              *
26 *                      AT&T - PROPRIETARY                      *
27 *                                                              *
28 *        THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF        *
29 *                    AT&T BELL LABORATORIES                    *
30 *         AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN         *
31 *            ACCORDANCE WITH APPLICABLE AGREEMENTS             *
32 *                                                              *
33 *                Copyright (c) 1995 AT&T Corp.                 *
34 *              Unpublished & Not for Publication               *
35 *                     All Rights Reserved                      *
36 *                                                              *
37 *       The copyright notice above does not evidence any       *
38 *      actual or intended publication of such source code      *
39 *                                                              *
40 *               This software was created by the               *
41 *           Advanced Software Technology Department            *
42 *                    AT&T Bell Laboratories                    *
43 *                                                              *
44 *               For further information contact                *
45 *                    {research,attmail}!dgk                    *
46 *                                                              *
47 ***************************************************************/
48
49 /* : : generated by proto : : */
50
51 #if !defined(__PROTO__)
52 #if defined(__STDC__) || defined(__cplusplus) || defined(_proto) || defined(c_plusplus)
53 #if defined(__cplusplus)
54 #define __MANGLE__      "C"
55 #else
56 #define __MANGLE__
57 #endif
58 #define __STDARG__
59 #define __PROTO__(x)    x
60 #define __OTORP__(x)
61 #define __PARAM__(n,o)  n
62 #if !defined(__STDC__) && !defined(__cplusplus)
63 #if !defined(c_plusplus)
64 #define const
65 #endif
66 #define signed
67 #define void            int
68 #define volatile
69 #define __V_            char
70 #else
71 #define __V_            void
72 #endif
73 #else
74 #define __PROTO__(x)    ()
75 #define __OTORP__(x)    x
76 #define __PARAM__(n,o)  o
77 #define __MANGLE__
78 #define __V_            char
79 #define const
80 #define signed
81 #define void            int
82 #define volatile
83 #endif
84 #if defined(__cplusplus) || defined(c_plusplus)
85 #define __VARARG__      ...
86 #else
87 #define __VARARG__
88 #endif
89 #if defined(__STDARG__)
90 #define __VA_START__(p,a)       va_start(p,a)
91 #else
92 #define __VA_START__(p,a)       va_start(p)
93 #endif
94 #endif
95 #include        "defs.h"
96 #include        <stak.h>
97 #include        <error.h>
98 #include        "variables.h"
99 #include        "path.h"
100 #include        "name.h"
101 #include        "builtins.h"
102 #include        <ls.h>
103
104 int     b_cd __PARAM__((int argc, char *argv[],__V_ *extra), (argc, argv, extra)) __OTORP__(int argc; char *argv[];__V_ *extra;){
105         register char *dir, *cdpath="";
106         register const char *dp;
107         int saverrno=0;
108         int rval,flag = (sh_isoption(SH_PHYSICAL)!=0);
109         char *oldpwd;
110         Namval_t *opwdnod, *pwdnod;
111         NOT_USED(extra);
112         if(sh_isoption(SH_RESTRICTED))
113                 error(ERROR_exit(1),e_restricted+4);
114         while((rval = optget(argv,sh_optcd))) switch(rval)
115         {
116                 case 'L':
117                         flag = 0;
118                         break;
119                 case 'P':
120                         flag = 1;
121                         break;
122                 case ':':
123                         error(2, opt_arg);
124                         break;
125                 case '?':
126                         error(ERROR_usage(2), opt_arg);
127                         break;
128         }
129         argv += opt_index;
130         argc -= opt_index;
131         dir =  argv[0];
132         if(error_info.errors>0 || argc >2)
133                 error(ERROR_usage(2),optusage((char*)0));
134         oldpwd = (char*)sh.pwd;
135         opwdnod = (sh.subshell?sh_assignok(OLDPWDNOD,1):OLDPWDNOD); 
136         pwdnod = (sh.subshell?sh_assignok(PWDNOD,1):PWDNOD); 
137         if(argc==2)
138                 dir = sh_substitute(oldpwd,dir,argv[1]);
139         else if(!dir || *dir==0)
140                 dir = nv_getval(HOME);
141         else if(*dir == '-' && dir[1]==0)
142                 dir = nv_getval(opwdnod);
143         if(!dir || *dir==0)
144                 error(ERROR_exit(1),argc==2?e_subst+4:e_direct);
145         if(*dir != '/')
146         {
147                 cdpath = nv_getval(nv_scoped(CDPNOD));
148                 if(!oldpwd)
149                         oldpwd = path_pwd(1);
150         }
151         if(!cdpath)
152                 cdpath = "";
153         if(*dir=='.')
154         {
155                 /* test for pathname . ./ .. or ../ */
156                 if(*(dp=dir+1) == '.')
157                         dp++;
158                 if(*dp==0 || *dp=='/')
159                         cdpath = "";
160         }
161         rval = -1;
162         do
163         {
164                 dp = cdpath;
165                 cdpath=path_join(cdpath,dir);
166                 if(*stakptr(PATH_OFFSET)!='/')
167                 {
168                         char *last=(char*)stakfreeze(1);
169                         stakseek(PATH_OFFSET);
170                         stakputs(oldpwd);
171                         stakputc('/');
172                         stakputs(last+PATH_OFFSET);
173                         stakputc(0);
174                 }
175                 if(!flag)
176                 {
177                         register char *cp;
178                         stakseek(PATH_MAX+PATH_OFFSET);
179 #ifdef SHOPT_FS_3D
180                         if(!(cp = pathcanon(stakptr(PATH_OFFSET),PATH_DOTDOT)))
181                                 continue;
182                         /* eliminate trailing '/' */
183                         while(*--cp == '/' && cp>stakptr(PATH_OFFSET))
184                                 *cp = 0;
185 #else
186                         if(*(cp=stakptr(PATH_OFFSET))=='/')
187                                 if(!pathcanon(cp,PATH_DOTDOT))
188                                         continue;
189 #endif /* SHOPT_FS_3D */
190                 }
191                 if((rval=chdir(path_relative(stakptr(PATH_OFFSET)))) >= 0)
192                         goto success;
193                 if(errno!=ENOENT && saverrno==0)
194                         saverrno=errno;
195         }
196         while(cdpath);
197         if(rval<0 && *dir=='/' && *(path_relative(stakptr(PATH_OFFSET)))!='/')
198                 rval = chdir(dir);
199         /* use absolute chdir() if relative chdir() fails */
200         if(rval<0)
201         {
202                 if(saverrno)
203                         errno = saverrno;
204                 error(ERROR_system(1),"%s:",dir);
205         }
206 success:
207         if(dir == nv_getval(opwdnod) || argc==2)
208                 dp = dir;       /* print out directory for cd - */
209         if(flag)
210         {
211                 dir = stakptr(PATH_OFFSET);
212                 if (!(dir=pathcanon(dir,PATH_PHYSICAL)))
213                 {
214                         dir = stakptr(PATH_OFFSET);
215                         error(ERROR_system(1),"%s:",dir);
216                 }
217                 stakseek(dir-stakptr(0));
218         }
219         dir = (char*)stakfreeze(1)+PATH_OFFSET;
220         if(*dp && *dp!= ':' && strchr(dir,'/'))
221                 sfputr(sfstdout,dir,'\n');
222         if(*dir != '/')
223                 return(0);
224         nv_putval(opwdnod,oldpwd,NV_RDONLY);
225         if(oldpwd)
226                 free(oldpwd);
227         flag = strlen(dir);
228         /* delete trailing '/' */
229         while(--flag>0 && dir[flag]=='/')
230                 dir[flag] = 0;
231         nv_putval(pwdnod,dir,NV_RDONLY);
232         nv_onattr(pwdnod,NV_NOFREE|NV_EXPORT);
233         sh.pwd = pwdnod->nvalue.cp;
234         return(0);
235 }
236
237 int     b_pwd __PARAM__((int argc, char *argv[],__V_ *extra), (argc, argv, extra)) __OTORP__(int argc; char *argv[];__V_ *extra;){
238         register int n, flag = (sh_isoption(SH_PHYSICAL)!=0);
239         register char *cp;
240         NOT_USED(extra);
241         NOT_USED(argc);
242         while((n = optget(argv,sh_optpwd))) switch(n)
243         {
244                 case 'L':
245                         flag = 0;
246                         break;
247                 case 'P':
248                         flag = 1;
249                         break;
250                 case ':':
251                         error(2, opt_arg);
252                         break;
253                 case '?':
254                         error(ERROR_usage(2), opt_arg);
255                         break;
256         }
257         if(error_info.errors)
258                 error(ERROR_usage(2),optusage((char*)0));
259         if(*(cp = path_pwd(0)) != '/')
260                 error(ERROR_system(1), e_pwd);
261         if(flag)
262         {
263 #ifdef SHOPT_FS_3D
264                 if((flag = mount(e_dot,NIL(char*),FS3D_GET|FS3D_VIEW,0))>=0)
265                 {
266                         cp = (char*)stakseek(++flag+PATH_MAX);
267                         mount(e_dot,cp,FS3D_GET|FS3D_VIEW|FS3D_SIZE(flag),0);
268                 }
269                 else
270 #endif /* SHOPT_FS_3D */
271                         cp = strcpy(stakseek(strlen(cp)+PATH_MAX),cp);
272                 pathcanon(cp,PATH_PHYSICAL);
273         }
274         sfputr(sfstdout,cp,'\n');
275         return(0);
276 }
277