package Print; # # $Date: 2006/05/08 18:46:57 $ # # Utilities to print information # # Brian Carrier [carrier@sleuthkit.org] # Copyright (c) 2001-2005 by Brian Carrier. All rights reserved # # This file is part of the Autopsy Forensic Browser (Autopsy) # # Autopsy is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # Autopsy is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Autopsy; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR ANY PARTICULAR PURPOSE. # IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, OR PROFITS OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. sub html_encode { my $text = shift; $text =~ s/&/&/gs; $text =~ s//>/gs; # @@@ LEADING SPACES and TABS # while ($text =~ s/^( )*\t/"$1    "/eig) {} # while ($text =~ s/^( )* /"$1 "/eig) {} return $text; } # remove control chars from printout sub print_output { my $out = shift; print "$out"; # This was removed because of Unicode support # perhaps later some more checks can be done... if (0) { while (my $out = shift) { foreach $_ (split(//, $out)) { if ( ($_ eq "\n") || ($_ eq "\r") || ($_ eq "\f") || ($_ eq "\t")) { print "$_"; } elsif ((ord($_) < 0x20) || (ord($_) > 0x7e)) { print "^" . ord($_); } else { print "$_"; } } } } } # Added to provide output in hexdump format # function gets called on a per-icat basis, # The offset value is the byte offset that this data # starts at, since the File.pm code calls it in 1024 # byte chunks) sub print_hexdump { my $out = shift; # data to output my $offset = shift; # starting byte offset in file my $buf = ""; foreach $i (split(//, $out)) { my $idx = $offset % 16; if ($idx == 0) { printf("%08X: ", $offset); } printf("%02X", ord($i)); if (($idx % 2) == 1) { printf(" "); } $buf[$idx] = $i; if ($idx == 15) { print " "; for (my $j = 0; $j < 16; $j++) { if ($buf[$j] =~ m/[ -~]/) { print $buf[$j]; } else { print "."; } $buf[$j] = 0; } print "\n"; } $offset++; } # print out last line if < 16 bytes long my $l = $offset % 16; if ($l) { my $t = (16 - $l) * 2 + (16 - $l) / 2; for (my $j = 0; $j < $t; $j++) { print " "; } print " "; for (my $j = 0; $j < $l; $j++) { if ($buf[$j] =~ m/[ -~]/) { print $buf[$j]; } else { print "."; } } print "\n"; } } ############################################ # # HTTP/HTML Headers and Footers # The page that makes the frameset does not have a body statement # This routine is used to make the minimum required header statements sub print_html_header_frameset { my $text = shift; print "Content-Type: text/html; charset=utf-8$::HTTP_NL$::HTTP_NL"; my $time = localtime(); print < $text EOF } sub print_html_footer_frameset { print "\n\n" . "$::HTTP_NL$::HTTP_NL"; } # Create the header information with the body tag sub print_html_header { print_html_header_frameset(shift); print "\n\n"; print "\n"; } sub print_html_footer { print "\n\n\n" . "$::HTTP_NL$::HTTP_NL"; } # Print the header with the margins set to 0 so that the tab buttons # are flush with the edges of the frame sub print_html_header_tabs { print_html_header_frameset(shift); print "\n\n"; print "\n"; $is_body = 1; } sub print_html_footer_tabs { print "\n\n\n" . "$::HTTP_NL$::HTTP_NL"; } # Header for front page to warn about java script sub print_html_header_javascript { my $text = shift; print "Content-Type: text/html; charset=utf-8$::HTTP_NL$::HTTP_NL"; my $time = localtime(); # The write line has to stay on one line print < $text EOF } sub print_html_footer_javascript { print "\n\n\n" . "$::HTTP_NL$::HTTP_NL"; } # For raw text outputs (Pass the name of a file if it is being saved) sub print_text_header { print "Content-Type: text/plain; charset=utf-8$::HTTP_NL"; if (scalar @_ > 0) { my $fname = shift(); print "Content-Disposition: inline; " . "filename=$fname;$::HTTP_NL"; } print "$::HTTP_NL"; } sub print_text_footer { print "$::HTTP_NL$::HTTP_NL"; } # For forced save outputs sub print_oct_header { print "Content-Type: application/octet-stream$::HTTP_NL"; if (scalar @_ > 0) { my $fname = shift(); print "Content-Disposition: inline; " . "filename=$fname;$::HTTP_NL"; } print "$::HTTP_NL"; } sub print_oct_footer { } # Error message that is used when an HTTP/HTML header is needed sub print_check_err { print_html_header(""); print shift() . "
\n"; print_html_footer(); sleep(1); exit 1; } # Error message when header already exists sub print_err { print shift() . "
\n"; sleep(1); print_html_footer(); exit 1; } ################################################################## # # Logging # # sub investig_log_fname { return "" unless (defined $::host_dir && $::host_dir ne ""); return "" unless (exists $Args::args{'inv'} && $Args::args{'inv'} ne ""); return "$::host_dir" . "$::LOGDIR/$Args::args{'inv'}.log"; } sub investig_exec_log_fname { return "" unless (defined $::host_dir && $::host_dir ne ""); return "" unless (exists $Args::args{'inv'} && $Args::args{'inv'} ne ""); return "$::host_dir" . "$::LOGDIR/$Args::args{'inv'}.exec.log"; } sub host_log_fname { return "" unless (defined $::host_dir && $::host_dir ne ""); return "$::host_dir" . "$::LOGDIR/host.log"; } sub case_log_fname { return "" unless (defined $::case_dir && $::case_dir ne ""); return "$::case_dir" . "case.log"; } # Log data to the investigators specific log file sub log_host_inv { return unless ($::USE_LOG == 1); my $str = shift; chomp $str; my $date = localtime; my $fname = investig_log_fname(); return if ($fname eq ""); open HOSTLOG, ">>$fname" or die "Can't open log: $fname"; print HOSTLOG "$date: $str\n"; close(HOSTLOG); return; } sub log_host_inv_exec { return unless ($::USE_LOG == 1); my $str = shift; chomp $str; my $date = localtime; my $fname = investig_exec_log_fname(); return if ($fname eq ""); open HOSTLOG, ">>$fname" or die "Can't open log: $fname"; print HOSTLOG "$date: $str\n"; close(HOSTLOG); return; } # log data to the general log file for the host sub log_host_info { return unless ($::USE_LOG == 1); my $str = shift; chomp $str; my $date = localtime; my $fname = host_log_fname(); return if ($fname eq ""); open HOSTLOG, ">>$fname" or die "Can't open log: $fname"; print HOSTLOG "$date: $str\n"; close(HOSTLOG); return; } sub log_case_info { return unless ($::USE_LOG == 1); my $str = shift; chomp $str; my $date = localtime; my $fname = case_log_fname(); return if ($fname eq ""); open CASELOG, ">>$fname" or die "Can't open log: $fname"; print CASELOG "$date: $str\n"; close(CASELOG); return; } sub log_session_info { return unless ($::USE_LOG == 1); my $str = shift; chomp $str; my $date = localtime; my $lname = "autopsy.log"; open AUTLOG, ">>$::LOCKDIR/$lname" or die "Can't open log: $lname"; print AUTLOG "$date: $str\n"; close(AUTLOG); return; } 1;