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