NO_MESS_SYSTEM support
diff --git a/code/default/gae_proxy/local/cert_util.py b/code/default/gae_proxy/local/cert_util.py
index 2de52f5de4..8b9c597e07 100644
--- a/code/default/gae_proxy/local/cert_util.py
+++ b/code/default/gae_proxy/local/cert_util.py
@@ -314,6 +314,7 @@ def win32_notify( msg="msg", title="Title"):
 
     @staticmethod
     def import_windows_ca(common_name, certfile):
+        xlog.debug("Begin to import Windows CA")
         import ctypes
         with open(certfile, 'rb') as fp:
             certdata = fp.read()
@@ -360,6 +361,7 @@ class CRYPT_HASH_BLOB(ctypes.Structure):
 
     @staticmethod
     def remove_windows_ca(name):
+        xlog.debug("Removing windows CA")
         import ctypes
         import ctypes.wintypes
         class CERT_CONTEXT(ctypes.Structure):
@@ -397,29 +399,34 @@ def get_linux_firefox_path():
         for filename in os.listdir(firefox_path):
             if filename.endswith(".default") and os.path.isdir(os.path.join(firefox_path, filename)):
                 config_path = os.path.join(firefox_path, filename)
+                #xlog.debug("Got Firefox path: %s", config_path)
                 return config_path
 
     @staticmethod
     def import_linux_firefox_ca(common_name, ca_file):
+        xlog.debug("Begin importing CA to Firefox")
         firefox_config_path = CertUtil.get_linux_firefox_path()
         if not firefox_config_path:
+            #xlog.debug("Not found Firefox path")
             return False
 
         if not any(os.path.isfile('%s/certutil' % x) for x in os.environ['PATH'].split(os.pathsep)):
             xlog.warning('please install *libnss3-tools* package to import GoAgent root ca')
             return False
 
+        xlog.info("Removing old cert to Firefox in %s", firefox_config_path)
         cmd_line = 'certutil -L -d %s |grep "GoAgent" &&certutil -d %s -D -n "%s" ' % (firefox_config_path, firefox_config_path, common_name)
         os.system(cmd_line) # remove old cert first
 
+        xlog.info("Add new cert to Firefox in %s", firefox_config_path)
         cmd_line = 'certutil -d %s -A -t "C,," -n "%s" -i "%s"' % (firefox_config_path, common_name, ca_file)
         os.system(cmd_line) # install new cert
         return True
 
     @staticmethod
-    def import_debian_ca(common_name, ca_file):
+    def import_linux_ca(common_name, ca_file):
 
-        def get_debian_ca_sha1(nss_path):
+        def get_linux_ca_sha1(nss_path):
             commonname = "GoAgent XX-Net - GoAgent" #TODO: here should be GoAgent - XX-Net
 
             cmd = ['certutil', '-L','-d', 'sql:%s' % nss_path, '-n', commonname]
@@ -450,10 +457,10 @@ def get_debian_ca_sha1(nss_path):
             xlog.warning('please install *libnss3-tools* package to import GoAgent root ca')
             return False
 
-        sha1 = get_debian_ca_sha1(nss_path)
+        sha1 = get_linux_ca_sha1(nss_path)
         ca_hash = CertUtil.ca_thumbprint.replace(':', '')
         if sha1 == ca_hash:
-            xlog.info("system cert exist")
+            xlog.info("Database $HOME/.pki/nssdb cert exist")
             return
 
 
@@ -461,10 +468,12 @@ def get_debian_ca_sha1(nss_path):
         # certutil -L -d sql:$HOME/.pki/nssdb
 
         # remove old cert first
+        xlog.info("Removing old cert in database $HOME/.pki/nssdb")
         cmd_line = 'certutil -L -d sql:$HOME/.pki/nssdb |grep "GoAgent" && certutil -d sql:$HOME/.pki/nssdb -D -n "%s" ' % ( common_name)
         os.system(cmd_line)
 
         # install new cert
+        xlog.info("Add cert to database $HOME/.pki/nssdb")
         cmd_line = 'certutil -d sql:$HOME/.pki/nssdb -A -t "C,," -n "%s" -i "%s"' % (common_name, ca_file)
         os.system(cmd_line)
         return True
@@ -538,33 +547,34 @@ def get_exist_ca_sha1():
 
     @staticmethod
     def import_ca(certfile):
+        xlog.debug("Importing CA")
         commonname = "GoAgent XX-Net - GoAgent" #TODO: here should be GoAgent - XX-Net
         if sys.platform.startswith('win'):
+            CertUtil.remove_windows_ca('%s CA' % CertUtil.ca_vendor)
             CertUtil.import_windows_ca(commonname, certfile)
         elif sys.platform == 'darwin':
             CertUtil.import_mac_ca(commonname, certfile)
         elif sys.platform.startswith('linux'):
