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