home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / nsprpub / config / pathsub.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  4.6 KB  |  220 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. /*
  20. ** Pathname subroutines.
  21. **
  22. ** Brendan Eich, 8/29/95
  23. */
  24. #include <assert.h>
  25. #include <sys/types.h>
  26. #include <dirent.h>
  27. #include <errno.h>
  28. #include <stdarg.h>
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include <unistd.h>
  33. #include <sys/stat.h>
  34. #include "pathsub.h"
  35. #ifdef USE_REENTRANT_LIBC
  36. #include "libc_r.h"
  37. #endif /* USE_REENTRANT_LIBC */
  38.  
  39. char *program;
  40.  
  41. void
  42. fail(char *format, ...)
  43. {
  44.     int error;
  45.     va_list ap;
  46.  
  47. #ifdef USE_REENTRANT_LIBC
  48.     R_STRERROR_INIT_R();
  49. #endif
  50.  
  51.     error = errno;
  52.     fprintf(stderr, "%s: ", program);
  53.     va_start(ap, format);
  54.     vfprintf(stderr, format, ap);
  55.     va_end(ap);
  56.     if (error)
  57.  
  58. #ifdef USE_REENTRANT_LIBC
  59.     R_STRERROR_R(errno);
  60.     fprintf(stderr, ": %s", r_strerror_r);
  61. #else
  62.     fprintf(stderr, ": %s", strerror(errno));
  63. #endif
  64.  
  65.     putc('\n', stderr);
  66.     exit(1);
  67. }
  68.  
  69. char *
  70. getcomponent(char *path, char *name)
  71. {
  72.     if (*path == '\0')
  73.     return 0;
  74.     if (*path == '/') {
  75.     *name++ = '/';
  76.     } else {
  77.     do {
  78.         *name++ = *path++;
  79.     } while (*path != '/' && *path != '\0');
  80.     }
  81.     *name = '\0';
  82.     while (*path == '/')
  83.     path++;
  84.     return path;
  85. }
  86.  
  87. #ifdef UNIXWARE
  88. /* Sigh.  The static buffer in Unixware's readdir is too small. */
  89. struct dirent * readdir(DIR *d)
  90. {
  91.         static struct dirent *buf = NULL;
  92. #define MAX_PATH_LEN 1024
  93.  
  94.  
  95.         if(buf == NULL)
  96.                 buf = (struct dirent *) malloc(sizeof(struct dirent) + MAX_PATH_LEN)
  97. ;
  98.         return(readdir_r(d, buf));
  99. }
  100. #endif
  101.  
  102. char *
  103. ino2name(ino_t ino, char *dir)
  104. {
  105.     DIR *dp;
  106.     struct dirent *ep;
  107.     char *name;
  108.  
  109.     dp = opendir("..");
  110.     if (!dp)
  111.     fail("cannot read parent directory");
  112.     for (;;) {
  113.     if (!(ep = readdir(dp)))
  114.         fail("cannot find current directory");
  115.     if (ep->d_ino == ino)
  116.         break;
  117.     }
  118.     name = xstrdup(ep->d_name);
  119.     closedir(dp);
  120.     return name;
  121. }
  122.  
  123. void *
  124. xmalloc(size_t size)
  125. {
  126.     void *p = malloc(size);
  127.     if (!p)
  128.     fail("cannot allocate %u bytes", size);
  129.     return p;
  130. }
  131.  
  132. char *
  133. xstrdup(char *s)
  134. {
  135.     return strcpy((char*)xmalloc(strlen(s) + 1), s);
  136. }
  137.  
  138. char *
  139. xbasename(char *path)
  140. {
  141.     char *cp;
  142.  
  143.     while ((cp = strrchr(path, '/')) && cp[1] == '\0')
  144.     *cp = '\0';
  145.     if (!cp) return path;
  146.     return cp + 1;
  147. }
  148.  
  149. void
  150. xchdir(char *dir)
  151. {
  152.     if (chdir(dir) < 0)
  153.     fail("cannot change directory to %s", dir);
  154. }
  155.  
  156. int
  157. relatepaths(char *from, char *to, char *outpath)
  158. {
  159.     char *cp, *cp2;
  160.     int len;
  161.     char buf[NAME_MAX];
  162.  
  163.     assert(*from == '/' && *to == '/');
  164.     for (cp = to, cp2 = from; *cp == *cp2; cp++, cp2++)
  165.     if (*cp == '\0')
  166.         break;
  167.     while (cp[-1] != '/')
  168.     cp--, cp2--;
  169.     if (cp - 1 == to) {
  170.     /* closest common ancestor is /, so use full pathname */
  171.     len = strlen(strcpy(outpath, to));
  172.     if (outpath[len] != '/') {
  173.         outpath[len++] = '/';
  174.         outpath[len] = '\0';
  175.     }
  176.     } else {
  177.     len = 0;
  178.     while ((cp2 = getcomponent(cp2, buf)) != 0) {
  179.         strcpy(outpath + len, "../");
  180.         len += 3;
  181.     }
  182.     while ((cp = getcomponent(cp, buf)) != 0) {
  183.         sprintf(outpath + len, "%s/", buf);
  184.         len += strlen(outpath + len);
  185.     }
  186.     }
  187.     return len;
  188. }
  189.  
  190. void
  191. reversepath(char *inpath, char *name, int len, char *outpath)
  192. {
  193.     char *cp, *cp2;
  194.     char buf[NAME_MAX];
  195.     struct stat sb;
  196.  
  197.     cp = strcpy(outpath + PATH_MAX - (len + 1), name);
  198.     cp2 = inpath;
  199.     while ((cp2 = getcomponent(cp2, buf)) != 0) {
  200.     if (strcmp(buf, ".") == 0)
  201.         continue;
  202.     if (strcmp(buf, "..") == 0) {
  203.         if (stat(".", &sb) < 0)
  204.         fail("cannot stat current directory");
  205.         name = ino2name(sb.st_ino, "..");
  206.         len = strlen(name);
  207.         cp -= len + 1;
  208.         strcpy(cp, name);
  209.         cp[len] = '/';
  210.         free(name);
  211.         xchdir("..");
  212.     } else {
  213.         cp -= 3;
  214.         strncpy(cp, "../", 3);
  215.         xchdir(buf);
  216.     }
  217.     }
  218.     strcpy(outpath, cp);
  219. }
  220.