-            CertUtil.import_debian_ca(commonname, certfile)
+            CertUtil.import_linux_ca(commonname, certfile)
             CertUtil.import_linux_firefox_ca(commonname, certfile)
             #CertUtil.import_ubuntu_system_ca(commonname, certfile) # we don't need install CA to system root, special user is enough
 
 
     @staticmethod
     def init_ca():
+        #xlog.debug("Initializing CA")
+
         #Check Certs Dir
         if not os.path.exists(CertUtil.ca_certdir):
             os.makedirs(CertUtil.ca_certdir)
 
         # Confirmed GoAgent CA exist
         if not os.path.exists(CertUtil.ca_keyfile):
-            xlog.info("no CA file exist")
+            xlog.info("no GAE CA file exist in XX-Net data dir")
 
-            xlog.info("clean old site certs")
+            xlog.info("clean old site certs in XX-Net cert dir")
             any(os.remove(x) for x in glob.glob(CertUtil.ca_certdir+'/*.crt')+glob.glob(CertUtil.ca_certdir+'/.*.crt'))
 
-            if os.name == 'nt':
-                CertUtil.remove_windows_ca('%s CA' % CertUtil.ca_vendor)
-
             CertUtil.generate_ca_file()
 
         # Load GoAgent CA
@@ -581,7 +591,8 @@ def init_ca():
             if serial_number != CertUtil.get_cert_serial_number(commonname):
                 any(os.remove(x) for x in certfiles)
 
-        CertUtil.import_ca(CertUtil.ca_keyfile)
+        if os.getenv("XXNET_NO_MESS_SYSTEM", "0") == "0" :
+            CertUtil.import_ca(CertUtil.ca_keyfile)
 
         # change the status,
         # web_control /cert_import_status will return True, else return False
@@ -590,7 +601,6 @@ def init_ca():
 
 
 
-
 if __name__ == '__main__':
     CertUtil.init_ca()
 
diff --git a/code/default/launcher/config.py b/code/default/launcher/config.py
index ec96708f5a..74318d3509 100644
--- a/code/default/launcher/config.py
+++ b/code/default/launcher/config.py
@@ -12,7 +12,7 @@
 config_path = os.path.join(data_path, 'launcher', 'config.yaml')
 
 config = {}
-
+need_save_config = False
 
 def load():
     global config, config_path
@@ -27,8 +27,10 @@ def load():
 
 def save():
     global config, config_path
+    global need_save_config
     try:
         yaml.dump(config, open(config_path, "w"))
+        need_save_config = False
     except Exception as e:
         xlog.warn("save config %s fail %s", config_path, e)
 
@@ -58,12 +60,14 @@ def _set(m, k_list, v):
 
 def set(path, val):
     global config
+    global need_save_config
     _set(config, path, val)
+    need_save_config = True
 
 
 def recheck_module_path():
     global config
-    need_save_config = False
+    global need_save_config
 
     xxnet_port = get(["modules", "gae_proxy", "LISTEN_PORT"], 8087)
 
@@ -91,6 +95,11 @@ def recheck_module_path():
     # if get(["modules", "gae_proxy", "control_port"], 0) == 0:
     #     set(["modules", "gae_proxy", "control_port"], 8084)
 
+    if get(["no_mess_system"], 0) == 1 or os.getenv("XXNET_NO_MESS_SYSTEM","0") != "0" :
+        xlog.debug("no_mess_system")
+        os.environ["XXNET_NO_MESS_SYSTEM"] = "1"
+        set(["no_mess_system"], 1)
+
     return need_save_config
 
 
diff --git a/code/default/launcher/create_shortcut_linux.sh b/code/default/launcher/create_shortcut_linux.sh
new file mode 100755
index 0000000000..21778cec7f
--- /dev/null
+++ b/code/default/launcher/create_shortcut_linux.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+
+# variable XXNETPATH is env by python call
+
+function createDesktopStartup() {
+    DESKDIR=~/Desktop/
+
+    if [[ -d $DESKDIR ]]; then
+        DESKFILE="$DESKDIR/XX-Net.desktop"
+    else
+        echo "$DESKDIR does not exist"
+        return -1
+    fi
+
+    # python won't call this script if lastrun in config matchs the current run
+
+    #if [[ -f $DESKFILE ]]; then
+    #    echo "$DESKFILE already exists"
+    #    return
+    #else
+    #    echo "$DESKFILE does not exist,create a new one"
+    #fi
+
+    NAME="XX-Net"
+    EXEC="$XXNETPATH/start > /dev/null"
+    ICON="$XXNETPATH/code/default/launcher/web_ui/favicon.ico"
+    TERMINAL="false"
+    TYPE="Application"
+    CATEGORIES="Development"
+    echo "[Desktop Entry]" > "$DESKFILE"
+    #echo "Version=$VERSION" >> "$DESKFILE"
+    echo "Name=$NAME" >> "$DESKFILE"
+    echo "Exec=$EXEC" >> "$DESKFILE"
+    echo "Terminal=$TERMINAL" >> "$DESKFILE"
+    echo "Icon=$ICON" >> "$DESKFILE"
+    echo "Type=$TYPE" >> "$DESKFILE"
+    echo "Categories=$CATEGORIES" >> "$DESKFILE"
+
+    chmod 744 $DESKFILE
+
+}
+
+# create a desktop startup file when the distro is Ubuntu.
+DIS=`cat /etc/issue 2> /dev/null`
+if [[ $DIS == *Ubuntu* ]]; then
+    createDesktopStartup
+else
+    echo "Not ubuntu. Not creating shortcut"
+fi
diff --git a/code/default/launcher/update.py b/code/default/launcher/update.py
index 6acc9a4f9c..f6244b2e5f 100644
--- a/code/default/launcher/update.py
+++ b/code/default/launcher/update.py
@@ -347,8 +347,17 @@ def check_push_update():
 
 def create_desktop_shortcut():
     import sys
