'notdef' means it's not used, so we remove it
[oweals/cde.git] / cde / lib / tt / lib / realpath.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 /*%%  (c) Copyright 1993, 1994 Hewlett-Packard Company                   */
24 /*%%  (c) Copyright 1993, 1994 International Business Machines Corp.     */
25 /*%%  (c) Copyright 1993, 1994 Sun Microsystems, Inc.                    */
26 /*%%  (c) Copyright 1993, 1994 Novell, Inc.                              */
27 /*%%  $XConsortium: realpath.c /main/3 1995/10/23 09:49:50 rswiston $                                                    */
28
29 #include <stdio.h>
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <sys/param.h>
33 #include <strings.h>            
34 #include <errno.h>
35
36 /* This is used when the operating system  does not  provide us  with
37  * a realpath implementation.  It's named differently so there is
38  * no name clash between it and the system version of realpath.
39  */
40
41 char *
42 _tt_internal_realpath(pathname, finalpath)
43 char *pathname;
44 char *finalpath;
45 {
46   struct stat sbuf;
47   char curpath[MAXPATHLEN],
48   workpath[MAXPATHLEN],
49   linkpath[MAXPATHLEN],
50   namebuf[MAXPATHLEN],
51   *where,
52   *ptr,
53   *last;
54   int len;
55   int nlink = 0;        /* To keep track of loops in the path. */
56
57    strcpy(curpath, pathname);
58
59    if (*pathname != '/') {
60 #if defined(__STDC__) && defined(hpux)
61       if (!getcwd(workpath)) {
62 #else
63       if (!getwd(workpath)) {   
64 #endif
65       strcpy(finalpath, ".");
66          return(NULL);
67        } 
68     } else *workpath = NULL;
69
70    /* curpath is the path we're still resolving      */
71    /* linkpath is the path a symbolic link points to */
72    /* workpath is the path we've resolved            */
73
74  loop:
75    where = curpath;
76    while (*where != NULL) {
77       if (!strcmp(where, ".")) {
78          where++;
79          continue;
80        }
81
82       /* deal with "./" */
83       if (!strncmp(where, "./", 2)) {
84          where += 2;
85          continue;
86        }
87
88       /* deal with "../" */
89       if (!strncmp(where, "../", 3)) {
90          where += 3;
91          ptr = last = workpath;
92          while (*ptr) {
93             if (*ptr == '/') last = ptr;
94             ptr++;
95           }
96          *last = NULL;
97          continue;
98        }
99
100       ptr = strchr(where, '/');
101       if (!ptr)
102          ptr = where + strlen(where) - 1;
103       else
104          *ptr = NULL;
105
106       strcpy(namebuf, workpath);
107
108       for (last = namebuf; *last; last++) continue;
109
110       /* tack on a trailing, or leading, `/` */
111       if (last == namebuf || *--last != '/') {
112         strcat(namebuf, "/");
113       }
114
115       strcat(namebuf, where);
116
117       where = ++ptr;
118       if (lstat(namebuf, &sbuf) == -1) {
119          strcpy(finalpath, namebuf);
120          return(NULL);
121        }
122       
123       if ((sbuf.st_mode & S_IFLNK) == S_IFLNK) {
124          /* Look for loop in path such as link to self. */
125          nlink++;                        
126          if (nlink > MAXSYMLINKS) {
127                  errno = ELOOP;
128                  return (NULL);
129          }
130          len = readlink(namebuf, linkpath, MAXPATHLEN);
131          if (len == 0) {
132             strcpy(finalpath, namebuf);
133             return(NULL);
134           }
135          *(linkpath + len) = NULL; /* readlink doesn't null-terminate result */
136          if (*linkpath == '/') *workpath = NULL;
137          if (*where) {
138             strcat(linkpath, "/");
139             strcat(linkpath, where);
140           }
141          strcpy(curpath, linkpath);
142          goto loop;
143        }
144
145       if ((sbuf.st_mode & S_IFDIR) == S_IFDIR) {
146          strcpy(workpath, namebuf);
147          continue;
148        }
149
150       if (*where) {
151          strcpy(finalpath, namebuf);
152          return(NULL);  /* path/notadir/morepath */
153        } else
154          strcpy(workpath, namebuf);
155     }
156    strcpy(finalpath, workpath);
157    return(finalpath);
158
159 }
160