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