+    import subprocess
+
+    work_path = os.path.dirname(os.path.abspath(__file__))
+    os.chdir(work_path)
+
     if sys.platform.startswith("linux"):
-        pass
+        if os.getenv("DESKTOP_SESSION","unknown") != "unknown" :  # make sure this is desktop linux
+            xxnet_path = os.path.abspath(os.path.join(root_path, os.pardir, os.pardir))
+            cmd='env XXNETPATH="' + xxnet_path + '" "' + work_path + '/create_shortcut_linux.sh"'
+            os.system(cmd)
+
     elif sys.platform == "win32":
         # import ctypes
         # msg = u"是否在桌面创建图标？"
@@ -357,10 +366,7 @@ def create_desktop_shortcut():
         # Yes:1 No:2
         #if res == 2:
         #    return
-        work_path = os.path.dirname(os.path.abspath(__file__))
-        os.chdir(work_path)
 
-        import subprocess
         subprocess.call(["Wscript.exe", "//E:JScript", "create_shortcut.js"], shell=False)
 
 def notify_install_tcpz_for_winXp():
@@ -368,7 +374,6 @@ def notify_install_tcpz_for_winXp():
     ctypes.windll.user32.MessageBoxW(None, u"请使用tcp-z对 tcpip.sys 打补丁，解决链接并发限制！", u"Patch XP needed", 0)
 
 def check_new_machine():
-
     current_path = os.path.dirname(os.path.abspath(__file__))
     if current_path != config.get(["update", "last_path"], ""):
         config.set(["update", "last_path"], current_path)
@@ -377,8 +382,9 @@ def check_new_machine():
         if sys.platform == "win32" and platform.release() == "XP":
             notify_install_tcpz_for_winXp()
 
-        xlog.info("generate desktop shortcut")
-        create_desktop_shortcut()
+        if os.getenv("XXNET_NO_MESS_SYSTEM", "0") == "0":
+            xlog.info("generate desktop shortcut")
+            create_desktop_shortcut()
 
 
 
diff --git a/start b/start
index 15c40213aa..111590abd9 100755
--- a/start
+++ b/start
@@ -64,45 +64,7 @@ if [ $os_name = 'Linux' ]; then
     fi
 fi
 
-# create a desktop startup file when the distro is Ubuntu.
-function createDesktopStartup() {
-    DESKFILE='XX-Net.desktop'
-    if [[ -f $DESKFILE ]]; then 
-        echo "$DESKFILE already exists"
-        return
-    else
-        echo "$DESKFILE does not exist,create a new one"
-    fi
-    NAME="XX-Net"
-    EXEC="$SCRIPTPATH/start > /dev/null"
-    ICON="$SCRIPTPATH/code/default/launcher/web_ui/favicon.ico"
-    TERMINAL="false"
-    TYPE="Application"
-    CATEGORIES="Development"
-    echo "[Desktop Entry]" >> $DESKFILE
-    echo "Version=$VERSION" >> $DESKFILE
-    echo "Name=$NAME" >> $DESKFILE
-    echo "Exec=$EXEC" >> $DESKFILE
-    echo "Terminal=$TERMINAL" >> $DESKFILE
-    echo "Icon=$ICON" >> $DESKFILE
-    echo "Type=$TYPE" >> $DESKFILE
-    echo "Categories=$CATEGORIES" >> $DESKFILE
-
-    chmod 744 $DESKFILE
-    DESKDIR=~/Desktop/
-    cp $DESKFILE $DESKDIR
-
-    if [[ -d $DESKDIR ]]; then
-        cp $DESKFILE $DESKDIR
-    else
-        echo "$DESKDIR does not exist"
-    fi
-}
 
-DIS=`cat /etc/issue 2> /dev/null`
-if [[ $DIS == *Ubuntu* ]]; then
-    createDesktopStartup
-fi
 
 # Start Application
 if [ $os_name = 'Darwin' ] && ! [ "$1" = '-hungup' ]; then

User can use env var or config to prevent XX-Net from modifying system