summaryrefslogtreecommitdiffstats
path: root/zenmap/install_scripts/macosx
diff options
context:
space:
mode:
Diffstat (limited to 'zenmap/install_scripts/macosx')
-rw-r--r--zenmap/install_scripts/macosx/Info.plist34
-rw-r--r--zenmap/install_scripts/macosx/README26
-rw-r--r--zenmap/install_scripts/macosx/gtkrc3
-rwxr-xr-xzenmap/install_scripts/macosx/launcher.sh63
-rwxr-xr-xzenmap/install_scripts/macosx/make-bundle.sh106
-rw-r--r--zenmap/install_scripts/macosx/zenmap.bundle144
-rw-r--r--zenmap/install_scripts/macosx/zenmap.icnsbin0 -> 145639 bytes
-rw-r--r--zenmap/install_scripts/macosx/zenmap_auth.m49
-rw-r--r--zenmap/install_scripts/macosx/zenmap_launcher.py43
9 files changed, 468 insertions, 0 deletions
diff --git a/zenmap/install_scripts/macosx/Info.plist b/zenmap/install_scripts/macosx/Info.plist
new file mode 100644
index 0000000..2f953cd
--- /dev/null
+++ b/zenmap/install_scripts/macosx/Info.plist
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleIdentifier</key>
+ <string>org.insecure.Zenmap</string>
+ <key>CFBundleName</key>
+ <string>Zenmap</string>
+ <key>NSHumanReadableCopyright</key>
+ <string>${APP_COPYRIGHT}</string>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>Zenmap</string>
+ <key>CFBundleGetInfoString</key>
+ <string>${VERSION}, ${APP_COPYRIGHT} ${APP_WEB_SITE}</string>
+ <key>CFBundleIconFile</key>
+ <string>zenmap.icns</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>${VERSION}</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>${VERSION}</string>
+ <key>LSMinimumSystemVersion</key>
+ <string>10.9</string>
+<key>GtkOSXLaunchScriptFile</key>
+<string>zenmap_launcher.py</string>
+</dict>
+</plist>
diff --git a/zenmap/install_scripts/macosx/README b/zenmap/install_scripts/macosx/README
new file mode 100644
index 0000000..f0695d2
--- /dev/null
+++ b/zenmap/install_scripts/macosx/README
@@ -0,0 +1,26 @@
+This is a description of the files in this directory, all of which have
+to do with packaging on Mac OS X. They are useful only for those wanting
+to build binary distributions of Zenmap for Mac OS X.
+
+== Info.plist
+A properties list file template that is filled out by make-bundle.sh
+
+== make-bundle.sh
+This script builds a .app bundle. It must be run from the root of the
+Zenmap source tree. The finished bundle is put in dist/Zenmap.app.
+
+== zenmap.icns
+The icon file for the bundle. It was created using the Icon Composer
+utility (open -a "Icon Composer").
+
+== zenmap_auth.c
+This is a simple wrapper program that attempts to run launcher.sh
+with privileges.
+
+== launcher.sh
+A launcher script that configures the environment for Zenmap, Python, and GTK
+before launching the main Zenmap script file.
+
+== zenmap.bundle
+An XML config file for gtk-mac-bundler which specifies files and metadata for
+the application bundle. https://wiki.gnome.org/Projects/GTK%2B/OSX/Building
diff --git a/zenmap/install_scripts/macosx/gtkrc b/zenmap/install_scripts/macosx/gtkrc
new file mode 100644
index 0000000..b74f0c9
--- /dev/null
+++ b/zenmap/install_scripts/macosx/gtkrc
@@ -0,0 +1,3 @@
+# Use Lucida Grande, the face used by other OS X applications.
+
+gtk-font-name="Lucida Grande"
diff --git a/zenmap/install_scripts/macosx/launcher.sh b/zenmap/install_scripts/macosx/launcher.sh
new file mode 100755
index 0000000..881c9f6
--- /dev/null
+++ b/zenmap/install_scripts/macosx/launcher.sh
@@ -0,0 +1,63 @@
+#!/bin/sh
+
+name=`basename "$0"`
+tmp="$0"
+tmp=`dirname "$tmp"`
+tmp=`dirname "$tmp"`
+bundle=`dirname "$tmp"`
+bundle_contents="$bundle"/Contents
+bundle_res="$bundle_contents"/Resources
+bundle_lib="$bundle_res"/lib
+bundle_bin="$bundle_res"/bin
+bundle_data="$bundle_res"/share
+bundle_etc="$bundle_res"/etc
+
+export DYLD_LIBRARY_PATH="$bundle_lib"
+export XDG_CONFIG_DIRS="$bundle_etc"/xdg
+export XDG_DATA_DIRS="$bundle_data"
+export GTK_DATA_PREFIX="$bundle_res"
+export GTK_EXE_PREFIX="$bundle_res"
+export GTK_PATH="$bundle_res"
+
+export GTK2_RC_FILES="$bundle_etc/gtk-2.0/gtkrc"
+export GTK_IM_MODULE_FILE="$bundle_etc/gtk-2.0/gtk.immodules"
+export GDK_PIXBUF_MODULE_FILE="$bundle_lib/gdk-pixbuf-2.0/2.10.0/loaders.cache"
+export PANGO_LIBDIR="$bundle_lib"
+export PANGO_SYSCONFDIR="$bundle_etc"
+
+#Set $PYTHON to point inside the bundle
+export PYTHON="$bundle_contents/MacOS/python"
+#Add the bundle's python modules
+PYTHONHOME="$bundle_res"
+export PYTHONHOME
+PYTHONPATH="$bundle_res/lib/zenmap"
+export PYTHONPATH
+
+# We need a UTF-8 locale.
+if [ -z ${lang+x} ]; then
+ # lang is unset, we are thus using the Apple locale because it's set to the currently used language,
+ # which is already in the good format
+ lang=`defaults read /Library/Preferences/.GlobalPreferences AppleLocale 2>/dev/null`
+ export LANG="`echo $lang`.UTF-8"
+fi
+
+if test -f "$bundle_lib/charset.alias"; then
+ export CHARSETALIASDIR="$bundle_lib"
+fi
+
+# Extra arguments can be added in environment.sh.
+EXTRA_ARGS=
+if test -f "$bundle_res/environment.sh"; then
+ source "$bundle_res/environment.sh"
+fi
+
+# Strip out the argument added by the OS.
+if /bin/expr "x$1" : "x-psn_.*" > /dev/null; then
+ shift 1
+fi
+
+# Make the real UID equal the effective UID. They are unequal when running
+# with privileges under AuthorizationExecuteWithPrivileges. GTK+ refuses to
+# run if they are different
+# Note that we're calling $PYTHON here to override the version in zenmap's shebang.
+$EXEC $PYTHON -c $'import os\nif os.getuid()!=os.geteuid():os.setuid(os.geteuid())\n'"os.execl(\"$PYTHON\",\"$PYTHON\",\"$bundle_bin/zenmap\")"
diff --git a/zenmap/install_scripts/macosx/make-bundle.sh b/zenmap/install_scripts/macosx/make-bundle.sh
new file mode 100755
index 0000000..7f37d05
--- /dev/null
+++ b/zenmap/install_scripts/macosx/make-bundle.sh
@@ -0,0 +1,106 @@
+#!/bin/bash -e
+set -x
+
+test "x$UNDER_JHBUILD" = "x" && exit 1
+
+# make-bundle.sh
+APP_NAME=Zenmap
+ZENMAP_DIST_DIR=$PWD/dist
+ZENMAP_BUILD_DIR=$PWD/build
+
+export ZENMAP_DIST_DIR
+export ZENMAP_BUILD_DIR
+
+BASE=$ZENMAP_DIST_DIR/$APP_NAME.app/Contents
+SCRIPT_DIR=`dirname "$0"`
+
+echo "Running $0."
+
+echo "Removing old build."
+rm -rf "$ZENMAP_DIST_DIR" "$ZENMAP_BUILD_DIR"
+
+echo "Building python-launcher"
+$CC $CPPFLAGS $CFLAGS $LDFLAGS -L$PREFIX/lib `python3-config --cflags --ldflags --embed` \
+ -o $PREFIX/bin/zenmap-launcher \
+ ~/gtk-mac-bundler/examples/python-launcher.c
+
+echo "Installing Zenmap to local system"
+python3 setup.py install vanilla --prefix "$PREFIX"
+
+echo "Generating dependencies"
+# Have to run this with ~/gtk/inst/python3 or deps have wrong paths
+export XDG_DATA_DIRS=$PREFIX/share
+export DYLD_LIBRARY_PATH=$PREFIX/lib
+export LD_LIBRARY_PATH=$PREFIX/lib
+export GTK_DATA_PREFIX=$PREFIX
+export GTK_EXE_PREFIX=$PREFIX
+export GTK_PATH=$PREFIX
+export PANGO_RC_FILE=$PREFIX/etc/pango/pangorc
+export PANGO_SYSCONFDIR=$PREFIX/etc
+export PANGO_LIBDIR=$PREFIX/lib
+export GDK_PIXBUF_MODULE_FILE=$PREFIX/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache
+export GTK_IM_MODULE_FILE=$PREFIX/etc/gtk-3.0/gtk.immodules
+export GI_TYPELIB_PATH=$PREFIX/lib/girepository-1.0
+
+python3 "$SCRIPT_DIR/../utils/get_deps.py" "$SCRIPT_DIR/pyreqs.xml"
+# gtk-mac-bundler (xml.dom.minidom) doesn't expand external entities
+xmllint --format --noent "$SCRIPT_DIR/zenmap.bundle" > "$SCRIPT_DIR/tmp.bundle"
+
+echo "Building bundle"
+gtk-mac-bundler "$SCRIPT_DIR/tmp.bundle"
+
+echo "Removing unneeded items"
+# GIR files not needed, only typelib
+rm -rf $BASE/Resources/share/gir-1.0/
+
+echo "Creating caches"
+pushd "$BASE/Resources"
+export GDK_PIXBUF_MODULEDIR=$(ls - lib/gdk-pixbuf-2.0/2.*/loaders)
+gdk-pixbuf-query-loaders > "$GDK_PIXBUF_MODULEDIR".cache
+gtk-update-icon-cache share/icons/hicolor
+popd
+
+# echo "Compiling Python to bytecode"
+PYTHONLIB=$(ls -d $BASE/Resources/lib/python3.*)
+# Remove compiled bytecode, recompile in legacy locations, allowing for removal of source.
+# See PEP-3147
+find "$PYTHONLIB" -depth \( -name 'zenmap*' -o -name 'radialnet' \) -prune -o -name __pycache__ -exec rm -rf '{}' \;
+python -m compileall -b -x 'zenmapGUI|zenmapCore|radialnet' "$PYTHONLIB"
+
+# Remove source if compiled is available, except for Zenmap itself:
+find "$PYTHONLIB" \( -name 'zenmap*' -o -name 'radialnet' \) -prune -o \( -name '*.pyc' -print \) | while read pyc; do
+rm -f "${pyc%.pyc}.py"
+done
+
+# Now compile Zenmap using default (not legacy) location.
+# If we had used legacy location, python.exe tries to write out the PEP-3147
+# location anyway when source is available.
+python -m compileall "$PYTHONLIB"/site-packages #|| true
+echo "Stripping unoptimized Python libraries"
+
+echo "Building using distutils"
+python3 setup.py build --executable "/usr/bin/env python3"
+python3 setup.py install vanilla --prefix "$BASE/Resources"
+
+echo "Renaming main Zenmap executable."
+mv $BASE/MacOS/$APP_NAME $BASE/MacOS/zenmap.bin
+# This is a dummy script, so we'll clean it up:
+#rm $BASE/MacOS/$APP_NAME-bin
+
+echo "Compiling and installing authorization wrapper."
+echo $CC $CPPFLAGS $OBJCFLAGS $LDFLAGS -v "$SCRIPT_DIR/zenmap_auth.m" -lobjc -framework Foundation -o "$BASE/MacOS/$APP_NAME"
+$CC $CPPFLAGS $OBJCFLAGS $LDFLAGS -v "$SCRIPT_DIR/zenmap_auth.m" -lobjc -framework Foundation -o "$BASE/MacOS/$APP_NAME"
+
+echo "Filling out Info.plist"
+python3 - "$SCRIPT_DIR/Info.plist" >"$BASE/Info.plist" <<'EOF'
+import sys
+from string import Template
+from zenmapCore.Version import *
+from zenmapCore.Name import *
+with open(sys.argv[1],"r") as f:
+ sys.stdout.write(Template(f.read()).substitute(
+ VERSION=VERSION,
+ APP_WEB_SITE=APP_WEB_SITE,
+ APP_COPYRIGHT=APP_COPYRIGHT
+ ))
+EOF
diff --git a/zenmap/install_scripts/macosx/zenmap.bundle b/zenmap/install_scripts/macosx/zenmap.bundle
new file mode 100644
index 0000000..dff4c31
--- /dev/null
+++ b/zenmap/install_scripts/macosx/zenmap.bundle
@@ -0,0 +1,144 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE app-bundle [
+<!ENTITY PYVER "3.10">
+<!ENTITY pyreqs SYSTEM "pyreqs.xml">
+]>
+<app-bundle>
+
+ <meta>
+ <!-- Where to pick up the GTK+ installation, icon themes,
+ etc. Note that "${env:JHBUILD_PREFIX}" is evaluated to the
+ value of the environment variable JHBUILD_PREFIX. You can
+ define additional prefixes and refer to them in paths
+ throughout this file on the form "${prefix:name}". This is
+ useful for installing certain libraries or even the
+ application itself separately. Note that JHBUILD_PREFIX is
+ defined by jhbuild, so it you are not using jhbuild you can
+ either define your own or just hardcode the path here.
+ -->
+ <prefix name="default">${env:JHBUILD_PREFIX}</prefix>
+
+ <!-- The project directory is the default location of the created
+ app. If you leave out the path, the current directory is
+ used. Note the usage of an environment variable here again.
+ -->
+ <destination overwrite="yes">${env:ZENMAP_DIST_DIR}</destination>
+
+ <!-- Comment this out to keep the install names in binaries. -->
+ <run-install-name-tool/>
+
+ <!-- REMOVED: A launcher script is pretty much mandatory here so that we can
+ set $PYTHON to point to the python in the bundle.
+ <launcher-script>${project}/launcher.sh</launcher-script>
+ -->
+
+ <!-- Indicate the active gtk version to use. This is needed only
+ for gtk+-3.0 projects. -->
+ <gtk>gtk+-3.0</gtk>
+ </meta>
+
+ <!-- The special macro "${project}" refers to the directory where
+ this bundle file is located. The application name and bundle
+ identifier are taken from the plist file.
+ -->
+ <plist>${project}/Info.plist</plist>
+
+<!-- See examples/python-launcher.bundle for info on entitlements if needed -->
+<!-- NEW! -->
+ <!-- Build gramps-launcher with:
+ gcc -L$PREFIX/lib `python-config -\-cflags -\-ldflags` \
+ -o $PREFIX/bin/python-launcher \
+ path/to/gtk-mac-bundler/examples/python-launcher.c
+ with the obvious substitution.
+ -->
+ <main-binary>
+ ${prefix}/bin/zenmap-launcher
+ </main-binary>
+
+ <!-- We need to pack our own Python to avoid compatibility problems. -->
+ <binary dest="${bundle}/Contents/MacOS">
+ ${prefix}/bin/python3
+ </binary>
+ <!-- Copy in GTK+ modules. Note the use of the
+ "${pkg:module:variable}" macro, which evaluates to a pkg-config
+ variable in the specified module. Note that any libraries that
+ binaries link to are also copied in automatically.
+ -->
+<!-- PNG is built-in -->
+ <binary>
+ ${prefix}/lib/gdk-pixbuf-2.0/${pkg:gdk-pixbuf-2.0:gdk_pixbuf_binary_version}/loaders/libpixbufloader-gif.so
+ </binary>
+
+<!-- Copy in the quartz input method. The rest aren't used on MacOS. -->
+ <binary>
+ ${prefix}/lib/${gtkdir}/${pkg:${gtk}:gtk_binary_version}/immodules/im-quartz.so
+ </binary>
+
+<!-- And the print backends -->
+ <binary>
+ ${prefix}/lib/${gtkdir}/${pkg:${gtk}:gtk_binary_version}/printbackends/*.so
+ </binary>
+
+ <!-- Python modules other than tnese are grabbed with get_deps.py -->
+ <binary>
+ ${prefix}/lib/python&PYVER;/site-packages/gi/*.so
+ </binary>
+ <binary>
+ ${prefix}/lib/python&PYVER;/site-packages/cairo/*.so
+ </binary>
+
+&pyreqs;
+
+ <binary>
+ ${prefix}/lib/libgtkmacintegration-gtk3.dylib
+ </binary>
+
+ <gir> ${prefix}/share/gir-1.0/Atk-1.0.gir </gir>
+ <gir> ${prefix}/share/gir-1.0/GLib-2.0.gir </gir>
+ <gir> ${prefix}/share/gir-1.0/GModule-2.0.gir </gir>
+ <gir> ${prefix}/share/gir-1.0/GObject-2.0.gir </gir>
+ <gir> ${prefix}/share/gir-1.0/Gdk-3.0.gir </gir>
+ <gir> ${prefix}/share/gir-1.0/GdkPixbuf-2.0.gir </gir>
+ <gir> ${prefix}/share/gir-1.0/Gio-2.0.gir </gir>
+ <gir> ${prefix}/share/gir-1.0/Gtk-3.0.gir </gir>
+ <gir> ${prefix}/share/gir-1.0/HarfBuzz-0.0.gir </gir>
+ <gir> ${prefix}/share/gir-1.0/Pango-1.0.gir </gir>
+ <gir> ${prefix}/share/gir-1.0/PangoCairo-1.0.gir </gir>
+ <gir> ${prefix}/share/gir-1.0/PangoOT-1.0.gir </gir>
+ <gir> ${prefix}/share/gir-1.0/cairo-1.0.gir </gir>
+ <gir> ${prefix}/share/gir-1.0/freetype2-2.0.gir </gir>
+
+ <!-- This python file sets up all of the environment variables
+ needed to run your program. The example contains those
+ necessary for running a basic Gtk program. -->
+ <data dest="${bundle}/Contents/Resources">
+ ${project}/zenmap_launcher.py
+ </data>
+
+ <data>
+ ${prefix}/share/glib-2.0/schemas
+ </data>
+
+
+ <!-- Copy icons. Note that the .icns file is an Apple format which
+ contains up to 4 sizes of icon. You can use
+ /Developer/Applications/Utilities/Icon Composer.app to import
+ artwork and create the file. -->
+ <data dest="${bundle}/Contents/Resources">
+ ${project}/zenmap.icns
+ </data>
+
+ <!-- Icon themes to copy. The "icons" property can be either of
+ "auto", "all", or "none". All or none should be
+ self-explanatory, while auto means that the script will try to
+ figure out which icons are needed. This is done by getting all
+ the strings from all copied binaries, and matching them against
+ icon names. To be safe, you should use "all". "none" is useful
+ if you want just the index.theme file but no icons, mostly
+ needed for the "hicolor" base theme.
+ >
+ <icon-theme icons="none">
+ Tango
+ </icon-theme -->
+
+</app-bundle>
diff --git a/zenmap/install_scripts/macosx/zenmap.icns b/zenmap/install_scripts/macosx/zenmap.icns
new file mode 100644
index 0000000..2ea4e86
--- /dev/null
+++ b/zenmap/install_scripts/macosx/zenmap.icns
Binary files differ
diff --git a/zenmap/install_scripts/macosx/zenmap_auth.m b/zenmap/install_scripts/macosx/zenmap_auth.m
new file mode 100644
index 0000000..b42e568
--- /dev/null
+++ b/zenmap/install_scripts/macosx/zenmap_auth.m
@@ -0,0 +1,49 @@
+//
+// zenmap_auth.m
+// Objective-C
+//
+// This program attempts to run an applescript script which asks for root
+// privileges. If the authorization fails or is canceled, Zenmap is run
+// without privileges using applescript.
+//
+// This program is the first link in the chain:
+// zenmap_auth -> zenmap_wrapper.py -> zenmap.bin
+//
+
+#import <Foundation/Foundation.h>
+#import <libgen.h>
+#define EXECUTABLE_NAME "zenmap.bin"
+
+int main(int argc, const char * argv[]) {
+ @autoreleasepool {
+ NSString *executable_path;
+ NSString *cwd;
+ size_t len_cwd;
+
+ cwd = [[NSBundle mainBundle] bundlePath];
+ len_cwd = [cwd length];
+ executable_path = cwd;
+ executable_path = [NSString stringWithFormat:@"%@/Contents/MacOS/%s", executable_path, EXECUTABLE_NAME];
+ NSLog(@"%@",executable_path);
+
+ NSDictionary *error = [NSDictionary new];
+ NSString *script = [NSString stringWithFormat:@"do shell script \"%@\" with administrator privileges", executable_path];
+NSLog(@"Executing: >>%@<<", script);
+ NSAppleScript *appleScript = [[NSAppleScript alloc] initWithSource:script];
+ if ([appleScript executeAndReturnError:&error]) {
+ NSLog(@"success!");
+ } else {
+ NSLog(@"Failed to execute applescript with admin privileges: %@", error[@"NSAppleScriptErrorMessage"]);
+ NSDictionary *error = [NSDictionary new];
+ NSString *script = [NSString stringWithFormat:@"do shell script \"%@\"", executable_path];
+NSLog(@"Executing: >>%@<<", script);
+ NSAppleScript *appleScript = [[NSAppleScript alloc] initWithSource:script];
+ if ([appleScript executeAndReturnError:&error]) {
+ NSLog(@"success!");
+ } else {
+ NSLog(@"Failed to execute applescript: %@", error[@"NSAppleScriptErrorMessage"]);
+ }
+ }
+ }
+ return 0;
+}
diff --git a/zenmap/install_scripts/macosx/zenmap_launcher.py b/zenmap/install_scripts/macosx/zenmap_launcher.py
new file mode 100644
index 0000000..98aca78
--- /dev/null
+++ b/zenmap/install_scripts/macosx/zenmap_launcher.py
@@ -0,0 +1,43 @@
+from os.path import join, dirname, abspath, normpath
+import sys, os
+import platform
+
+
+bundlepath = sys.argv[0]
+
+bundle_contents = join(bundlepath, 'Contents')
+bundle_res = join(bundle_contents, 'Resources')
+
+bundle_lib = join(bundle_res, 'lib')
+bundle_bin = join(bundle_res, 'bin')
+bundle_data = join(bundle_res, 'share')
+bundle_etc = join(bundle_res, 'etc')
+
+os.environ['XDG_DATA_DIRS'] = bundle_data
+os.environ['DYLD_LIBRARY_PATH'] = bundle_lib
+os.environ['LD_LIBRARY_PATH'] = bundle_lib
+os.environ['GTK_DATA_PREFIX'] = bundle_res
+os.environ['GTK_EXE_PREFIX'] = bundle_res
+os.environ['GTK_PATH'] = bundle_res
+
+os.environ['PANGO_RC_FILE'] = join(bundle_etc, 'pango', 'pangorc')
+os.environ['PANGO_SYSCONFDIR'] = bundle_etc
+os.environ['PANGO_LIBDIR'] = bundle_lib
+os.environ['GDK_PIXBUF_MODULE_FILE'] = join(bundle_lib, 'gdk-pixbuf-2.0',
+ '2.10.0', 'loaders.cache')
+if int(platform.release().split('.')[0]) > 10:
+ os.environ['GTK_IM_MODULE_FILE'] = join(bundle_etc, 'gtk-3.0',
+ 'gtk.immodules')
+
+os.environ['GI_TYPELIB_PATH'] = join(bundle_lib, 'girepository-1.0')
+
+#Set $PYTHON to point inside the bundle
+PYVER = 'python3.10'
+sys.path.append(bundle_res)
+
+os.environ['USERPROFILE'] = os.environ['HOME']
+os.environ['APPDATA'] = join(os.environ['HOME'], 'Library', 'Application Support')
+# Replace my_app with the file or module with your main() function.
+from zenmapGUI import App
+App.run()
+