Autopsy  4.19.3
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  */
19 package org.sleuthkit.autopsy.datamodel;
20 
21 import java.io.FileOutputStream;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.text.SimpleDateFormat;
25 import java.util.TimeZone;
26 import java.util.concurrent.Future;
27 import java.util.function.Supplier;
28 import java.util.logging.Level;
29 import javax.swing.SwingWorker;
30 import org.netbeans.api.progress.ProgressHandle;
31 import org.openide.util.NbBundle;
34 import org.sleuthkit.datamodel.AbstractFile;
35 import org.sleuthkit.datamodel.Content;
36 import org.sleuthkit.datamodel.ContentVisitor;
37 import org.sleuthkit.datamodel.DerivedFile;
38 import org.sleuthkit.datamodel.Directory;
39 import org.sleuthkit.datamodel.File;
40 import org.sleuthkit.datamodel.LayoutFile;
41 import org.sleuthkit.datamodel.LocalFile;
42 import org.sleuthkit.datamodel.LocalDirectory;
43 import org.sleuthkit.datamodel.ReadContentInputStream;
44 import org.sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException;
45 import org.sleuthkit.datamodel.SlackFile;
46 import org.sleuthkit.datamodel.TskCoreException;
47 import org.sleuthkit.datamodel.VirtualDirectory;
48 
52 public 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 
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 }
static String getStringTime(long epochSeconds, TimeZone tzone)
static final SimpleDateFormat dateFormatter
ExtractFscContentVisitor(java.io.File dest, ProgressHandle progress, SwingWorker< T, V > worker, boolean source)
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, long startingOffset, long endingOffset)
static String getSystemName(Content content)
static String getStringTime(long epochSeconds, Content content)
static< T, V > void extract(Content cntnt, java.io.File dest, ProgressHandle progress, SwingWorker< T, V > worker)
static TimeZone getTimeZone(Content content)
static String getStringTimeISO8601(long epochSeconds, TimeZone tzone)
static final SimpleDateFormat dateFormatterISO8601
static final SystemNameVisitor systemName
ExtractFscContentVisitor< T, V > getChildVisitor(java.io.File childFile, ProgressHandle progress, SwingWorker< T, V > worker)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
static String getStringTimeISO8601(long epochSeconds, Content c)
void writeFile(Content file, java.io.File dest, ProgressHandle progress, SwingWorker< T, V > worker, boolean source)
static void writeToFile(Content content, java.io.File outputFile)
static long writeToFile(Content content, java.io.File outputFile, Supplier< Boolean > cancelCheck)
static boolean isDotDirectory(AbstractFile dir)

Copyright © 2012-2022 Basis Technology. Generated on: Tue Jun 27 2023
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.