smb-conf-upgrade   [plain text]


#! /usr/bin/perl -w

#
# Copyright (c) 2007 Apple Inc. All rights reserved.
#
# @APPLE_LICENSE_HEADER_START@
#
# This file contains Original Code and/or Modifications of Original Code
# as defined in and that are subject to the Apple Public Source License
# Version 2.0 (the 'License'). You may not use this file except in
# compliance with the License. Please obtain a copy of the License at
# http://www.opensource.apple.com/apsl/ and read it before using this
# file.
#
# The Original Code and all software distributed under the License are
# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
# Please see the License for the specific language governing rights and
# limitations under the License.
#
# @APPLE_LICENSE_HEADER_END@
#

use strict;
$0 = 'smb-config-upgrade';

# Standard install script variables:
# $1: Full path to the installation package.
# $2: Full path to the installation destination.
# $3: Installation volume (or mountpoint) to receive the payload.
# $4: The root directory for the system.
# $SCRIPT_NAME: Filename of the operation executable

my $pkg_path = shift || '';
my $install_dest = shift || '';
my $install_volume = shift || '';
my $install_operation = $ENV{SCRIPT_NAME} ? $ENV{SCRIPT_NAME} : 'postupgrade';

my $SMB_BACKUP = $ENV{SMB_BACKUP} ? $ENV{SMB_BACKUP}
			    : "$install_volume/etc/smb.conf.old";
my $SMB_CONF = $ENV{SMB_CONF} ? $ENV{SMB_CONF}
			    : "$install_volume/etc/smb.conf";
my $SMB_TEMPLATE = $ENV{SMB_TEMPLATE} ? $ENV{SMB_TEMPLATE}
			    : "$install_volume/etc/smb.conf.template";

sub slurp
{
    my $path = shift;
    my $fh;
    my $data;

    local $/=undef;

    open ($fh, "< $path") or return undef;

    $data = <$fh>;
    close $fh;
    return $data;
}

sub write_file
{
    require File::Temp;

    my $config = shift;
    my $data = shift;

    my ($fh, $name) = File::Temp::tempfile(
				TEMPLATE =>'.smb.upgrade.XXXXXXXX',
				UNLINK => 0,
				DIR => "$install_volume/etc");

    $fh->write($data);
    $fh->flush();
    $fh->sync();

    rename $name, $config
	or die "$0: unable to replace $config: $!";

    chmod 0644, $config;
    $fh->close();

    return 1;
}

my $template;	# Contents of /etc/smb.conf.template
my $smbconf;	# Contents of /etc/smb.conf
my $required;	# /etc/smb.conf.template required section

unless ($template = slurp($SMB_TEMPLATE)) {
    die "$0: smb.conf template is corrupt or missing";
}

unless ($smbconf = slurp($SMB_CONF)) {
    # If there's no smb.conf, just keep going and create it.
    warn "$0: smb.conf is corrupt or missing";
    $smbconf = "";
}

# Now capture the required config section from the template.
$template =~
m/
    (
	;\s+BEGIN\s+required
	.*
	;\s+END\s+required[^\n]*$
    )
/smx;

if (!defined($1) || length($1) == 0) {
    print "$0: missing or corrupt required configuration section in $SMB_TEMPLATE\n";
    exit 1;
}

# We now have the required section from the template.
$required=$1;

# Now substitute the required config section from the template.
unless ($smbconf =~
s/
	;\s+BEGIN\s+required
	.*
	;\s+END\s+required[^\n]*$
/$required/smx) {
    # The substitution failed, so /etc/smb.conf is probably in some
    # munged format that we don't recognize. We should just replace
    # the whole thing.
    warn "$0: replacing entire contents of $SMB_CONF";
    $smbconf = $template;
}

rename $SMB_CONF, $SMB_BACKUP
    or warn "$0: unable to back $SMB_CONF up to $SMB_BACKUP: $!";

# Write out the merged config file.
unless (write_file($SMB_CONF, $smbconf)) {
    die "$0: unable to replace $SMB_CONF";
}

exit 0;