home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / fish / programming / mkid / src / paths.c < prev    next >
C/C++ Source or Header  |  1991-02-01  |  5KB  |  284 lines

  1. /* Copyright (c) 1986, Greg McGary */
  2. static char sccsid[] = "@(#)paths.c    1.1 86/10/09";
  3.  
  4. #include    "bool.h"
  5. #include    <stdio.h>
  6. #include    "string.h"
  7.  
  8. bool canCrunch();
  9. char *getDirToName();
  10. char *rootName();
  11. char *skipJunk();
  12. char *spanPath();
  13. char *suffName();
  14.  
  15. char *
  16. spanPath(dir, arg)
  17.     char        *dir;
  18.     char        *arg;
  19. {
  20.     static char    pathBuf[BUFSIZ];
  21.     char        *path;
  22.     char        *argTail;
  23.     char        *dirTail;
  24.     int        argLength;
  25.     int        dirLength;
  26.  
  27.     for (dirTail = &dir[strlen(dir)-1]; *dirTail == '/'; dirTail--)
  28.         *dirTail = '\0';
  29.  
  30.     (path = pathBuf)[0] = '\0';    /* was lower REJ */
  31.     /* while dir and arg are the same loop REJ */
  32. #ifdef AMIGA
  33.     /* two complete path names, find minimal traverse, using ///... */
  34.     /* first, the volume names must match */
  35.     dirTail = strchr(dir,':');
  36.     argTail = strchr(arg,':');
  37.     if (dirTail && argTail)    /* should always be true, but paranoia */
  38.     {
  39.         dirLength = dirTail - dir;
  40.         argLength = argTail - arg;
  41.  
  42.         if (argLength == dirLength)
  43.         {
  44.             if (!strnicmp(arg, dir, argLength))
  45.             {
  46.                 arg = argTail;
  47.                 dir = dirTail;
  48. #endif
  49.     for (;;) {
  50.         dir = skipJunk(dir);
  51.         if ((dirTail = strchr(dir, '/')) == NULL)
  52.             dirTail = &dir[strlen(dir)];
  53.         dirLength = dirTail - dir;
  54.  
  55.         arg = skipJunk(arg);
  56.         if ((argTail = strchr(arg, '/')) == NULL)
  57.             break;
  58.         argLength = argTail - arg;
  59.  
  60.         if (argLength != dirLength)
  61.             break;
  62.         if (!strnequ(arg, dir, argLength))
  63.             break;
  64.         arg = argTail;
  65.         dir = dirTail;
  66.     }
  67.  
  68.     for (; dir && *dir; dir = skipJunk(strchr(dir, '/'))) {
  69. #ifdef UNIX
  70.         strcpy(path, "../");
  71.         path += 3;
  72. #endif
  73. #ifdef AMIGA
  74.         *path++ = '/';
  75.         *path = '\0';
  76. #endif
  77.     }
  78. #ifdef AMIGA
  79.             }
  80.         }
  81.     }
  82. #endif
  83.  
  84.     strcat(path, arg);
  85.     return pathBuf;
  86. }
  87.  
  88. char *
  89. skipJunk(path)
  90.     char        *path;
  91. {
  92.     if (path == NULL)
  93.         return NULL;
  94. #ifdef AMIGA
  95.     if (*path == ':' || *path == '/')
  96.         path++;
  97. #endif
  98. #ifdef UNIX
  99.     while (*path == '/')
  100.         path++;
  101.     while (path[0] == '.' && path[1] == '/') {
  102.         path += 2;
  103.         while (*path == '/')
  104.             path++;
  105.     }
  106.     if (strequ(path, "."))
  107.         path++;
  108. #endif
  109.     
  110.     return path;
  111. }
  112.  
  113. char *
  114. rootName(path)
  115.     char        *path;
  116. {
  117.     static char    pathBuf[BUFSIZ];
  118.     char        *root;
  119.     char        *dot;
  120.  
  121.     if ((root = strrchr(path, '/')) == NULL)
  122. #ifdef AMIGA
  123.         if ((root = strrchr(path, ':')) == NULL)
  124.             root = path;
  125.         else
  126.             root++;
  127. #endif
  128. #ifdef UNIX
  129.         root = path;
  130. #endif
  131.     else
  132.         root++;
  133.     
  134.     if ((dot = strrchr(root, '.')) == NULL)
  135.         strcpy(pathBuf, root);
  136.     else {
  137.         strncpy(pathBuf, root, dot - root);
  138.         pathBuf[dot - root] = '\0';
  139.     }
  140.  
  141.     return pathBuf;
  142. }
  143.  
  144. char *
  145. suffName(path)
  146.     char        *path;
  147. {
  148.     char        *dot;
  149.  
  150.     if ((dot = strrchr(path, '.')) == NULL)
  151.         return "";
  152.     return dot;
  153. }
  154.  
  155. bool
  156. canCrunch(path1, path2)
  157.     char        *path1;
  158.     char        *path2;
  159. {
  160.     char        *slash1;
  161.     char        *slash2;
  162.  
  163.     slash1 = strrchr(path1, '/');
  164.     slash2 = strrchr(path2, '/');
  165. #ifdef AMIGA
  166.     if (slash1 == NULL)
  167.         slash1 = strrchr(path1,':');
  168.     if (slash2 == NULL)
  169.         slash2 = strrchr(path2,':');
  170. #endif
  171.  
  172.     if (slash1 == NULL && slash2 == NULL)
  173.         return strequ(suffName(path1), suffName(path2));
  174.     if ((slash1 - path1) != (slash2 - path2))
  175.         return FALSE;
  176.     if (!strnequ(path1, path2, slash1 - path1))
  177.         return FALSE;
  178.     return strequ(suffName(slash1), suffName(slash2));
  179. }
  180.  
  181. #ifdef UNIX
  182. #include    <sys/types.h>
  183. #include    <sys/stat.h>
  184. #ifdef NDIR
  185. #include    <ndir.h>
  186. #else
  187. #include    <sys/dir.h>
  188. #endif
  189. #endif UNIX
  190.  
  191. static char    dot[]     = ".";
  192. static char    dotdot[] = "..";
  193.  
  194. /*
  195.     Return our directory name relative to the first parent dir
  196.     that contains a file with a name that matches `topName'.
  197.     Fail if we hit the root, or if any dir in our way is unreadable.
  198. */
  199. char *
  200. getDirToName(topName)
  201.     char        *topName;
  202. {
  203.     static char    nameBuf[BUFSIZ];
  204.     char        *name;
  205. #ifdef UNIX
  206.     register struct direct    *dirp;
  207.     register DIR    *dirdp;
  208.     struct    stat    dStat;
  209.     struct    stat    ddStat;
  210. #endif
  211. #ifdef AMIGA
  212.     char        path[64];
  213.     char        *temp;
  214. #endif
  215.  
  216.     name = &nameBuf[sizeof(nameBuf)-1];
  217.     *name = '\0';
  218.     for (;;) {
  219. #ifdef UNIX
  220.         if (stat(topName, &dStat) == 0) {
  221.             if (!*name)
  222.                 name = dot;
  223.             else
  224.                 chdir(name);
  225.             return name;
  226.         }
  227.         if (stat(dot, &dStat) < 0)
  228.             return NULL;
  229.         if ((dirdp = opendir(dotdot)) == NULL)
  230.             return NULL;
  231.         if (fstat(dirdp->dd_fd, &ddStat) < 0)
  232.             return NULL;
  233.         if (chdir(dotdot) < 0)
  234.             return NULL;
  235.         if (dStat.st_dev == ddStat.st_dev) {
  236.             if (dStat.st_ino == ddStat.st_ino)
  237.                 return NULL;
  238.             do {
  239.                 if ((dirp = readdir(dirdp)) == NULL)
  240.                     return NULL;
  241.             } while (dirp->d_ino != dStat.st_ino);
  242.         } else {
  243.             do {
  244.                 if ((dirp = readdir(dirdp)) == NULL)
  245.                     return NULL;
  246.                 stat(dirp->d_name, &ddStat);
  247.             } while (ddStat.st_ino != dStat.st_ino || ddStat.st_dev != dStat.st_dev);
  248.         }
  249.         closedir(dirdp);
  250.     
  251.         if (*name != '\0')
  252.             *--name = '/';
  253.         name -= dirp->d_namlen;
  254.         strncpy(name, dirp->d_name, dirp->d_namlen);
  255. #endif UNIX
  256. #ifdef AMIGA
  257.         if (access(topName,0) == 0) {    /* got it */
  258.             if (!*name)
  259.                 name = "";
  260.             else 
  261.                 if (chdir(name) == -1)
  262.                     return NULL;
  263.             return name;
  264.         }
  265.         if (getcd(0,path) == -1 || path[strlen(path)-1] == ':')
  266.             return NULL;
  267.  
  268.         /* add current dir to list */
  269.         if (*name != '\0')
  270.             *--name = '/';
  271.  
  272.         /* assumes xxx:yyy[{/zzz}...] */
  273.         if ((temp = strrchr(path,'/')) == NULL)
  274.             temp = strchr(path,':');    /* root - take volume */
  275.         else
  276.             temp++;        /* point past '/' */
  277.         name -= strlen(temp);
  278.         strncpy(name, temp, strlen(temp));
  279.  
  280.         chdir("/");
  281. #endif
  282.     }
  283. }
  284.