Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

252 lines
5.4 KiB

  1. /* $Source: /u/mark/src/pax/RCS/pathname.c,v $
  2. *
  3. * $Revision: 1.2 $
  4. *
  5. * pathname.c - directory/pathname support functions
  6. *
  7. * DESCRIPTION
  8. *
  9. * These functions provide directory/pathname support for PAX
  10. *
  11. * AUTHOR
  12. *
  13. * Mark H. Colburn, NAPS International (mark@jhereg.mn.org)
  14. *
  15. * Sponsored by The USENIX Association for public distribution.
  16. *
  17. * Copyright (c) 1989 Mark H. Colburn.
  18. * All rights reserved.
  19. *
  20. * Redistribution and use in source and binary forms are permitted
  21. * provided that the above copyright notice is duplicated in all such
  22. * forms and that any documentation, advertising materials, and other
  23. * materials related to such distribution and use acknowledge that the
  24. * software was developed * by Mark H. Colburn and sponsored by The
  25. * USENIX Association.
  26. *
  27. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  28. * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  29. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  30. *
  31. * $Log: pathname.c,v $
  32. * Revision 1.2 89/02/12 10:05:13 mark
  33. * 1.2 release fixes
  34. *
  35. * Revision 1.1 88/12/23 18:02:21 mark
  36. * Initial revision
  37. *
  38. */
  39. #ifndef lint
  40. static char *ident = "$Id: pathname.c,v 1.2 89/02/12 10:05:13 mark Exp $";
  41. static char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
  42. #endif /* ! lint */
  43. /* Headers */
  44. #include "pax.h"
  45. /* dirneed - checks for the existance of directories and possibly create
  46. *
  47. * DESCRIPTION
  48. *
  49. * Dirneed checks to see if a directory of the name pointed to by name
  50. * exists. If the directory does exist, then dirneed returns 0. If
  51. * the directory does not exist and the f_dir_create flag is set,
  52. * then dirneed will create the needed directory, recursively creating
  53. * any needed intermediate directory.
  54. *
  55. * If f_dir_create is not set, then no directories will be created
  56. * and a value of -1 will be returned if the directory does not
  57. * exist.
  58. *
  59. * PARAMETERS
  60. *
  61. * name - name of the directory to create
  62. *
  63. * RETURNS
  64. *
  65. * Returns a 0 if the creation of the directory succeeded or if the
  66. * directory already existed. If the f_dir_create flag was not set
  67. * and the named directory does not exist, or the directory creation
  68. * failed, a -1 will be returned to the calling routine.
  69. */
  70. #ifdef __STDC__
  71. int dirneed(char *name)
  72. #else
  73. int dirneed(name)
  74. char *name;
  75. #endif
  76. {
  77. char *cp;
  78. char *last;
  79. int ok;
  80. static Stat sb;
  81. #ifdef DF_TRACE_DEBUG
  82. printf("DF_TRACE_DEBUG: int dirneed() in pathname.c\n");
  83. #endif
  84. last = (char *)NULL;
  85. for (cp = name; *cp;) {
  86. if (*cp++ == '/') {
  87. last = cp;
  88. }
  89. }
  90. if (last == (char *)NULL) {
  91. return (STAT(".", &sb));
  92. }
  93. *--last = '\0';
  94. ok = STAT(*name ? name : ".", &sb) == 0
  95. ? ((sb.sb_mode & S_IFMT) == S_IFDIR)
  96. : (f_dir_create && dirneed(name) == 0 && dirmake(name, &sb) == 0);
  97. *last = '/';
  98. return (ok ? 0 : -1);
  99. }
  100. /* nameopt - optimize a pathname
  101. *
  102. * DESCRIPTION
  103. *
  104. * Confused by "<symlink>/.." twistiness. Returns the number of final
  105. * pathname elements (zero for "/" or ".") or -1 if unsuccessful.
  106. *
  107. * PARAMETERS
  108. *
  109. * char *begin - name of the path to optimize
  110. *
  111. * RETURNS
  112. *
  113. * Returns 0 if successful, non-zero otherwise.
  114. *
  115. */
  116. #ifdef __STDC__
  117. int nameopt(char *begin)
  118. #else
  119. int nameopt(begin)
  120. char *begin;
  121. #endif
  122. {
  123. char *name;
  124. char *item;
  125. int idx;
  126. int absolute;
  127. char *element[PATHELEM];
  128. #ifdef DF_TRACE_DEBUG
  129. printf("DF_TRACE_DEBUG: ok = STAT() in pathname.c\n");
  130. #endif
  131. absolute = (*(name = begin) == '/');
  132. idx = 0;
  133. for (;;) {
  134. if (idx == PATHELEM) {
  135. warn(begin, "Too many elements");
  136. return (-1);
  137. }
  138. while (*name == '/') {
  139. ++name;
  140. }
  141. if (*name == '\0') {
  142. break;
  143. }
  144. element[idx] = item = name;
  145. while (*name && *name != '/') {
  146. ++name;
  147. }
  148. if (*name) {
  149. *name++ = '\0';
  150. }
  151. if (strcmp(item, "..") == 0) {
  152. if (idx == 0) {
  153. if (!absolute) {
  154. ++idx;
  155. }
  156. } else if (strcmp(element[idx - 1], "..") == 0) {
  157. ++idx;
  158. } else {
  159. --idx;
  160. }
  161. } else if (strcmp(item, ".") != 0) {
  162. ++idx;
  163. }
  164. }
  165. if (idx == 0) {
  166. element[idx++] = absolute ? "" : ".";
  167. }
  168. element[idx] = (char *)NULL;
  169. name = begin;
  170. if (absolute) {
  171. *name++ = '/';
  172. }
  173. for (idx = 0; item = element[idx]; ++idx, *name++ = '/') {
  174. while (*item) {
  175. *name++ = *item++;
  176. }
  177. }
  178. *--name = '\0';
  179. return (idx);
  180. }
  181. /* dirmake - make a directory
  182. *
  183. * DESCRIPTION
  184. *
  185. * Dirmake makes a directory with the appropritate permissions.
  186. *
  187. * PARAMETERS
  188. *
  189. * char *name - Name of directory make
  190. * Stat *asb - Stat structure of directory to make
  191. *
  192. * RETURNS
  193. *
  194. * Returns zero if successful, -1 otherwise.
  195. *
  196. */
  197. #ifdef __STDC__
  198. int dirmake(char *name, Stat *asb)
  199. #else
  200. int dirmake(name, asb)
  201. char *name;
  202. Stat *asb;
  203. #endif
  204. {
  205. #ifdef DF_TRACE_DEBUG
  206. printf("DF_TRACE_DEBUG: int dirmake() in pathname.c\n");
  207. #endif
  208. #ifdef DF_POSIX //DF_DSC permission stuff no working in POSIX
  209. // mkdir (name,0777);
  210. // return (0);
  211. #endif
  212. if (mkdir(name, (int) (asb->sb_mode & S_IPOPN)) < 0) {
  213. return (-1);
  214. }
  215. if (asb->sb_mode & S_IPEXE) {
  216. //printf("name X%sX mode X%ldX\n", name, asb->sb_mode);
  217. chmod(name, (int) (asb->sb_mode & S_IPERM));
  218. }
  219. if (f_owner) {
  220. chown(name, (int) asb->sb_uid, (int) asb->sb_gid);
  221. }
  222. return (0);
  223. }