[X2go-Commits] x2goclient.git - release/4.0.0.x (branch) updated: 4.0.0.3-2-g5bcc8e1

X2Go dev team git-admin at x2go.org
Fri Mar 1 21:27:11 CET 2013


The branch, release/4.0.0.x has been updated
       via  5bcc8e1aa722ea013d68fa863b764af5027b2b2e (commit)
       via  16d3a91db10c575f0447a3f1df8b3011752ba475 (commit)
      from  d351dcec2702444a87ff9eafb5a1733281be6e85 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 5bcc8e1aa722ea013d68fa863b764af5027b2b2e
Author: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
Date:   Fri Mar 1 21:24:53 2013 +0100

    Add scripts and additional files for building X2Go Client disk images for Mac OS X. (Fixes: #131).

commit 16d3a91db10c575f0447a3f1df8b3011752ba475
Author: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
Date:   Fri Mar 1 21:23:03 2013 +0100

    Continue development...

-----------------------------------------------------------------------

Summary of changes:
 VERSION                         |    2 +-
 debian/changelog                |    9 +
 macbuild.sh                     |   68 ++
 macdmg.DS_Store                 |  Bin 0 -> 15364 bytes
 pkg-dmg                         | 1523 +++++++++++++++++++++++++++++++++++++++
 png/macinstaller_background.png |  Bin 0 -> 59943 bytes
 svg/macinstaller_background.svg |  630 ++++++++++++++++
 version.h                       |    2 +-
 x2goclient.pro                  |    3 -
 x2goplugin.rc                   |   12 +-
 10 files changed, 2238 insertions(+), 11 deletions(-)
 create mode 100755 macbuild.sh
 create mode 100644 macdmg.DS_Store
 create mode 100755 pkg-dmg
 create mode 100644 png/macinstaller_background.png
 create mode 100644 svg/macinstaller_background.svg

The diff of changes is:
diff --git a/VERSION b/VERSION
index 3ab15cd..6813a82 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-4.0.0.3
+4.0.0.4
diff --git a/debian/changelog b/debian/changelog
index 31ac841..bce38bb 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,12 @@
+x2goclient (4.0.0.4-0~x2go1) UNRELEASED; urgency=low
+
+  [ Clemens Lang ]
+  * New upstream version (4.0.0.4):
+    - Add scripts and additional files for building X2Go Client
+      disk images for Mac OS X. (Fixes: #131).
+
+ -- Mike Gabriel <mike.gabriel at das-netzwerkteam.de>  Fri, 01 Mar 2013 21:20:27 +0100
+
 x2goclient (4.0.0.3-0~x2go1) unstable; urgency=low
 
   * Fix version in version.h, VERSION and x2goplugin.rc.
diff --git a/macbuild.sh b/macbuild.sh
new file mode 100755
index 0000000..70084e6
--- /dev/null
+++ b/macbuild.sh
@@ -0,0 +1,68 @@
+#!/bin/sh
+NAME=x2goclient
+APPBUNDLE=./$NAME.app
+DMGFILE=./$NAME.dmg
+PROJECT=./$NAME.pro
+PKG_DMG=./pkg-dmg
+
+NXPROXY=`which nxproxy`
+LIBXCOMP=libXcomp.3.dylib
+LIBPNG=libpng15.15.dylib
+LIBJPEG=libjpeg.9.dylib
+LIBZ=libz.1.dylib
+
+set -e
+
+function phase() {
+	echo
+	echo "***"
+	echo "*** ${1}…"
+	echo "***"
+	echo
+}
+
+phase "Cleaning"
+make clean
+rm -rf "$APPBUNDLE"
+rm -rf "$DMGFILE"
+
+phase "Running lrelease"
+lrelease "$PROJECT"
+
+phase "Running qmake"
+qmake -config release \
+	CONFIG+=x86_64 \
+	QMAKE_MAC_SDK=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk \
+	QMAKE_MACOSX_DEPLOYMENT_TARGET=10.7
+
+phase "Running make"
+make -j2
+
+phase "Copying nxproxy"
+mkdir -p "$APPBUNDLE/Contents/exe"
+cp "$NXPROXY" "$APPBUNDLE/Contents/exe"
+dylibbundler \
+	--fix-file "$APPBUNDLE/Contents/exe/nxproxy" \
+	--bundle-deps \
+	--dest-dir "$APPBUNDLE/Contents/Frameworks" \
+	--install-path "@executable_path/../Frameworks/" \
+	--create-dir
+
+phase "Bundling up using macdeployqt"
+macdeployqt "$APPBUNDLE" -verbose=2
+
+phase "Creating DMG"
+$PKG_DMG \
+	--source "$APPBUNDLE" \
+	--sourcefile \
+	--target "$DMGFILE" \
+	--volname "x2goclient" \
+	--verbosity 2 \
+	--mkdir "/.background" \
+	--copy "./png/macinstaller_background.png:/.background" \
+	--copy "./macdmg.DS_Store:/.DS_Store" \
+	--copy "./LICENSE" \
+	--copy "./COPYING" \
+	--symlink "/Applications: " \
+	--icon "./icons/x2go-mac.icns" \
+	--format "UDBZ"
diff --git a/macdmg.DS_Store b/macdmg.DS_Store
new file mode 100644
index 0000000..b5db793
Binary files /dev/null and b/macdmg.DS_Store differ
diff --git a/pkg-dmg b/pkg-dmg
new file mode 100755
index 0000000..82b9010
--- /dev/null
+++ b/pkg-dmg
@@ -0,0 +1,1523 @@
+#!/usr/bin/perl
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is pkg-dmg, a Mac OS X disk image (.dmg) packager
+#
+# The Initial Developer of the Original Code is
+# Mark Mentovai <mark at moxienet.com>.
+# Portions created by the Initial Developer are Copyright (C) 2005
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+use strict;
+use warnings;
+
+=pod
+
+=head1 NAME
+
+B<pkg-dmg> - Mac OS X disk image (.dmg) packager
+
+=head1 SYNOPSIS
+
+B<pkg-dmg>
+B<--source> I<source-folder>
+B<--target> I<target-image>
+[B<--format> I<format>]
+[B<--volname> I<volume-name>]
+[B<--tempdir> I<temp-dir>]
+[B<--mkdir> I<directory>]
+[B<--copy> I<source>[:I<dest>]]
+[B<--symlink> I<source>[:I<dest>]]
+[B<--license> I<file>]
+[B<--resource> I<file>]
+[B<--icon> I<icns-file>]
+[B<--attribute> I<a>:I<file>[:I<file>...]
+[B<--idme>]
+[B<--sourcefile>]
+[B<--verbosity> I<level>]
+[B<--dry-run>]
+
+=head1 DESCRIPTION
+
+I<pkg-dmg> takes a directory identified by I<source-folder> and transforms
+it into a disk image stored as I<target-image>.  The disk image will
+occupy the least space possible for its format, or the least space that the
+authors have been able to figure out how to achieve.
+
+=head1 OPTIONS
+
+=over 5
+
+==item B<--source> I<source-folder>
+
+Identifies the directory that will be packaged up.  This directory is not
+touched, a copy will be made in a temporary directory for staging purposes.
+See B<--tempdir>.
+
+==item B<--target> I<target-image>
+
+The disk image to create.  If it exists and is not in use, it will be
+overwritten.  If I<target-image> already contains a suitable extension,
+it will be used unmodified.  If no extension is present, or the extension
+is incorrect for the selected format, the proper extension will be added.
+See B<--format>.
+
+==item B<--format> I<format>
+
+The format to create the disk image in.  Valid values for I<format> are:
+     - UDZO - zlib-compressed, read-only; extension I<.dmg>
+     - UDBZ - bzip2-compressed, read-only; extension I<.dmg>;
+              create and use on 10.4 ("Tiger") and later only
+     - UDRO - uncompressed, read-only; extension I<.dmg>
+     - UDRW - uncompressed, read-write; extension I<.dmg>
+     - UDSP - uncompressed, read-write, sparse; extension I<.sparseimage>
+
+UDZO is the default format.
+
+See L<hdiutil(1)> for a description of these formats.
+
+=item B<--volname> I<volume-name>
+
+The name of the volume in the disk image.  If not specified, I<volume-name>
+defaults to the name of the source directory from B<--source>.
+
+=item B<--tempdir> I<temp-dir>
+
+A temporary directory to stage intermediate files in.  I<temp-dir> must
+have enough space available to accommodate twice the size of the files
+being packaged.  If not specified, defaults to the same directory that
+the I<target-image> is to be placed in.  B<pkg-dmg> will remove any
+temporary files it places in I<temp-dir>.
+
+=item B<--mkdir> I<directory>
+
+Specifies a directory that should be created in the disk image.
+I<directory> and any ancestor directories will be created.  This is
+useful in conjunction with B<--copy>, when copying files to directories
+that may not exist in I<source-folder>.  B<--mkdir> may appear multiple
+times.
+
+=item B<--copy> I<source>[:I<dest>]
+
+Additional files to copy into the disk image.  If I<dest> is
+specified, I<source> is copied to the location I<dest> identifies,
+otherwise, I<source> is copied to the root of the new volume.  B<--copy>
+provides a way to package up a I<source-folder> by adding files to it
+without modifying the original I<source-folder>.  B<--copy> may appear
+multiple times.
+
+This option is useful for adding .DS_Store files and window backgrounds
+to disk images.
+
+=item B<--symlink> I<source>[:I<dest>]
+
+Like B<--copy>, but allows symlinks to point out of the volume. Empty symlink
+destinations are interpreted as "like the source path, but inside the dmg"
+
+This option is useful for adding symlinks to external resources,
+e.g. to /Applications.
+
+=item B<--license> I<file>
+
+A plain text file containing a license agreement to be displayed before
+the disk image is mounted.  English is the only supported language.  To
+include license agreements in other languages, in multiple languages,
+or to use formatted text, prepare a resource and use L<--resource>.
+
+=item B<--resource> I<file>
+
+A resource file to merge into I<target-image>.  If I<format> is UDZO, UDBZ,
+or UDRO, the disk image will be flattened to a single-fork file that contains
+the resource but may be freely transferred without any special encodings.
+I<file> must be in a format suitable for L<Rez(1)>.  See L<Rez(1)> for a
+description of the format, and L<hdiutil(1)> for a discussion on flattened
+disk images.  B<--resource> may appear multiple times.
+
+This option is useful for adding license agreements and other messages
+to disk images.
+
+=item B<--icon> I<icns-file>
+
+Specifies an I<icns> file that will be used as the icon for the root of
+the volume.  This file will be copied to the new volume and the custom
+icon attribute will be set on the root folder.
+
+=item B<--attribute> I<a>:I<file>[:I<file>...]
+
+Sets the attributes of I<file> to the attribute list in I<a>.  See
+L<SetFile(1)>
+
+=item B<--idme>
+
+Enable IDME to make the disk image "Internet-enabled."  The first time
+the image is mounted, if IDME processing is enabled on the system, the
+contents of the image will be copied out of the image and the image will
+be placed in the trash with IDME disabled.
+
+=item B<--sourcefile>
+
+If this option is present, I<source-folder> is treated as a file, and is
+placed as a file within the volume's root folder.  Without this option,
+I<source-folder> is treated as the volume root itself.
+
+=item B<--verbosity> I<level>
+
+Adjusts the level of loudness of B<pkg-dmg>.  The possible values for
+I<level> are:
+     0 - Only error messages are displayed.
+     1 - Print error messages and command invocations.
+     2 - Print everything, including command output.
+
+The default I<level> is 2.
+
+=item B<--dry-run>
+
+When specified, the commands that would be executed are printed, without
+actually executing them.  When commands depend on the output of previous
+commands, dummy values are displayed.
+
+=back
+
+=head1 NON-OPTIONS
+
+=over 5
+
+=item
+
+Resource forks aren't copied.
+
+=item
+
+The root folder of the created volume is designated as the folder
+to open when the volume is mounted.  See L<bless(8)>.
+
+=item
+
+All files in the volume are set to be world-readable, only writable
+by the owner, and world-executable when appropriate.  All other
+permissions bits are cleared.
+
+=item
+
+When possible, disk images are created without any partition tables.  This
+is what L<hdiutil(1)> refers to as I<-layout NONE>, and saves a handful of
+kilobytes.  The alternative, I<SPUD>, contains a partition table that
+is not terribly handy on disk images that are not intended to represent any
+physical disk.
+
+=item
+
+Read-write images are created with journaling off.  Any read-write image
+created by this tool is expected to be transient, and the goal of this tool
+is to create images which consume a minimum of space.
+
+=back
+
+=head1 EXAMPLE
+
+pkg-dmg --source /Applications/DeerPark.app --target ~/DeerPark.dmg
+  --sourcefile --volname DeerPark --icon ~/DeerPark.icns
+  --mkdir /.background
+  --copy DeerParkBackground.png:/.background/background.png
+  --copy DeerParkDSStore:/.DS_Store
+  --symlink /Applications:"/Drag to here"
+
+=head1 REQUIREMENTS
+
+I<pkg-dmg> has been tested with Mac OS X releases 10.2 ("Jaguar")
+through 10.4 ("Tiger").  Certain adjustments to behavior are made
+depending on the host system's release.  Mac OS X 10.3 ("Panther") or
+later are recommended.
+
+=head1 LICENSE
+
+MPL 1.1/GPL 2.0/LGPL 2.1.  Your choice.
+
+=head1 AUTHOR
+
+Mark Mentovai
+
+=head1 SEE ALSO
+
+L<bless(8)>, L<diskutil(8)>, L<hdid(8)>, L<hdiutil(1)>, L<Rez(1)>,
+L<rsync(1)>, L<SetFile(1)>
+
+=cut
+
+use Fcntl;
+use POSIX;
+use Getopt::Long;
+
+sub argumentEscape(@);
+sub cleanupDie($);
+sub command(@);
+sub commandInternal($@);
+sub commandInternalVerbosity($$@);
+sub commandOutput(@);
+sub commandOutputVerbosity($@);
+sub commandVerbosity($@);
+sub copyFiles($@);
+sub diskImageMaker($$$$$$$$);
+sub giveExtension($$);
+sub hdidMountImage($@);
+sub isFormatReadOnly($);
+sub licenseMaker($$);
+sub pathSplit($);
+sub setAttributes($@);
+sub trapSignal($);
+sub usage();
+
+# Variables used as globals
+my(@gCleanup, %gConfig, $gDarwinMajor, $gDryRun, $gVerbosity);
+
+# Use the commands by name if they're expected to be in the user's
+# $PATH (/bin:/sbin:/usr/bin:/usr/sbin).  Otherwise, go by absolute
+# path.  These may be overridden with --config.
+%gConfig = ('cmd_bless'          => 'bless',
+            'cmd_chmod'          => 'chmod',
+            'cmd_diskutil'       => 'diskutil',
+            'cmd_du'             => 'du',
+            'cmd_hdid'           => 'hdid',
+            'cmd_hdiutil'        => 'hdiutil',
+            'cmd_mkdir'          => 'mkdir',
+            'cmd_mktemp'         => 'mktemp',
+            'cmd_Rez'            => '/usr/bin/Rez',
+            'cmd_rm'             => 'rm',
+            'cmd_rsync'          => 'rsync',
+            'cmd_SetFile'        => '/usr/bin/SetFile',
+
+            # create_directly indicates whether hdiutil create supports
+            # -srcfolder and -srcdevice.  It does on >= 10.3 (Panther).
+            # This is fixed up for earlier systems below.  If false,
+            # hdiutil create is used to create empty disk images that
+            # are manually filled.
+            'create_directly'    => 1,
+
+            # If hdiutil attach -mountpoint exists, use it to avoid
+            # mounting disk images in the default /Volumes.  This reduces
+            # the likelihood that someone will notice a mounted image and
+            # interfere with it.  Only available on >= 10.3 (Panther),
+            # fixed up for earlier systems below.
+            #
+            # This is presently turned off for all systems, because there
+            # is an infrequent synchronization problem during ejection.
+            # diskutil eject might return before the image is actually
+            # unmounted.  If pkg-dmg then attempts to clean up its
+            # temporary directory, it could remove items from a read-write
+            # disk image or attempt to remove items from a read-only disk
+            # image (or a read-only item from a read-write image) and fail,
+            # causing pkg-dmg to abort.  This problem is experienced
+            # under Tiger, which appears to eject asynchronously where
+            # previous systems treated it as a synchronous operation.
+            # Using hdiutil attach -mountpoint didn't always keep images
+            # from showing up on the desktop anyway.
+            'hdiutil_mountpoint' => 0,
+
+            # hdiutil makehybrid results in optimized disk images that
+            # consume less space and mount more quickly.  Use it when
+            # it's available, but that's only on >= 10.3 (Panther).
+            # If false, hdiutil create is used instead.  Fixed up for
+            # earlier systems below.
+            'makehybrid'         => 1,
+
+            # hdiutil create doesn't allow specifying a folder to open
+            # at volume mount time, so those images are mounted and
+            # their root folders made holy with bless -openfolder.  But
+            # only on >= 10.3 (Panther).  Earlier systems are out of luck.
+            # Even on Panther, bless refuses to run unless root.
+            # Fixed up below.
+            'openfolder_bless'   => 1,
+
+            # It's possible to save a few more kilobytes by including the
+            # partition only without any partition table in the image.
+            # This is a good idea on any system, so turn this option off.
+            #
+            # Except it's buggy.  "-layout NONE" seems to be creating
+            # disk images with more data than just the partition table
+            # stripped out.  You might wind up losing the end of the
+            # filesystem - the last file (or several) might be incomplete.
+            'partition_table'    => 1,
+
+            # To create a partition table-less image from something
+            # created by makehybrid, the hybrid image needs to be
+            # mounted and a new image made from the device associated
+            # with the relevant partition.  This requires >= 10.4
+            # (Tiger), presumably because earlier systems have
+            # problems creating images from devices themselves attached
+            # to images.  If this is false, makehybrid images will
+            # have partition tables, regardless of the partition_table
+            # setting.  Fixed up for earlier systems below.
+            'recursive_access'   => 1);
+
+# --verbosity
+$gVerbosity = 2;
+
+# --dry-run
+$gDryRun = 0;
+
+# %gConfig fix-ups based on features and bugs present in certain releases.
+my($ignore, $uname_r, $uname_s);
+($uname_s, $ignore, $uname_r, $ignore, $ignore) = POSIX::uname();
+if($uname_s eq 'Darwin') {
+  ($gDarwinMajor, $ignore) = split(/\./, $uname_r, 2);
+
+  # $major is the Darwin major release, which for our purposes, is 4 higher
+  # than the interesting digit in a Mac OS X release.
+  if($gDarwinMajor <= 6) {
+    # <= 10.2 (Jaguar)
+    # hdiutil create does not support -srcfolder or -srcdevice
+    $gConfig{'create_directly'} = 0;
+    # hdiutil attach does not support -mountpoint
+    $gConfig{'hdiutil_mountpoint'} = 0;
+    # hdiutil mkhybrid does not exist
+    $gConfig{'makehybrid'} = 0;
+  }
+  if($gDarwinMajor <= 7) {
+    # <= 10.3 (Panther)
+    # Can't mount a disk image and then make a disk image from the device
+    $gConfig{'recursive_access'} = 0;
+    # bless does not support -openfolder on 10.2 (Jaguar) and must run
+    # as root under 10.3 (Panther)
+    $gConfig{'openfolder_bless'} = 0;
+  }
+}
+else {
+  # If it's not Mac OS X, just assume all of those good features are
+  # available.  They're not, but things will fail long before they
+  # have a chance to make a difference.
+  #
+  # Now, if someone wanted to document some of these private formats...
+  print STDERR ($0.": warning, not running on Mac OS X, ".
+   "this could be interesting.\n");
+}
+
+# Non-global variables used in Getopt
+my(@attributes, @copyFiles, @createSymlinks, $iconFile, $idme, $licenseFile,
+ @makeDirs, $outputFormat, @resourceFiles, $sourceFile, $sourceFolder,
+ $targetImage, $tempDir, $volumeName);
+
+# --format
+$outputFormat = 'UDZO';
+
+# --idme
+$idme = 0;
+
+# --sourcefile
+$sourceFile = 0;
+
+# Leaving this might screw up the Apple tools.
+delete $ENV{'NEXT_ROOT'};
+
+# This script can get pretty messy, so trap a few signals.
+$SIG{'INT'} = \&trapSignal;
+$SIG{'HUP'} = \&trapSignal;
+$SIG{'TERM'} = \&trapSignal;
+
+Getopt::Long::Configure('pass_through');
+GetOptions('source=s'    => \$sourceFolder,
+           'target=s'    => \$targetImage,
+           'volname=s'   => \$volumeName,
+           'format=s'    => \$outputFormat,
+           'tempdir=s'   => \$tempDir,
+           'mkdir=s'     => \@makeDirs,
+           'copy=s'      => \@copyFiles,
+           'symlink=s'   => \@createSymlinks,
+           'license=s'   => \$licenseFile,
+           'resource=s'  => \@resourceFiles,
+           'icon=s'      => \$iconFile,
+           'attribute=s' => \@attributes,
+           'idme'        => \$idme,
+           'sourcefile'  => \$sourceFile,
+           'verbosity=i' => \$gVerbosity,
+           'dry-run'     => \$gDryRun,
+           'config=s'    => \%gConfig); # "hidden" option not in usage()
+
+if(@ARGV) {
+  # All arguments are parsed by Getopt
+  usage();
+  exit(1);
+}
+
+if($gVerbosity<0 || $gVerbosity>2) {
+  usage();
+  exit(1);
+}
+
+if(!defined($sourceFolder) || $sourceFolder eq '' ||
+ !defined($targetImage) || $targetImage eq '') {
+  # --source and --target are required arguments
+  usage();
+  exit(1);
+}
+
+# Make sure $sourceFolder doesn't contain trailing slashes.  It messes with
+# rsync.
+while(substr($sourceFolder, -1) eq '/') {
+  chop($sourceFolder);
+}
+
+if(!defined($volumeName)) {
+  # Default volumeName is the name of the source directory.
+  my(@components);
+  @components = pathSplit($sourceFolder);
+  $volumeName = pop(@components);
+}
+
+my(@tempDirComponents, $targetImageFilename);
+ at tempDirComponents = pathSplit($targetImage);
+$targetImageFilename = pop(@tempDirComponents);
+
+if(defined($tempDir)) {
+  @tempDirComponents = pathSplit($tempDir);
+}
+else {
+  # Default tempDir is the same directory as what is specified for
+  # targetImage
+  $tempDir = join('/', @tempDirComponents);
+}
+
+# Ensure that the path of the target image has a suitable extension.  If
+# it didn't, hdiutil would add one, and we wouldn't be able to find the
+# file.
+#
+# Note that $targetImageFilename is not being reset.  This is because it's
+# used to build other names below, and we don't need to be adding all sorts
+# of extra unnecessary extensions to the name.
+my($originalTargetImage, $requiredExtension);
+$originalTargetImage = $targetImage;
+if($outputFormat eq 'UDSP') {
+  $requiredExtension = '.sparseimage';
+}
+else {
+  $requiredExtension = '.dmg';
+}
+$targetImage = giveExtension($originalTargetImage, $requiredExtension);
+
+if($targetImage ne $originalTargetImage) {
+  print STDERR ($0.": warning: target image extension is being added\n");
+  print STDERR ('  The new filename is '.
+   giveExtension($targetImageFilename,$requiredExtension)."\n");
+}
+
+# Make a temporary directory in $tempDir for our own nefarious purposes.
+my(@output, $tempSubdir, $tempSubdirTemplate);
+$tempSubdirTemplate=join('/', @tempDirComponents,
+ 'pkg-dmg.'.$$.'.XXXXXXXX');
+if(!(@output = commandOutput($gConfig{'cmd_mktemp'}, '-d',
+ $tempSubdirTemplate)) || $#output != 0) {
+  cleanupDie('mktemp failed');
+}
+
+if($gDryRun) {
+  (@output)=($tempSubdirTemplate);
+}
+
+($tempSubdir) = @output;
+
+push(@gCleanup,
+ sub {commandVerbosity(0, $gConfig{'cmd_rm'}, '-rf', $tempSubdir);});
+
+my($tempMount, $tempRoot, @tempsToMake);
+$tempRoot = $tempSubdir.'/stage';
+$tempMount = $tempSubdir.'/mount';
+push(@tempsToMake, $tempRoot);
+if($gConfig{'hdiutil_mountpoint'}) {
+  push(@tempsToMake, $tempMount);
+}
+
+if(command($gConfig{'cmd_mkdir'}, @tempsToMake) != 0) {
+  cleanupDie('mkdir tempRoot/tempMount failed');
+}
+
+# This cleanup object is not strictly necessary, because $tempRoot is inside
+# of $tempSubdir, but the rest of the script relies on this object being
+# on the cleanup stack and expects to remove it.
+push(@gCleanup,
+ sub {commandVerbosity(0, $gConfig{'cmd_rm'}, '-rf', $tempRoot);});
+
+# If $sourceFile is true, it means that $sourceFolder is to be treated as
+# a file and placed as a file within the volume root, as opposed to being
+# treated as the volume root itself.  rsync will do this by default, if no
+# trailing '/' is present.  With a trailing '/', $sourceFolder becomes
+# $tempRoot, instead of becoming an entry in $tempRoot.
+if(command($gConfig{'cmd_rsync'}, '-aC', '--include', '*.so',
+ '--copy-unsafe-links', $sourceFolder.($sourceFile?'':'/'),$tempRoot) != 0) {
+  cleanupDie('rsync failed');
+}
+
+if(@makeDirs) {
+  my($makeDir, @tempDirsToMake);
+  foreach $makeDir (@makeDirs) {
+    if($makeDir =~ /^\//) {
+      push(@tempDirsToMake, $tempRoot.$makeDir);
+    }
+    else {
+      push(@tempDirsToMake, $tempRoot.'/'.$makeDir);
+    }
+  }
+  if(command($gConfig{'cmd_mkdir'}, '-p', @tempDirsToMake) != 0) {
+    cleanupDie('mkdir failed');
+  }
+}
+
+# copy files and/or create symlinks
+copyFiles($tempRoot, 'copy', @copyFiles);
+copyFiles($tempRoot, 'symlink', @createSymlinks);
+
+if($gConfig{'create_directly'}) {
+  # If create_directly is false, the contents will be rsynced into a
+  # disk image and they would lose their attributes.
+  setAttributes($tempRoot, @attributes);
+}
+
+if(defined($iconFile)) {
+  if(command($gConfig{'cmd_rsync'}, '-aC', '--include', '*.so',
+   '--copy-unsafe-links', $iconFile, $tempRoot.'/.VolumeIcon.icns') != 0) {
+    cleanupDie('rsync failed for volume icon');
+  }
+
+  # It's pointless to set the attributes of the root when diskutil create
+  # -srcfolder is being used.  In that case, the attributes will be set
+  # later, after the image is already created.
+  if(isFormatReadOnly($outputFormat) &&
+   (command($gConfig{'cmd_SetFile'}, '-a', 'C', $tempRoot) != 0)) {
+    cleanupDie('SetFile failed');
+  }
+}
+
+if(command($gConfig{'cmd_chmod'}, '-R', 'a+rX,a-st,u+w,go-w',
+ $tempRoot) != 0) {
+  cleanupDie('chmod failed');
+}
+
+my($unflattenable);
+if(isFormatReadOnly($outputFormat)) {
+  $unflattenable = 1;
+}
+else {
+  $unflattenable = 0;
+}
+
+diskImageMaker($tempRoot, $targetImage, $outputFormat, $volumeName,
+ $tempSubdir, $tempMount, $targetImageFilename, defined($iconFile));
+
+if(defined($licenseFile) && $licenseFile ne '') {
+  my($licenseResource);
+  $licenseResource = $tempSubdir.'/license.r';
+  if(!licenseMaker($licenseFile, $licenseResource)) {
+    cleanupDie('licenseMaker failed');
+  }
+  push(@resourceFiles, $licenseResource);
+  # Don't add a cleanup object because licenseResource is in tempSubdir.
+}
+
+if(@resourceFiles) {
+  # Add resources, such as a license agreement.
+
+  # Only unflatten read-only and compressed images.  It's not supported
+  # on other image times.
+  if($unflattenable &&
+   (command($gConfig{'cmd_hdiutil'}, 'unflatten', $targetImage)) != 0) {
+    cleanupDie('hdiutil unflatten failed');
+  }
+  # Don't push flatten onto the cleanup stack.  If we fail now, we'll be
+  # removing $targetImage anyway.
+
+  # Type definitions come from Carbon.r.
+  if(command($gConfig{'cmd_Rez'}, 'Carbon.r', @resourceFiles, '-a', '-o',
+   $targetImage) != 0) {
+    cleanupDie('Rez failed');
+  }
+
+  # Flatten.  This merges the resource fork into the data fork, so no
+  # special encoding is needed to transfer the file.
+  if($unflattenable &&
+   (command($gConfig{'cmd_hdiutil'}, 'flatten', $targetImage)) != 0) {
+    cleanupDie('hdiutil flatten failed');
+  }
+}
+
+# $tempSubdir is no longer needed.  It's buried on the stack below the
+# rm of the fresh image file.  Splice in this fashion is equivalent to
+# pop-save, pop, push-save.
+splice(@gCleanup, -2, 1);
+# No need to remove licenseResource separately, it's in tempSubdir.
+if(command($gConfig{'cmd_rm'}, '-rf', $tempSubdir) != 0) {
+  cleanupDie('rm -rf tempSubdir failed');
+}
+
+if($idme) {
+  if(command($gConfig{'cmd_hdiutil'}, 'internet-enable', '-yes',
+   $targetImage) != 0) {
+    cleanupDie('hdiutil internet-enable failed');
+  }
+}
+
+# Done.
+
+exit(0);
+
+# argumentEscape(@arguments)
+#
+# Takes a list of @arguments and makes them shell-safe.
+sub argumentEscape(@) {
+  my(@arguments);
+  @arguments = @_;
+  my($argument, @argumentsOut);
+  foreach $argument (@arguments) {
+    $argument =~ s%([^A-Za-z0-9_\-/.=+,])%\\$1%g;
+    push(@argumentsOut, $argument);
+  }
+  return @argumentsOut;
+}
+
+# cleanupDie($message)
+#
+# Displays $message as an error message, and then runs through the
+# @gCleanup stack, performing any cleanup operations needed before
+# exiting.  Does not return, exits with exit status 1.
+sub cleanupDie($) {
+  my($message);
+  ($message) = @_;
+  print STDERR ($0.': '.$message.(@gCleanup?' (cleaning up)':'')."\n");
+  while(@gCleanup) {
+    my($subroutine);
+    $subroutine = pop(@gCleanup);
+    &$subroutine;
+  }
+  exit(1);
+}
+
+# command(@arguments)
+#
+# Runs the specified command at the verbosity level defined by $gVerbosity.
+# Returns nonzero on failure, returning the exit status if appropriate.
+# Discards command output.
+sub command(@) {
+  my(@arguments);
+  @arguments = @_;
+  return commandVerbosity($gVerbosity, at arguments);
+}
+
+# commandInternal($command, @arguments)
+#
+# Runs the specified internal command at the verbosity level defined by
+# $gVerbosity.
+# Returns zero(!) on failure, because commandInternal is supposed to be a
+# direct replacement for the Perl system call wrappers, which, unlike shell
+# commands and C equivalent system calls, return true (instead of 0) to
+# indicate success.
+sub commandInternal($@) {
+  my(@arguments, $command);
+  ($command, @arguments) = @_;
+  return commandInternalVerbosity($gVerbosity, $command, @arguments);
+}
+
+# commandInternalVerbosity($verbosity, $command, @arguments)
+#
+# Run an internal command, printing a bogus command invocation message if
+# $verbosity is true.
+#
+# If $command is unlink:
+# Removes the files specified by @arguments.  Wraps unlink.
+#
+# If $command is symlink:
+# Creates the symlink specified by @arguments. Wraps symlink.
+sub commandInternalVerbosity($$@) {
+  my(@arguments, $command, $verbosity);
+  ($verbosity, $command, @arguments) = @_;
+  if($command eq 'unlink') {
+    if($verbosity || $gDryRun) {
+      print(join(' ', 'rm', '-f', argumentEscape(@arguments))."\n");
+    }
+    if($gDryRun) {
+      return $#arguments+1;
+    }
+    return unlink(@arguments);
+  }
+  elsif($command eq 'symlink') {
+    if($verbosity || $gDryRun) {
+      print(join(' ', 'ln', '-s', argumentEscape(@arguments))."\n");
+    }
+    if($gDryRun) {
+      return 1;
+    }
+    my($source, $target);
+    ($source, $target) = @arguments;
+    return symlink($source, $target);
+  }
+}
+
+# commandOutput(@arguments)
+#
+# Runs the specified command at the verbosity level defined by $gVerbosity.
+# Output is returned in an array of lines.  undef is returned on failure.
+# The exit status is available in $?.
+sub commandOutput(@) {
+  my(@arguments);
+  @arguments = @_;
+  return commandOutputVerbosity($gVerbosity, @arguments);
+}
+
+# commandOutputVerbosity($verbosity, @arguments)
+#
+# Runs the specified command at the verbosity level defined by the
+# $verbosity argument.  Output is returned in an array of lines.  undef is
+# returned on failure.  The exit status is available in $?.
+#
+# If an error occurs in fork or exec, an error message is printed to
+# stderr and undef is returned.
+#
+# If $verbosity is 0, the command invocation is not printed, and its
+# stdout is not echoed back to stdout.
+#
+# If $verbosity is 1, the command invocation is printed.
+#
+# If $verbosity is 2, the command invocation is printed and the output
+# from stdout is echoed back to stdout.
+#
+# Regardless of $verbosity, stderr is left connected.
+sub commandOutputVerbosity($@) {
+  my(@arguments, $verbosity);
+  ($verbosity, @arguments) = @_;
+  my($pid);
+  if($verbosity || $gDryRun) {
+    print(join(' ', argumentEscape(@arguments))."\n");
+  }
+  if($gDryRun) {
+    return(1);
+  }
+  if (!defined($pid = open(*COMMAND, '-|'))) {
+    printf STDERR ($0.': fork: '.$!."\n");
+    return undef;
+  }
+  elsif ($pid) {
+    # parent
+    my(@lines);
+    while(!eof(*COMMAND)) {
+      my($line);
+      chop($line = <COMMAND>);
+      if($verbosity > 1) {
+        print($line."\n");
+      }
+      push(@lines, $line);
+    }
+    close(*COMMAND);
+    if ($? == -1) {
+      printf STDERR ($0.': fork: '.$!."\n");
+      return undef;
+    }
+    elsif ($? & 127) {
+      printf STDERR ($0.': exited on signal '.($? & 127).
+       ($? & 128 ? ', core dumped' : '')."\n");
+      return undef;
+    }
+    return @lines;
+  }
+  else {
+    # child; this form of exec is immune to shell games
+    if(!exec {$arguments[0]} (@arguments)) {
+      printf STDERR ($0.': exec: '.$!."\n");
+      exit(-1);
+    }
+  }
+}
+
+# commandVerbosity($verbosity, @arguments)
+#
+# Runs the specified command at the verbosity level defined by the
+# $verbosity argument.  Returns nonzero on failure, returning the exit
+# status if appropriate.  Discards command output.
+sub commandVerbosity($@) {
+  my(@arguments, $verbosity);
+  ($verbosity, @arguments) = @_;
+  if(!defined(commandOutputVerbosity($verbosity, @arguments))) {
+    return -1;
+  }
+  return $?;
+}
+
+# copyFiles($tempRoot, $method, @arguments)
+#
+# Copies files or create symlinks in the disk image.
+# See --copy and --symlink descriptions for details.
+# If $method is 'copy', @arguments are interpreted as source:target, if $method
+# is 'symlink', @arguments are interpreted as symlink:target.
+sub copyFiles($@) {
+  my(@fileList, $method, $tempRoot);
+  ($tempRoot, $method, @fileList) = @_;
+  my($file, $isSymlink);
+  $isSymlink = ($method eq 'symlink');
+  foreach $file (@fileList) {
+    my($source, $target);
+    ($source, $target) = split(/:/, $file);
+    if(!defined($target) and $isSymlink) {
+      # empty symlink targets would result in an invalid target and fail,
+      # but they shall be interpreted as "like source path, but inside dmg"
+      $target = $source;
+    }
+    if(!defined($target)) {
+      $target = $tempRoot;
+    }
+    elsif($target =~ /^\//) {
+      $target = $tempRoot.$target;
+    }
+    else {
+      $target = $tempRoot.'/'.$target;
+    }
+
+    my($success);
+    if($isSymlink) {
+      $success = commandInternal('symlink', $source, $target);
+    }
+    else {
+      $success = !command($gConfig{'cmd_rsync'}, '-aC', '--include', '*.so',
+                          '--copy-unsafe-links', $source, $target);
+    }
+    if(!$success) {
+      cleanupDie('copyFiles failed for method '.$method);
+    }
+  }
+}
+
+# diskImageMaker($source, $destination, $format, $name, $tempDir, $tempMount,
+#  $baseName, $setRootIcon)
+#
+# Creates a disk image in $destination of format $format corresponding to the
+# source directory $source.  $name is the volume name.  $tempDir is a good
+# place to write temporary files, which should be empty (aside from the other
+# things that this script might create there, like stage and mount).
+# $tempMount is a mount point for temporary disk images.  $baseName is the
+# name of the disk image, and is presently unused.  $setRootIcon is true if
+# a volume icon was added to the staged $source and indicates that the
+# custom volume icon bit on the volume root needs to be set.
+sub diskImageMaker($$$$$$$$) {
+  my($baseName, $destination, $format, $name, $setRootIcon, $source,
+   $tempDir, $tempMount);
+  ($source, $destination, $format, $name, $tempDir, $tempMount,
+   $baseName, $setRootIcon) = @_;
+  if(isFormatReadOnly($format)) {
+    my($uncompressedImage);
+
+    if($gConfig{'makehybrid'}) {
+      my($hybridImage);
+      $hybridImage = giveExtension($tempDir.'/hybrid', '.dmg');
+
+      if(command($gConfig{'cmd_hdiutil'}, 'makehybrid', '-hfs',
+       '-hfs-volume-name', $name,
+       ($gConfig{'openfolder_bless'} ? ('-hfs-openfolder', $source) : ()),
+       '-ov', $source, '-o', $hybridImage) != 0) {
+        cleanupDie('hdiutil makehybrid failed');
+      }
+
+      $uncompressedImage = $hybridImage;
+
+      # $source is no longer needed and will be removed before anything
+      # else can fail.  splice in this form is the same as pop/push.
+      splice(@gCleanup, -1, 1,
+       sub {commandInternalVerbosity(0, 'unlink', $hybridImage);});
+
+      if(command($gConfig{'cmd_rm'}, '-rf', $source) != 0) {
+        cleanupDie('rm -rf failed');
+      }
+
+      if(!$gConfig{'partition_table'} && $gConfig{'recursive_access'}) {
+        # Even if we do want to create disk images without partition tables,
+        # it's impossible unless recursive_access is set.
+        my($rootDevice, $partitionDevice, $partitionMountPoint);
+
+        if(!(($rootDevice, $partitionDevice, $partitionMountPoint) =
+         hdidMountImage($tempMount, '-readonly', $hybridImage))) {
+          cleanupDie('hdid mount failed');
+        }
+
+        push(@gCleanup, sub {commandVerbosity(0,
+         $gConfig{'cmd_diskutil'}, 'eject', $rootDevice);});
+
+        my($udrwImage);
+        $udrwImage = giveExtension($tempDir.'/udrw', '.dmg');
+
+        if(command($gConfig{'cmd_hdiutil'}, 'create', '-format', 'UDRW',
+         '-ov', '-srcdevice', $partitionDevice, $udrwImage) != 0) {
+          cleanupDie('hdiutil create failed');
+        }
+
+        $uncompressedImage = $udrwImage;
+
+        # Going to eject before anything else can fail.  Get the eject off
+        # the stack.
+        pop(@gCleanup);
+
+        # $hybridImage will be removed soon, but until then, it needs to
+        # stay on the cleanup stack.  It needs to wait until after
+        # ejection.  $udrwImage is staying around.  Make it appear as
+        # though it's been done before $hybridImage.
+        #
+        # splice in this form is the same as popping one element to
+        # @tempCleanup and pushing the subroutine.
+        my(@tempCleanup);
+        @tempCleanup = splice(@gCleanup, -1, 1,
+         sub {commandInternalVerbosity(0, 'unlink', $udrwImage);});
+        push(@gCleanup, @tempCleanup);
+
+        if(command($gConfig{'cmd_diskutil'}, 'eject', $rootDevice) != 0) {
+          cleanupDie('diskutil eject failed');
+        }
+
+        # Pop unlink of $uncompressedImage
+        pop(@gCleanup);
+
+        if(commandInternal('unlink', $hybridImage) != 1) {
+          cleanupDie('unlink hybridImage failed: '.$!);
+        }
+      }
+    }
+    else {
+      # makehybrid is not available, fall back to making a UDRW and
+      # converting to a compressed image.  It ought to be possible to
+      # create a compressed image directly, but those come out far too
+      # large (journaling?) and need to be read-write to fix up the
+      # volume icon anyway.  Luckily, we can take advantage of a single
+      # call back into this function.
+      my($udrwImage);
+      $udrwImage = giveExtension($tempDir.'/udrw', '.dmg');
+
+      diskImageMaker($source, $udrwImage, 'UDRW', $name, $tempDir,
+       $tempMount, $baseName, $setRootIcon);
+
+      # The call back into diskImageMaker already removed $source.
+
+      $uncompressedImage = $udrwImage;
+    }
+
+    # The uncompressed disk image is now in its final form.  Compress it.
+    # Jaguar doesn't support hdiutil convert -ov, but it always allows
+    # overwriting.
+    # bzip2-compressed UDBZ images can only be created and mounted on 10.4
+    # and later.  The bzip2-level imagekey is only effective when creating
+    # images in 10.5.  In 10.4, bzip2-level is harmlessly ignored, and the
+    # default value of 1 is always used.
+    if(command($gConfig{'cmd_hdiutil'}, 'convert', '-format', $format,
+     ($format eq 'UDZO' ? ('-imagekey', 'zlib-level=9') : ()),
+     ($format eq 'UDBZ' ? ('-imagekey', 'bzip2-level=9') : ()),
+     (defined($gDarwinMajor) && $gDarwinMajor <= 6 ? () : ('-ov')),
+     $uncompressedImage, '-o', $destination) != 0) {
+      cleanupDie('hdiutil convert failed');
+    }
+
+    # $uncompressedImage is going to be unlinked before anything else can
+    # fail.  splice in this form is the same as pop/push.
+    splice(@gCleanup, -1, 1,
+     sub {commandInternalVerbosity(0, 'unlink', $destination);});
+
+    if(commandInternal('unlink', $uncompressedImage) != 1) {
+      cleanupDie('unlink uncompressedImage failed: '.$!);
+    }
+
+    # At this point, the only thing that the compressed block has added to
+    # the cleanup stack is the removal of $destination.  $source has already
+    # been removed, and its cleanup entry has been removed as well.
+  }
+  elsif($format eq 'UDRW' || $format eq 'UDSP') {
+    my(@extraArguments);
+    if(!$gConfig{'partition_table'}) {
+      @extraArguments = ('-layout', 'NONE');
+    }
+
+    if($gConfig{'create_directly'}) {
+      # Use -fs HFS+ to suppress the journal.
+      if(command($gConfig{'cmd_hdiutil'}, 'create', '-format', $format,
+       @extraArguments, '-fs', 'HFS+', '-volname', $name,
+       '-ov', '-srcfolder', $source, $destination) != 0) {
+        cleanupDie('hdiutil create failed');
+      }
+
+      # $source is no longer needed and will be removed before anything
+      # else can fail.  splice in this form is the same as pop/push.
+      splice(@gCleanup, -1, 1,
+       sub {commandInternalVerbosity(0, 'unlink', $destination);});
+
+      if(command($gConfig{'cmd_rm'}, '-rf', $source) != 0) {
+        cleanupDie('rm -rf failed');
+      }
+    }
+    else {
+      # hdiutil create does not support -srcfolder or -srcdevice, it only
+      # knows how to create blank images.  Figure out how large an image
+      # is needed, create it, and fill it.  This is needed for Jaguar.
+
+      # Use native block size for hdiutil create -sectors.
+      delete $ENV{'BLOCKSIZE'};
+
+      my(@duOutput, $ignore, $sizeBlocks, $sizeOverhead, $sizeTotal, $type);
+      if(!(@output = commandOutput($gConfig{'cmd_du'}, '-s', $tempRoot)) ||
+       $? != 0) {
+        cleanupDie('du failed');
+      }
+      ($sizeBlocks, $ignore) = split(' ', $output[0], 2);
+
+      # The filesystem itself takes up 152 blocks of its own blocks for the
+      # filesystem up to 8192 blocks, plus 64 blocks for every additional
+      # 4096 blocks or portion thereof.
+      $sizeOverhead = 152 + 64 * POSIX::ceil(
+       (($sizeBlocks - 8192) > 0) ? (($sizeBlocks - 8192) / (4096 - 64)) : 0);
+
+      # The number of blocks must be divisible by 8.
+      my($mod);
+      if($mod = ($sizeOverhead % 8)) {
+        $sizeOverhead += 8 - $mod;
+      }
+
+      # sectors is taken as the size of a disk, not a filesystem, so the
+      # partition table eats into it.
+      if($gConfig{'partition_table'}) {
+        $sizeOverhead += 80;
+      }
+
+      # That was hard.  Leave some breathing room anyway.  Use 1024 sectors
+      # (512kB).  These read-write images wouldn't be useful if they didn't
+      # have at least a little free space.
+      $sizeTotal = $sizeBlocks + $sizeOverhead + 1024;
+
+      # Minimum sizes - these numbers are larger on Jaguar than on later
+      # systems.  Just use the Jaguar numbers, since it's unlikely to wind
+      # up here on any other release.
+      if($gConfig{'partition_table'} && $sizeTotal < 8272) {
+        $sizeTotal = 8272;
+      }
+      if(!$gConfig{'partition_table'} && $sizeTotal < 8192) {
+        $sizeTotal = 8192;
+      }
+
+      # hdiutil create without -srcfolder or -srcdevice will not accept
+      # -format.  It uses -type.  Fortunately, the two supported formats
+      # here map directly to the only two supported types.
+      if ($format eq 'UDSP') {
+        $type = 'SPARSE';
+      }
+      else {
+        $type = 'UDIF';
+      }
+
+      if(command($gConfig{'cmd_hdiutil'}, 'create', '-type', $type,
+       @extraArguments, '-fs', 'HFS+', '-volname', $name,
+       '-ov', '-sectors', $sizeTotal, $destination) != 0) {
+        cleanupDie('hdiutil create failed');
+      }
+
+      push(@gCleanup,
+       sub {commandInternalVerbosity(0, 'unlink', $destination);});
+
+      # The rsync will occur shortly.
+    }
+
+    my($mounted, $rootDevice, $partitionDevice, $partitionMountPoint);
+
+    $mounted=0;
+    if(!$gConfig{'create_directly'} || $gConfig{'openfolder_bless'} ||
+     $setRootIcon) {
+      # The disk image only needs to be mounted if:
+      #  create_directly is false, because the content needs to be copied
+      #  openfolder_bless is true, because bless -openfolder needs to run
+      #  setRootIcon is true, because the root needs its attributes set.
+      if(!(($rootDevice, $partitionDevice, $partitionMountPoint) =
+       hdidMountImage($tempMount, $destination))) {
+        cleanupDie('hdid mount failed');
+      }
+
+      $mounted=1;
+
+      push(@gCleanup, sub {commandVerbosity(0,
+       $gConfig{'cmd_diskutil'}, 'eject', $rootDevice);});
+    }
+
+    if(!$gConfig{'create_directly'}) {
+      # Couldn't create and copy directly in one fell swoop.  Now that
+      # the volume is mounted, copy the files.  --copy-unsafe-links is
+      # unnecessary since it was used to copy everything to the staging
+      # area.  There can be no more unsafe links.
+      if(command($gConfig{'cmd_rsync'}, '-aC', '--include', '*.so',
+       $source.'/',$partitionMountPoint) != 0) {
+        cleanupDie('rsync to new volume failed');
+      }
+
+      # We need to get the rm -rf of $source off the stack, because it's
+      # being cleaned up here.  There are two items now on top of it:
+      # removing the target image and, above that, ejecting it.  Splice it
+      # out.
+      my(@tempCleanup);
+      @tempCleanup = splice(@gCleanup, -2);
+      # The next splice is the same as popping once and pushing @tempCleanup.
+      splice(@gCleanup, -1, 1, @tempCleanup);
+
+      if(command($gConfig{'cmd_rm'}, '-rf', $source) != 0) {
+        cleanupDie('rm -rf failed');
+      }
+    }
+
+    if($gConfig{'openfolder_bless'}) {
+      # On Tiger, the bless docs say to use --openfolder, but only
+      # --openfolder is accepted on Panther.  Tiger takes it with a single
+      # dash too.  Jaguar is out of luck.
+      if(command($gConfig{'cmd_bless'}, '-openfolder',
+       $partitionMountPoint) != 0) {
+        cleanupDie('bless failed');
+      }
+    }
+
+    setAttributes($partitionMountPoint, @attributes);
+
+    if($setRootIcon) {
+      # When "hdiutil create -srcfolder" is used, the root folder's
+      # attributes are not copied to the new volume.  Fix up.
+
+      if(command($gConfig{'cmd_SetFile'}, '-a', 'C',
+       $partitionMountPoint) != 0) {
+        cleanupDie('SetFile failed');
+      }
+    }
+
+    if($mounted) {
+      # Pop diskutil eject
+      pop(@gCleanup);
+
+      if(command($gConfig{'cmd_diskutil'}, 'eject', $rootDevice) != 0) {
+        cleanupDie('diskutil eject failed');
+      }
+    }
+
+    # End of UDRW/UDSP section.  At this point, $source has been removed
+    # and its cleanup entry has been removed from the stack.
+  }
+  else {
+    cleanupDie('unrecognized format');
+    print STDERR ($0.": unrecognized format\n");
+    exit(1);
+  }
+}
+
+# giveExtension($file, $extension)
+#
+# If $file does not end in $extension, $extension is added.  The new
+# filename is returned.
+sub giveExtension($$) {
+  my($extension, $file);
+  ($file, $extension) = @_;
+  if(substr($file, -length($extension)) ne $extension) {
+    return $file.$extension;
+  }
+  return $file;
+}
+
+# hdidMountImage($mountPoint, @arguments)
+#
+# Runs the hdid command with arguments specified by @arguments.
+# @arguments may be a single-element array containing the name of the
+# disk image to mount.  Returns a three-element array, with elements
+# corresponding to:
+#  - The root device of the mounted image, suitable for ejection
+#  - The device corresponding to the mounted partition
+#  - The mounted partition's mount point
+#
+# If running on a system that supports easy mounting at points outside
+# of the default /Volumes with hdiutil attach, it is used instead of hdid,
+# and $mountPoint is used as the mount point.
+#
+# The root device will differ from the partition device when the disk
+# image contains a partition table, otherwise, they will be identical.
+#
+# If hdid fails, undef is returned.
+sub hdidMountImage($@) {
+  my(@arguments, @command, $mountPoint);
+  ($mountPoint, @arguments) = @_;
+  my(@output);
+
+  if($gConfig{'hdiutil_mountpoint'}) {
+    @command=($gConfig{'cmd_hdiutil'}, 'attach', @arguments,
+     '-mountpoint', $mountPoint);
+  }
+  else {
+    @command=($gConfig{'cmd_hdid'}, @arguments);
+  }
+
+  if(!(@output = commandOutput(@command)) ||
+   $? != 0) {
+    return undef;
+  }
+
+  if($gDryRun) {
+    return('/dev/diskX','/dev/diskXsY','/Volumes/'.$volumeName);
+  }
+
+  my($line, $restOfLine, $rootDevice);
+
+  foreach $line (@output) {
+    my($device, $mountpoint);
+    if($line !~ /^\/dev\//) {
+      # Consider only lines that correspond to /dev entries
+      next;
+    }
+    ($device, $restOfLine) = split(' ', $line, 2);
+
+    if(!defined($rootDevice) || $rootDevice eq '') {
+      # If this is the first device seen, it's the root device to be
+      # used for ejection.  Keep it.
+      $rootDevice = $device;
+    }
+
+    if($restOfLine =~ /(\/.*)/) {
+      # The first partition with a mount point is the interesting one.  It's
+      # usually Apple_HFS and usually the last one in the list, but beware of
+      # the possibility of other filesystem types and the Apple_Free partition.
+      # If the disk image contains no partition table, the partition will not
+      # have a type, so look for the mount point by looking for a slash.
+      $mountpoint = $1;
+      return($rootDevice, $device, $mountpoint);
+    }
+  }
+
+  # No mount point?  This is bad.  If there's a root device, eject it.
+  if(defined($rootDevice) && $rootDevice ne '') {
+    # Failing anyway, so don't care about failure
+    commandVerbosity(0, $gConfig{'cmd_diskutil'}, 'eject', $rootDevice);
+  }
+
+  return undef;
+}
+
+# isFormatReadOnly($format)
+#
+# Returns true if $format corresponds to a read-only disk image format.
+# Returns false otherwise.
+sub isFormatReadOnly($) {
+  my($format);
+  ($format) = @_;
+  return $format eq 'UDZO' || $format eq 'UDBZ' || $format eq 'UDRO';
+}
+
+# licenseMaker($text, $resource)
+#
+# Takes a plain text file at path $text and creates a license agreement
+# resource containing the text at path $license.  English-only, and
+# no special formatting.  This is the bare-bones stuff.  For more
+# intricate license agreements, create your own resource.
+#
+# ftp://ftp.apple.com/developer/Development_Kits/SLAs_for_UDIFs_1.0.dmg
+sub licenseMaker($$) {
+  my($resource, $text);
+  ($text, $resource) = @_;
+  if(!sysopen(*TEXT, $text, O_RDONLY)) {
+    print STDERR ($0.': licenseMaker: sysopen text: '.$!."\n");
+    return 0;
+  }
+  if(!sysopen(*RESOURCE, $resource, O_WRONLY|O_CREAT|O_EXCL)) {
+    print STDERR ($0.': licenseMaker: sysopen resource: '.$!."\n");
+    return 0;
+  }
+  print RESOURCE << '__EOT__';
+// See /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers/Script.h for language IDs.
+data 'LPic' (5000) {
+  // Default language ID, 0 = English
+  $"0000"
+  // Number of entries in list
+  $"0001"
+
+  // Entry 1
+  // Language ID, 0 = English
+  $"0000"
+  // Resource ID, 0 = STR#/TEXT/styl 5000
+  $"0000"
+  // Multibyte language, 0 = no
+  $"0000"
+};
+
+resource 'STR#' (5000, "English") {
+  {
+    // Language (unused?) = English
+    "English",
+    // Agree
+    "Agree",
+    // Disagree
+    "Disagree",
+__EOT__
+    # This stuff needs double-quotes for interpolations to work.
+    print RESOURCE ("    // Print, ellipsis is 0xC9\n");
+    print RESOURCE ("    \"Print\xc9\",\n");
+    print RESOURCE ("    // Save As, ellipsis is 0xC9\n");
+    print RESOURCE ("    \"Save As\xc9\",\n");
+    print RESOURCE ('    // Descriptive text, curly quotes are 0xD2 and 0xD3'.
+     "\n");
+    print RESOURCE ('    "If you agree to the terms of this license '.
+     "agreement, click \xd2Agree\xd3 to access the software.  If you ".
+     "do not agree, press \xd2Disagree.\xd3\"\n");
+print RESOURCE << '__EOT__';
+  };
+};
+
+// Beware of 1024(?) byte (character?) line length limitation.  Split up long
+// lines.
+// If straight quotes are used ("), remember to escape them (\").
+// Newline is \n, to leave a blank line, use two of them.
+// 0xD2 and 0xD3 are curly double-quotes ("), 0xD4 and 0xD5 are curly
+//   single quotes ('), 0xD5 is also the apostrophe.
+data 'TEXT' (5000, "English") {
+__EOT__
+
+  while(!eof(*TEXT)) {
+    my($line);
+    chop($line = <TEXT>);
+
+    while(defined($line)) {
+      my($chunk);
+
+      # Rez doesn't care for lines longer than (1024?) characters.  Split
+      # at less than half of that limit, in case everything needs to be
+      # backwhacked.
+      if(length($line)>500) {
+        $chunk = substr($line, 0, 500);
+        $line = substr($line, 500);
+      }
+      else {
+        $chunk = $line;
+        $line = undef;
+      }
+
+      if(length($chunk) > 0) {
+        # Unsafe characters are the double-quote (") and backslash (\), escape
+        # them with backslashes.
+        $chunk =~ s/(["\\])/\\$1/g;
+
+        print RESOURCE '  "'.$chunk.'"'."\n";
+      }
+    }
+    print RESOURCE '  "\n"'."\n";
+  }
+  close(*TEXT);
+
+  print RESOURCE << '__EOT__';
+};
+
+data 'styl' (5000, "English") {
+  // Number of styles following = 1
+  $"0001"
+
+  // Style 1.  This is used to display the first two lines in bold text.
+  // Start character = 0
+  $"0000 0000"
+  // Height = 16
+  $"0010"
+  // Ascent = 12
+  $"000C"
+  // Font family = 1024 (Lucida Grande)
+  $"0400"
+  // Style bitfield, 0x1=bold 0x2=italic 0x4=underline 0x8=outline
+  // 0x10=shadow 0x20=condensed 0x40=extended
+  $"00"
+  // Style, unused?
+  $"02"
+  // Size = 12 point
+  $"000C"
+  // Color, RGB
+  $"0000 0000 0000"
+};
+__EOT__
+  close(*RESOURCE);
+
+  return 1;
+}
+
+# pathSplit($pathname)
+#
+# Splits $pathname into an array of path components.
+sub pathSplit($) {
+  my($pathname);
+  ($pathname) = @_;
+  return split(/\//, $pathname);
+}
+
+# setAttributes($root, @attributeList)
+#
+# @attributeList is an array, each element of which must be in the form
+# <a>:<file>.  <a> is a list of attributes, per SetFile.  <file> is a file
+# which is taken as relative to $root (even if it appears as an absolute
+# path.)  SetFile is called to set the attributes on each file in
+# @attributeList.
+sub setAttributes($@) {
+  my(@attributes, $root);
+  ($root, @attributes) = @_;
+  my($attribute);
+  foreach $attribute (@attributes) {
+    my($attrList, $file, @fileList, @fixedFileList);
+    ($attrList, @fileList) = split(/:/, $attribute);
+    if(!defined($attrList) || !@fileList) {
+      cleanupDie('--attribute requires <attributes>:<file>');
+    }
+    @fixedFileList=();
+    foreach $file (@fileList) {
+      if($file =~ /^\//) {
+        push(@fixedFileList, $root.$file);
+      }
+      else {
+        push(@fixedFileList, $root.'/'.$file);
+      }
+    }
+    if(command($gConfig{'cmd_SetFile'}, '-a', $attrList, @fixedFileList)) {
+      cleanupDie('SetFile failed to set attributes');
+    }
+  }
+  return;
+}
+
+sub trapSignal($) {
+  my($signalName);
+  ($signalName) = @_;
+  cleanupDie('exiting on SIG'.$signalName);
+}
+
+sub usage() {
+  print STDERR (
+"usage: pkg-dmg --source <source-folder>\n".
+"               --target <target-image>\n".
+"              [--format <format>]           (default: UDZO)\n".
+"              [--volname <volume-name>]     (default: same name as source)\n".
+"              [--tempdir <temp-dir>]        (default: same dir as target)\n".
+"              [--mkdir <directory>]         (make directory in image)\n".
+"              [--copy <source>[:<dest>]]    (extra files to add)\n".
+"              [--symlink <source>[:<dest>]] (extra symlinks to add)\n".
+"              [--license <file>]            (plain text license agreement)\n".
+"              [--resource <file>]           (flat .r files to merge)\n".
+"              [--icon <icns-file>]          (volume icon)\n".
+"              [--attribute <a>:<file>]      (set file attributes)\n".
+"              [--idme]                      (make Internet-enabled image)\n".
+"              [--sourcefile]                (treat --source as a file)\n".
+"              [--verbosity <level>]         (0, 1, 2; default=2)\n".
+"              [--dry-run]                   (print what would be done)\n");
+  return;
+}
diff --git a/png/macinstaller_background.png b/png/macinstaller_background.png
new file mode 100644
index 0000000..cf3435c
Binary files /dev/null and b/png/macinstaller_background.png differ
diff --git a/svg/macinstaller_background.svg b/svg/macinstaller_background.svg
new file mode 100644
index 0000000..989ce3e
--- /dev/null
+++ b/svg/macinstaller_background.svg
@@ -0,0 +1,630 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="700"
+   height="498.16937"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.48.1 r9760"
+   sodipodi:docname="macinstaller_background.svg"
+   inkscape:export-filename="/Users/clemens/Development/x2goclient-4.0.0.1/png/macinstaller_background.png"
+   inkscape:export-xdpi="89.790001"
+   inkscape:export-ydpi="89.790001">
+  <defs
+     id="defs4">
+    <marker
+       inkscape:stockid="Arrow2Lend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Lend"
+       style="overflow:visible">
+      <path
+         id="path5378"
+         style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow1Lend"
+       style="overflow:visible">
+      <path
+         id="path5360"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+         transform="matrix(-0.8,0,0,-0.8,-10,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <linearGradient
+       gradientUnits="userSpaceOnUse"
+       y2="120.54888"
+       x2="133.85397"
+       y1="-49.590809"
+       x1="278.59366"
+       id="linearGradient2808"
+       xlink:href="#linearGradient2802"
+       inkscape:collect="always" />
+    <metadata
+       id="CorelCorpID_0Corel-Layer" />
+    <linearGradient
+       y2="135.464"
+       x2="207.00999"
+       y1="135.464"
+       x1="202.494"
+       gradientUnits="userSpaceOnUse"
+       id="id0">
+      <stop
+         id="stop9"
+         style="stop-color:black"
+         offset="0" />
+      <stop
+         id="stop11"
+         style="stop-color:#6E707F"
+         offset="1" />
+    </linearGradient>
+    <style
+       id="style6"
+       type="text/css">
+   
+    .fil1 {fill:#6699FF}
+    .fil0 {fill:white}
+    .fil2 {fill:#6E707F}
+    .fil4 {fill:white}
+    .fil3 {fill:url(#id0)}
+   
+  </style>
+    <linearGradient
+       id="linearGradient2844">
+      <stop
+         id="stop2846"
+         offset="0"
+         style="stop-color:#deeaed;stop-opacity:1;" />
+      <stop
+         id="stop2848"
+         offset="1"
+         style="stop-color:white;stop-opacity:1;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2852">
+      <stop
+         id="stop2854"
+         offset="0"
+         style="stop-color:white;stop-opacity:1;" />
+      <stop
+         id="stop2856"
+         offset="1"
+         style="stop-color:#69f;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2802"
+       inkscape:collect="always">
+      <stop
+         id="stop2804"
+         offset="0"
+         style="stop-color:white;stop-opacity:1;" />
+      <stop
+         id="stop2806"
+         offset="1"
+         style="stop-color:white;stop-opacity:0;" />
+    </linearGradient>
+    <inkscape:perspective
+       id="perspective28"
+       inkscape:persp3d-origin="180.52499 : 90.333333 : 1"
+       inkscape:vp_z="361.04999 : 135.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 135.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       id="linearGradient2855">
+      <stop
+         id="stop2857"
+         offset="0"
+         style="stop-color:#ffffff;stop-opacity:1;" />
+      <stop
+         id="stop2859"
+         offset="1"
+         style="stop-color:#246ed8;stop-opacity:1;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2863">
+      <stop
+         id="stop2865"
+         offset="0"
+         style="stop-color:#ffffff;stop-opacity:1;" />
+      <stop
+         id="stop2867"
+         offset="1"
+         style="stop-color:#246ed8;stop-opacity:1;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2877">
+      <stop
+         id="stop2879"
+         offset="0"
+         style="stop-color:#ffffff;stop-opacity:1;" />
+      <stop
+         id="stop2881"
+         offset="1"
+         style="stop-color:#246ed8;stop-opacity:1;" />
+    </linearGradient>
+    <pattern
+       inkscape:collect="always"
+       xlink:href="#Wavywhite"
+       id="pattern4837"
+       patternTransform="matrix(1.0895522,0,0,1.0923077,-3.8512144,-24.413743)" />
+    <pattern
+       inkscape:stockid="Wavy white"
+       id="Wavywhite"
+       height="5.1805778"
+       width="30.066020"
+       patternUnits="userSpaceOnUse"
+       inkscape:collect="always">
+      <path
+         id="path4539"
+         d="M 7.597,0.061 C 5.079,-0.187 2.656,0.302 -0.01,1.788 L -0.01,3.061 C 2.773,1.431 5.173,1.052 7.472,1.280 C 9.770,1.508 11.969,2.361 14.253,3.218 C 18.820,4.931 23.804,6.676 30.066,3.061 L 30.062,1.788 C 23.622,5.497 19.246,3.770 14.691,2.061 C 12.413,1.207 10.115,0.311 7.597,0.061 z "
+         style="fill:white;stroke:none;" />
+    </pattern>
+    <linearGradient
+       id="linearGradient3333">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.41880342;"
+         offset="0"
+         id="stop3335" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.60683763;"
+         offset="1"
+         id="stop3337" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient3235">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop3237" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop3239" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient3177">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop3179" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop3181" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 135.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="361.04999 : 135.5 : 1"
+       inkscape:persp3d-origin="180.52499 : 90.333333 : 1"
+       id="perspective2592" />
+    <linearGradient
+       id="linearGradient2600">
+      <stop
+         style="stop-color:white;stop-opacity:1;"
+         offset="0"
+         id="stop2602" />
+      <stop
+         style="stop-color:#69f;stop-opacity:0;"
+         offset="1"
+         id="stop2604" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2606">
+      <stop
+         style="stop-color:#deeaed;stop-opacity:1;"
+         offset="0"
+         id="stop2608" />
+      <stop
+         style="stop-color:white;stop-opacity:1;"
+         offset="1"
+         id="stop2610" />
+    </linearGradient>
+    <style
+       type="text/css"
+       id="style2618">
+   
+    .fil1 {fill:#6699FF}
+    .fil0 {fill:white}
+    .fil2 {fill:#6E707F}
+    .fil4 {fill:white}
+    .fil3 {fill:url(#id0)}
+   
+  </style>
+    <linearGradient
+       id="linearGradient2620"
+       gradientUnits="userSpaceOnUse"
+       x1="202.494"
+       y1="135.464"
+       x2="207.00999"
+       y2="135.464">
+      <stop
+         offset="0"
+         style="stop-color:black"
+         id="stop2622" />
+      <stop
+         offset="1"
+         style="stop-color:#6E707F"
+         id="stop2624" />
+    </linearGradient>
+    <metadata
+       id="metadata2626" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient1948-5"
+       id="linearGradient2628"
+       x1="107.24445"
+       y1="268.11078"
+       x2="107.64762"
+       y2="207.717"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2802-8"
+       id="linearGradient2630"
+       x1="278.59366"
+       y1="-49.590809"
+       x2="133.85397"
+       y2="120.54888"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.0000171,0,0,1.0000148,0,-0.00400005)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3177"
+       id="linearGradient3183"
+       x1="0"
+       y1="135.96677"
+       x2="65.034927"
+       y2="135.96677"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,1.0470449,0,-6.8968197)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3235"
+       id="linearGradient3241"
+       x1="50.316132"
+       y1="121.91985"
+       x2="96.761787"
+       y2="121.91985"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(2.9166667,0,0,1,-146.75538,31.608847)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3333"
+       id="linearGradient3339"
+       x1="18.062202"
+       y1="-45.155499"
+       x2="162.5598"
+       y2="144.4976"
+       gradientUnits="userSpaceOnUse" />
+    <inkscape:perspective
+       id="perspective2513"
+       inkscape:persp3d-origin="46.062992 : 30.708661 : 1"
+       inkscape:vp_z="92.125984 : 46.062992 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 46.062992 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <metadata
+       id="CorelCorpID_0Corel-Layer-7" />
+    <linearGradient
+       y2="135.464"
+       x2="207.00999"
+       y1="135.464"
+       x1="202.494"
+       gradientUnits="userSpaceOnUse"
+       id="id0-8">
+      <stop
+         id="stop9-2"
+         style="stop-color:black"
+         offset="0" />
+      <stop
+         id="stop11-0"
+         style="stop-color:#6E707F"
+         offset="1" />
+    </linearGradient>
+    <style
+       id="style6-9"
+       type="text/css">
+   
+    .fil1 {fill:#6699FF}
+    .fil0 {fill:white}
+    .fil2 {fill:#6E707F}
+    .fil4 {fill:white}
+    .fil3 {fill:url(#id0)}
+   
+  </style>
+    <linearGradient
+       id="linearGradient1948-5"
+       inkscape:collect="always">
+      <stop
+         id="stop1950-8"
+         offset="0"
+         style="stop-color:#69f;stop-opacity:1;" />
+      <stop
+         id="stop1952-2"
+         offset="1"
+         style="stop-color:#69f;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2844-1">
+      <stop
+         id="stop2846-5"
+         offset="0"
+         style="stop-color:#deeaed;stop-opacity:1;" />
+      <stop
+         id="stop2848-5"
+         offset="1"
+         style="stop-color:white;stop-opacity:1;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2852-4">
+      <stop
+         id="stop2854-4"
+         offset="0"
+         style="stop-color:white;stop-opacity:1;" />
+      <stop
+         id="stop2856-9"
+         offset="1"
+         style="stop-color:#69f;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2802-8"
+       inkscape:collect="always">
+      <stop
+         id="stop2804-7"
+         offset="0"
+         style="stop-color:white;stop-opacity:1;" />
+      <stop
+         id="stop2806-7"
+         offset="1"
+         style="stop-color:white;stop-opacity:0;" />
+    </linearGradient>
+    <inkscape:perspective
+       id="perspective28-7"
+       inkscape:persp3d-origin="180.52499 : 90.333333 : 1"
+       inkscape:vp_z="361.04999 : 135.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 135.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3333"
+       id="radialGradient3152"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1,0,0,0.26159009,0,114.82274)"
+       spreadMethod="pad"
+       cx="218.5"
+       cy="155.5"
+       fx="218.5"
+       fy="155.5"
+       r="170.25" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="4"
+     inkscape:cx="136.66909"
+     inkscape:cy="434.40442"
+     inkscape:document-units="px"
+     inkscape:current-layer="g3095"
+     showgrid="false"
+     inkscape:window-width="1440"
+     inkscape:window-height="852"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(202.23253,-561.2639)" />
+  <g
+     inkscape:groupmode="layer"
+     id="layer2"
+     inkscape:label="Overlay"
+     transform="translate(202.23253,180.09827)">
+    <g
+       id="g3123"
+       transform="matrix(1.6018307,0,0,1.6018307,-202.23253,-180.09829)">
+      <g
+         id="g4178"
+         transform="translate(0,-741.36217)">
+        <rect
+           class="fil0"
+           x="0"
+           y="741.36218"
+           width="437"
+           height="311"
+           id="rect15"
+           style="fill:#246ed8;fill-opacity:1;fill-rule:evenodd" />
+        <path
+           inkscape:connector-curvature="0"
+           id="_209413168"
+           d="m 437,784.19187 -51.09387,15.50719 2.67726,4.9352 c 6.60756,-2.00336 11.66542,-2.6798 15.19269,-2.00795 3.25174,0.58094 5.90188,2.5612 7.67698,5.85451 1.04846,1.94516 1.89718,6.04621 2.19343,12.0477 l -7.03186,64.98019 -59.80306,-44.70714 c -4.42729,-3.18215 -7.53098,-6.41256 -9.22528,-9.55591 -3.46793,-6.43388 0.85501,-11.40513 12.70895,-14.99915 l -2.67726,-4.93521 -76.93112,23.32126 2.64501,4.93521 c 7.77402,-2.35704 14.59537,-2.68786 20.48271,-0.99188 5.6952,1.75585 13.23574,6.08392 22.61162,12.9912 l 87.12409,65.17372 -9.03175,91.88189 c -0.61305,7.6728 -2.35469,13.2366 -4.87069,16.9587 -2.51526,3.7235 -6.46083,6.489 -11.70901,8.0802 l 2.67726,4.9352 54.22273,-16.4265 -2.67726,-4.9352 c -11.65923,3.535 -19.07883,2.2888 -22.38583,-3.8465 -1.69355,-3.142 -2.0307,-7.9169 -1.16123,-14.27342 l 7.67699,-73.01199 20.7085,15.26526 0,-33.38521 -17.99898,-13.32989 7.7415,-71.63303 c 1.48071,-14.02881 3.14397,-23.09161 5.77386,-27.02267 1.05552,-1.57859 2.55398,-3.01
 644 4.48
 362,-4.35459 l 0,-7.45119 z"
+           style="opacity:0.27156552;fill:#ffffff;fill-rule:evenodd" />
+        <polygon
+           transform="matrix(18.028797,-5.4662042,7.48364,13.884058,-4968.8161,-1621.9047)"
+           style="opacity:0.27156552;fill:#ffffff;fill-rule:evenodd"
+           points="179.314,250.52 185.945,250.339 185.945,250.702 179.314,250.52 "
+           class="fil4"
+           id="_209583128" />
+        <polygon
+           transform="matrix(18.028797,-5.4662042,7.48364,13.884058,-4968.8161,-1621.9047)"
+           style="opacity:0.27156552;fill:#ffffff;fill-rule:evenodd"
+           points="186.914,251.524 186.953,251.532 186.988,251.541 187.02,251.55 187.048,251.56 187.074,251.571 187.097,251.581 187.118,251.592 187.137,251.603 187.154,251.615 187.169,251.627 187.178,251.635 187.184,251.64 179.314,251.425 179.314,251.425 185.945,251.243 185.945,251.492 186.724,251.505 186.777,251.507 186.827,251.512 186.872,251.517 "
+           class="fil4"
+           id="_209423624" />
+        <polygon
+           transform="matrix(18.028797,-5.4662042,7.48364,13.884058,-4968.8161,-1621.9047)"
+           style="opacity:0.27156552;fill:#ffffff;fill-rule:evenodd"
+           points="187.498,252.105 187.529,252.163 187.572,252.245 187.616,252.333 187.661,252.426 187.707,252.524 187.723,252.56 179.314,252.329 179.314,252.329 "
+           class="fil4"
+           id="_208944912" />
+        <polygon
+           transform="matrix(18.028797,-5.4662042,7.48364,13.884058,-4968.8161,-1621.9047)"
+           style="opacity:0.27156552;fill:#ffffff;fill-rule:evenodd"
+           points="179.314,253.234 187.916,252.998 188.124,253.475 179.314,253.234 "
+           class="fil4"
+           id="_209380624" />
+        <polygon
+           transform="matrix(18.028797,-5.4662042,7.48364,13.884058,-4968.8161,-1621.9047)"
+           style="opacity:0.27156552;fill:#ffffff;fill-rule:evenodd"
+           points="179.314,254.138 188.306,253.892 188.525,254.391 179.314,254.138 "
+           class="fil4"
+           id="_209438256" />
+        <polygon
+           transform="matrix(18.028797,-5.4662042,7.48364,13.884058,-4968.8161,-1621.9047)"
+           style="opacity:0.27156552;fill:#ffffff;fill-rule:evenodd"
+           points="179.314,255.043 188.697,254.786 188.925,255.306 179.314,255.043 "
+           class="fil4"
+           id="_209597128" />
+        <polygon
+           transform="matrix(18.028797,-5.4662042,7.48364,13.884058,-4968.8161,-1621.9047)"
+           style="opacity:0.27156552;fill:#ffffff;fill-rule:evenodd"
+           points="179.314,255.947 189.088,255.679 189.325,256.221 179.314,255.947 "
+           class="fil4"
+           id="_209596936" />
+        <polygon
+           transform="matrix(18.028797,-5.4662042,7.48364,13.884058,-4968.8161,-1621.9047)"
+           style="opacity:0.27156552;fill:#ffffff;fill-rule:evenodd"
+           points="179.314,256.851 189.479,256.573 189.725,257.137 179.314,256.851 "
+           class="fil4"
+           id="_209588560" />
+        <polygon
+           transform="matrix(18.028797,-5.4662042,7.48364,13.884058,-4968.8161,-1621.9047)"
+           style="opacity:0.27156552;fill:#ffffff;fill-rule:evenodd"
+           points="190.058,258.05 179.314,257.756 179.314,257.756 189.87,257.467 190.094,257.979 "
+           class="fil4"
+           id="_209560832" />
+        <polygon
+           transform="matrix(18.028797,-5.4662042,7.48364,13.884058,-4968.8161,-1621.9047)"
+           style="opacity:0.27156552;fill:#ffffff;fill-rule:evenodd"
+           points="179.314,258.66 189.896,258.37 189.607,258.942 179.314,258.66 "
+           class="fil4"
+           id="_209558944" />
+        <polygon
+           transform="matrix(18.028797,-5.4662042,7.48364,13.884058,-4968.8161,-1621.9047)"
+           style="opacity:0.27156552;fill:#ffffff;fill-rule:evenodd"
+           points="179.314,259.565 189.432,259.288 189.155,259.834 179.314,259.565 "
+           class="fil4"
+           id="_209559488" />
+        <polygon
+           transform="matrix(18.028797,-5.4662042,7.48364,13.884058,-4968.8161,-1621.9047)"
+           style="opacity:0.27156552;fill:#ffffff;fill-rule:evenodd"
+           points="179.314,260.469 188.968,260.205 188.704,260.727 179.314,260.469 "
+           class="fil4"
+           id="_209558344" />
+        <polygon
+           transform="matrix(18.028797,-5.4662042,7.48364,13.884058,-4968.8161,-1621.9047)"
+           style="opacity:0.27156552;fill:#ffffff;fill-rule:evenodd"
+           points="179.314,261.374 188.504,261.122 188.253,261.619 179.314,261.374 "
+           class="fil4"
+           id="_209557016" />
+        <path
+           inkscape:connector-curvature="0"
+           id="_209557776"
+           d="m 365.29439,1038.3307 -42.80402,14.0315 13.25731,0 32.25624,-8.9995 -2.70953,-5.032 z"
+           style="opacity:0.27156552;fill:#ffffff;fill-rule:evenodd" />
+        <path
+           inkscape:connector-curvature="0"
+           id="_209553608"
+           d="m 377.68079,1019.485 -100.25238,32.8772 6.51576,0 77.28594,-21.5553 -1.61282,-3.024 13.35409,-4.3062 0.38707,-0.1451 0.38708,-0.1452 0.32256,-0.1452 0.32256,-0.1693 0.29031,-0.1693 0.2903,-0.1694 0.25805,-0.1693 0.25805,-0.1936 0.25805,-0.1935 0.2258,-0.2177 0.25805,-0.2178 0.19353,-0.2419 0.2258,-0.2419 0.22579,-0.2661 0.19354,-0.2903 0.22579,-0.3387 0.22579,-0.4113 0.16129,-0.2661 z"
+           style="opacity:0.27156552;fill:#ffffff;fill-rule:evenodd" />
+        <polygon
+           transform="matrix(18.028797,-5.4662042,7.48364,13.884058,-4968.8161,-1621.9047)"
+           style="opacity:0.27156552;fill:#ffffff;fill-rule:evenodd"
+           points="179.314,263.183 187.576,262.956 187.455,263.196 187.414,263.277 187.378,263.348 187.348,263.403 179.314,263.183 "
+           class="fil4"
+           id="_209553416" />
+        <polygon
+           transform="matrix(18.028797,-5.4662042,7.48364,13.884058,-4968.8161,-1621.9047)"
+           style="opacity:0.27156552;fill:#ffffff;fill-rule:evenodd"
+           points="179.314,262.278 188.04,262.039 187.801,262.511 179.314,262.278 "
+           class="fil4"
+           id="_209552080" />
+        <path
+           inkscape:connector-curvature="0"
+           id="_208969032"
+           d="m 434.1292,749.04063 c -3.01919,0.0519 -6.08889,0.5109 -9.03175,1.40315 l -298.91852,90.64809 c -13.45309,4.07889 -19.90606,15.88823 -14.32177,26.24852 l 99.73628,185.02181 6.32222,0 -99.51049,-184.58636 c -4.96389,-9.2093 0.78272,-19.69552 12.74122,-23.32125 l 293.49947,-89.00303 c 4.03635,-1.22379 8.30229,-1.49837 12.35414,-0.99188 l 0,-5.34647 c -0.96071,-0.0644 -1.90069,-0.0892 -2.8708,-0.0726 z"
+           style="opacity:0.27156552;fill:#ffffff;fill-rule:evenodd" />
+        <path
+           inkscape:connector-curvature="0"
+           style="opacity:0.27156552;fill:#ffffff;fill-rule:evenodd"
+           d="m 365.29439,1038.3307 -42.80402,14.0315 13.25731,0 32.25624,-8.9995 -2.70953,-5.032 z"
+           id="path3356" />
+      </g>
+      <g
+         id="g3095">
+        <text
+           xml:space="preserve"
+           style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.28717142;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.80357139000000000;stroke-dasharray:none;font-family:Sans"
+           x="23.857143"
+           y="51.142857"
+           id="text4974"
+           sodipodi:linespacing="125%"><tspan
+             sodipodi:role="line"
+             id="tspan4976"
+             x="23.857143"
+             y="51.142857"
+             style="font-size:24.97142799999999951px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.28717142;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.80357139000000000;stroke-dasharray:none;font-family:Tahoma;-inkscape-font-specification:Tahoma">x2goclient</tspan></text>
+        <rect
+           style="fill:url(#radialGradient3152);fill-opacity:1;stroke:#000000;stroke-width:0.5;stroke-miterlimit:4;stroke-opacity:0.80357139;stroke-dasharray:none"
+           id="rect4982"
+           width="340"
+           height="88.571426"
+           x="48.5"
+           y="111.21429"
+           rx="5"
+           ry="5" />
+        <path
+           style="fill:#ffffff;fill-opacity:0.78431373999999998;stroke:#000000;stroke-width:0.68171998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+           d="m 225.32812,138.37425 0,10.05263 -31.75,0 0,6.91767 0,0.3109 0,6.91767 31.75,0 0,10.05263 L 243.42187,155.5 z"
+           id="path6168"
+           inkscape:connector-curvature="0"
+           sodipodi:nodetypes="cccccccccc" />
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/version.h b/version.h
index b44511f..f858ac4 100644
--- a/version.h
+++ b/version.h
@@ -15,5 +15,5 @@
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
 ***************************************************************************/
 
-#define VERSION "4.0.0.3"
+#define VERSION "4.0.0.4"
 
diff --git a/x2goclient.pro b/x2goclient.pro
index 3d13687..5d2206d 100755
--- a/x2goclient.pro
+++ b/x2goclient.pro
@@ -159,7 +159,6 @@ x2go_linux_static {
 macx {
 	message(building $$TARGET with ldap and cups)
 	LIBS += -framework LDAP -lcups -lcrypto -lssl -lz
-	CONFIG += x86 x86_64 ppc
 }
 win32-* {
 	message(building $$TARGET for windows without ldap and cups)
@@ -169,8 +168,6 @@ win32-* {
 QT += svg network
 ICON = icons/x2go-mac.icns
 QMAKE_INFO_PLIST = Info.plist
-QMAKE_MAC_SDK = /Developer/SDKs/MacOSX10.5.sdk
-QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.5
 
 plugin {
 	DEFINES += CFGPLUGIN
diff --git a/x2goplugin.rc b/x2goplugin.rc
index 70eccaf..d49572e 100644
--- a/x2goplugin.rc
+++ b/x2goplugin.rc
@@ -1,8 +1,8 @@
 1 TYPELIB "x2goplugin.rc"
 
 1 VERSIONINFO
- FILEVERSION 4,0,0,3
- PRODUCTVERSION 4,0,0,3
+ FILEVERSION 4,0,0,4
+ PRODUCTVERSION 4,0,0,4
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -21,13 +21,13 @@ BEGIN
             VALUE "FileDescription", "Allows you to start X2Go session in a webbrowser\0"
 	    VALUE "FileExtents", "x2go\0"
 	    VALUE "FileOpenName", "Configuration File for X2Go Session (*.x2go)\0"
-            VALUE "FileVersion", "4, 0, 0 ,3\0"
+            VALUE "FileVersion", "4, 0, 0 ,4\0"
             VALUE "InternalName", "x2goplugin\0"
-            VALUE "LegalCopyright", "Copyright © 2010-2012 Obviously Nice\0"
+            VALUE "LegalCopyright", "Copyright © 2010-2013 Obviously Nice\0"
 	    VALUE "MIMEType", "application/x2go\0"
             VALUE "OriginalFilename", "npx2goplugin.dll\0"
-            VALUE "ProductName", "X2GoClient Plug-in 4.0.0.3\0"
-            VALUE "ProductVersion", "4, 0, 0, 3\0"
+            VALUE "ProductName", "X2GoClient Plug-in 4.0.0.4\0"
+            VALUE "ProductVersion", "4, 0, 0, 4\0"
         END
     END
     BLOCK "VarFileInfo"


hooks/post-receive
-- 
x2goclient.git (X2Go Client)

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "x2goclient.git" (X2Go Client).




More information about the x2go-commits mailing list