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;
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)
File(SleuthkitCase db, long objId, long fsObjId, TSK_FS_ATTR_TYPE_ENUM attrType, short attrId, String name, long metaAddr, int metaSeq, TSK_FS_NAME_TYPE_ENUM dirType, TSK_FS_META_TYPE_ENUM metaType, TSK_FS_NAME_FLAG_ENUM dirFlag, short metaFlags, long size, long ctime, long crtime, long atime, long mtime, short modes, int uid, int gid, String md5Hash, FileKnown knownState, String parentPath)
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)
public< T > T accept(ContentVisitor< T > v)
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: Mon Apr 24 2017
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.