pkgGen
pkgGen is a perl script that parses the output from logGen and copies the files to a fake root directory. You can use this tree to build a package using packagemaker, iceberg or some other packaging tool.
The script comes in an installer package that places it in ``/usr/local/sbin`:
Source
# pkgGen v1
# Zack Smith
# Based on a script originally created by Geoff Franks (Buy him the Beer)
# Hauptman-Woodward Medical Research Institute
#
# This script takes two parameters. The first is the path to the
# LogGen > log file. The second is the folder which you would like to
# create your Root directory for the PKG installer to base from. This folder
# MUST NOT exist, or the script will fail.
#
# It parses the log file, regenerating the drectory structure of added files
# and directories, preserving permissions, modification times, and resource
# forks as tightly as possible. IMPORTANT: To preserve all permissions, run this
# with root level permissions.
# More to come later...
use strict;
#Set up some globalish variables- charset for the encoding on the log file
#srclog for the log file, root dir for the base directory, and loglines for data
my $CHARSET = "utf-8";
my $SRCLOG;
my $ROOTDIR;
my @loglines;
#function for warn about usage and exit
sub usage{
warn "Usage: pkgGen <path to logGen output txt file> <path of pkg fauxroot>\n";
exit(1);
}
#function for checking arguments
sub getarguments{
#we need arguments
if($#ARGV == -1){
&usage;
exit(0);
#and only 2
}elsif($#ARGV != 1){
&usage;
exit(0);
}
#so if we have them, set the two args
$SRCLOG = shift @ARGV;
$ROOTDIR= shift @ARGV;
#if the log file doesn't exist, quit now.
unless(-e $SRCLOG){
&usage;
exit(0);
}
}
#first line actually run- check the arguments.
&getarguments;
#create the root directory with default perms of root:admin, 1775 (sticky bit)
mkdir($ROOTDIR) or die ("Could not create $ROOTDIR");
chown "root","admin", $ROOTDIR;
chmod oct("1775"), $ROOTDIR;
#open the log file, and read it in
open FILE , "<:encoding($CHARSET)", $SRCLOG or die ("Could not open log file $SRCLOG");
# Split the log file into an array of lines to loop through
@loglines = <FILE>;
close FILE;
#loop through the lines
for my $line (@loglines)
{
#any matches to this unless statement are lines you do not want parsed
# if the script dies due to meaningless filler info like the date, install
# mesages - anything not referring to a file, add them here to be ignored
unless (
$line =~ /(setuid|setgid|sticky_bit|world_writable) \)$/ ||
# ABOVE: Only paths we don't need are theese.
$line =~ /^[^\/](.*)/ ) # Any line that doesn't with a solidus we junk
{
# set up some variables for use within the loop- type for file type, file
# for file path
my $type;
my $file;
if ($line =~ /(.*)\/$/)
{
$type = "dir";
$file = "$1";
# print "Dir: $file\n";
}
else
{
#check to see if it's a file
if ($line =~ /(.*)$/)
{
#set that it's a file, and save the path.
$type = "file";
$file = "$1";
# print "File: $file\n";
}
else
{
#otherwise, I don't know what the line means, so quit and say what
#the line was
print "Unknown line: $line\n";
die("Exiting prematurely...");
}
}
#get an array of directories leading up to the file
my @dirs = split "/" , $file;
my $dir;
my $count = scalar(@dirs);
#loop through all but the file/directory name itself
for (my $i = 0; $i < $count - 1; $i++)
{
#grab the next directory in the array
$dir .= shift @dirs;
$dir .= "/";
#grab file attributes on the real directory
my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,
$blksize,$blocks) = stat("/$dir");
#translate the mode/type to just the permissions mode
$mode = sprintf("%04o",$mode & 07777);
#if the directory doesn't exist in the recreated structure
unless (-d "${ROOTDIR}${dir}")
{
#make it, setting ownership and perms to the original's
#print "Mode: $mode\n";
#print "mkdir ${ROOTDIR}${dir}"
mkdir("$ROOTDIR/$dir");
chown($uid,$gid,"$ROOTDIR/$dir");
chmod oct($mode), "$ROOTDIR/$dir";
}
}
#by the time we get here, we know the parent directories exist
if ( $type eq "file")
{
#so it's time to copy the file if it's a file
print "Copying $file\n";
# print "cp -vp \"$file\" \"${ROOTDIR}${file}\"\n"
system "cp -p \"$file\" \"${ROOTDIR}${file}\"";
}
else
{
#or if it's a directory,
if ( $type eq "dir")
{
#recreate it with the original perms/ownership
my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,
$ctime,$blksize,$blocks) = stat("/$file");
print "Creating $file\n";
$mode = sprintf("%o",$mode & 07777);
# print "cp -Rvp \"$file\" \"${ROOTDIR}${file}\"\n"
$file =~ s/\/$//; # Remove trailing solidus for cp sytax
system "cp -Rnp \"$file\" \"${ROOTDIR}${file}\"";
# Recursively copy any new directories
chown($uid,$gid,"${ROOTDIR}${file}");
chmod oct($mode), "${ROOTDIR}${file}";
}
else
{
die( "How the heck did we get here?\n");
}
}
}
}
#after it loops through the log file, that's pretty much it, so it exits.