Autopsy  4.21.0
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;
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)
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 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)
public< T > T accept(ContentVisitor< T > v)
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-2024 Sleuth Kit Labs. Generated on: Mon Mar 17 2025
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.