Autopsy  4.4.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-2017 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 java.util.prefs.PreferenceChangeEvent;
30 import java.util.prefs.PreferenceChangeListener;
31 import javax.swing.SwingWorker;
32 import org.netbeans.api.progress.ProgressHandle;
33 import org.openide.util.NbBundle;
36 import org.sleuthkit.datamodel.AbstractFile;
37 import org.sleuthkit.datamodel.Content;
38 import org.sleuthkit.datamodel.ContentVisitor;
39 import org.sleuthkit.datamodel.DerivedFile;
40 import org.sleuthkit.datamodel.Directory;
41 import org.sleuthkit.datamodel.File;
42 import org.sleuthkit.datamodel.Image;
43 import org.sleuthkit.datamodel.LayoutFile;
44 import org.sleuthkit.datamodel.LocalFile;
45 import org.sleuthkit.datamodel.LocalDirectory;
46 import org.sleuthkit.datamodel.ReadContentInputStream;
47 import org.sleuthkit.datamodel.SlackFile;
48 import org.sleuthkit.datamodel.TskCoreException;
49 import org.sleuthkit.datamodel.VirtualDirectory;
50 
54 public final class ContentUtils {
55 
56  private final static Logger logger = Logger.getLogger(ContentUtils.class.getName());
58  private static final SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
59  private static final SimpleDateFormat dateFormatterISO8601 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
60 
61  static {
62  UserPreferences.addChangeListener(new PreferenceChangeListener() {
63  @Override
64  public void preferenceChange(PreferenceChangeEvent evt) {
65  if (evt.getKey().equals(UserPreferences.DISPLAY_TIMES_IN_LOCAL_TIME)) {
66  displayTimesInLocalTime = UserPreferences.displayTimesInLocalTime();
67  }
68  }
69  });
70  }
71 
72  // don't instantiate
73  private ContentUtils() {
74  throw new AssertionError();
75  }
76 
85  public static String getStringTime(long epochSeconds, TimeZone tzone) {
86  String time = "0000-00-00 00:00:00";
87  if (epochSeconds != 0) {
88  synchronized (dateFormatter) {
89  dateFormatter.setTimeZone(tzone);
90  time = dateFormatter.format(new java.util.Date(epochSeconds * 1000));
91  }
92  }
93  return time;
94  }
95 
96  public static String getStringTimeISO8601(long epochSeconds, TimeZone tzone) {
97  String time = "0000-00-00T00:00:00Z"; //NON-NLS
98  if (epochSeconds != 0) {
99  synchronized (dateFormatterISO8601) {
100  dateFormatterISO8601.setTimeZone(tzone);
101  time = dateFormatterISO8601.format(new java.util.Date(epochSeconds * 1000));
102  }
103  }
104 
105  return time;
106  }
107 
116  public static String getStringTime(long epochSeconds, Content c) {
117  return getStringTime(epochSeconds, getTimeZone(c));
118  }
119 
129  public static String getStringTimeISO8601(long epochSeconds, Content c) {
130  return getStringTimeISO8601(epochSeconds, getTimeZone(c));
131  }
132 
133  public static TimeZone getTimeZone(Content c) {
134 
135  try {
137  return TimeZone.getTimeZone("GMT");
138  } else {
139  final Content dataSource = c.getDataSource();
140  if ((dataSource != null) && (dataSource instanceof Image)) {
141  Image image = (Image) dataSource;
142  return TimeZone.getTimeZone(image.getTimeZone());
143  } else {
144  //case such as top level VirtualDirectory
145  return TimeZone.getDefault();
146  }
147  }
148  } catch (TskCoreException ex) {
149  return TimeZone.getDefault();
150  }
151  }
152  private static final SystemNameVisitor systemName = new SystemNameVisitor();
153 
154  public static String getSystemName(Content content) {
155  return content.accept(systemName);
156  }
157 
158  private static class SystemNameVisitor extends ContentVisitor.Default<String> {
159 
161  }
162 
163  @Override
164  protected String defaultVisit(Content cntnt) {
165  return cntnt.getName() + ":" + Long.toString(cntnt.getId());
166  }
167  }
168  private static final int TO_FILE_BUFFER_SIZE = 8192;
169 
188  public static <T> long writeToFile(Content content, java.io.File outputFile,
189  ProgressHandle progress, Future<T> worker, boolean source) throws IOException {
190  InputStream in = new ReadContentInputStream(content);
191 
192  // Get the unit size for a progress bar
193  int unit = (int) (content.getSize() / 100);
194  long totalRead = 0;
195 
196  try (FileOutputStream out = new FileOutputStream(outputFile, false)) {
197  byte[] buffer = new byte[TO_FILE_BUFFER_SIZE];
198  int len = in.read(buffer);
199  while (len != -1) {
200  // If there is a worker, check for a cancelation
201  if (worker != null && worker.isCancelled()) {
202  break;
203  }
204  out.write(buffer, 0, len);
205  len = in.read(buffer);
206  totalRead += len;
207  // If there is a progress bar and this is the source file,
208  // report any progress
209  if (progress != null && source && totalRead >= TO_FILE_BUFFER_SIZE) {
210  int totalProgress = (int) (totalRead / unit);
211  progress.progress(content.getName(), totalProgress);
212  // If it's not the source, just update the file being processed
213  } else if (progress != null && !source) {
214  progress.progress(content.getName());
215  }
216  }
217  } finally {
218  in.close();
219  }
220  return totalRead;
221  }
222 
223  public static void writeToFile(Content content, java.io.File outputFile) throws IOException {
224  writeToFile(content, outputFile, null, null, false);
225  }
226 
239  public static long writeToFile(Content content, java.io.File outputFile,
240  Supplier<Boolean> cancelCheck) throws IOException {
241  InputStream in = new ReadContentInputStream(content);
242  long totalRead = 0;
243 
244  try (FileOutputStream out = new FileOutputStream(outputFile, false)) {
245  byte[] buffer = new byte[TO_FILE_BUFFER_SIZE];
246  int len = in.read(buffer);
247  while (len != -1) {
248  out.write(buffer, 0, len);
249  totalRead += len;
250  if (cancelCheck.get()) {
251  break;
252  }
253  len = in.read(buffer);
254  }
255  } finally {
256  in.close();
257  }
258  return totalRead;
259  }
260 
266  public static boolean isDotDirectory(AbstractFile dir) {
267  String name = dir.getName();
268  return name.equals(".") || name.equals("..");
269  }
270 
276  public static class ExtractFscContentVisitor<T, V> extends ContentVisitor.Default<Void> {
277 
278  java.io.File dest;
279  ProgressHandle progress;
280  SwingWorker<T, V> worker;
281  boolean source = false;
282 
295  public ExtractFscContentVisitor(java.io.File dest,
296  ProgressHandle progress, SwingWorker<T, V> worker, boolean source) {
297  this.dest = dest;
298  this.progress = progress;
299  this.worker = worker;
300  this.source = source;
301  }
302 
303  public ExtractFscContentVisitor(java.io.File dest) {
304  this.dest = dest;
305  }
306 
311  public static <T, V> void extract(Content cntnt, java.io.File dest, ProgressHandle progress, SwingWorker<T, V> worker) {
312  cntnt.accept(new ExtractFscContentVisitor<>(dest, progress, worker, true));
313  }
314 
315  @Override
316  public Void visit(File f) {
317  try {
318  ContentUtils.writeToFile(f, dest, progress, worker, source);
319  } catch (IOException ex) {
320  logger.log(Level.SEVERE,
321  "Trouble extracting file to " + dest.getAbsolutePath(), //NON-NLS
322  ex);
323  }
324  return null;
325  }
326 
327  @Override
328  public Void visit(LayoutFile f) {
329  try {
330  ContentUtils.writeToFile(f, dest, progress, worker, source);
331  } catch (IOException ex) {
332  logger.log(Level.SEVERE,
333  "Trouble extracting unallocated content file to " + dest.getAbsolutePath(), //NON-NLS
334  ex);
335  }
336  return null;
337  }
338 
339  @Override
340  public Void visit(DerivedFile df) {
341  try {
342  ContentUtils.writeToFile(df, dest, progress, worker, source);
343  } catch (IOException ex) {
344  logger.log(Level.SEVERE,
345  "Error extracting derived file to " + dest.getAbsolutePath(), //NON-NLS
346  ex);
347  }
348  return null;
349  }
350 
351  @Override
352  public Void visit(LocalFile lf) {
353  try {
354  ContentUtils.writeToFile(lf, dest, progress, worker, source);
355  } catch (IOException ex) {
356  logger.log(Level.SEVERE,
357  "Error extracting local file to " + dest.getAbsolutePath(), //NON-NLS
358  ex);
359  }
360  return null;
361  }
362 
363  @Override
364  public Void visit(SlackFile f) {
365  try {
366  ContentUtils.writeToFile(f, dest, progress, worker, source);
367  } catch (IOException ex) {
368  logger.log(Level.SEVERE,
369  "Trouble extracting slack file to " + dest.getAbsolutePath(), //NON-NLS
370  ex);
371  }
372  return null;
373  }
374 
375  @Override
376  public Void visit(Directory dir) {
377  return visitDir(dir);
378  }
379 
380  @Override
381  public Void visit(VirtualDirectory dir) {
382  return visitDir(dir);
383  }
384 
385  @Override
386  public Void visit(LocalDirectory dir) {
387  return visitDir(dir);
388  }
389 
390  private java.io.File getFsContentDest(Content fsc) {
391  String path = dest.getAbsolutePath() + java.io.File.separator
392  + fsc.getName();
393  return new java.io.File(path);
394  }
395 
396  public Void visitDir(AbstractFile dir) {
397 
398  // don't extract . and .. directories
399  if (isDotDirectory(dir)) {
400  return null;
401  }
402 
403  dest.mkdir();
404 
405  try {
406  int numProcessed = 0;
407  // recurse on children
408  for (Content child : dir.getChildren()) {
409  if (child instanceof AbstractFile){ //ensure the directory's artifact children are ignored
410  java.io.File childFile = getFsContentDest(child);
411  ExtractFscContentVisitor<T, V> childVisitor
412  = new ExtractFscContentVisitor<>(childFile, progress, worker, false);
413  // If this is the source directory of an extract it
414  // will have a progress and worker, and will keep track
415  // of the progress bar's progress
416  if (worker != null && worker.isCancelled()) {
417  break;
418  }
419  if (progress != null && source) {
420  progress.progress(child.getName(), numProcessed);
421  }
422  child.accept(childVisitor);
423  numProcessed++;
424  }
425  }
426  } catch (TskCoreException ex) {
427  logger.log(Level.SEVERE,
428  "Trouble fetching children to extract.", ex); //NON-NLS
429  }
430 
431  return null;
432  }
433 
434  @Override
435  protected Void defaultVisit(Content content) {
436  throw new UnsupportedOperationException(NbBundle.getMessage(this.getClass(),
437  "ContentUtils.exception.msg",
438  content.getClass().getSimpleName()));
439  }
440  }
441 
447  public static boolean shouldDisplayTimesInLocalTime() {
449  }
450 
451 }
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 String getSystemName(Content content)
static< T, V > void extract(Content cntnt, java.io.File dest, ProgressHandle progress, SwingWorker< T, V > worker)
static String getStringTimeISO8601(long epochSeconds, TimeZone tzone)
static final SimpleDateFormat dateFormatterISO8601
static final SystemNameVisitor systemName
static String getStringTime(long epochSeconds, Content c)
synchronized static Logger getLogger(String name)
Definition: Logger.java:161
static String getStringTimeISO8601(long epochSeconds, Content c)
static void addChangeListener(PreferenceChangeListener listener)
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-2016 Basis Technology. Generated on: Fri Sep 29 2017
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.