1
2
3
4
5
6 using System;
7 using System.Collections;
8 using System.IO;
9 using System.Os;
10 using paths;
11
12 bool TargetIsDirectory(const string& target)
13 {
14 byte[statBufSize] statBuf;
15 int result = stat(target.Chars(), &statBuf[0], statBufSize);
16 if (result == -1)
17 {
18 return false;
19 }
20 FileStatus status;
21 GetFileStatus(&statBuf[0], status);
22 return status.fileType == FileType.directory;
23 }
24
25 void CopyFiles(const List<string>& files, const string& target, const List<FileType>& fileTypes,
26 bool targetDirExists, bool recursive, FileCopyOptions copyOptions)
27 {
28 long n = files.Count();
29 for (long i = 0; i < n; ++i;)
30 {
31 const string& file = files[i];
32 FileType fileType = fileTypes[i];
33 if (fileType == FileType.directory)
34 {
35 DirectoryReader reader(file);
36 DirectoryEntry dirEntry;
37 List<string> sourceFilePaths;
38 while (reader.Read(dirEntry))
39 {
40 if (dirEntry.IsDot() || dirEntry.IsDotDot())
41 {
42 continue;
43 }
44 string sourceFilePath = Path.Combine(file, dirEntry.name);
45 sourceFilePaths.Add(sourceFilePath);
46 }
47 string targetDir = target;
48 if (targetDirExists)
49 {
50 targetDir = Path.Combine(target, Path.GetFileName(file));
51 if (!Directory.Exists(targetDir))
52 {
53 MkDir(targetDir.Chars());
54 }
55 if ((copyOptions & FileCopyOptions.dontPreserveTimestamps) == FileCopyOptions.none)
56 {
57 DateTime accessTime;
58 DateTime modificationTime;
59 Directory.GetTimes(file, accessTime, modificationTime);
60 Directory.SetTimes(targetDir, accessTime, modificationTime);
61 }
62 }
63 Copy(sourceFilePaths, targetDir, recursive, copyOptions);
64 }
65 else if (fileType == FileType.regular)
66 {
67 string targetFilePath = Path.Combine(target, Path.GetFileName(file));
68 File.Copy(file, targetFilePath, copyOptions);
69 }
70 else
71 {
72 throw Exception("'" + file + "' not regular or directory");
73 }
74 }
75 }
76
77 void Copy(const List<string>& files, const string& target, bool recursive, FileCopyOptions copyOptions)
78 {
79 if (!TargetIsDirectory(target))
80 {
81 if (files.Count() == 1)
82 {
83 string file = files.Front();
84 FileStatus status;
85 Stat(file.Chars(), status);
86 if (status.fileType == FileType.directory)
87 {
88 if (!recursive)
89 {
90 throw Exception("'" + file + "' is directory and not --recursive specified");
91 }
92 }
93 else if (status.fileType == FileType.regular)
94 {
95 File.Copy(file, target, copyOptions);
96 return;
97 }
98 else
99 {
100 throw Exception("'" + file + "' not regular or directory");
101 }
102 }
103 else if (files.Count() > 1)
104 {
105 throw Exception("'" + target + "' not directory");
106 }
107 }
108 List<FileType> fileTypes = GetFileTypes(files, recursive);
109 bool targetDirExists = Directory.Exists(target);
110 if (!targetDirExists)
111 {
112 MkDir(target.Chars());
113 }
114 CopyFiles(files, target, fileTypes, targetDirExists, recursive, copyOptions);
115 }