#!/usr/bin/perl
# $Id: extract_segment,v 1.0 92/07/31 17:39:29 cap Exp $
# Extract a segment from an O-file
#
# Usage: extract_seg file name output
#     file: executable file to extract from
#     name: name of the segment to extract
#     output: name of the file on which to write the segment
#
require 'mach-o.pl';

if ($#ARGV != 2) {
    die "usage: extract_seg file name output\n";
} else {
    $file = $ARGV[0];
    $targetsegname = $ARGV[1];
    $outfile = $ARGV[2];
}

open(FILE, "+<$file") || die "Can't open input file $file\n";
open(OUTFILE, ">$outfile") || die "Can't open output file $outfile\n";

# load the mach_header
($magic, $cputype, $cpusubtype, $filetype, $ncmds, $sizeofcmds, $flags) = 
	&read_mach_header(FILE);

# load the load commands
for ($cmdnum = 0; $cmdnum < $ncmds; $cmdnum++) {
    # read the load_command struct
    ($cmd, $cmdsize) = &peek_load_command(FILE);

    if ($cmd != $LC_SEGMENT) {
	seek(FILE, $cmdsize, 1);	# skip this command
    } else {
        ($cmd, $cmdsize, $segname, $vmaddr, $vmsize, $fileoff, $filesize,
         $maxprot, $initprot, $nsects, $flags) = &read_segment_command(FILE);

        if ($segname ne $targetsegname) {
	    # skip to next command
	    &seek_past_segment_command(FILE, $cmdsize);
        } else {
	    seek(FILE, $fileoff, 0);	# go to start of segment
	    read(FILE, $buf, $filesize);
   	    print OUTFILE $buf;
	    $success = 1;
	    last;
        }
    }
}

close(FILE);
if ($success) {
    exit 0;
} else {
    print "failed\n";
    exit 1;
}

