1 /*
2 
3  *      Copyright (c) 1984, 1985, 1986 AT&T
4  *      All Rights Reserved
5 
6  *      THIS IS UNPUBLISHED PROPRIETARY SOURCE
7  *      CODE OF AT&T.
8  *      The copyright notice above does not
9  *      evidence any actual or intended
10  *      publication of such source code.
11 
12  */
13 
14 /* @(#)cannon.c	1.1 */
15 
16 /*
17  *  cannon_path - Generate canonical pathname from given pathname
18  *
19  *   David Korn
20  *   AT&T Bell Laboratories
21  *   Room 5D-112
22  *   Murray Hill, N. J. 07974
23  *   Tel. x7975
24  *
25  *   Written December 1982
26  */
27 
28 #ifdef BSD
29 #define strrchr rindex
30 #endif	/* BSD */
31 extern char *strrchr();
32 extern char *strcpy();
33 
34 /*
35  *  canonicalize path-name
36  *  The canonicalized pathname replaces path
37  */
38 
39 void	cannon_path(path)
40 char *path;
41 {
42 	register char *a1;
43 	register char *newdir = path;
44 	register char *dp;
45 	/* eliminate redundant / */
46 	a1 = newdir;
47 	for(dp=a1;*dp = *a1++;dp++)
48 	{
49 		if(*dp == '/')
50 			while(*a1 == '/')
51 				a1++;
52 	}
53 	/* check for ./ and ../ */
54 	a1 = newdir;
55 	while(*a1)
56 	{
57 		if(*a1++ != '/' || *a1 != '.')
58 			continue;
59 		/* pathname begins with /.  */
60 		dp = a1-1;
61 		if(*++a1 == '/')	/* skip ./  */
62 			a1++;
63 		else if(*a1 == '.')
64 		{
65 			/* pathname begins with /.. */
66 			if(*++a1 != '/' && *a1 != 0)
67 				/* file name begins with .. */
68 				continue;
69 			else
70 			{
71 				/* parent directory */
72 				*dp = 0;
73 				if((dp=strrchr(newdir,'/')) == 0)
74 					dp = newdir;
75 				*dp = *a1++;
76 			}
77 		}
78 		else if(*a1 == 0)
79 			*dp = 0;
80 		else
81 			continue;
82 		if(*dp == 0)
83 			break;
84 		strcpy(dp+1,a1);
85 		a1 = dp;
86 	}
87 	for(a1=newdir;*a1;a1++);	/* skip to last character*/
88 	if(*--a1 == '/')		/* eliminate trailing / */
89 		*a1 = 0;
90 	if(*newdir == 0)
91 	{
92 		*newdir = '/';
93 		newdir[1] = 0;
94 	}
95 }
96