Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / lib / tt / lib / realpath.hp.c
1 /*%%  (c) Copyright 1993, 1994 Hewlett-Packard Company                   */
2 /*%%  (c) Copyright 1993, 1994 International Business Machines Corp.     */
3 /*%%  (c) Copyright 1993, 1994 Sun Microsystems, Inc.                    */
4 /*%%  (c) Copyright 1993, 1994 Novell, Inc.                              */
5 /*%%  $XConsortium: realpath.hp.c /main/3 1995/10/23 09:49:57 rswiston $                                                         */
6 /* @(#)realpath.hp.c    1.3 93/07/30
7  * Version of realpath for HP/UX systems */
8
9 #include <stdio.h>
10 #include <sys/types.h>
11 #include <sys/stat.h>
12 #include <sys/param.h>
13 #include <strings.h>
14
15 char *
16 realpath(pathname, finalpath)
17 char *pathname;
18 char *finalpath;
19 {
20   struct stat sbuf;
21   char curpath[MAXPATHLEN],
22   workpath[MAXPATHLEN],
23   linkpath[MAXPATHLEN],
24   namebuf[MAXPATHLEN],
25   *where,
26   *ptr,
27   *last;
28   int len;
29
30    strcpy(curpath, pathname);
31
32    if (*pathname != '/') {
33 #if defined(__STDC__)
34       if (!getcwd(workpath)) {
35 #else
36       if (!getwd(workpath)) {
37 #endif
38          strcpy(finalpath, ".");
39          return(NULL);
40        }
41     } else *workpath = NULL;
42
43    /* curpath is the path we're still resolving      */
44    /* linkpath is the path a symbolic link points to */
45    /* workpath is the path we've resolved            */
46
47  loop:
48    where = curpath;
49    while (*where != NULL) {
50       if (!strcmp(where, ".")) {
51          where++;
52          continue;
53        }
54
55       /* deal with "./" */
56       if (!strncmp(where, "./", 2)) {
57          where += 2;
58          continue;
59        }
60
61       /* deal with "../" */
62       if (!strncmp(where, "../", 3)) {
63          where += 3;
64          ptr = last = workpath;
65          while (*ptr) {
66             if (*ptr == '/') last = ptr;
67             ptr++;
68           }
69          *last = NULL;
70          continue;
71        }
72
73       ptr = strchr(where, '/');
74       if (!ptr)
75          ptr = where + strlen(where) - 1;
76       else
77          *ptr = NULL;
78
79       strcpy(namebuf, workpath);
80       for (last = namebuf; *last; last++) continue;
81       /* tack on a trailing, or leading, `/` */
82       if (last == namebuf || *--last != '/') {
83         strcat(namebuf, "/");
84       }
85       strcat(namebuf, where);
86
87       where = ++ptr;
88       if (lstat(namebuf, &sbuf) == -1) {
89          strcpy(finalpath, namebuf);
90          return(NULL);
91        }
92
93       if ((sbuf.st_mode & S_IFLNK) == S_IFLNK) {
94          len = readlink(namebuf, linkpath, MAXPATHLEN);
95          if (len == 0) {
96             strcpy(finalpath, namebuf);
97             return(NULL);
98           }
99          *(linkpath + len) = NULL; /* readlink doesn't null-terminate result */
100          if (*linkpath == '/') *workpath = NULL;
101          if (*where) {
102             strcat(linkpath, "/");
103             strcat(linkpath, where);
104           }
105          strcpy(curpath, linkpath);
106          goto loop;
107        }
108
109       if ((sbuf.st_mode & S_IFDIR) == S_IFDIR) {
110          strcpy(workpath, namebuf);
111          continue;
112        }
113
114       if (*where) {
115          strcpy(finalpath, namebuf);
116          return(NULL);  /* path/notadir/morepath */
117        } else
118          strcpy(workpath, namebuf);
119     }
120    strcpy(finalpath, workpath);
121    return(finalpath);
122
123 }
124