pathsub.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:7k
源码类别:

CA认证

开发平台:

WINDOWS

  1. /* 
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is the Netscape security libraries.
  13.  * 
  14.  * The Initial Developer of the Original Code is Netscape
  15.  * Communications Corporation.  Portions created by Netscape are 
  16.  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
  17.  * Rights Reserved.
  18.  * 
  19.  * Contributor(s):
  20.  * 
  21.  * Alternatively, the contents of this file may be used under the
  22.  * terms of the GNU General Public License Version 2 or later (the
  23.  * "GPL"), in which case the provisions of the GPL are applicable 
  24.  * instead of those above.  If you wish to allow use of your 
  25.  * version of this file only under the terms of the GPL and not to
  26.  * allow others to use your version of this file under the MPL,
  27.  * indicate your decision by deleting the provisions above and
  28.  * replace them with the notice and other provisions required by
  29.  * the GPL.  If you do not delete the provisions above, a recipient
  30.  * may use your version of this file under either the MPL or the
  31.  * GPL.
  32.  */
  33. /*
  34. ** Pathname subroutines.
  35. */
  36. #include <assert.h>
  37. #ifdef FREEBSD
  38. #include <sys/types.h>
  39. #endif /* FREEBSD */
  40. #include <dirent.h>
  41. #include <errno.h>
  42. #include <stdarg.h>
  43. #include <stdio.h>
  44. #include <stdlib.h>
  45. #include <string.h>
  46. #include <unistd.h>
  47. #include <sys/types.h>
  48. #include <sys/stat.h>
  49. #include "pathsub.h"
  50. #ifdef USE_REENTRANT_LIBC
  51. #include "libc_r.h"
  52. #endif /* USE_REENTRANT_LIBC */
  53. char *program;
  54. void
  55. fail(char *format, ...)
  56. {
  57.     int error;
  58.     va_list ap;
  59. #ifdef USE_REENTRANT_LIBC
  60.     R_STRERROR_INIT_R();
  61. #endif
  62.     error = errno;
  63.     fprintf(stderr, "%s: ", program);
  64.     va_start(ap, format);
  65.     vfprintf(stderr, format, ap);
  66.     va_end(ap);
  67.     if (error)
  68. #ifdef USE_REENTRANT_LIBC
  69.     R_STRERROR_R(errno);
  70. fprintf(stderr, ": %s", r_strerror_r);
  71. #else
  72. fprintf(stderr, ": %s", strerror(errno));
  73. #endif
  74.     putc('n', stderr);
  75.     abort();
  76.     exit(1);
  77. }
  78. char *
  79. getcomponent(char *path, char *name)
  80. {
  81.     if (*path == '')
  82. return 0;
  83.     if (*path == '/') {
  84. *name++ = '/';
  85.     } else {
  86. do {
  87.     *name++ = *path++;
  88. } while (*path != '/' && *path != '');
  89.     }
  90.     *name = '';
  91.     while (*path == '/')
  92. path++;
  93.     return path;
  94. }
  95. #ifdef UNIXWARE
  96. /* The static buffer in Unixware's readdir is too small. */
  97. struct dirent * readdir(DIR *d)
  98. {
  99.     static struct dirent *buf = NULL;
  100. #define MAX_PATH_LEN 1024
  101.     if (buf == NULL)
  102. buf = (struct dirent *)xmalloc(sizeof(struct dirent) + MAX_PATH_LEN) ;
  103.     return readdir_r(d, buf);
  104. }
  105. #endif
  106. /* APPARENT BUG - ignores argument "dir", uses ".." instead. */
  107. char *
  108. ino2name(ino_t ino, char *dir)
  109. {
  110.     DIR *dp;
  111.     struct dirent *ep;
  112.     char *name;
  113.     dp = opendir(".."); /* XXX */
  114.     if (!dp)
  115. fail("cannot read parent directory");
  116.     for (;;) {
  117. if (!(ep = readdir(dp)))
  118.     fail("cannot find current directory");
  119. if (ep->d_ino == ino)
  120.     break;
  121.     }
  122.     name = xstrdup(ep->d_name);
  123.     closedir(dp);
  124.     return name;
  125. }
  126. void *
  127. xmalloc(size_t size)
  128. {
  129.     void *p;
  130.     if (size <= 0)
  131. fail("attempted to allocate %u bytes", size);
  132.     p = malloc(size);
  133.     if (!p)
  134. fail("cannot allocate %u bytes", size);
  135.     return p;
  136. }
  137. char *
  138. xstrdup(char *s)
  139. {
  140.     if (!s || !s[0]) 
  141. fail("Null pointer or empty string passed to xstrdup()");
  142.     return strcpy((char*)xmalloc(strlen(s) + 1), s);
  143. }
  144. char *
  145. xbasename(char *path)
  146. {
  147.     char *cp;
  148.     if (!path || !path[0]) 
  149. fail("Null pointer or empty string passed to xbasename()");
  150.     while ((cp = strrchr(path, '/')) && cp[1] == '')
  151. *cp = '';
  152.     if (!cp) return path;
  153.     return cp + 1;
  154. }
  155. void
  156. xchdir(char *dir)
  157. {
  158.     if (!dir || !dir[0]) 
  159. fail("Null pointer or empty string passed to xchdir()");
  160.     if (chdir(dir) < 0)
  161. fail("cannot change directory to %s", dir);
  162. }
  163. int
  164. relatepaths(char *from, char *to, char *outpath)
  165. {
  166.     char *cp, *cp2;
  167.     int len;
  168.     char buf[NAME_MAX];
  169.     assert(*from == '/' && *to == '/');
  170.     if (!from || *from != '/')
  171. fail("relatepaths: from path does not start with /");
  172.     if (!to || *to != '/')
  173. fail("relatepaths: to   path does not start with /");
  174.     for (cp = to, cp2 = from; *cp == *cp2; cp++, cp2++)
  175. if (*cp == '')
  176.     break;
  177.     while (cp[-1] != '/')
  178. cp--, cp2--;
  179.     if (cp - 1 == to) {
  180. /* closest common ancestor is /, so use full pathname */
  181. len = strlen(strcpy(outpath, to));
  182. if (outpath[len] != '/') {
  183.     outpath[len++] = '/';
  184.     outpath[len] = '';
  185. }
  186.     } else {
  187. len = 0;
  188. while ((cp2 = getcomponent(cp2, buf)) != 0) {
  189.     strcpy(outpath + len, "../");
  190.     len += 3;
  191. }
  192. while ((cp = getcomponent(cp, buf)) != 0) {
  193.     sprintf(outpath + len, "%s/", buf);
  194.     len += strlen(outpath + len);
  195. }
  196.     }
  197.     return len;
  198. }
  199. void
  200. reversepath(char *inpath, char *name, int len, char *outpath)
  201. {
  202.     char *cp, *cp2;
  203.     char buf[NAME_MAX];
  204.     struct stat sb;
  205.     cp = strcpy(outpath + PATH_MAX - (len + 1), name);
  206.     cp2 = inpath;
  207.     while ((cp2 = getcomponent(cp2, buf)) != 0) {
  208. if (strcmp(buf, ".") == 0)
  209.     continue;
  210. if (strcmp(buf, "..") == 0) {
  211.     if (stat(".", &sb) < 0)
  212. fail("cannot stat current directory");
  213.     name = ino2name(sb.st_ino, "..");
  214.     len = strlen(name);
  215.     cp -= len + 1;
  216.     strcpy(cp, name);
  217.     cp[len] = '/';
  218.     free(name);
  219.     xchdir("..");
  220. } else {
  221.     cp -= 3;
  222.     strncpy(cp, "../", 3);
  223.     xchdir(buf);
  224. }
  225.     }
  226.     strcpy(outpath, cp);
  227. }
  228. void
  229. diagnosePath(const char * path)
  230. {
  231.     char * myPath;
  232.     char *      slash;
  233.     int rv;
  234.     struct stat sb;
  235.     char  buf[BUFSIZ];
  236.     if (!path || !path[0]) 
  237. fail("Null pointer or empty string passed to mkdirs()");
  238.     myPath = strdup(path);
  239.     if (!myPath)
  240. fail("strdup() failed!");
  241.     do {
  242.      rv = lstat(myPath, &sb);
  243. if (rv < 0) {
  244.     perror(myPath);
  245. } else if (S_ISLNK(sb.st_mode)) {
  246.     rv = readlink(myPath, buf, sizeof buf);
  247.     if (rv < 0) {
  248.      perror("readlink");
  249. buf[0] = 0;
  250.     } else {
  251.      buf[rv] = 0;
  252.     }
  253.     fprintf(stderr, "%s is a link to %sn", myPath, buf);
  254. } else if (S_ISDIR(sb.st_mode)) {
  255.     fprintf(stderr, "%s is a directoryn", myPath);
  256.     rv = access(myPath, X_OK);
  257.     if (rv < 0) {
  258.      fprintf(stderr, "%s: no search permissionn", myPath);
  259.     }
  260. } else {
  261.     fprintf(stderr, "%s is a file !?!n", myPath);
  262.     rv = access(myPath, F_OK);
  263.     if (rv < 0) {
  264.      fprintf(stderr, "%s does not existn", myPath);
  265.     }
  266. }
  267. /* chop path off one level. */
  268. slash = strrchr(myPath, '/');
  269. if (!slash)
  270.     slash = strrchr(myPath, '\');
  271. if (!slash)
  272.     slash = myPath;
  273. *slash = 0;
  274.     } while (myPath[0]);
  275.     free(myPath);
  276. }