121345Sdist /* 2*37209Sbostic * Copyright (c) 1989 The Regents of the University of California. 3*37209Sbostic * All rights reserved. 4*37209Sbostic * 5*37209Sbostic * Redistribution and use in source and binary forms are permitted 6*37209Sbostic * provided that the above copyright notice and this paragraph are 7*37209Sbostic * duplicated in all such forms and that any documentation, 8*37209Sbostic * advertising materials, and other materials related to such 9*37209Sbostic * distribution and use acknowledge that the software was developed 10*37209Sbostic * by the University of California, Berkeley. The name of the 11*37209Sbostic * University may not be used to endorse or promote products derived 12*37209Sbostic * from this software without specific prior written permission. 13*37209Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14*37209Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15*37209Sbostic * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1621345Sdist */ 179986Ssam 1826565Sdonn #if defined(LIBC_SCCS) && !defined(lint) 19*37209Sbostic static char sccsid[] = "@(#)getcwd.c 5.4 (Berkeley) 03/18/89"; 20*37209Sbostic #endif /* LIBC_SCCS and not lint */ 2121345Sdist 2210088Ssam #include <sys/param.h> 2310088Ssam #include <sys/stat.h> 24*37209Sbostic #include <dirent.h> 259986Ssam 269986Ssam char * 27*37209Sbostic getwd(store) 28*37209Sbostic char *store; 299986Ssam { 30*37209Sbostic extern int errno; 31*37209Sbostic register DIR *dir; 32*37209Sbostic register struct dirent *dp; 33*37209Sbostic register int first; 34*37209Sbostic register char *pp, *pu; 35*37209Sbostic struct stat s, tmp; 36*37209Sbostic dev_t root_dev; 37*37209Sbostic ino_t root_ino; 38*37209Sbostic char path[MAXPATHLEN], up[MAXPATHLEN], *strerror(); 399986Ssam 40*37209Sbostic if (stat("/", &s)) 41*37209Sbostic goto err; 42*37209Sbostic root_dev = s.st_dev; 43*37209Sbostic root_ino = s.st_ino; 44*37209Sbostic if (stat(".", &s)) 45*37209Sbostic goto err; 46*37209Sbostic pp = path + sizeof(path) - 1; 47*37209Sbostic *pp = '\0'; 48*37209Sbostic for (pu = up, first = 1;; first = 0) { 49*37209Sbostic if (root_dev == s.st_dev && root_ino == s.st_ino) { 50*37209Sbostic *store = '/'; 51*37209Sbostic (void)strcpy(store + 1, pp); 52*37209Sbostic return(store); 5310155Ssam } 54*37209Sbostic *pu++ = '.'; 55*37209Sbostic *pu++ = '.'; 56*37209Sbostic *pu = '\0'; 57*37209Sbostic if (!(dir = opendir(up))) { 58*37209Sbostic (void)strcpy(path, "getwd: opendir failed."); 59*37209Sbostic return((char *)NULL); 60*37209Sbostic } 61*37209Sbostic *pu++ = '/'; 62*37209Sbostic while (dp = readdir(dir)) { 63*37209Sbostic if (dp->d_name[0] == '.' && (!dp->d_name[1] || 64*37209Sbostic dp->d_name[1] == '.' && !dp->d_name[2])) 65*37209Sbostic continue; 66*37209Sbostic bcopy(dp->d_name, pu, dp->d_namlen + 1); 67*37209Sbostic if (lstat(up, &tmp)) 68*37209Sbostic goto err; 69*37209Sbostic if (tmp.st_dev == s.st_dev && tmp.st_ino == s.st_ino) { 70*37209Sbostic if (!first) 71*37209Sbostic *--pp = '/'; 72*37209Sbostic pp -= dp->d_namlen; 73*37209Sbostic bcopy(dp->d_name, pp, dp->d_namlen); 7410155Ssam break; 7510155Ssam } 76*37209Sbostic } 77*37209Sbostic closedir(dir); 78*37209Sbostic *pu = '\0'; 79*37209Sbostic if (lstat(up, &s)) { 80*37209Sbostic err: (void)sprintf(path, "getwd: %s", strerror(errno)); 81*37209Sbostic return((char *)NULL); 82*37209Sbostic } 839986Ssam } 849986Ssam } 85