Autopsy 4.22.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
ContentUtils.java
Go to the documentation of this file.
1/*
2 * Autopsy Forensic Browser
3 *
4 * Copyright 2011-2018 Basis Technology Corp.
5 * Contact: carrier <at> sleuthkit <dot> org
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19package org.sleuthkit.autopsy.datamodel;
20
21import java.io.FileOutputStream;
22import java.io.IOException;
23import java.io.InputStream;
24import java.text.SimpleDateFormat;
25import java.util.TimeZone;
26import java.util.concurrent.Future;
27import java.util.function.Supplier;
28import java.util.logging.Level;
29import javax.swing.SwingWorker;
30import org.netbeans.api.progress.ProgressHandle;
31import org.openide.util.NbBundle;
32import org.sleuthkit.autopsy.core.UserPreferences;
33import org.sleuthkit.autopsy.coreutils.Logger;
34import org.sleuthkit.datamodel.AbstractFile;
35import org.sleuthkit.datamodel.Content;
36import org.sleuthkit.datamodel.ContentVisitor;
37import org.sleuthkit.datamodel.DerivedFile;
38import org.sleuthkit.datamodel.Directory;
39import org.sleuthkit.datamodel.File;
40import org.sleuthkit.datamodel.LayoutFile;
41import org.sleuthkit.datamodel.LocalFile;
42import org.sleuthkit.datamodel.LocalDirectory;
43import org.sleuthkit.datamodel.ReadContentInputStream;
44import org.sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException;
45import org.sleuthkit.datamodel.SlackFile;
46import org.sleuthkit.datamodel.TskCoreException;
47import org.sleuthkit.datamodel.VirtualDirectory;
48
52public final class ContentUtils {
53
54 private final static Logger logger = Logger.getLogger(ContentUtils.class.getName());
55 private static final SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
56 private static final SimpleDateFormat dateFormatterISO8601 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
57
61 private ContentUtils() {
62 throw new AssertionError();
63 }
64
73 @Deprecated
74 public static String getStringTime(long epochSeconds, TimeZone tzone) {
75 String time = "0000-00-00 00:00:00";
76 if (epochSeconds != 0) {
77 synchronized (dateFormatter) {
78 dateFormatter.setTimeZone(tzone);
79 time = dateFormatter.format(new java.util.Date(epochSeconds * 1000));
80 }
81 }
82 return time;
83 }
84
93 @Deprecated
94 public static String getStringTimeISO8601(long epochSeconds, TimeZone tzone) {
95 String time = "0000-00-00T00:00:00Z"; //NON-NLS
96 if (epochSeconds != 0) {
97 synchronized (dateFormatterISO8601) {
98 dateFormatterISO8601.setTimeZone(tzone);
99 time = dateFormatterISO8601.format(new java.util.Date(epochSeconds * 1000));
100 }
101 }
102
103 return time;
104 }
105
116 @Deprecated
117 public static String getStringTime(long epochSeconds, Content content) {
118 return getStringTime(epochSeconds, getTimeZone(content));
119 }
120
132 @Deprecated
133 public static String getStringTimeISO8601(long epochSeconds, Content c) {
134 return getStringTimeISO8601(epochSeconds, getTimeZone(c));
135 }
136
146 @Deprecated
147 public static TimeZone getTimeZone(Content content) {
149 return TimeZone.getTimeZone(UserPreferences.getTimeZoneForDisplays());
150 } else {
151 return TimeZone.getDefault();
152 }
153 }
154 private static final SystemNameVisitor systemName = new SystemNameVisitor();
155
163 public static String getSystemName(Content content) {
164 return content.accept(systemName);
165 }
166
171 private static class SystemNameVisitor extends ContentVisitor.Default<String> {
172
173 SystemNameVisitor() {
174 }
175
176 @Override
177 protected String defaultVisit(Content cntnt) {
178 return cntnt.getName() + ":" + Long.toString(cntnt.getId());
179 }
180 }
181 private static final int TO_FILE_BUFFER_SIZE = 8192;
182
201 public static <T> long writeToFile(Content content, java.io.File outputFile,
202 ProgressHandle progress, Future<T> worker, boolean source) throws IOException {
203 InputStream in = new ReadContentInputStream(content);
204
205 // Get the unit size for a progress bar
206 int unit = (int) (content.getSize() / 100);
207 long totalRead = 0;
208
209 try (FileOutputStream out = new FileOutputStream(outputFile, false)) {
210 byte[] buffer = new byte[TO_FILE_BUFFER_SIZE];
211 int len = in.read(buffer);
212 while (len != -1) {
213 // If there is a worker, check for a cancelation
214 if (worker != null && worker.isCancelled()) {
215 break;
216 }
217 out.write(buffer, 0, len);
218 len = in.read(buffer);
219 totalRead += len;
220 // If there is a progress bar and this is the source file,
221 // report any progress
222 if (progress != null && source && totalRead >= TO_FILE_BUFFER_SIZE) {
223 int totalProgress = (int) (totalRead / unit);
224 progress.progress(content.getName(), totalProgress);
225 // If it's not the source, just update the file being processed
226 } else if (progress != null && !source) {
227 progress.progress(content.getName());
228 }
229 }
230 } finally {
231 in.close();
232 }
233 return totalRead;
234 }
235
244 public static void writeToFile(Content content, java.io.File outputFile) throws IOException {
245 writeToFile(content, outputFile, null, null, false);
246 }
247
262 public static long writeToFile(Content content, java.io.File outputFile,
263 Supplier<Boolean> cancelCheck) throws IOException {
264 InputStream in = new ReadContentInputStream(content);
265 long totalRead = 0;
266
267 try (FileOutputStream out = new FileOutputStream(outputFile, false)) {
268 byte[] buffer = new byte[TO_FILE_BUFFER_SIZE];
269 int len = in.read(buffer);
270 while (len != -1) {
271 out.write(buffer, 0, len);
272 totalRead += len;
273 if (cancelCheck.get()) {
274 break;
275 }
276 len = in.read(buffer);
277 }
278 } finally {
279 in.close();
280 }
281 return totalRead;
282 }
283
300 public static long writeToFile(Content content, java.io.File outputFile,
301 Supplier<Boolean> cancelCheck, long startingOffset, long endingOffset) throws IOException {
302
303 InputStream in = new ReadContentInputStream(content);
304 long totalRead = 0;
305 try (FileOutputStream out = new FileOutputStream(outputFile, false)) {
306 long offsetSkipped = in.skip(startingOffset);
307 if (offsetSkipped != startingOffset) {
308 in.close();
309 throw new IOException(String.format("Skipping file to starting offset {0} was not successful only skipped to offset {1}.", startingOffset, offsetSkipped));
310 }
311 byte[] buffer = new byte[TO_FILE_BUFFER_SIZE];
312 int len = in.read(buffer);
313 long writeFileLength = endingOffset - startingOffset;
314 writeFileLength = writeFileLength - TO_FILE_BUFFER_SIZE;
315 while (len != -1 && writeFileLength != 0) {
316 out.write(buffer, 0, len);
317 totalRead += len;
318 if (cancelCheck.get()) {
319 break;
320 }
321 if (writeFileLength > TO_FILE_BUFFER_SIZE) {
322 len = in.read(buffer);
323 writeFileLength = writeFileLength - TO_FILE_BUFFER_SIZE;
324 } else {
325 int writeLength = (int)writeFileLength;
326 byte[] lastBuffer = new byte[writeLength];
327 len = in.read(lastBuffer);
328 out.write(lastBuffer, 0, len);
329 totalRead += len;
330 writeFileLength = 0;
331 }
332 }
333
334 } finally {
335 in.close();
336 }
337 return totalRead;
338 }
339
347 public static boolean isDotDirectory(AbstractFile dir) {
348 String name = dir.getName();
349 return name.equals(".") || name.equals("..");
350 }
351
357 public static class ExtractFscContentVisitor<T, V> extends ContentVisitor.Default<Void> {
358
359 java.io.File dest;
360 ProgressHandle progress;
361 SwingWorker<T, V> worker;
362 boolean source = false;
363
376 public ExtractFscContentVisitor(java.io.File dest,
377 ProgressHandle progress, SwingWorker<T, V> worker, boolean source) {
378 this.dest = dest;
379 this.progress = progress;
380 this.worker = worker;
381 this.source = source;
382 }
383
384 public ExtractFscContentVisitor(java.io.File dest) {
385 this.dest = dest;
386 }
387
392 public static <T, V> void extract(Content cntnt, java.io.File dest, ProgressHandle progress, SwingWorker<T, V> worker) {
393 cntnt.accept(new ExtractFscContentVisitor<>(dest, progress, worker, true));
394 }
395
410 protected void writeFile(Content file, java.io.File dest, ProgressHandle progress, SwingWorker<T, V> worker, boolean source) throws IOException {
411 ContentUtils.writeToFile(file, dest, progress, worker, source);
412 }
413
420 protected Void visitFile(Content file, String fileType) {
421 try {
422 writeFile(file, dest, progress, worker, source);
423 } catch (ReadContentInputStreamException ex) {
424 logger.log(Level.WARNING,
425 String.format("Error reading file '%s' (id=%d).",
426 file.getName(), file.getId()), ex); //NON-NLS
427 } catch (IOException ex) {
428 logger.log(Level.SEVERE,
429 String.format("Error extracting %s '%s' (id=%d) to '%s'.",
430 fileType, file.getName(), file.getId(), dest.getAbsolutePath()), ex); //NON-NLS
431 }
432 return null;
433 }
434
435 @Override
436 public Void visit(File file) {
437 return visitFile(file, "file");
438 }
439
440 @Override
441 public Void visit(LayoutFile file) {
442 return visitFile(file, "unallocated content file");
443 }
444
445 @Override
446 public Void visit(DerivedFile file) {
447 return visitFile(file, "derived file");
448 }
449
450 @Override
451 public Void visit(LocalFile file) {
452 return visitFile(file, "local file");
453 }
454
455 @Override
456 public Void visit(SlackFile file) {
457 return visitFile(file, "slack file");
458 }
459
460 @Override
461 public Void visit(Directory dir) {
462 return visitDir(dir);
463 }
464
465 @Override
466 public Void visit(VirtualDirectory dir) {
467 return visitDir(dir);
468 }
469
470 @Override
471 public Void visit(LocalDirectory dir) {
472 return visitDir(dir);
473 }
474
475 private java.io.File getFsContentDest(Content content) {
476 String path = dest.getAbsolutePath() + java.io.File.separator
477 + content.getName();
478 return new java.io.File(path);
479 }
480
491 protected ExtractFscContentVisitor<T, V> getChildVisitor(java.io.File childFile, ProgressHandle progress, SwingWorker<T, V> worker) {
492 return new ExtractFscContentVisitor<>(childFile, progress, worker, false);
493 }
494
495 public Void visitDir(AbstractFile dir) {
496
497 // don't extract . and .. directories
498 if (isDotDirectory(dir)) {
499 return null;
500 }
501
502 dest.mkdir();
503
504 try {
505 int numProcessed = 0;
506 // recurse on children
507 for (Content child : dir.getChildren()) {
508 if (child instanceof AbstractFile) { //ensure the directory's artifact children are ignored
509 java.io.File childFile = getFsContentDest(child);
510 ExtractFscContentVisitor<T, V> childVisitor = getChildVisitor(childFile, progress, worker);
511 // If this is the source directory of an extract it
512 // will have a progress and worker, and will keep track
513 // of the progress bar's progress
514 if (worker != null && worker.isCancelled()) {
515 break;
516 }
517 if (progress != null && source) {
518 progress.progress(child.getName(), numProcessed);
519 }
520 child.accept(childVisitor);
521 numProcessed++;
522 }
523 }
524 } catch (TskCoreException ex) {
525 logger.log(Level.SEVERE,
526 "Trouble fetching children to extract.", ex); //NON-NLS
527 }
528
529 return null;
530 }
531
532 @Override
533 protected Void defaultVisit(Content content) {
534 throw new UnsupportedOperationException(NbBundle.getMessage(this.getClass(),
535 "ContentUtils.exception.msg",
536 content.getClass().getSimpleName()));
537 }
538 }
539
547 @Deprecated
548 public static boolean shouldDisplayTimesInLocalTime() {
550 }
551
552}
synchronized static Logger getLogger(String name)
Definition Logger.java:124
static< T, V > void extract(Content cntnt, java.io.File dest, ProgressHandle progress, SwingWorker< T, V > worker)
void writeFile(Content file, java.io.File dest, ProgressHandle progress, SwingWorker< T, V > worker, boolean source)
ExtractFscContentVisitor< T, V > getChildVisitor(java.io.File childFile, ProgressHandle progress, SwingWorker< T, V > worker)
ExtractFscContentVisitor(java.io.File dest, ProgressHandle progress, SwingWorker< T, V > worker, boolean source)
static TimeZone getTimeZone(Content content)
static final SimpleDateFormat dateFormatter
static final SimpleDateFormat dateFormatterISO8601
static void writeToFile(Content content, java.io.File outputFile)
static String getStringTime(long epochSeconds, Content content)
static String getStringTimeISO8601(long epochSeconds, Content c)
static boolean isDotDirectory(AbstractFile dir)
static String getStringTime(long epochSeconds, TimeZone tzone)
static final SystemNameVisitor systemName
static< T > long writeToFile(Content content, java.io.File outputFile, ProgressHandle progress, Future< T > worker, boolean source)
static long writeToFile(Content content, java.io.File outputFile, Supplier< Boolean > cancelCheck)
static String getSystemName(Content content)
static String getStringTimeISO8601(long epochSeconds, TimeZone tzone)
static long writeToFile(Content content, java.io.File outputFile, Supplier< Boolean > cancelCheck, long startingOffset, long endingOffset)

Copyright © 2012-2024 Sleuth Kit Labs. Generated on:
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.