#!/usr/bin/perl

# Creates chntpw.img.gz in current directory for network booting chntpw
# with pxelinux's memdisk module (requires root privs)

my($PATH,$SCRIPT)=($0=~/(.*\/)(.*)/);

##################################
### BEGIN CONFIGURABLE OPTIONS ###

# if this script is not on the CD you may want this...
#$PATH="path/to/mounted/chntpw/iso/image";

# files to leave off the image
my @SKIP=($SCRIPT, qw(
README.TXT
ISOLINUX.BIN
ISOLINUX.CFG
SYSLINUX.EXE
));

# disk image parameters (bytes/sector, sectors/cluster)
my($SECTSZ,$CLUSTSZ)=(512,2);

### END CONFIGURABLE OPTIONS ###
################################

# check root privs
if($<) {
  print STDERR <<TEXT; exit 1;
This script need to be run as root.
(to mount the image over the loopback device)
TEXT
}

# check output dir
unless(-w '.') {
  print STDERR <<TEXT; exit 1;
The current directory is not writable.
Please cd to a writable directory and try again.
TEXT
}

# compute image size (in blocks) and rootdir entries
my($BLKSZ,$blks,$dirents,%skip,$files)=($SECTSZ * $CLUSTSZ,0,0);
$skip{$_}++ foreach(@SKIP);
foreach(<${PATH}*>, '/usr/lib/syslinux/ldlinux.sys') {
  my($fn)=(m|([^/]*)$|);
  next if($skip{uc $fn});
  $files.=" $_" if($fn ne 'ldlinux.sys');
  my $sz=(stat)[7];
  $blks+=int(($sz+$BLKSZ-1)/$BLKSZ);
  $dirents++;
}
$dirents=int(($dirents+15)/16)*16;

# FAT16 requires at least 4094 blocks
$blks=4094 if($blks < 4094);

# make mount point
use File::Temp qw(tempdir);
my $mnt=tempdir();

exec <<SH
# make filesystem image
mkdosfs -C -f 1 -F 16 -r $dirents -s $CLUSTSZ -S $SECTSZ chntpw.img $blks

# mount image
mount -t vfat -o loop chntpw.img $mnt

# blank image
#dd if=/dev/zero of=$mnt/zero
#rm $mnt/zero

# fill image
cp $files $mnt

# unmount image
umount $mnt

# make image bootable
syslinux chntpw.img

# compress image
gzip -9 <chntpw.img >chntpw.img.gz

# clean up
rmdir $mnt
rm chntpw.img
SH
