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