1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package goldengate.common.file.filesystembased;
22
23 import goldengate.common.command.exception.CommandAbstractException;
24 import goldengate.common.command.exception.Reply550Exception;
25 import goldengate.common.command.exception.Reply553Exception;
26 import goldengate.common.digest.FilesystemBasedDigest;
27 import goldengate.common.file.AbstractDir;
28 import goldengate.common.file.FileInterface;
29 import goldengate.common.file.OptsMLSxInterface;
30 import goldengate.common.file.SessionInterface;
31 import goldengate.common.file.filesystembased.specific.FilesystemBasedCommonsIo;
32 import goldengate.common.file.filesystembased.specific.FilesystemBasedDirJdkAbstract;
33 import goldengate.common.logging.GgInternalLogger;
34 import goldengate.common.logging.GgInternalLoggerFactory;
35
36 import java.io.File;
37 import java.io.FileFilter;
38 import java.io.FileInputStream;
39 import java.io.FileNotFoundException;
40 import java.io.IOException;
41 import java.text.DateFormat;
42 import java.text.SimpleDateFormat;
43 import java.util.ArrayList;
44 import java.util.Calendar;
45 import java.util.Date;
46 import java.util.List;
47 import java.util.Locale;
48 import java.util.zip.CRC32;
49 import java.util.zip.CheckedInputStream;
50
51
52
53
54
55
56
57 public abstract class FilesystemBasedDirImpl extends AbstractDir {
58
59
60
61 private static final GgInternalLogger logger = GgInternalLoggerFactory
62 .getLogger(FilesystemBasedDirImpl.class);
63
64
65
66
67 protected static FilesystemBasedDirJdkAbstract filesystemBasedFtpDirJdk = null;
68
69
70
71
72
73 public static void initJdkDependent(
74 FilesystemBasedDirJdkAbstract filesystemBasedFtpDirJdkChoice) {
75 filesystemBasedFtpDirJdk = filesystemBasedFtpDirJdkChoice;
76 initWindowsSupport();
77 }
78
79
80
81
82
83 public FilesystemBasedDirImpl(SessionInterface session,
84 OptsMLSxInterface optsMLSx) {
85 this.session = session;
86 this.optsMLSx = optsMLSx;
87 this.optsMLSx.setOptsModify((byte) 1);
88 this.optsMLSx.setOptsPerm((byte) 1);
89 this.optsMLSx.setOptsSize((byte) 1);
90 this.optsMLSx.setOptsType((byte) 1);
91 }
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106 protected List<String> wildcardFiles(String pathWithWildcard)
107 throws CommandAbstractException {
108 List<String> resultPaths = new ArrayList<String>();
109
110 if (!(pathWithWildcard.contains("*") || pathWithWildcard.contains("?") || pathWithWildcard
111 .contains("~"))) {
112
113
114 if (getSession().getAuth().isBusinessPathValid(pathWithWildcard)) {
115 resultPaths.add(pathWithWildcard);
116 }
117 return resultPaths;
118 }
119
120 if (!FilesystemBasedDirJdkAbstract.ueApacheCommonsIo) {
121 throw new Reply553Exception("Wildcards in pathname is not allowed");
122 }
123 File wildcardFile;
124 File rootFile;
125 if (isAbsoluteWindows(pathWithWildcard)) {
126 wildcardFile = new File(pathWithWildcard);
127 rootFile = getCorrespondingRoot(wildcardFile);
128 } else {
129 rootFile = new File(((FilesystemBasedAuthImpl) getSession()
130 .getAuth()).getBaseDirectory());
131 wildcardFile = new File(rootFile, pathWithWildcard);
132 }
133
134 List<String> subdirs = new ArrayList<String>();
135 while (wildcardFile != null) {
136 File parent = wildcardFile.getParentFile();
137 if (parent == null) {
138 subdirs.add(0, wildcardFile.getPath());
139 break;
140 }
141 subdirs.add(0, wildcardFile.getName());
142 if (parent.equals(rootFile)) {
143
144 subdirs.add(0, parent.getPath());
145 break;
146 }
147 wildcardFile = parent;
148 }
149 List<File> basedPaths = new ArrayList<File>();
150
151 basedPaths.add(new File(subdirs.get(0)));
152 int i = 1;
153
154 while (i < subdirs.size()) {
155
156 FileFilter fileFilter = FilesystemBasedCommonsIo
157 .getWildcardFileFilter(subdirs.get(i));
158 List<File> newBasedPaths = new ArrayList<File>();
159
160 for (File dir: basedPaths) {
161 if (dir.isDirectory()) {
162 for (File match: dir.listFiles(fileFilter)) {
163 newBasedPaths.add(match);
164 }
165 }
166 }
167
168 basedPaths = newBasedPaths;
169 i ++;
170 }
171
172 for (File file: basedPaths) {
173 String relativePath = ((FilesystemBasedAuthImpl) getSession()
174 .getAuth()).getRelativePath(normalizePath(file
175 .getAbsolutePath()));
176 String newpath = this.validatePath(relativePath);
177 resultPaths.add(newpath);
178 }
179 return resultPaths;
180 }
181
182
183
184
185
186
187
188
189 protected File getFileFromPath(String path) throws CommandAbstractException {
190 String newdir = validatePath(path);
191 if (isAbsoluteWindows(newdir)) {
192 return new File(newdir);
193 }
194 String truedir = ((FilesystemBasedAuthImpl) getSession().getAuth())
195 .getAbsolutePath(newdir);
196 return new File(truedir);
197 }
198
199
200
201
202
203
204
205
206 protected File getTrueFile(String path) throws CommandAbstractException {
207 checkIdentify();
208 String newpath = consolidatePath(path);
209 List<String> paths = wildcardFiles(normalizePath(newpath));
210 if (paths.size() != 1) {
211 throw new Reply550Exception("File not found: " + paths.size() +
212 " founds");
213 }
214 String extDir = paths.get(0);
215 extDir = this.validatePath(extDir);
216 File file = getFileFromPath(extDir);
217 if (!file.isFile()) {
218 throw new Reply550Exception("Path is not a file: " + path);
219 }
220 return file;
221 }
222
223
224
225
226
227
228
229 protected String getRelativePath(File file) {
230 return ((FilesystemBasedAuthImpl) getSession().getAuth())
231 .getRelativePath(normalizePath(file.getAbsolutePath()));
232 }
233
234 public boolean changeDirectory(String path) throws CommandAbstractException {
235 checkIdentify();
236 String newpath = consolidatePath(path);
237 List<String> paths = wildcardFiles(newpath);
238 if (paths.size() != 1) {
239 logger.warn("CD error: {}", newpath);
240 throw new Reply550Exception("Directory not found: " + paths.size() +
241 " founds");
242 }
243 String extDir = paths.get(0);
244 extDir = this.validatePath(extDir);
245 if (isDirectory(extDir)) {
246 currentDir = extDir;
247 return true;
248 }
249 throw new Reply550Exception("Directory not found: "+extDir);
250 }
251
252 public boolean changeDirectoryNotChecked(String path) throws CommandAbstractException {
253 checkIdentify();
254 String newpath = consolidatePath(path);
255 List<String> paths = wildcardFiles(newpath);
256 if (paths.size() != 1) {
257 logger.warn("CD error: {}", newpath);
258 throw new Reply550Exception("Directory not found: " + paths.size() +
259 " founds");
260 }
261 String extDir = paths.get(0);
262 extDir = this.validatePath(extDir);
263 return true;
264 }
265
266 public String mkdir(String directory) throws CommandAbstractException {
267 checkIdentify();
268 String newdirectory = consolidatePath(directory);
269 File dir = new File(newdirectory);
270 String parent = dir.getParentFile().getPath();
271 List<String> paths = wildcardFiles(normalizePath(parent));
272 if (paths.size() != 1) {
273 throw new Reply550Exception("Base Directory not found: " +
274 paths.size() + " founds");
275 }
276 String newDir = paths.get(0) + SEPARATOR + dir.getName();
277 newDir = this.validatePath(newDir);
278 File newdir = getFileFromPath(newDir);
279 if (newdir.mkdir()) {
280 return newDir;
281 }
282 throw new Reply550Exception("Cannot create directory " + newDir);
283 }
284
285 public String rmdir(String directory) throws CommandAbstractException {
286 checkIdentify();
287 String newdirectory = consolidatePath(directory);
288 List<String> paths = wildcardFiles(normalizePath(newdirectory));
289 if (paths.size() != 1) {
290 throw new Reply550Exception("Directory not found: " + paths.size() +
291 " founds");
292 }
293 String extDir = paths.get(0);
294 extDir = this.validatePath(extDir);
295 File dir = getFileFromPath(extDir);
296 if (dir.delete()) {
297 return extDir;
298 }
299 throw new Reply550Exception("Cannot delete directory " + extDir);
300 }
301
302 public boolean isDirectory(String path) throws CommandAbstractException {
303 checkIdentify();
304 File dir = getFileFromPath(path);
305 return dir.isDirectory();
306 }
307
308 public boolean isFile(String path) throws CommandAbstractException {
309 checkIdentify();
310 return getFileFromPath(path).isFile();
311 }
312
313 public String getModificationTime(String path)
314 throws CommandAbstractException {
315 checkIdentify();
316 File file = getFileFromPath(path);
317 if (file.exists()) {
318 return getModificationTime(file);
319 }
320 throw new Reply550Exception("\"" + path + "\" does not exist");
321 }
322
323
324
325
326
327
328
329 protected String getModificationTime(File file) {
330 long mstime = file.lastModified();
331 Calendar calendar = Calendar.getInstance();
332 calendar.setTimeInMillis(mstime);
333 int year = calendar.get(Calendar.YEAR);
334 int month = calendar.get(Calendar.MONTH) + 1;
335 int day = calendar.get(Calendar.DAY_OF_MONTH);
336 int hour = calendar.get(Calendar.HOUR_OF_DAY);
337 int minute = calendar.get(Calendar.MINUTE);
338 int second = calendar.get(Calendar.SECOND);
339 int ms = calendar.get(Calendar.MILLISECOND);
340 StringBuilder sb = new StringBuilder(18);
341 sb.append(year);
342 if (month < 10) {
343 sb.append(0);
344 }
345 sb.append(month);
346 if (day < 10) {
347 sb.append(0);
348 }
349 sb.append(day);
350 if (hour < 10) {
351 sb.append(0);
352 }
353 sb.append(hour);
354 if (minute < 10) {
355 sb.append(0);
356 }
357 sb.append(minute);
358 if (second < 10) {
359 sb.append(0);
360 }
361 sb.append(second);
362 sb.append('.');
363 if (ms < 10) {
364 sb.append(0);
365 }
366 if (ms < 100) {
367 sb.append(0);
368 }
369 sb.append(ms);
370 return sb.toString();
371 }
372
373 public List<String> list(String path) throws CommandAbstractException {
374 checkIdentify();
375
376 String newpath = path;
377 if (newpath == null || newpath.length() == 0) {
378 newpath = currentDir;
379 }
380 if (newpath.startsWith("-a") || newpath.startsWith("-A")) {
381 String[] args = newpath.split(" ");
382 if (args.length > 1) {
383 newpath = args[1];
384 } else {
385 newpath = currentDir;
386 }
387 }
388 newpath = consolidatePath(newpath);
389 List<String> paths = wildcardFiles(newpath);
390 if (paths.isEmpty()) {
391 throw new Reply550Exception("No files found");
392 }
393
394 List<String> newPaths = new ArrayList<String>();
395 for (String file: paths) {
396 File dir = getFileFromPath(file);
397 if (dir.exists()) {
398 if (dir.isDirectory()) {
399 String[] files = dir.list();
400 for (String finalFile: files) {
401 String relativePath = ((FilesystemBasedAuthImpl) getSession()
402 .getAuth()).getRelativePath(finalFile);
403 newPaths.add(relativePath);
404 }
405 } else {
406 newPaths.add(file);
407 }
408 }
409 }
410 return newPaths;
411 }
412
413 public List<String> listFull(String path, boolean lsFormat)
414 throws CommandAbstractException {
415 checkIdentify();
416 boolean listAllFiles = false;
417 String newpath = path;
418 if (newpath == null || newpath.length() == 0) {
419 newpath = currentDir;
420 }
421 if (newpath.startsWith("-a") || newpath.startsWith("-A")) {
422 String[] args = newpath.split(" ");
423 if (args.length > 1) {
424 newpath = args[1];
425 } else {
426 newpath = currentDir;
427 }
428 listAllFiles = true;
429 }
430 newpath = consolidatePath(newpath);
431
432 List<String> paths = wildcardFiles(newpath);
433 if (paths.isEmpty()) {
434 throw new Reply550Exception("No files found");
435 }
436
437 List<String> newPaths = new ArrayList<String>();
438 for (String file: paths) {
439 File dir = getFileFromPath(file);
440 if (dir.exists()) {
441 if (dir.isDirectory()) {
442 File[] files = dir.listFiles();
443 for (File finalFile: files) {
444 if (lsFormat) {
445 newPaths.add(lsInfo(finalFile));
446 } else {
447 newPaths.add(mlsxInfo(finalFile));
448 }
449 }
450 } else {
451 if (lsFormat) {
452 newPaths.add(lsInfo(dir));
453 } else {
454 newPaths.add(mlsxInfo(dir));
455 }
456 }
457 }
458 }
459 if (listAllFiles) {
460 File dir = new File(getFileFromPath(newpath), SEPARATOR + "..");
461 if (lsFormat) {
462 newPaths.add(lsInfo(dir));
463 } else {
464 newPaths.add(mlsxInfo(dir));
465 }
466 }
467 return newPaths;
468 }
469
470 public String fileFull(String path, boolean lsFormat)
471 throws CommandAbstractException {
472 checkIdentify();
473 String newpath = consolidatePath(path);
474 List<String> paths = wildcardFiles(normalizePath(newpath));
475 if (paths.size() != 1) {
476 throw new Reply550Exception("No files found " + paths.size() +
477 " founds");
478 }
479 File file = getFileFromPath(paths.get(0));
480 if (file.exists()) {
481 if (lsFormat) {
482 return "Listing of \"" + paths.get(0) + "\"\n" + lsInfo(file) +
483 "\nEnd of listing";
484 }
485 return "Listing of \"" + paths.get(0) + "\"\n" + mlsxInfo(file) +
486 "\nEnd of listing";
487 }
488 return "No file with name \"" + path + "\"";
489 }
490
491
492
493
494
495
496 protected boolean isFullTime() {
497
498 return false;
499 }
500
501
502
503
504
505
506 protected String lsInfo(File file) {
507
508
509
510 StringBuilder builder = new StringBuilder();
511 builder.append((file.isDirectory()? 'd' : '-'));
512 builder.append((file.canRead()? 'r' : '-'));
513 builder.append((file.canWrite()? 'w' : '-'));
514 if (filesystemBasedFtpDirJdk != null)
515 builder.append(filesystemBasedFtpDirJdk.canExecute(file)? 'x' : '-');
516 else
517 builder.append('-');
518
519 builder.append("---");
520 builder.append("---");
521 builder.append(' ');
522 builder.append("1 ");
523 builder.append("anybody\t");
524 builder.append("anygroup\t");
525 builder.append(file.length());
526 builder.append('\t');
527 long lastmod = file.lastModified();
528 String fmt = null;
529
530
531
532
533 long currentTime = System.currentTimeMillis();
534 if (currentTime > lastmod + 6L * 30L * 24L * 60L * 60L * 1000L
535 || currentTime < lastmod - 60L * 60L * 1000L) {
536
537
538
539
540
541
542
543 fmt = "MMM dd yyyy";
544 } else {
545 fmt = "MMM dd HH:mm";
546 }
547
548 SimpleDateFormat dateFormat = (SimpleDateFormat) DateFormat
549 .getDateTimeInstance(DateFormat.LONG, DateFormat.LONG,
550 Locale.ENGLISH);
551 dateFormat.applyPattern(fmt);
552 builder.append(dateFormat.format(new Date(lastmod)));
553 builder.append('\t');
554 builder.append(file.getName());
555 return builder.toString();
556 }
557
558
559
560
561
562
563 protected String mlsxInfo(File file) {
564
565 StringBuilder builder = new StringBuilder(" ");
566 if (getOptsMLSx().getOptsSize() == 1) {
567 builder.append("Size=");
568 builder.append(file.length());
569 builder.append(';');
570 }
571 if (getOptsMLSx().getOptsModify() == 1) {
572 builder.append("Modify=");
573 builder.append(this.getModificationTime(file));
574 builder.append(';');
575 }
576 if (getOptsMLSx().getOptsType() == 1) {
577 builder.append("Type=");
578 try {
579 if (getFileFromPath(currentDir).equals(file)) {
580 builder.append("cdir");
581 } else {
582 if (file.isDirectory()) {
583 builder.append("dir");
584 } else {
585 builder.append("file");
586 }
587 }
588 } catch (CommandAbstractException e) {
589 if (file.isDirectory()) {
590 builder.append("dir");
591 } else {
592 builder.append("file");
593 }
594 }
595 builder.append(';');
596 }
597 if (getOptsMLSx().getOptsPerm() == 1) {
598 builder.append("Perm=");
599 if (file.isFile()) {
600 if (file.canWrite()) {
601 builder.append('a');
602 builder.append('d');
603 builder.append('f');
604 builder.append('w');
605 }
606 if (file.canRead()) {
607 builder.append('r');
608 }
609 } else {
610
611 if (file.canWrite()) {
612 builder.append('c');
613 try {
614 if (this.validatePath(file) != null) {
615 builder.append('d');
616 builder.append('m');
617 builder.append('p');
618 }
619 } catch (CommandAbstractException e) {
620 }
621 }
622 if (file.canRead()) {
623 builder.append('l');
624 builder.append('e');
625 }
626 }
627 builder.append(';');
628 }
629
630 builder.append(' ');
631 builder.append(file.getName());
632 return builder.toString();
633 }
634
635 public long getFreeSpace() throws CommandAbstractException {
636 checkIdentify();
637 File directory = getFileFromPath(currentDir);
638 if (filesystemBasedFtpDirJdk != null)
639 return filesystemBasedFtpDirJdk.getFreeSpace(directory);
640 else
641 return Integer.MAX_VALUE;
642 }
643
644 public FileInterface setUniqueFile()
645 throws CommandAbstractException {
646 checkIdentify();
647 File file = null;
648 try {
649 file = File.createTempFile(getSession().getAuth().getUser(),
650 this.session.getUniqueExtension(), getFileFromPath(currentDir));
651 } catch (IOException e) {
652 throw new Reply550Exception("Cannot create unique file");
653 }
654 String currentFile = getRelativePath(file);
655 return newFile(normalizePath(currentFile), false);
656 }
657
658 public boolean canRead() throws CommandAbstractException {
659 checkIdentify();
660 return getFileFromPath(currentDir).canRead();
661 }
662
663 public boolean canWrite() throws CommandAbstractException {
664 checkIdentify();
665 File file = getFileFromPath(currentDir);
666 return file.canWrite();
667 }
668
669 public boolean exists() throws CommandAbstractException {
670 checkIdentify();
671 return getFileFromPath(currentDir).exists();
672 }
673
674 public long getCRC(String path) throws CommandAbstractException {
675 File file = getTrueFile(path);
676 try {
677 CheckedInputStream cis = null;
678 try {
679
680 cis = new CheckedInputStream(new FileInputStream(file),
681 new CRC32());
682 } catch (FileNotFoundException e) {
683 throw new Reply550Exception("File not found: " + path);
684 }
685 byte[] buf = new byte[session.getBlockSize()];
686 while (cis.read(buf) >= 0) {
687 }
688 return cis.getChecksum().getValue();
689 } catch (IOException e) {
690 throw new Reply550Exception("Error while reading file: " + path);
691 }
692 }
693
694 public byte[] getMD5(String path) throws CommandAbstractException {
695 File file = getTrueFile(path);
696 try {
697 if (FilesystemBasedFileParameterImpl.useNio) {
698 return FilesystemBasedDigest.getHashMd5Nio(file);
699 }
700 return FilesystemBasedDigest.getHashMd5(file);
701 } catch (IOException e1) {
702 throw new Reply550Exception("Error while reading file: " + path);
703 }
704 }
705
706 public byte[] getSHA1(String path) throws CommandAbstractException {
707 File file = getTrueFile(path);
708 try {
709 if (FilesystemBasedFileParameterImpl.useNio) {
710 return FilesystemBasedDigest.getHashSha1Nio(file);
711 }
712 return FilesystemBasedDigest.getHashSha1(file);
713 } catch (IOException e1) {
714 throw new Reply550Exception("Error while reading file: " + path);
715 }
716 }
717
718 }