home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1986, Greg McGary */
- static char sccsid[] = "@(#)paths.c 1.1 86/10/09";
-
- #include <bool.h>
- #include <stdio.h>
- #include <string.h>
-
- bool canCrunch();
- char *getDirToName();
- char *rootName();
- char *skipJunk();
- char *spanPath();
- char *suffName();
-
- char *
- spanPath(dir, arg)
- char *dir;
- char *arg;
- {
- static char pathBuf[BUFSIZ];
- char *path;
- char *argTail;
- char *dirTail;
- int argLength;
- int dirLength;
-
- for (dirTail = &dir[strlen(dir)-1]; *dirTail == '/'; dirTail--)
- *dirTail = '\0';
- for (;;) {
- dir = skipJunk(dir);
- if ((dirTail = strchr(dir, '/')) == NULL)
- dirTail = &dir[strlen(dir)];
- dirLength = dirTail - dir;
-
- arg = skipJunk(arg);
- if ((argTail = strchr(arg, '/')) == NULL)
- break;
- argLength = argTail - arg;
-
- if (argLength != dirLength)
- break;
- if (!strnequ(arg, dir, argLength))
- break;
- arg = argTail;
- dir = dirTail;
- }
-
- (path = pathBuf)[0] = '\0';
- for (; dir && *dir; dir = skipJunk(strchr(dir, '/'))) {
- strcpy(path, "../");
- path += 3;
- }
- strcat(path, arg);
- return pathBuf;
- }
-
- char *
- skipJunk(path)
- char *path;
- {
- if (path == NULL)
- return NULL;
- while (*path == '/')
- path++;
- while (path[0] == '.' && path[1] == '/') {
- path += 2;
- while (*path == '/')
- path++;
- }
- if (strequ(path, "."))
- path++;
-
- return path;
- }
-
- char *
- rootName(path)
- char *path;
- {
- static char pathBuf[BUFSIZ];
- char *root;
- char *dot;
-
- if ((root = strrchr(path, '/')) == NULL)
- root = path;
- else
- root++;
-
- if ((dot = strrchr(root, '.')) == NULL)
- strcpy(pathBuf, root);
- else {
- strncpy(pathBuf, root, dot - root);
- pathBuf[dot - root] = '\0';
- }
- return pathBuf;
- }
-
- char *
- suffName(path)
- char *path;
- {
- char *dot;
-
- if ((dot = strrchr(path, '.')) == NULL)
- return "";
- return dot;
- }
-
- bool
- canCrunch(path1, path2)
- char *path1;
- char *path2;
- {
- char *slash1;
- char *slash2;
-
- slash1 = strrchr(path1, '/');
- slash2 = strrchr(path2, '/');
-
- if (slash1 == NULL && slash2 == NULL)
- return strequ(suffName(path1), suffName(path2));
- if ((slash1 - path1) != (slash2 - path2))
- return FALSE;
- if (!strnequ(path1, path2, slash1 - path1))
- return FALSE;
- return strequ(suffName(slash1), suffName(slash2));
- }
- #include <sys/types.h>
- #include <sys/stat.h>
- #ifdef NDIR
- #include <ndir.h>
- #else
- #include <sys/dir.h>
- #endif
-
- static char dot[] = ".";
- static char dotdot[] = "..";
-
- /*
- Return our directory name relative to the first parent dir
- that contains a file with a name that matches `topName'.
- Fail if we hit the root, or if any dir in our way is unreadable.
- */
- char *
- getDirToName(topName)
- char *topName;
- {
- register struct direct *dirp;
- register DIR *dirdp;
- static char nameBuf[BUFSIZ];
- char *name;
- struct stat dStat;
- struct stat ddStat;
-
- name = &nameBuf[sizeof(nameBuf)-1];
- *name = '\0';
- for (;;) {
- if (stat(topName, &dStat) == 0) {
- if (!*name)
- name = dot;
- else
- chdir(name);
- return name;
- } if (stat(dot, &dStat) < 0)
- return NULL;
- if ((dirdp = opendir(dotdot)) == NULL)
- return NULL;
- if (fstat(dirdp->dd_fd, &ddStat) < 0)
- return NULL;
- if (chdir(dotdot) < 0)
- return NULL;
- if (dStat.st_dev == ddStat.st_dev) {
- if (dStat.st_ino == ddStat.st_ino)
- return NULL;
- do {
- if ((dirp = readdir(dirdp)) == NULL)
- return NULL;
- } while (dirp->d_ino != dStat.st_ino);
- } else {
- do {
- if ((dirp = readdir(dirdp)) == NULL)
- return NULL;
- stat(dirp->d_name, &ddStat);
- } while (ddStat.st_ino != dStat.st_ino || ddStat.st_dev != dStat.st_dev);
- }
- closedir(dirdp);
-
- if (*name != '\0')
- *--name = '/';
- name -= dirp->d_namlen;
- strncpy(name, dirp->d_name, dirp->d_namlen);
- }
- }
-