#!/usr/bin/perl -w
use strict;
use warnings FATAL=>'all';

=comment
pfsense_extract.pl - extract pfSense configs from an input stream
(c) 2010 BFC Computing, LLC.  Licensed under the same terms as pfSense.

This is useful for taking an image file of a damaged pfSense install
and pulling out config files.  If you can mount the image normally, you
should do that first.

Due to the nature of the filesystem, there are often many copies of a
config file in a disk image, from each time it was saved.  You will
find a bunch of output files named: pfsense-config-1.xml, pfsense-config-2.xml,
etc.  You can then use tools like diff to find out which the right one was.

Example:
   dd if=/dev/sdg of=broken_pfsense_image.dd bs=2M conv=sync,noerror
   strings broken_pfsense_image.dd | perl pfsense_extract.pl

Processing a 1GB image as per the example takes about 20 seconds on a standard
2GHz desktop machine.
=cut

my $BASENAME='pfsense-config-X.xml';
my $counter = 0;
my ($outfile);
my $do_output = 0;

while (<>) {

    chomp;

    if ($_ eq '<pfsense>') {
	$counter++;
	my $filename = $BASENAME;
	$filename =~ s/X/$counter/;
	open($outfile,">$filename");
	$do_output = 1;
    }

    if ($do_output) {
	print $outfile $_ . "n";
    }

    if ($_ eq '</pfsense>') {
	close $outfile;
	$do_output = 0;
    }

}
