Leaked source code of windows server 2003
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.

334 lines
7.1 KiB

  1. #include <cache.hxx>
  2. #include <conmgr.hxx>
  3. #include <time.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <dirent.h>
  7. #include <fcntl.h>
  8. #include <unistd.h>
  9. #include <errno.h>
  10. extern int errno;
  11. /* Code swiped from cachecfg.cxx */
  12. static BOOL _NormalisePath(LPCTSTR pszPath, LPCTSTR pszEnvVar,
  13. LPTSTR pszResult, UINT cbResult)
  14. {
  15. TCHAR szEnvVar[MAX_PATH];
  16. // don't count the NULL
  17. ExpandEnvironmentStrings(pszEnvVar, szEnvVar, sizeof(szEnvVar)-1);
  18. DWORD dwEnvVar = lstrlen(szEnvVar);
  19. if (CompareString(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, szEnvVar,
  20. dwEnvVar, pszPath, dwEnvVar) == 2)
  21. {
  22. if (lstrlen(pszPath) + dwEnvVar < cbResult)
  23. {
  24. strncpy(pszResult, pszEnvVar, MAX_PATH);
  25. strncat(pszResult, pszPath + dwEnvVar, MAX_PATH);
  26. return TRUE;
  27. }
  28. }
  29. return FALSE;
  30. }
  31. void UnixNormalisePath(LPTSTR pszOrigPath, LPCTSTR pszEnvVar)
  32. {
  33. TCHAR szScratch[MAX_PATH];
  34. if (_NormalisePath(pszOrigPath,pszEnvVar,szScratch,sizeof(szScratch)))
  35. strncpy(pszOrigPath,szScratch,MAX_PATH);
  36. }
  37. void UnixNormaliseIfCachePath(LPTSTR pszOrigPath, LPCTSTR pszEnvVar,
  38. LPCTSTR pszKeyName)
  39. {
  40. if (!strncmp(pszKeyName,CACHE_PATH_VALUE,lstrlen(CACHE_PATH_VALUE)))
  41. UnixNormalisePath(pszOrigPath,pszEnvVar);
  42. }
  43. int UnixPathExists(LPCTSTR pszPath)
  44. {
  45. struct stat statbuf;
  46. if (stat(pszPath, &statbuf) < 0)
  47. {
  48. /* If path does not exist */
  49. if (errno == ENOENT)
  50. return 0;
  51. else
  52. return -1;
  53. }
  54. /* TODO */
  55. /* Make sure path points to a directory */
  56. return 1;
  57. }
  58. void UnixGetValidParentPath(LPTSTR szDevice)
  59. {
  60. TCHAR szDeviceExists[MAX_PATH];
  61. PTSTR pszDeviceExists = NULL;
  62. PTSTR pszEnd = NULL;
  63. if (!szDevice)
  64. return;
  65. lstrcpy(szDeviceExists, szDevice);
  66. pszDeviceExists = szDeviceExists;
  67. pszEnd = szDeviceExists + lstrlen(szDeviceExists);
  68. for(;;)
  69. {
  70. int fPathExists;
  71. if (pszEnd == pszDeviceExists)
  72. break;
  73. fPathExists = UnixPathExists(pszDeviceExists);
  74. if (fPathExists == -1)
  75. {
  76. /* Error */
  77. break;
  78. }
  79. else
  80. if (fPathExists == 0)
  81. {
  82. /* Path does not exist */
  83. while (*pszEnd != DIR_SEPARATOR_CHAR &&
  84. pszEnd != pszDeviceExists)
  85. pszEnd--;
  86. *pszEnd = '\0';
  87. continue;
  88. }
  89. else
  90. {
  91. /* Path exists */
  92. lstrcpy(szDevice, pszDeviceExists);
  93. break;
  94. }
  95. }
  96. }
  97. /* CopyDir */
  98. static int DoCopy();
  99. static int UnixCopyCacheFile(const char* file_src,
  100. const char* file_dest,
  101. mode_t fmode);
  102. static int UnixCreateCacheFolder( const char* dir_dest, mode_t fmode);
  103. #ifndef BUFSIZ
  104. #define BUFSIZ 4096
  105. #endif /* BUFSIZ */
  106. #define CUR_DIR "."
  107. #define PREV_DIR ".."
  108. static char* pathdir1 = NULL;
  109. static char* pathdir2 = NULL;
  110. int CopyDir(const char* dirname1, const char* dirname2)
  111. {
  112. int Error = 0;
  113. struct stat statdir1, statdir2;
  114. if (!dirname1 || !dirname2)
  115. {
  116. goto Cleanup;
  117. }
  118. /* We are assuming that dirname1 and dirname2 are absolute paths */
  119. if (stat(dirname1, &statdir1) < 0)
  120. {
  121. Error = errno;
  122. goto Cleanup;
  123. }
  124. else
  125. if (!S_ISDIR(statdir1.st_mode))
  126. {
  127. Error = -1; /* source is not directory */
  128. goto Cleanup;
  129. }
  130. if (stat(dirname2, &statdir2) < 0)
  131. {
  132. if (errno != ENOENT)
  133. {
  134. Error = errno;
  135. goto Cleanup;
  136. }
  137. /* It is fine if the destination dir does not exist
  138. * provided all directories above the leaf dir exist
  139. */
  140. }
  141. else
  142. if (!S_ISDIR(statdir2.st_mode))
  143. {
  144. Error = -1; /* destination is not directory */
  145. goto Cleanup;
  146. }
  147. pathdir1 = (char*)malloc((MAX_PATH+1)*sizeof(char));
  148. pathdir2 = (char*)malloc((MAX_PATH+1)*sizeof(char));
  149. lstrcpy(pathdir1, dirname1);
  150. lstrcpy(pathdir2, dirname2);
  151. Error = DoCopy();
  152. Cleanup:
  153. if (pathdir1)
  154. free(pathdir1);
  155. if (pathdir2)
  156. free(pathdir2);
  157. pathdir1 = pathdir2 = NULL;
  158. return Error;
  159. }
  160. int DoCopy()
  161. {
  162. struct stat statbuf;
  163. struct dirent *dirp;
  164. DIR *dp;
  165. int Error;
  166. char *ptr1, *ptr2;
  167. if (stat(pathdir1, &statbuf) < 0)
  168. {
  169. Error = errno;
  170. goto Cleanup;
  171. }
  172. /* Check if this is a regular file */
  173. if ((statbuf.st_mode & S_IFMT) == S_IFREG)
  174. {
  175. Error = UnixCopyCacheFile(pathdir1, pathdir2, statbuf.st_mode);
  176. goto Cleanup;
  177. }
  178. /* Now, we are dealing with a directory */
  179. if ((Error = UnixCreateCacheFolder(pathdir2, statbuf.st_mode)))
  180. goto Cleanup;
  181. ptr1 = pathdir1 + lstrlen(pathdir1);
  182. *ptr1++ = '/';
  183. *ptr1 = 0;
  184. ptr2 = pathdir2 + lstrlen(pathdir2);
  185. *ptr2++ = '/';
  186. *ptr2 = 0;
  187. if ((dp = opendir(pathdir1)) == NULL)
  188. {
  189. Error = errno;
  190. goto Cleanup;
  191. }
  192. while ((dirp = readdir(dp)) != NULL)
  193. {
  194. if (!lstrcmp(dirp->d_name, CUR_DIR) ||
  195. !lstrcmp(dirp->d_name, PREV_DIR))
  196. continue;
  197. lstrcpy(ptr1, dirp->d_name);
  198. lstrcpy(ptr2, dirp->d_name);
  199. if ((Error = DoCopy()))
  200. break;
  201. }
  202. ptr1[-1] = 0;
  203. ptr2[-1] = 0;
  204. /* If this fails, ignore this error */
  205. closedir(dp);
  206. Cleanup:
  207. return Error;
  208. }
  209. static int UnixCreateCacheFolder( const char* path_dest, mode_t mode_src)
  210. {
  211. int Error = 0;
  212. struct stat statbuf2;
  213. if (stat(path_dest, &statbuf2) < 0)
  214. {
  215. if (errno == ENOENT)
  216. {
  217. if (mkdir(path_dest, mode_src) < 0)
  218. {
  219. Error = errno;
  220. goto Cleanup;
  221. }
  222. }
  223. else
  224. {
  225. Error = errno;
  226. goto Cleanup;
  227. }
  228. }
  229. else
  230. if (!S_ISDIR(statbuf2.st_mode))
  231. Error = -1; /* we are expecting a directory */
  232. Cleanup:
  233. return Error;
  234. }
  235. int UnixCopyCacheFile(const char* file_src, const char* file_dest, mode_t fmode)
  236. {
  237. int Error = 0;
  238. int fd1, fd2;
  239. char buf[BUFSIZ];
  240. int nread, nwrite;
  241. if ((fd1 = open(file_src, O_RDONLY)) < 0)
  242. {
  243. Error = errno;
  244. goto Cleanup;
  245. }
  246. if ((fd2 = open(file_dest, O_CREAT|O_TRUNC|O_WRONLY, fmode)) < 0)
  247. {
  248. Error = errno;
  249. goto Cleanup;
  250. }
  251. while((nread = read(fd1, buf, BUFSIZ)) > 0)
  252. {
  253. if ((nwrite = write(fd2, buf, nread)) != nread)
  254. {
  255. Error = errno;
  256. goto Cleanup;
  257. }
  258. }
  259. Error = 0;
  260. Cleanup:
  261. if (fd1 > 0)
  262. close(fd1);
  263. if (fd2 > 0)
  264. close(fd2);
  265. return Error;
  266. }