1 /*
2 * CDDL HEADER START
3 *
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.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21 /* Copyright (c) 1988 AT&T */
22 /* All Rights Reserved */
23 /*
24 * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
26 */
27 /*
28 * Copyright 2006-2020 J. Schilling
29 *
30 * @(#)abspath.c 1.8 20/09/06 J. Schilling
31 */
32 #if defined(sun)
33 #pragma ident "@(#)abspath.c 1.8 20/09/06 J. Schilling"
34 #endif
35 /*
36 * @(#)abspath.c 1.4 06/12/12
37 */
38
39 #if defined(sun)
40 #pragma ident "@(#)abspath.c"
41 #pragma ident "@(#)sccs:lib/mpwlib/abspath.c"
42 #endif
43
44 #include <defines.h>
45
46 char *fixpath __PR((char *p));
47 static void push __PR((char **chrptr, char **stktop));
48 static char pop __PR((char **stktop));
49
50 /*
51 * fixpath() (formerly abspath() from AT&T) is buggy: it
52 * is unable to remove "./" at the beginning and it
53 * returns -1 leaving a corrupted path buffer in case
54 * it contained too many "/../" entries.
55 *
56 * better use resolvepath().
57 */
fixpath(p)58 char *fixpath(p)
59 char *p;
60 {
61 int state;
62 int slashes;
63 char *stktop;
64 char *slash="/";
65 char *inptr;
66 char c;
67
68 state = 0;
69 stktop = inptr = p;
70 while ((c = *inptr) != '\0')
71 {
72 switch (state)
73 {
74 case 0: if (c=='/') state = 1;
75 push(&inptr,&stktop);
76 break;
77 case 1: if (c=='.') state = 2;
78 else state = 0;
79 push(&inptr,&stktop);
80 break;
81 case 2: if (c=='.') state = 3;
82 else if (c=='/') state = 5;
83 else state = 0;
84 push(&inptr,&stktop);
85 break;
86 case 3: if (c=='/') state = 4;
87 else state = 0;
88 push(&inptr,&stktop);
89 break;
90 case 4: for (slashes = 0; slashes < 3; )
91 {
92 if(pop(&stktop)=='/') ++slashes;
93 if (stktop < p) return((char *) -1);
94 }
95 push(&slash,&stktop);
96 slash--;
97 state = 1;
98 break;
99 case 5: pop(&stktop);
100 if (stktop < p) return((char *) -1);
101 pop(&stktop);
102 if (stktop < p) return((char *) -1);
103 state = 1;
104 break;
105 }
106 }
107 *stktop='\0';
108 return(p);
109 }
110
111 static void
push(chrptr,stktop)112 push(chrptr,stktop)
113
114 char **chrptr;
115 char **stktop;
116
117 {
118 **stktop = **chrptr;
119 (*stktop)++;
120 (*chrptr)++;
121 }
122
123 static char
pop(stktop)124 pop(stktop)
125
126 char **stktop;
127
128 {
129 char chr;
130 (*stktop)--;
131 chr = **stktop;
132 return(chr);
133 }
134