home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / config / pathsub.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  4.7 KB  |  233 lines

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18. /*
  19. ** Pathname subroutines.
  20. **
  21. ** Brendan Eich, 8/29/95
  22. */
  23. #include <assert.h>
  24. #include <sys/types.h>
  25. #include <dirent.h>
  26. #include <errno.h>
  27. #include <stdarg.h>
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #ifndef XP_OS2
  32. #include <unistd.h>
  33. #endif
  34. #include <sys/stat.h>
  35. #include "pathsub.h"
  36.  
  37. #ifdef USE_REENTRANT_LIBC
  38. #include <libc_r.h>
  39. #endif
  40.  
  41. #ifdef XP_OS2
  42. #include <direct.h>
  43. #include <io.h>
  44. #include <sys\utime.h>
  45. #include <sys\types.h>
  46. #endif
  47.  
  48. #ifdef SUNOS4
  49. #include "sunos4.h"
  50. #endif
  51.  
  52. char *program;
  53.  
  54. void
  55. fail(char *format, ...)
  56. {
  57.     int error;
  58.     va_list ap;
  59.  
  60. #ifdef USE_REENTRANT_LIBC
  61.     R_STRERROR_INIT_R();
  62. #endif
  63.  
  64.     error = errno;
  65.     fprintf(stderr, "%s: ", program);
  66.     va_start(ap, format);
  67.     vfprintf(stderr, format, ap);
  68.     va_end(ap);
  69.     if (error)
  70.  
  71. #ifdef USE_REENTRANT_LIBC
  72.     R_STRERROR_R(errno);
  73.     fprintf(stderr, ": %s", r_strerror_r);
  74. #else
  75.     fprintf(stderr, ": %s", strerror(errno));
  76. #endif
  77.  
  78.     putc('\n', stderr);
  79.     exit(1);
  80. }
  81.  
  82. char *
  83. getcomponent(char *path, char *name)
  84. {
  85.     if (*path == '\0')
  86.     return 0;
  87.     if (*path == '/') {
  88.     *name++ = '/';
  89.     } else {
  90.     do {
  91.         *name++ = *path++;
  92.     } while (*path != '/' && *path != '\0');
  93.     }
  94.     *name = '\0';
  95.     while (*path == '/')
  96.     path++;
  97.     return path;
  98. }
  99.  
  100. #ifdef LAME_READDIR
  101. #include <sys/param.h>
  102. /*
  103. ** The static buffer in Unixware's readdir is too small.
  104. */
  105. struct dirent *readdir(DIR *d)
  106. {
  107.         static struct dirent *buf = NULL;
  108.  
  109.         if(buf == NULL)
  110.                 buf = (struct dirent *) malloc(sizeof(struct dirent) + MAXPATHLEN);
  111.         return(readdir_r(d, buf));
  112. }
  113. #endif
  114.  
  115. char *
  116. ino2name(ino_t ino, char *dir)
  117. {
  118.     DIR *dp;
  119.     struct dirent *ep;
  120.     char *name;
  121.  
  122.     dp = opendir("..");
  123.     if (!dp)
  124.     fail("cannot read parent directory");
  125.     for (;;) {
  126.     if (!(ep = readdir(dp)))
  127.         fail("cannot find current directory");
  128.     if (ep->d_ino == ino)
  129.         break;
  130.     }
  131.     name = xstrdup(ep->d_name);
  132.     closedir(dp);
  133.     return name;
  134. }
  135.  
  136. void *
  137. xmalloc(size_t size)
  138. {
  139.     void *p = malloc(size);
  140.     if (!p)
  141.     fail("cannot allocate %u bytes", size);
  142.     return p;
  143. }
  144.  
  145. char *
  146. xstrdup(char *s)
  147. {
  148.     return strcpy(xmalloc(strlen(s) + 1), s);
  149. }
  150.  
  151. char *
  152. xbasename(char *path)
  153. {
  154.     char *cp;
  155.  
  156.     while ((cp = strrchr(path, '/')) && cp[1] == '\0')
  157.     *cp = '\0';
  158.     if (!cp) return path;
  159.     return cp + 1;
  160. }
  161.  
  162. void
  163. xchdir(char *dir)
  164. {
  165.     if (chdir(dir) < 0)
  166.     fail("cannot change directory to %s", dir);
  167. }
  168.  
  169. int
  170. relatepaths(char *from, char *to, char *outpath)
  171. {
  172.     char *cp, *cp2;
  173.     int len;
  174.     char buf[NAME_MAX];
  175.  
  176.     assert(*from == '/' && *to == '/');
  177.     for (cp = to, cp2 = from; *cp == *cp2; cp++, cp2++)
  178.     if (*cp == '\0')
  179.         break;
  180.     while (cp[-1] != '/')
  181.     cp--, cp2--;
  182.     if (cp - 1 == to) {
  183.     /* closest common ancestor is /, so use full pathname */
  184.     len = strlen(strcpy(outpath, to));
  185.     if (outpath[len] != '/') {
  186.         outpath[len++] = '/';
  187.         outpath[len] = '\0';
  188.     }
  189.     } else {
  190.     len = 0;
  191.     while ((cp2 = getcomponent(cp2, buf)) != 0) {
  192.         strcpy(outpath + len, "../");
  193.         len += 3;
  194.     }
  195.     while ((cp = getcomponent(cp, buf)) != 0) {
  196.         sprintf(outpath + len, "%s/", buf);
  197.         len += strlen(outpath + len);
  198.     }
  199.     }
  200.     return len;
  201. }
  202.  
  203. void
  204. reversepath(char *inpath, char *name, int len, char *outpath)
  205. {
  206.     char *cp, *cp2;
  207.     char buf[NAME_MAX];
  208.     struct stat sb;
  209.  
  210.     cp = strcpy(outpath + PATH_MAX - (len + 1), name);
  211.     cp2 = inpath;
  212.     while ((cp2 = getcomponent(cp2, buf)) != 0) {
  213.     if (strcmp(buf, ".") == 0)
  214.         continue;
  215.     if (strcmp(buf, "..") == 0) {
  216.         if (stat(".", &sb) < 0)
  217.         fail("cannot stat current directory");
  218.         name = ino2name(sb.st_ino, "..");
  219.         len = strlen(name);
  220.         cp -= len + 1;
  221.         strcpy(cp, name);
  222.         cp[len] = '/';
  223.         free(name);
  224.         xchdir("..");
  225.     } else {
  226.         cp -= 3;
  227.         strncpy(cp, "../", 3);
  228.         xchdir(buf);
  229.     }
  230.     }
  231.     strcpy(outpath, cp);
  232. }
  233.