[
  {
    "path": ".circleci/ENVIRONMENT.txt",
    "content": "ENV VARIABLES:\n   (used by deploy_ec2@app1_install, deploy_ec2@app1_upgrade):\n      APP1_ADMIN_PASS =  password to set admin user to.\n      APP1_SSH_HOST   =  ec2 machine\n      APP1_SSH_USER   =  ec2 username (with sudo)\n   (used by deploy_ec2@app2_install, deploy_ec2@app2_upgrade):\n      APP2_ADMIN_PASS =  password to set admin user to.\n      APP2_SSH_HOST   =  ec2 machine\n      APP2_SSH_USER   =  ec2 username (with sudo)\n\nSSH PERMISSIONS: (used by deploy_ec2)\n   (private key for ec2 machine named in $APP1_SSH_HOST above)\n   (private key for ec2 machine named in $APP2_SSH_HOST above)\n\nAWS PERMISSIONS: (used by deploy_s3)\n   Access Key ID\n   Secret Access Key\n"
  },
  {
    "path": ".circleci/config.yml",
    "content": "\n# vim:expandtab:ts=3\n\nversion: 2\n\n############################################################################\n\nreferences:\n   checkout_job_steps: &checkout_job_steps\n      steps:\n         - checkout\n         - run:\n            name: Checking out dependencies\n            command: |\n               mkdir -p ../BUILDS\n               ./build.pl \\\n                  --build-type=FOSS \\\n                  --build-hostname=build.zimbra.org \\\n                  --build-release=\"$CIRCLE_PROJECT_USERNAME\" \\\n                  --build-release-no=$(.circleci/misc/glean_version.pl) \\\n                  --build-release-candidate=beta \\\n                  --build-thirdparty-server=zdev-vm008.eng.zimbra.com \\\n                  --deploy-url-prefix=\"https://files.zimbra.com/dev-releases/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/$CIRCLE_BRANCH-$CIRCLE_BUILD_NUM\" \\\n                  --git-default-branch=\"$CIRCLE_BRANCH,develop\" \\\n                  --build-os=\"UBUNTU16_64\" \\\n                  --pkg-os-tag=\"u16\" \\\n                  --build-no=\"$CIRCLE_BUILD_NUM\" \\\n                  --build-ts=\"$(date \"+%Y%m%d%M%H%S\")\" \\\n                  --ant-options=\"-DskipTests=1\" \\\n                  --no-interactive \\\n                  --disable-bundle \\\n                  --dump-config-to=\"$PWD/config.build\" \\\n                  --stop-after-checkout \\\n                  --exclude-git-repos=zm-timezones \\\n                  2>&1 \\\n               | tee ../BUILDS/checkout.log;\n\n               # FIXME: remove this hack, and fix --dump-config-to\n               sed -i \\\n                  -e '/^DUMP_CONFIG_TO/d' \\\n                  -e '/^STOP_AFTER_CHECKOUT/d' \\\n                  -e '/^INTERACTIVE/d' \\\n                  -e '/^BUILD_OS/d' \\\n                  -e '/^PKG_OS_TAG/d' \\\n                  -e '/^BUILD_ARCH/d' \\\n                  -e '/\\<UBUNTU16_64\\>/d' \\\n                  -e '/\\<BUILDS\\>/d' \\\n                  config.build;\n         - persist_to_workspace:\n            root: ../..\n            paths:\n               - checkout\n               - .zcs-deps\n\n   build_job_steps: &build_job_steps\n      steps:\n         - attach_workspace:\n            at: ../..\n         - run:\n            name: Creating build\n            command: |\n               rm ../BUILDS/checkout.log\n               ENV_GIT_UPDATE_INCLUDE=@ \\\n                  ./build.pl 2>&1 \\\n                     --build-os=\"$ZIMBRA_BUILD_OS\" \\\n                     --pkg-os-tag=\"$ZIMBRA_OS_TAG\" \\\n                     --no-interactive \\\n               | tee -a ../BUILDS/build-${ZIMBRA_OS_TAG}.log\n         - store_artifacts:\n            path: ../BUILDS\n         - persist_to_workspace:\n            root: ../..\n            paths: checkout/BUILDS\n\n   deploy_s3_job_steps: &deploy_s3_job_steps\n      steps:\n         - attach_workspace:\n            at: ../..\n         - deploy:\n            name: Deploying to S3\n            command: |\n               for i in ../BUILDS/*\n               do\n                  if [ -d \"$i\" ]\n                  then\n                     # NOTE: We are not using $CIRCLE_BUILD_NUM as its different for each job of the workflow\n                     #       Instead, we need $CIRCLE_BUILD_NUM allocated for 'checkout' job, (stored in config.build)\n                     BUILD_NO=$(cat config.build | sed -ne '/^BUILD_NO\\>/ { s/.*=\\s*//p }'); [ ! -z \"$BUILD_NO\" ] || exit 2;\n\n                     aws s3 sync \"$i\" \"s3://files.zimbra.com/dev-releases/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/$CIRCLE_BRANCH-$BUILD_NO/\" \\\n                        --acl public-read \\\n                        --region us-east-1\n                  fi\n               done\n\n   deploy_ec2_job_steps: &deploy_ec2_job_steps\n      steps:\n         - attach_workspace:\n            at: ../..\n         - deploy:\n            name: Deploying to EC2\n            command: |\n               MY_SSH_HOST_var=\"${EC2_TARGET}_SSH_HOST\";\n               MY_SSH_USER_var=\"${EC2_TARGET}_SSH_USER\";\n               MY_ADMIN_PASS_var=\"${EC2_TARGET}_ADMIN_PASS\";\n\n               .circleci/jobs/deploy_ec2/deploy.sh \\\n                  -o ${OPERATION} \\\n                  -t ${PKG_OS_TAG} \\\n                  -h ${!MY_SSH_HOST_var} \\\n                  -u ${!MY_SSH_USER_var} \\\n                  -a ${!MY_ADMIN_PASS_var}\n\n   std_filters: &std_filters\n      filters:\n         branches:\n            only:\n               - master\n               - develop\n\n############################################################################\n\njobs:\n   checkout:\n      working_directory: ~/checkout/zm-build\n      shell: /bin/bash -euo pipefail\n      docker:\n         - image: zimbra/zm-base-os:devcore-ubuntu-16.04\n      <<: *checkout_job_steps\n\n   build_u16:\n      working_directory: ~/checkout/zm-build\n      shell: /bin/bash -euo pipefail\n      environment:\n         - ZIMBRA_OS_TAG: u16\n         - ZIMBRA_BUILD_OS: UBUNTU16_64\n      docker:\n         - image: zimbra/zm-base-os:devcore-ubuntu-16.04\n      <<: *build_job_steps\n\n   build_u14:\n      working_directory: ~/checkout/zm-build\n      shell: /bin/bash -euo pipefail\n      environment:\n         - ZIMBRA_OS_TAG: u14\n         - ZIMBRA_BUILD_OS: UBUNTU14_64\n      docker:\n         - image: zimbra/zm-base-os:devcore-ubuntu-14.04\n      <<: *build_job_steps\n\n   build_u12:\n      working_directory: ~/checkout/zm-build\n      shell: /bin/bash -euo pipefail\n      environment:\n         - ZIMBRA_OS_TAG: u12\n         - ZIMBRA_BUILD_OS: UBUNTU12_64\n      docker:\n         - image: zimbra/zm-base-os:devcore-ubuntu-12.04\n      <<: *build_job_steps\n\n   build_r7:\n      working_directory: ~/checkout/zm-build\n      shell: /bin/bash -euo pipefail\n      environment:\n         - ZIMBRA_OS_TAG: r7\n         - ZIMBRA_BUILD_OS: RHEL7_64\n      docker:\n         - image: zimbra/zm-base-os:devcore-centos-7\n      <<: *build_job_steps\n\n   build_r6:\n      working_directory: ~/checkout/zm-build\n      shell: /bin/bash -euo pipefail\n      environment:\n         - ZIMBRA_OS_TAG: r6\n         - ZIMBRA_BUILD_OS: RHEL6_64\n      docker:\n         - image: zimbra/zm-base-os:devcore-centos-6\n      <<: *build_job_steps\n\n   deploy_s3:\n      working_directory: ~/checkout/zm-build\n      shell: /bin/bash -euo pipefail\n      docker:\n         - image: zimbra/zm-base-os:core-ubuntu\n      <<: *deploy_s3_job_steps\n\n   deploy_ec2@app1_install:\n      working_directory: ~/checkout/zm-build\n      shell: /bin/bash -euo pipefail\n      environment:\n         - EC2_TARGET: APP1\n         - OPERATION: install\n         - PKG_OS_TAG: u16\n      docker:\n         - image: zimbra/zm-base-os:core-ubuntu\n      <<: *deploy_ec2_job_steps\n\n   deploy_ec2@app1_upgrade:\n      working_directory: ~/checkout/zm-build\n      shell: /bin/bash -euo pipefail\n      environment:\n         - EC2_TARGET: APP1\n         - OPERATION: upgrade\n         - PKG_OS_TAG: u16\n      docker:\n         - image: zimbra/zm-base-os:core-ubuntu\n      <<: *deploy_ec2_job_steps\n\n   deploy_ec2@app2_install:\n      working_directory: ~/checkout/zm-build\n      shell: /bin/bash -euo pipefail\n      environment:\n         - EC2_TARGET: APP2\n         - OPERATION: install\n         - PKG_OS_TAG: r6\n      docker:\n         - image: zimbra/zm-base-os:core-ubuntu\n      <<: *deploy_ec2_job_steps\n\n   deploy_ec2@app2_upgrade:\n      working_directory: ~/checkout/zm-build\n      shell: /bin/bash -euo pipefail\n      environment:\n         - EC2_TARGET: APP2\n         - OPERATION: upgrade\n         - PKG_OS_TAG: r6\n      docker:\n         - image: zimbra/zm-base-os:core-ubuntu\n      <<: *deploy_ec2_job_steps\n\n############################################################################\n\nworkflows:\n   version: 2\n   main:\n      jobs:\n         - checkout\n\n         #########################\n\n         - build_u16:\n            requires:\n               - checkout\n         - build_u14:\n            requires:\n               - checkout\n         - build_u12:\n            requires:\n               - checkout\n#         - build_r7:\n#            requires:\n#               - checkout\n         - build_r6:\n            requires:\n               - checkout\n\n         #########################\n\n         - deploy_s3_hold:\n            type: approval\n            requires:\n               - build_u16\n               - build_u14\n               - build_u12\n#               - build_r7    (core dump issue while running ant)\n               - build_r6\n            <<: *std_filters\n\n         - deploy_s3:\n            requires:\n               - deploy_s3_hold\n            <<: *std_filters\n\n         #########################\n\n         - app1_ec2_install:\n            type: approval\n            requires:\n               - build_u16\n            <<: *std_filters\n\n         - app1_ec2_upgrade:\n            type: approval\n            requires:\n               - build_u16\n            <<: *std_filters\n\n         - deploy_ec2@app1_install:\n            requires:\n               - app1_ec2_install\n            <<: *std_filters\n\n         - deploy_ec2@app1_upgrade:\n            requires:\n               - app1_ec2_upgrade\n            <<: *std_filters\n\n         #########################\n\n         - app2_ec2_install:\n            type: approval\n            requires:\n               - build_r6\n            <<: *std_filters\n\n         - app2_ec2_upgrade:\n            type: approval\n            requires:\n               - build_r6\n            <<: *std_filters\n\n         - deploy_ec2@app2_install:\n            requires:\n               - app2_ec2_install\n            <<: *std_filters\n\n         - deploy_ec2@app2_upgrade:\n            requires:\n               - app2_ec2_upgrade\n            <<: *std_filters\n"
  },
  {
    "path": ".circleci/jobs/deploy_ec2/deploy.sh",
    "content": "#!/bin/bash\n\nset -euo pipefail\n\nSCRIPT_DIR=$(CDPATH= cd \"$(dirname \"$0\")\" && pwd);\nCIRCLE_DIR=$(dirname \"$(dirname \"$SCRIPT_DIR\")\")\n\nusage()\n{\n   echo \"Usage: $0 -o <upgrade|install> -t <u16|u14|u12|r7|r6> -h <ssh-ec2-host> -u <ssh-ec2-user> -a <admin-pass-to-set>\" 1>&2;\n   echo 1>&2;\n   echo \"Example:\" 1>&2;\n   echo \"   $0 -o upgrade -t u16 -h ec2-xx-xx-xx-xx.us-east-2.compute.amazonaws.com -u ubuntu -a admin123\" 1>&2;\n   exit 1\n}\n\n#######################################################################\n##### PARSE ARGS, SANITIZE #####\n#######################################################################\n\nset +u\nwhile getopts \"o:t:h:u:a:\" cur_opt; do\n    case \"${cur_opt}\" in\n        o)\n            OPERATION=\"${OPTARG}\"\n            if [ \"$OPERATION\" != \"upgrade\" ] && [ \"$OPERATION\" != \"install\" ]\n            then\n\t       usage\n            fi\n            ;;\n        t)\n            PKG_OS_TAG=${OPTARG}\n            case \"$PKG_OS_TAG\" in\n               u16) DIR=$(echo $CIRCLE_DIR/../../BUILDS/UBUNTU16_64* | head -1); ;;\n               u14) DIR=$(echo $CIRCLE_DIR/../../BUILDS/UBUNTU14_64* | head -1); ;;\n               u12) DIR=$(echo $CIRCLE_DIR/../../BUILDS/UBUNTU12_64* | head -1); ;;\n                r7) DIR=$(echo $CIRCLE_DIR/../../BUILDS/RHEL7_64* | head -1); ;;\n                r6) DIR=$(echo $CIRCLE_DIR/../../BUILDS/RHEL6_64* | head -1); ;;\n                *) usage; ;;\n            esac\n            ;;\n        h)\n            MY_SSH_HOST=${OPTARG}\n            ;;\n        u)\n            MY_SSH_USER=${OPTARG}\n            ;;\n        a)\n            MY_ADMIN_PASS=${OPTARG}\n            ;;\n        *)\n            usage\n            ;;\n    esac\ndone\nshift $((OPTIND-1))\n\nif [ -z \"$MY_SSH_USER\" ] || [ -z \"$MY_SSH_HOST\" ] || [ -z \"$MY_ADMIN_PASS\" ] || [ -z \"$PKG_OS_TAG\" ]\nthen\n   usage;\nfi\n\nif [ ! -f \"$CIRCLE_DIR/config.yml\" ]\nthen\n   echo \"Rerun from within .circleci directory\";\n   exit 1\nfi\n\nif [ ! -d \"$DIR\" ]\nthen\n   echo \"Could not find the BUILD\";\n   exit 1;\nfi\nset -u\n\n##### END GETOPT #####\n#######################################################################\n\n\n#######################################################################\n##### RSYNC #####\n#######################################################################\n\nSSH_OPTS=(\n   \"-o\" \"UserKnownHostsFile=/dev/null\"\n   \"-o\" \"StrictHostKeyChecking=no\"\n   \"-o\" \"CheckHostIP=no\"\n   \"-o\" \"ServerAliveInterval=100\"\n)\n\nRsync()\n{\n   rsync -e \"ssh ${SSH_OPTS[*]}\" \"$@\"\n}\n\nSsh()\n{\n   ssh \"${SSH_OPTS[@]}\" \"$@\"\n}\n\n#Rsync --delete -avz $CIRCLE_DIR/../zm-build \"$MY_SSH_USER@$MY_SSH_HOST:\"\nRsync --delete -avz \"$DIR/\" \"$MY_SSH_USER@$MY_SSH_HOST:BUILD/\"\nRsync $CIRCLE_DIR/jobs/deploy_ec2/install.conf.in \"$MY_SSH_USER@$MY_SSH_HOST:BUILD/install.conf.in\"\nRsync $CIRCLE_DIR/jobs/deploy_ec2/upgrade.conf.in \"$MY_SSH_USER@$MY_SSH_HOST:BUILD/upgrade.conf.in\"\n\n##### END RSYNC #####\n#######################################################################\n\n\n#######################################################################\n##### FORWARD SCRIPT TO EXECUTE #####\n#######################################################################\n\nSsh \"$MY_SSH_USER@$MY_SSH_HOST\" -- tee /tmp/injected_bash_script.sh <<\"SCRIPT_EOM\"\n#!/bin/bash\n\n[ -z \"$DOMAIN_NAME\" ] && echo \"DOMAIN_NAME is not defined\" && exit 1;\n[ -z \"$ADMIN_PASS\"  ] && echo \"ADMIN_PASS is not defined\"  && exit 1;\n[ -z \"$OPERATION\"   ] && echo \"OPERATION is not defined\"   && exit 1;\n[ -z \"$PKG_OS_TAG\"  ] && echo \"PKG_OS_TAG is not defined\"  && exit 1;\n\nset -euxo pipefail\n\nsetUp()\n{\n   echo -----------------------------------\n   echo System Setup specific to EC2\n   echo -----------------------------------\n\n   [ -f /etc/hosts.orig ] || sudo cp /etc/hosts /etc/hosts.orig\n   [ -f /etc/resolv.conf.orig ] || sudo cp /etc/resolv.conf /etc/resolv.conf.orig\n   EC2_IP=$(hostname      | sed -e 's/[.\\s].*$//' -e 's/^ip-//' -e 's/[-]/./g')\n   EC2_RESOLVE=$(hostname | sed -e 's/[.\\s].*$//' -e 's/^ip-//' -e 's/[-]/./g' -e 's/[.][0-9]*[.][0-9]*$/.0.2/')\n   sudo sed -i -e \"\\$a$EC2_IP $(hostname -f) $(hostname)\" -e \"/ip-/ { /$(hostname)/d; }\" /etc/hosts\n   sudo sed -i -e \"/^search/i\\\\nameserver $EC2_RESOLVE\\nnameserver 8.8.8.8\" -e \"/nameserver 8.8.8.8/d\" -e \"/nameserver $EC2_RESOLVE/d\" /etc/resolv.conf\n\n   echo -----------------------------------\n   echo System Cleanup\n   echo -----------------------------------\n\n   set +e;\n   sudo killall master zmstat-fd\n   sudo killall -u zimbra\n   sudo killall -u postfix\n   sudo pkill -f 'amavi[s]'\n   sleep 10\n   sudo killall -9 master zmstat-fd\n   sudo killall -9 -u zimbra\n   sudo killall -9 -u postfix\n   sudo pkill -9 -f 'amavi[s]'\n   sleep 10\n   [[ \"$PKG_OS_TAG\" =~ u* ]] && sudo apt-get remove --purge -y zimbra-*\n   [[ \"$PKG_OS_TAG\" =~ r* ]] && sudo yum erase -y zimbra-*\n   sudo rm -rf /opt/zimbra\n\n   [[ \"$PKG_OS_TAG\" =~ u* ]] && sudo apt-get install -y perl\n   [[ \"$PKG_OS_TAG\" =~ r* ]] && sudo yum install -y perl\n   if [[ \"$PKG_OS_TAG\" =~ r6 ]]\n   then\n      if [ ! -f /usr/lib/python2.6/site-packages/yum/__init__.py.patched ]\n      then\n         #We are running into a curious yum bug - See https://bugzilla.redhat.com/show_bug.cgi?id=993567\n\n         sudo yum -y install wget patch\n         sudo wget http://s3.amazonaws.com/files.zimbra.com/dev-releases/hold/r6-yum-patch/yum.patch -O ~/yum.patch\n         sudo cp /usr/lib/python2.6/site-packages/yum/__init__.py{,.orig}\n         sudo patch -p0 < ~/yum.patch\n         sudo cp /usr/lib/python2.6/site-packages/yum/__init__.py{,.patched}\n      fi\n   fi\n   echo\n}\n\nbuildCleanUp()\n{\n   echo -----------------------------------\n   echo Build Cleanup, Uncompress new tarball\n   echo -----------------------------------\n\n   sudo rm -rf ~/WDIR\n   mkdir ~/WDIR\n   tar -C ~/WDIR -xzf BUILD/zcs-*.tgz\n}\n\nprepareConfig()\n{\n   echo -----------------------------------\n   echo Create install configuration\n   echo -----------------------------------\n\n   HOSTNAME=\"$(hostname --fqdn)\"\n   RESOLVE=\"$(cat /etc/resolv.conf | awk '/^\\s*nameserver/ { print $2; }' | grep -v ^127 | head -1)\"\n   sed -e \"s/template_resolv/$RESOLVE/\" \\\n       -e \"s/template_hostname/$HOSTNAME/\" \\\n       -e \"s/template_domainname/$DOMAIN_NAME/\" \\\n       -e \"s/template_admin_pass/$ADMIN_PASS/g\" \\\n   ~/BUILD/install.conf.in > ~/WDIR/install.conf\n   cat ~/BUILD/upgrade.conf.in > ~/WDIR/upgrade.conf\n}\n\nupdatePackages()\n{\n   echo -----------------------------------\n   echo Setup local archives\n   echo -----------------------------------\n\n   if [[ \"$PKG_OS_TAG\" =~ u ]]\n   then\n      sudo rm -f /etc/apt/sources.list.d/zimbra-*.list\n\n      echo \"deb [trusted=yes] file://$(echo $HOME/BUILD/archives/*/$PKG_OS_TAG) ./\"                                                           | sudo tee -a /etc/apt/sources.list.d/zimbra-local.list\n      echo \"deb [trusted=yes] https://files.zimbra.com/dev-releases/hold/Zimbra/zm-zextras/develop-52/archives/zimbra-zextras/$PKG_OS_TAG ./\" | sudo tee -a /etc/apt/sources.list.d/zimbra-zextras.list\n      echo \"deb [trusted=yes] https://files.zimbra.com/dev-releases/hold/Zimbra/zm-timezones/develop-35/archives/zimbra-foss/$PKG_OS_TAG  ./\" | sudo tee -a /etc/apt/sources.list.d/zimbra-foss.list\n\n      #echo \"deb [arch=amd64] https://repo.zimbra.com/apt/zimbra-zextras xenial zimbra\" | sudo tee -a /etc/apt/sources.list.d/zimbra-zextras.list\n      #echo \"deb [arch=amd64] https://repo.zimbra.com/apt/zimbra-foss xenial zimbra\"    | sudo tee -a /etc/apt/sources.list.d/zimbra-foss.list\n\n      sudo apt-get update -qq\n   fi\n\n   if [[ \"$PKG_OS_TAG\" =~ r ]]\n   then\n      sudo rm -f /etc/yum.repos.d/zimbra-*.repo\n\n      sudo tee -a /etc/yum.repos.d/zimbra-local.repo <<EOM\n[zimbra-local-zm-build]\nname=zimbra-local\nbaseurl=file://$(echo $HOME/BUILD/archives/*/$PKG_OS_TAG)\nenabled=1\ngpgcheck=0\nprotect=0\nEOM\n\n      sudo tee -a /etc/yum.repos.d/zimbra-zextras.repo <<EOM\n[zimbra-zextras-zm-zextras]\nname=zimbra-zextras\nbaseurl=https://files.zimbra.com/dev-releases/hold/Zimbra/zm-zextras/develop-52/archives/zimbra-zextras/$PKG_OS_TAG\nenabled=1\ngpgcheck=0\nprotect=0\nEOM\n\n      sudo tee -a /etc/yum.repos.d/zimbra-foss.repo <<EOM\n[zimbra-foss-zm-timezones]\nname=zimbra-foss\nbaseurl=https://files.zimbra.com/dev-releases/hold/Zimbra/zm-timezones/develop-35/archives/zimbra-foss/$PKG_OS_TAG\nenabled=1\ngpgcheck=0\nprotect=0\nEOM\n\n      sudo yum clean all\n   fi\n}\n\ndeploy()\n{\n   echo -----------------------------------\n   echo Upgrade/Install\n   echo -----------------------------------\n\n   cd ~/WDIR/zcs-*/;\n   sudo ./install.sh $1\n}\n\npostInstallConfiguration()\n{\n   echo -----------------------------------\n   echo Additional Settings\n   echo -----------------------------------\n\n   sudo su - zimbra -c \"zmprov -l md $DOMAIN_NAME zimbraVirtualHostname $DOMAIN_NAME\"\n   sudo su - zimbra -c \"zmprov -l mcf zimbraReverseProxyAdminEnabled TRUE\"\n   sudo su - zimbra -c \"zmproxyctl restart\"\n\n   sudo su - zimbra -c \"zmprov -l mcf zimbraPublicServiceHostname $DOMAIN_NAME\"\n   sudo su - zimbra -c \"zmprov -l mcf zimbraPublicServicePort 443\"\n   sudo su - zimbra -c \"zmprov -l mcf zimbraPublicServiceProtocol https\"\n   sudo su - zimbra -c \"zmprov mc default zimbraFeatureNotebookEnabled TRUE\"\n   sudo su - zimbra -c \"zmmailboxdctl restart\"\n}\n\nMain() {\n   echo $OPERATION\n   if [ \"$OPERATION\" == \"upgrade\" ]; then\n      buildCleanUp\n      prepareConfig\n      updatePackages\n      deploy ~/WDIR/upgrade.conf\n   else\n      setUp\n      buildCleanUp\n      prepareConfig\n      updatePackages\n      deploy ~/WDIR/install.conf\n      postInstallConfiguration\n   fi\n}\n\nMain\necho -----------------------------------\necho INSTALL FINISHED\necho -----------------------------------\nSCRIPT_EOM\n\n#######################################################################\n##### EXECUTE SCRIPT IN EC2 #####\n#######################################################################\n\n# XXX:  All variables have to be explicitly forwarded to the script below, and it runs inside the remote machines's context\n\nSsh \"$MY_SSH_USER@$MY_SSH_HOST\" -- \"DOMAIN_NAME=$MY_SSH_HOST\" \"ADMIN_PASS=$MY_ADMIN_PASS\" \"OPERATION=$OPERATION\" \"PKG_OS_TAG=$PKG_OS_TAG\" bash /tmp/injected_bash_script.sh\n\necho DEPLOY FINISHED - https://$MY_SSH_HOST/\n"
  },
  {
    "path": ".circleci/jobs/deploy_ec2/install.conf.in",
    "content": "AVDOMAIN=\"template_domainname\"\nAVUSER=\"admin@template_domainname\"\nCREATEADMIN=\"admin@template_domainname\"\nCREATEADMINPASS=\"template_admin_pass\"\nCREATEDOMAIN=\"template_domainname\"\nDOCREATEADMIN=\"yes\"\nDOCREATEDOMAIN=\"yes\"\nDOTRAINSA=\"yes\"\nENABLEDEFAULTBACKUP=\"yes\"\nEXPANDMENU=\"no\"\nHOSTNAME=\"template_hostname\"\nHTTPPORT=\"8080\"\nHTTPPROXYPORT=\"80\"\nHTTPPROXY=\"TRUE\"\nHTTPSPORT=\"8443\"\nHTTPSPROXYPORT=\"443\"\nIMAPPORT=\"7143\"\nIMAPPROXYPORT=\"143\"\nIMAPSSLPORT=\"7993\"\nIMAPSSLPROXYPORT=\"993\"\nINSTALL_PACKAGES=\"zimbra-core zimbra-ldap zimbra-logger zimbra-mta zimbra-dnscache zimbra-snmp zimbra-store zimbra-apache zimbra-spell zimbra-proxy\"\nINSTALL_WEBAPPS=\"service zimlet zimbra zimbraAdmin\"\nLDAPADMINPASS=\"zpass-ldap-admin\"\nLDAPAMAVISPASS=\"zpass-ldap-amavis\"\nldap_bes_searcher_password=\"zpass-bes\"\nLDAPBESSEARCHSET=\"set\"\nldap_dit_base_dn_config=\"cn=zimbra\"\nLDAPHOST=\"template_hostname\"\nldap_nginx_password=\"zpass-nginx\"\nLDAPPORT=\"389\"\nLDAPPOSTPASS=\"zpass-ldap-post\"\nLDAPREPLICATIONTYPE=\"master\"\nLDAPREPPASS=\"zpass-ldap-rep\"\nLDAPROOTPASS=\"zpass-ldap-root\"\nmailboxd_directory=\"/opt/zimbra/mailboxd\"\nmailboxd_keystore=\"/opt/zimbra/mailboxd/etc/keystore\"\nmailboxd_keystore_password=\"zpass-mailboxd\"\nMAILBOXDMEMORY=\"1484\"\nmailboxd_server=\"jetty\"\nmailboxd_truststore_password=\"changeit\"\nMAILPROXY=\"TRUE\"\nMODE=\"https\"\nMYSQLMEMORYPERCENT=\"30\"\nPACKAGE_SERVER=\"repo.zimbra.com\"\nPOPPORT=\"7110\"\nPOPPROXYPORT=\"110\"\nPOPSSLPORT=\"7995\"\nPOPSSLPROXYPORT=\"995\"\npostfix_mail_owner=\"postfix\"\npostfix_setgid_group=\"postdrop\"\nPROXYMODE=\"https\"\nREMOVE=\"no\"\nRUNARCHIVING=\"no\"\nRUNAV=\"yes\"\nRUNCBPOLICYD=\"no\"\nRUNDKIM=\"yes\"\nRUNSA=\"yes\"\nRUNVMHA=\"no\"\nSERVICEWEBAPP=\"yes\"\nSMTPDEST=\"admin@template_domainname\"\nSMTPHOST=\"template_hostname\"\nSMTPNOTIFY=\"yes\"\nSMTPSOURCE=\"admin@template_domainname\"\nSNMPNOTIFY=\"yes\"\nSNMPTRAPHOST=\"template_hostname\"\nSPELLURL=\"http://template_hostname:7780/aspell.php\"\nssl_default_digest=\"sha256\"\nSTARTSERVERS=\"yes\"\nSYSTEMMEMORY=\"5.8\"\nTRAINSAHAM=\"ham@template_domainname\"\nTRAINSASPAM=\"spam@template_domainname\"\nUIWEBAPPS=\"yes\"\nUPGRADE=\"no\"\nUSESPELL=\"yes\"\nUSE_ZIMBRA_PACKAGE_SERVER=\"yes\"\nVERSIONUPDATECHECKS=\"TRUE\"\nVIRUSQUARANTINE=\"virus-quarantine@template_domainname\"\nzimbraBackupReportEmailRecipients=\"admin@template_domainname\"\nzimbraBackupReportEmailSender=\"admin@template_domainname\"\nzimbraDNSMasterIP=\"template_resolve\"\nzimbraDNSTCPUpstream=\"no\"\nzimbraDNSUseTCP=\"yes\"\nzimbraDNSUseUDP=\"yes\"\nzimbraFeatureBriefcasesEnabled=\"Enabled\"\nzimbraFeatureTasksEnabled=\"Enabled\"\nzimbraIPMode=\"ipv4\"\nzimbra_ldap_userdn=\"uid=zimbra,cn=admins,cn=zimbra\"\nzimbraMailProxy=\"TRUE\"\nzimbraPrefTimeZoneId=\"America/Chicago\"\nZIMBRA_REQ_SECURITY=\"yes\"\nzimbra_require_interprocess_security=\"1\"\nzimbraReverseProxyLookupTarget=\"TRUE\"\nzimbraVersionCheckNotificationEmail=\"admin@template_domainname\"\nzimbraVersionCheckNotificationEmailFrom=\"admin@template_domainname\"\nzimbraVersionCheckSendNotifications=\"TRUE\"\nzimbraWebProxy=\"TRUE\"\n"
  },
  {
    "path": ".circleci/jobs/deploy_ec2/upgrade.conf.in",
    "content": "PACKAGE_SERVER=\"repo.zimbra.com\"\nREMOVE=\"no\"\nUPGRADE=\"yes\"\nUSE_ZIMBRA_PACKAGE_SERVER=\"yes\"\nVERSIONUPDATECHECKS=\"TRUE\"\nINSTALL_PACKAGES=\"zimbra-core zimbra-ldap zimbra-logger zimbra-mta zimbra-dnscache zimbra-snmp zimbra-store zimbra-apache zimbra-spell zimbra-memcached zimbra-proxy \"\n"
  },
  {
    "path": ".circleci/misc/glean_version.pl",
    "content": "#!/usr/bin/perl\n\nuse version;\n\nif($ENV{CIRCLE_BRANCH} =~ \"^release/([0-9]+[.][0-9]+[.][0-9]+)\")\n{\n   print $1 . \"\\n\";\n}\nelse\n{\n   my $V = \"1.0.0\";\n\n   close(STDERR);\n   open(FD, \"-|\", \"git\", \"ls-remote\");\n   while (<FD>)\n   {\n      if ( $_ =~ /refs.*\\/release\\/([0-9]+[.][0-9]+[.])([0-9]+)/ )\n      {\n         my $nV = $1 . ( $2 + 1 );\n\n         if( ( version->parse($nV) <=> version->parse($V) ) gt 0 )\n         {\n            $V = $nV;\n         }\n      }\n   }\n\n   close(FD);\n\n   print $V . \"\\n\"\n}\n"
  },
  {
    "path": ".circleci/misc/status_api.sh",
    "content": "#!/bin/bash\n\nset -e -o pipefail\n\ncurl -Ls \"https://circleci.com/api/v1.1/project/github/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/$CIRCLE_BUILD_NUM?circle-token=$CIRCLE_API_TOKEN\"\n"
  },
  {
    "path": ".gitignore",
    "content": ".build.last_no_ts\n.build.number\n.idea\nconfig.build\nRE/BUILD\nRE/MAJOR\nRE/MICRO\nRE/MINOR\n"
  },
  {
    "path": ".project",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<projectDescription>\n\t<name>ZimbraBuild</name>\n\t<comment></comment>\n\t<projects>\n\t</projects>\n\t<buildSpec>\n\t</buildSpec>\n\t<natures>\n\t</natures>\n</projectDescription>\n"
  },
  {
    "path": "RE/MICRO_WIN",
    "content": "1_M1\n"
  },
  {
    "path": "RE/README.txt",
    "content": "Included:\n\nBinary release:\n\tREADME.txt - this file\n\tinstall.sh - install script\n\tbin/ - binaries used during install\n\tdata/ - contains installation data\n\tpackages/ - contains ZCS rpms\n\tdocs/ - more documentation\n\nSource release:\n\tREADME.txt - this file\n\tsrc/ - source files\n\tdocs/ - more documentation\n\nInstalling from binary:\n\ttar xzf zcs.tgz\n\tcd zcs\n\t./install.sh\n\nInstalling from source:\n \tConsult the file readme_source.txt\n"
  },
  {
    "path": "RE/RELEASE",
    "content": "1\n"
  },
  {
    "path": "README.md",
    "content": "# zm-build\n\n## Introduction\n\nThis repository contains the build script and supporting files required to create a [FOSS](https://en.wikipedia.org/wiki/Free_and_open-source_software) build of the [Zimbra Collaboration Suite](https://www.zimbra.com/). \n\n## Overview\n\n* `build.pl` - Invoke this script to produce a build.  See the *Building* section \n  below for an example.\n* `instructions/`\n    * `FOSS_remote_list.pl` - Maps between remote label and URL\n    * `FOSS_repo_list.pl` - Specifies which branches (or tags) are checked out to\n      build each component repository.\n    * `FOSS_staging_list.pl` - defines the staging order and details.\n\n## Setup with Zimbra Development Images (used for building)\n\n* Set up docker on your box\n* You can then pull and run using development images (built from Zimbra/zm-base-os.git)\n* In case you need to customize the images for your purposes, you could maintain your own Dockerfile such as this:\n\n        $ cat Dockerfile\n        FROM zimbra/zm-base-os:devcore-ubuntu-16.04\n        RUN sudo apt-get install emacs my-special-tool etc..\n        RUN ...\n\n        $ docker build -t myuser/my-devcore-ubuntu-16 .\n        $ docker run -it myuser/my-devcore-ubuntu-16 bash\n\n### Ubuntu 16.04\n\n    docker run -it zimbra/zm-base-os:devcore-ubuntu-16.04 bash\n\n### CentOS 7\n\n    docker run -it zimbra/zm-base-os:devcore-centos-7 bash\n\n### CentOS 6\n\n    docker run -it zimbra/zm-base-os:devcore-centos-6 bash\n\n    # some tools are installed inside /home/build/.zm-dev-tools/, zm-build automatically sources this path.\n\n## Setup (traditional)\n\n### Ubuntu 16.04\n\nThe following steps assume that your are starting with a clean VM and are\nlogged in as a non-root user with `sudo` privileges.\n\n    sudo apt-get update\n    sudo apt-get install software-properties-common openjdk-8-jdk ant ant-optional ant-contrib ruby git maven build-essential debhelper\n\n### CentOS 7\n\n    sudo yum groupinstall 'Development Tools'\n    sudo yum install java-1.8.0-openjdk ant ant-junit ruby git maven cpan wget perl-IPC-Cmd\n\n### CentOS 6\n\n    sudo yum groupinstall 'Development Tools'\n    sudo yum remove java-1.7.0-openjdk java-1.6.0-openjdk ant\n    sudo yum install java-1.8.0-openjdk java-1.8.0-openjdk-devel ruby git cpan wget\n    # install specific perl modules\n    sudo cpan IPC::Cmd\n    cd /tmp\n    # install maven\n    wget http://mirror.metrocast.net/apache/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz\n    sudo tar -xf apache-maven-3.3.9-bin.tar.gz\n    sudo mv apache-maven-3.3.9 /opt\n    echo 'export PATH=\"/opt/apache-maven-3.3.9/bin:$PATH\"' | sudo tee -a /etc/profile.d/maven.sh\n    # install current version of ant\n    wget https://www.apache.org/dist/ant/binaries/apache-ant-1.9.9-bin.zip\n    sudo unzip apache-ant-1.9.9-bin.zip\n    sudo mv apache-ant-1.9.9 /opt\n    echo 'export PATH=\"/opt/apache-ant-1.9.9/bin:$PATH\"' | sudo tee -a /etc/profile.d/ant.sh\n\n## Building\nCreate a directory for your build and check-out the `zm-build` repository:\nBuild from develop branch\n\n    mkdir installer-build\n    cd installer-build\n    git clone https://github.com/Zimbra/zm-build.git\n    cd zm-build\n    git checkout origin/develop\n    ENV_CACHE_CLEAR_FLAG=true ./build.pl --ant-options -DskipTests=true --ant-options -DskipCoverage=true --ant-options -DskipSonarScan=true --git-default-branch=develop --build-release-no=10.1.0 --build-type=FOSS --build-release=LIBERTY --build-release-candidate=GA --build-thirdparty-server=files.zimbra.com --no-interactive\n\nBuild 10.1.0\n\n```\nmkdir installer-build\ncd installer-build\ngit clone --depth 1 --branch 10.1.0 git@github.com:Zimbra/zm-build.git\ncd zm-build\nENV_CACHE_CLEAR_FLAG=true ./build.pl --ant-options -DskipTests=true --git-default-tag=10.1.0 --build-release-no=10.1.0 --build-type=FOSS --build-release=LIBERTY --build-release-candidate=GA --build-thirdparty-server=files.zimbra.com --no-interactive\n```\n\nTo build a specific patch example 10.0.8 run the following:\n\n```\nmkdir installer-build\ncd installer-build\ngit clone --depth 1 --branch 10.0.6 git@github.com:Zimbra/zm-build.git\ncd zm-build\nENV_CACHE_CLEAR_FLAG=true ./build.pl --ant-options -DskipTests=true --git-default-tag=10.0.8,10.0.7,10.0.6,10.0.5,10.0.4,10.0.3,10.0.2,10.0.1,10.0.0-GA --build-release-no=10.0.8 --build-type=FOSS --build-release=LIBERTY --build-release-candidate=GA --build-thirdparty-server=files.zimbra.com --no-interactive\n```\n\nOr for example 9.0.0.p40 run the following:\n\n```\nmkdir installer-build\ncd installer-build\ngit clone --depth 1 --branch 9.0.0.p38 git@github.com:Zimbra/zm-build.git\ncd zm-build\nENV_CACHE_CLEAR_FLAG=true ./build.pl --ant-options -DskipTests=true --git-default-tag=9.0.0.p40,9.0.0.p39,9.0.0.p38,9.0.0.p37,9.0.0.p36,9.0.0.p35,9.0.0.p34,9.0.0.p33,9.0.0.p32.1,9.0.0.p32,9.0.0.p31,9.0.0.p30,9.0.0.p29,9.0.0.p28,9.0.0.p27,9.0.0.p26,9.0.0.p25,9.0.0.p24.1,9.0.0.p24,9.0.0.p23,9.0.0.p22,9.0.0.p21,9.0.0.p20,9.0.0.p19,9.0.0.p18,9.0.0.p17,9.0.0.p16,9.0.0.p15,9.0.0.p14,9.0.0.p13,9.0.0.p12,9.0.0.p11,9.0.0.p10,9.0.0.p9,9.0.0.p8,9.0.0.p7,9.0.0.p6.1,9.0.0.p6,9.0.0.p5,9.0.0.p4,9.0.0.p3,9.0.0.p2,9.0.0.p1,9.0.0 --build-release-no=9.0.0 --build-type=FOSS --build-release=KEPLER --build-release-candidate=GA --build-thirdparty-server=files.zimbra.com --no-interactive\n```\n\nThe `build.pl` command is used to build the product. Run it with the `-h` option for help:\n\n    Usage: ./build.pl <options>\n    Supported options:\n       --build-no=i\n       --build-ts=i\n       --build-artifacts-base-dir=s\n       --build-sources-base-dir=s\n       --build-release=s\n       --build-release-no=s\n       --build-release-candidate=s\n       --build-type=s\n       --build-thirdparty-server=s\n       --build-prod-flag!\n       --build-debug-flag!\n       --build-dev-tool-base-dir=s\n       --interactive!\n       --git-overrides=s%\n       --git-default-tag=s\n       --git-default-remote=s\n       --git-default-branch=s\n       --stop-after-checkout!\n\nYou _can_ specify all the options on the command-line, as follows:\n\n    ./build.pl --build-no=1713 --build-ts=`date +'%Y%m%d%H%M%S'` \\\n      --build-release=JUDASPRIEST --build-release-no=8.7.6 \\\n      --build-release-candidate=GA --build-type=FOSS \\\n      --build-thirdparty-server=files.zimbra.com --no-interactive\n\nThe completed build will be archived into a `*.tgz` file that is stored in the appropriate platform and release-specific\nsubdirectory of the `BUILDS` directory.  The above command, run on an Ubuntu 16.04 machine, created the following:\n\n    $HOME/installer_build/BUILDS/UBUNTU16_64/JUDASPRIEST-876/20170322153033_FOSS/zm-build/zcs-8.7.6_1713.UBUNTU16_64.20170322153033.tgz\n\nYou can also specify any or all of the required options by placing them in a file\ncalled `config.build`.  This file should be at the top level of the `zm-build`\ndirectory.  For example:\n\n    BUILD_NO                    = 1713\n    BUILD_RELEASE               = JUDASPRIEST\n    BUILD_RELEASE_NO            = 8.7.6\n    BUILD_RELEASE_CANDIDATE     = GA\n    BUILD_TYPE                  = FOSS\n    BUILD_THIRDPARTY_SERVER     = files.zimbra.com\n    INTERACTIVE                 = 0\n\nThen just run `./build.pl`.\n\nThe above command, run on a CentOS 7 machine with the options as shown in `config.build`, created the following:\n\n    $HOME/installer-build/BUILDS/RHEL7_64/JUDASPRIEST-876/20170323061131_FOSS/zm-build/zcs-8.7.6_GA_1713.RHEL7_64.20170323061131.tgz\n\n# Development\n\n## Setup\n\nThe following is a walk-through of the basic steps required to do ZCS development.  The first step is to simply install a current FOSS build on the machine that you wish to use.  The instructions that follow assume that this has been done.\n\n\n1. Create `/home/zimbra` and make `zimbra` the owner.\n\n\t\tsudo mkdir /home/zimbra\n\t\tsudo chown zimbra:zimbra /home/zimbra\n\n2. Install  `git`, `ant`, and `ant-contrib` by whichever method is appropriate for your distro:\n\n\t\tsudo apt-get install git ant ant-contrib\n\n\tor\n\n\t\tsudo yum install git ant ant-contrib\n\n3. Configure `/opt/zimbra/.ssh/config` to use your ssh key for the git remotes that you need to access.\n4. Perform the following edits on `/opt/zimbra/.bash_profile`\n   * Comment-out `export LANG=C` and `export LC_ALL=C`.\n   * Add export `LANG=en_US.UTF-8`\n   * Add export `ANT_OPTS=-Ddev.home=/home/zimbra`\n5. Change permissions on files and folders that you will be updating; e.g.,\n\n\t\tsudo chmod -R o+w /opt/zimbra/lib/\n\t\tsudo chmod -R o+w /opt/zimbra/jetty/\n\t\tsudo chown zimbra:zimbra /opt/zimbra\n\t\t\n\t**Note:** If you run `zmfixperms`, some of these permissions will be overwritten.\n\n6. Add file `/opt/zimbra/.gitconfig` and update as needed.  At a minimum:\n\n\t\t[user]\n\t\t\temail = YOUR-EMAIL-ADDRESS\n\t\t\tname = YOUR-FIRST-AND-LAST-NAME\n\n7. As the `zimbra` user, create a base directory under `/home/zimbra` from which to work.\n\n\t\tcd /home/zimbra\n\t\tmkdir zcs\n\t\tcd zcs\n\n8. Now you can clone any repositories that you require and get to work.\n\n## Email Delivery\n\nIf you want email delivery to work, set up a DNS server on your host\nmachine or another VM and configure `zimbraDNSMasterIP` to point to it.\nTo configure `zimbraDNSMasterIP`, do the following as the `zimbra` user:\n\n\tzmprov ms `zmhostname` zimbraDNSMasterIP DNS-SERVER-IP-ADDRESS\n\nYou may receive the following error when trying to send email:\n\n\tNo SMTP hosts available for domain\n\nIf this occurs, you need to manually configure `zimbraSmtpHostname` for your domain(s).\nTo configure `zimbraSmtpHostname`, do the following as the `zimbra` user:\n\n\tzmprov md DOMAIN-NAME zimbraSmtpHostname `zmhostname`\n\n## zm-mailbox example\n\nAs the `zimbra` user, `cd /home/zimbra/zcs`.  Then clone the `zm-mailbox` repository from github\n\n\tgit clone git@github.com:Zimbra/zm-mailbox.git\n\nThe following sub-directories `zm-mailbox` build and deploy separately:\n\n\tclient\n\tcommon\n\tmilter-conf\n\tnative\n\tsoap\n\tstore\n\tstore-conf\n\nThe top-level `build.xml` is used by the `zm-build` scripts to create\nan installer package.  You will not use that for normal development.  There are build-order\ndependencies between the above-listed deployment targets.  These can be determined by \ninspection of the `ivy.xml` files within each subdirectory.\n\nFor example:\n\n\tgrep 'org=\"zimbra\"' store/ivy.xml\n\n\t<dependency org=\"zimbra\" name=\"zm-common\" rev=\"latest.integration\"/>\n\t<dependency org=\"zimbra\" name=\"zm-soap\" rev=\"latest.integration\"/>\n\t<dependency org=\"zimbra\" name=\"zm-client\" rev=\"latest.integration\"/>\n\t<dependency org=\"zimbra\" name=\"zm-native\" rev=\"latest.integration\"/>\n\nHere you can see that the deployment target, `zm-store` (the `store` \nsubdirectory), depends upon `common`, `soap`, `client`, and `native`.  Here is the current\nordering dependencies among all of the `zm-mailbox` deployment targets. The higher-numbered \ndeployment targets depend upon the lower-numbered ones.  Note that `milter-conf` and \n`store-conf` have no cross-dependencies.\n\n1. `native`\n2. `common`\n3. `soap`\n4. `client`\n5. `store`\n\nSo, from the `native` sub-directory:\n\n\tant -Dzimbra.buildinfo.version=8.7.6_GA clean compile publish-local deploy\n\t\nComments:\n\n- The requirement to include `-Dzimbra.buildinfo.version=8.7.6_GA` to ant is due to a change\n  that was made when the FOSS code was moved to GitHub.  You can also just add that option\n  to your `ANT_OPTS` enviroment variable that you defined in `$HOME/.bash_profile` as follows:\n  \n\t  export ANT_OPTS=\"-Ddev.home=/home/zimbra -Dzimbra.buildinfo.version=8.7.6_GA\"\n\t  \n  If you do that, then you can omit that `-D...` argument to the `ant` command and future\n  examples will reflect that.\n- The `publish-local` target adds the artifact to `/home/zimbra/.zcs-deps`, which is \n  included in the Ivy resolution path.\n- The `deploy` target installs the artifact to its run-time location and restarts the appropriate\n  service(s). This will allow you to test your changes.\n\nThen, from the `common`, `soap`, `client`, and `store` sub-directories (in that order):\n\n\tant clean compile publish-local deploy\n\n## Adding a new LDAP Attribute\n\n**WARNING:It is absolutely imperative to avoid duplicate IDs for attributes.\nUnfortunately, that currently isn't a trivial thing to do.  Need to check\nZimbra 8 and Zimbra X along with all development branches.\nIf customers get different setups using different IDs, this makes future upgrade\nscenarios a complete nightmare**\n\nStart by cloning _both_ the `zm-ldap-utilites` and the `zm-mailbox` repositories from GitHub.\nCheck out the appropriate branch of each. Then proceed as follows:\n\n* Add your new attribute to `zm-mailbox/store/conf/attrs/zimbra-attrs.xml`\n* From `zm-common/store` invoke the following command:\n\n\t\tant generate-getters\n\n* Do the following as `root`:\n\n\t\tchmod -R o+w /opt/zimbra/common/etc/openldap/schema\n\t\tchmod o+w /opt/zimbra/conf/zimbra.ldif\n\t\tchmod +w /opt/zimbra/conf/attrs/zimbra-attrs.xml\n\t\tchmod -R o+w /opt/zimbra/common/etc/openldap/zimbra\n\n* Back as the `zimbra` user, invoke the following command from `zm-mailbox/common`:\n\n\t\tant deploy publish-local\n\n* Then from the `zm-mailbox/store` directory:\n\n\t\tant deploy update-ldap-schema\n\n\nYour ZCS development server should now be running with the new attribute(s).  You can test that\nby querying them and modifying them with `zmprov`.  You can `git add ...` and `git commit`\nyour changes now.\n\n\n"
  },
  {
    "path": "build.pl",
    "content": "#!/usr/bin/perl\n\nuse strict;\nuse warnings;\n\nuse Config;\nuse Cwd;\nuse Data::Dumper;\nuse File::Basename;\nuse File::Copy;\nuse Getopt::Long;\nuse IPC::Cmd qw/run/;\nuse Net::Domain;\nuse Term::ANSIColor;\n\nmy $GLOBAL_PATH_TO_SCRIPT_FILE;\nmy $GLOBAL_PATH_TO_SCRIPT_DIR;\nmy $GLOBAL_PATH_TO_TOP;\nmy $CWD;\n\nmy %CFG = ();\n\nBEGIN\n{\n   $ENV{ANSI_COLORS_DISABLED} = 1 if ( !-t STDOUT );\n   $GLOBAL_PATH_TO_SCRIPT_FILE = Cwd::abs_path(__FILE__);\n   $GLOBAL_PATH_TO_SCRIPT_DIR  = dirname($GLOBAL_PATH_TO_SCRIPT_FILE);\n   $GLOBAL_PATH_TO_TOP         = dirname($GLOBAL_PATH_TO_SCRIPT_DIR);\n   $CWD                        = getcwd();\n}\n\nchdir($GLOBAL_PATH_TO_TOP);\n\n##############################################################################################\n\nsub LoadConfiguration($)\n{\n   my $args = shift;\n\n   my $cfg_name    = $args->{name};\n   my $cmd_hash    = $args->{hash_src};\n   my $default_sub = $args->{default_sub};\n\n   my @cfg_list = ();\n   push( @cfg_list, \"config.build\" );\n   push( @cfg_list, \".build.last_no_ts\" ) if ( $ENV{ENV_RESUME_FLAG} );\n\n   my $val;\n   my $src;\n\n   if ( !defined $val )\n   {\n      y/A-Z_/a-z-/ foreach ( my $cmd_name = $cfg_name );\n\n      if ( $cmd_hash && exists $cmd_hash->{$cmd_name} )\n      {\n         $val = $cmd_hash->{$cmd_name};\n         $src = \"cmdline\";\n      }\n   }\n\n   if ( !defined $val )\n   {\n      foreach my $file_basename (@cfg_list)\n      {\n         my $file = \"$GLOBAL_PATH_TO_SCRIPT_DIR/$file_basename\";\n         my $hash = LoadProperties($file)\n           if ( -f $file );\n\n         if ( $hash && exists $hash->{$cfg_name} )\n         {\n            $val = $hash->{$cfg_name};\n            $src = $file_basename;\n            last;\n         }\n      }\n   }\n\n   if ( !defined $val )\n   {\n      if ($default_sub)\n      {\n         $val = &$default_sub($cfg_name);\n         $src = \"default\";\n      }\n   }\n\n   if ( defined $val )\n   {\n      if ( ref($val) eq \"HASH\" )\n      {\n         foreach my $k ( keys %{$val} )\n         {\n            $CFG{$cfg_name}{$k} = ${$val}{$k};\n\n            printf( \" %-35s: %-17s : %s\\n\", $cfg_name, $cmd_hash ? $src : \"detected\", $k . \" => \" . ${$val}{$k} );\n         }\n      }\n      else\n      {\n         $CFG{$cfg_name} = $val;\n         if (ref($val) eq 'ARRAY')\n         {\n            printf( \" %-35s: %-17s : %s\\n\", $cfg_name, $cmd_hash ? $src : \"detected\", join(' ', @$val) );\n         }\n         else\n         {\n            printf( \" %-35s: %-17s : %s\\n\", $cfg_name, $cmd_hash ? $src : \"detected\", $val );\n         }\n      }\n   }\n}\n\nsub InitGlobalBuildVars()\n{\n   {\n      my $destination_name_func = sub {\n         return \"$CFG{BUILD_OS}-$CFG{BUILD_RELEASE}-$CFG{BUILD_RELEASE_NO_SHORT}-$CFG{BUILD_TS}-$CFG{BUILD_TYPE}-$CFG{BUILD_NO}\";\n      };\n\n      my $build_dir_func = sub {\n         return \"$CFG{BUILD_SOURCES_BASE_DIR}/.staging/$CFG{DESTINATION_NAME}\";\n      };\n\n      my %cmd_hash = ();\n\n      my @cmd_args = (\n         { name => \"BUILD_NO\",                   type => \"=i\",  hash_src => \\%cmd_hash, default_sub => sub { return GetNewBuildNo(); }, },\n         { name => \"BUILD_TS\",                   type => \"=i\",  hash_src => \\%cmd_hash, default_sub => sub { return GetNewBuildTs(); }, },\n         { name => \"BUILD_OS\",                   type => \"=s\",  hash_src => \\%cmd_hash, default_sub => sub { return GetBuildOS(); }, },\n         { name => \"BUILD_DESTINATION_BASE_DIR\", type => \"=s\",  hash_src => \\%cmd_hash, default_sub => sub { return \"$GLOBAL_PATH_TO_TOP/BUILDS\"; }, },\n         { name => \"BUILD_SOURCES_BASE_DIR\",     type => \"=s\",  hash_src => \\%cmd_hash, default_sub => sub { return $GLOBAL_PATH_TO_TOP; }, },\n         { name => \"BUILD_RELEASE\",              type => \"=s\",  hash_src => \\%cmd_hash, default_sub => sub { Die(\"@_ not specified\"); }, },\n         { name => \"BUILD_RELEASE_NO\",           type => \"=s\",  hash_src => \\%cmd_hash, default_sub => sub { Die(\"@_ not specified\"); }, },\n         { name => \"BUILD_RELEASE_CANDIDATE\",    type => \"=s\",  hash_src => \\%cmd_hash, default_sub => sub { Die(\"@_ not specified\"); }, },\n         { name => \"BUILD_REVISION\",             type => \"=s\",  hash_src => \\%cmd_hash, default_sub => sub { \"1\"; }, },\n         { name => \"BUILD_TYPE\",                 type => \"=s\",  hash_src => \\%cmd_hash, default_sub => sub { Die(\"@_ not specified\"); }, },\n         { name => \"BUILD_THIRDPARTY_SERVER\",    type => \"=s\",  hash_src => \\%cmd_hash, default_sub => sub { Die(\"@_ not specified\"); }, },\n         { name => \"BUILD_PROD_FLAG\",            type => \"!\",   hash_src => \\%cmd_hash, default_sub => sub { return 1; }, },\n         { name => \"BUILD_DEBUG_FLAG\",           type => \"!\",   hash_src => \\%cmd_hash, default_sub => sub { return 0; }, },\n         { name => \"BUILD_DEV_TOOL_BASE_DIR\",    type => \"=s\",  hash_src => \\%cmd_hash, default_sub => sub { return \"$ENV{HOME}/.zm-dev-tools\"; }, },\n         { name => \"INTERACTIVE\",                type => \"!\",   hash_src => \\%cmd_hash, default_sub => sub { return 1; }, },\n         { name => \"DISABLE_TAR\",                type => \"!\",   hash_src => \\%cmd_hash, default_sub => sub { return 0; }, },\n         { name => \"DISABLE_BUNDLE\",             type => \"!\",   hash_src => \\%cmd_hash, default_sub => sub { return 0; }, },\n         { name => \"EXCLUDE_GIT_REPOS\",          type => \"=s\",  hash_src => \\%cmd_hash, default_sub => sub { return \"\"; }, },\n         { name => \"GIT_OVERRIDES\",              type => \"=s%\", hash_src => \\%cmd_hash, default_sub => sub { return {}; }, },\n         { name => \"GIT_DEFAULT_TAG\",            type => \"=s\",  hash_src => \\%cmd_hash, default_sub => sub { return undef; }, },\n         { name => \"GIT_DEFAULT_REMOTE\",         type => \"=s\",  hash_src => \\%cmd_hash, default_sub => sub { return undef; }, },\n         { name => \"GIT_DEFAULT_BRANCH\",         type => \"=s\",  hash_src => \\%cmd_hash, default_sub => sub { return undef; }, },\n         { name => \"GIT_DEFAULT_REPO_NAME_SUFFIX\", type => \"=s\",  hash_src => \\%cmd_hash, default_sub => sub { return undef; }, },\n         { name => \"STOP_AFTER_CHECKOUT\",        type => \"!\",   hash_src => \\%cmd_hash, default_sub => sub { return 0; }, },\n         { name => \"ANT_OPTIONS\",                type => \"=s@\",  hash_src => \\%cmd_hash, default_sub => sub { return undef; }, },\n         { name => \"MVN_OPTIONS\",                type => \"=s\",  hash_src => \\%cmd_hash, default_sub => sub { return undef; }, },\n         { name => \"BUILD_HOSTNAME\",             type => \"=s\",  hash_src => \\%cmd_hash, default_sub => sub { return Net::Domain::hostfqdn; }, },\n         { name => \"BUILD_ARCH\",                 type => \"=s\",  hash_src => \\%cmd_hash, default_sub => sub { return GetBuildArch(); }, },\n         { name => \"PKG_OS_TAG\",                 type => \"=s\",  hash_src => \\%cmd_hash, default_sub => sub { return GetPkgOsTag(); }, },\n         { name => \"BUILD_REVISION_NORMALIZED\",  type => \"=s\",  hash_src => \\%cmd_hash, default_sub => sub { NormalizeBuildRevision($CFG{BUILD_REVISION}) }, },\n         { name => \"BUILD_RELEASE_NO_SHORT\",     type => \"=s\",  hash_src => \\%cmd_hash, default_sub => sub { my $x = $CFG{BUILD_RELEASE_NO}; $x =~ s/[.]//g; return $x; }, },\n         { name => \"DESTINATION_NAME\",           type => \"=s\",  hash_src => \\%cmd_hash, default_sub => sub { return &$destination_name_func; }, },\n         { name => \"BUILD_DIR\",                  type => \"=s\",  hash_src => \\%cmd_hash, default_sub => sub { return &$build_dir_func; }, },\n         { name => \"DEPLOY_URL_PREFIX\",          type => \"=s\",  hash_src => \\%cmd_hash, default_sub => sub { $CFG{LOCAL_DEPLOY} = 1; return \"http://\" . Net::Domain::hostfqdn . \":8008/$CFG{DESTINATION_NAME}\"; }, },\n         { name => \"DUMP_CONFIG_TO\",             type => \"=s\",  hash_src => \\%cmd_hash, default_sub => sub { return undef; }, },\n      );\n\n      {\n         my @cmd_opts =\n           map { $_->{opt} =~ y/A-Z_/a-z-/; $_; }    # convert the opt named to lowercase to make command line options\n           map { { opt => $_->{name}, opt_s => $_->{type} } }    # create a new hash with keys opt, opt_s\n           grep { $_->{type} }                                   # get only names which have a valid type\n           @cmd_args;\n\n         my $help_func = sub {\n            print \"Usage: $0 <options>\\n\";\n            print \"Supported options: \\n\";\n            print \"   --\" . \"$_->{opt}$_->{opt_s}\\n\" foreach (@cmd_opts);\n            exit(0);\n         };\n         if ( !GetOptions( \\%cmd_hash, ( map { $_->{opt} . $_->{opt_s} } @cmd_opts ), help => $help_func ) )\n         {\n            print Die(\"wrong commandline options, use --help\");\n         }\n      }\n      print \"=========================================================================================================\\n\";\n      LoadConfiguration($_) foreach (@cmd_args);\n      print \"=========================================================================================================\\n\";\n\n      Die( \"Bad version '$CFG{BUILD_RELEASE_NO}'\", \"$@\" )\n        if ( $CFG{BUILD_RELEASE_NO} !~ m/^\\d+[.]\\d+[.]\\d+$/ );\n   }\n\n   foreach my $x (`grep -o '\\\\<[E][N][V]_[A-Z_]*\\\\>' '$GLOBAL_PATH_TO_SCRIPT_FILE' | sort | uniq`)\n   {\n      chomp($x);\n      my $fmt2v = \" %-35s: %s\\n\";\n      printf( $fmt2v, $x, defined $ENV{$x} ? $ENV{$x} : \"(undef)\" );\n   }\n\n   print \"=========================================================================================================\\n\";\n   {\n      $ENV{PATH} = join(\n         \":\",\n         \"$CFG{BUILD_DEV_TOOL_BASE_DIR}/bin/Sencha/Cmd/4.0.2.67\",    #remove nw specific requirements\n         reverse sort glob(\"$CFG{BUILD_DEV_TOOL_BASE_DIR}/*/bin\"),\n         \"$CFG{BUILD_DEV_TOOL_BASE_DIR}/bin\",\n         \"$ENV{PATH}\"\n      );\n\n      my $cc    = DetectPrerequisite(\"cc\");\n      my $cpp   = DetectPrerequisite(\"c++\");\n      my $java  = DetectPrerequisite( \"java\", $ENV{JAVA_HOME} ? \"$ENV{JAVA_HOME}/bin\" : \"\" );\n      my $javac = DetectPrerequisite( \"javac\", $ENV{JAVA_HOME} ? \"$ENV{JAVA_HOME}/bin\" : \"\" );\n      my $mvn   = DetectPrerequisite(\"mvn\");\n      my $ant   = DetectPrerequisite(\"ant\");\n      my $ruby  = DetectPrerequisite(\"ruby\");\n      my $make  = DetectPrerequisite(\"make\");\n\n      $ENV{JAVA_HOME} ||= dirname( dirname( Cwd::realpath($javac) ) );\n      $ENV{PATH} = \"$ENV{JAVA_HOME}/bin:$ENV{PATH}\";\n\n      my $fmt2v = \" %-35s: %s\\n\";\n      printf( $fmt2v, \"USING javac\", \"$javac (JAVA_HOME=$ENV{JAVA_HOME})\" );\n      printf( $fmt2v, \"USING java\",  $java );\n      printf( $fmt2v, \"USING maven\", $mvn );\n      printf( $fmt2v, \"USING ant\",   $ant );\n      printf( $fmt2v, \"USING cc\",    $cc );\n      printf( $fmt2v, \"USING c++\",   $cpp );\n      printf( $fmt2v, \"USING ruby\",  $ruby );\n      printf( $fmt2v, \"USING make\",  $make );\n   }\n\n   print \"=========================================================================================================\\n\";\n\n   if ( $CFG{DUMP_CONFIG_TO} )\n   {\n      open( my $fh, \">\", $CFG{DUMP_CONFIG_TO} ) or Die(\"Could not open '$CFG{DUMP_CONFIG_TO}'\");\n\n      print $fh \"# Dumping config to file...\\n\\n\";\n\n      foreach my $k ( sort keys %CFG )\n      {\n         my $v = $CFG{$k};\n         if ( ref($v) eq \"HASH\" )\n         {\n            foreach my $sk ( sort keys %$v )\n            {\n               printf $fh \"%-30s = %s\\n\", '%' . $k, \"$sk=$v->{$sk}\";\n            }\n         }\n         else\n         {\n            printf $fh \"%-30s = %s\\n\", $k, $v;\n         }\n      }\n\n      print \"NOTE: DUMPED CONFIG TO FILE - $CFG{DUMP_CONFIG_TO}\\n\";\n   }\n\n   print \"NOTE: THIS WILL STOP AFTER CHECKOUTS\\n\"\n     if ( $CFG{STOP_AFTER_CHECKOUT} );\n\n   if ( $CFG{INTERACTIVE} )\n   {\n      print \"Press enter to proceed\";\n      read STDIN, $_, 1;\n   }\n}\n\nsub TranslateToPackagePath\n{\n   my $deploy_pkg_into = shift;\n\n   if ( my $pkg_dir = $deploy_pkg_into )\n   {\n      $pkg_dir = \"zimbra-\" . lc( $CFG{BUILD_TYPE} )\n        if ( $pkg_dir eq \"bundle\" && $CFG{DISABLE_BUNDLE} );\n\n      $pkg_dir .= \"-$ENV{ENV_ARCHIVE_SUFFIX_STR}\"\n        if ( $pkg_dir ne \"bundle\" && $ENV{ENV_ARCHIVE_SUFFIX_STR} );\n\n      return \"$CFG{BUILD_DIR}/zm-packages/$pkg_dir/$CFG{PKG_OS_TAG}\";\n   }\n   else\n   {\n      return undef;\n   }\n}\n\nsub Prepare()\n{\n   RemoveTargetInDir( \".zcs-deps\",   $ENV{HOME} ) if ( $ENV{ENV_CACHE_CLEAR_FLAG} );\n   RemoveTargetInDir( \".ivy2/cache\", $ENV{HOME} ) if ( $ENV{ENV_CACHE_CLEAR_FLAG} );\n\n   open( FD, \">\", \"$GLOBAL_PATH_TO_SCRIPT_DIR/.build.last_no_ts\" );\n   print FD \"BUILD_NO=$CFG{BUILD_NO}\\n\";\n   print FD \"BUILD_TS=$CFG{BUILD_TS}\\n\";\n   close(FD);\n\n   SysExec( \"mkdir\", \"-p\", \"$CFG{BUILD_DIR}\" );\n   SysExec( \"mkdir\", \"-p\", \"$CFG{BUILD_DIR}/logs\" );\n   SysExec( \"mkdir\", \"-p\", \"$ENV{HOME}/.zcs-deps\" );\n   SysExec( \"mkdir\", \"-p\", \"$ENV{HOME}/.ivy2/cache\" );\n\n   SysExec( \"find\", $CFG{BUILD_DIR}, \"-type\", \"f\", \"-name\", \".built.*\", \"-delete\" ) if ( $ENV{ENV_CACHE_CLEAR_FLAG} );\n\n   my @TP_JARS = (\n      \"https://files.zimbra.com/repository/ant-1.7.0-ziputil-patched/ant-1.7.0-ziputil-patched-1.0.jar\",\n      \"https://files.zimbra.com/repository/ant-contrib/ant-contrib-1.0b1.jar\",\n      \"https://files.zimbra.com/repository/jruby/jruby-complete-1.6.3.jar\",\n      \"https://files.zimbra.com/repository/applet/plugin.jar\",\n      \"https://files.zimbra.com/repository/servlet-api/servlet-api-3.1.jar\",\n      \"https://files.zimbra.com/repository/unbound-ldapsdk/unboundid-ldapsdk-2.3.5-se.jar\",\n   );\n\n   for my $j_url (@TP_JARS)\n   {\n      if ( my $f = \"$ENV{HOME}/.zcs-deps/\" . basename($j_url) )\n      {\n         if ( !-f $f )\n         {\n            SysExec( \"wget\", $j_url, \"-O\", \"$f.tmp\" );\n            SysExec( \"mv\", \"$f.tmp\", $f );\n         }\n      }\n   }\n\n   my ( $MAJOR, $MINOR, $MICRO ) = split( /[.]/, $CFG{BUILD_RELEASE_NO} );\n\n   EchoToFile( \"$GLOBAL_PATH_TO_SCRIPT_DIR/RE/BUILD\", $CFG{BUILD_NO} );\n   EchoToFile( \"$GLOBAL_PATH_TO_SCRIPT_DIR/RE/MAJOR\", $MAJOR );\n   EchoToFile( \"$GLOBAL_PATH_TO_SCRIPT_DIR/RE/MINOR\", $MINOR );\n   EchoToFile( \"$GLOBAL_PATH_TO_SCRIPT_DIR/RE/MICRO\", \"${MICRO}_$CFG{BUILD_RELEASE_CANDIDATE}\" );\n\n   close(FD);\n}\n\nsub EvalFile($;$)\n{\n   my $fname = shift;\n\n   my $file = \"$GLOBAL_PATH_TO_SCRIPT_DIR/$fname\";\n\n   Die( \"Error in '$file'\", \"$@\" )\n     if ( !-f $file );\n\n   my @ENTRIES;\n\n   eval `cat '$file'`;\n   Die( \"Error in '$file'\", \"$@\" )\n     if ($@);\n\n   return \\@ENTRIES;\n}\n\nsub LoadRepos()\n{\n   my @agg_repos = ();\n\n   my %exclusions = ();\n   map { $exclusions{$_} = 1; } split(/,/, $CFG{EXCLUDE_GIT_REPOS});\n\n   push( @agg_repos, grep { !exists $exclusions{$_->{name}} } @{ EvalFile(\"instructions/$CFG{BUILD_TYPE}_repo_list.pl\") } );\n\n   return \\@agg_repos;\n}\n\n\nsub LoadRemotes()\n{\n   my %details = @{ EvalFile(\"instructions/$CFG{BUILD_TYPE}_remote_list.pl\") };\n\n   return \\%details;\n}\n\n\nsub LoadBuilds($)\n{\n   my $repo_list = shift;\n\n   my @agg_builds = ();\n\n   push( @agg_builds, @{ EvalFile(\"instructions/$CFG{BUILD_TYPE}_staging_list.pl\") } );\n\n   my %repo_hash = map { $_->{name} => 1 } @$repo_list;\n\n   my @filtered_builds =\n     grep { my $d = $_->{dir}; $d =~ s/\\/.*//; $repo_hash{$d} }    # extract the repository from the 'dir' entry, filter out entries which do not exist in repo_list\n     @agg_builds;\n\n   return \\@filtered_builds;\n}\n\n\nsub Checkout($)\n{\n   my $repo_list = shift;\n\n   print \"\\n\";\n   print \"=========================================================================================================\\n\";\n   print \" Processing \" . scalar(@$repo_list) . \" repositories\\n\";\n   print \"=========================================================================================================\\n\";\n   print \"\\n\";\n\n   my $repo_remote_details = LoadRemotes();\n\n   for my $repo_details (@$repo_list)\n   {\n      Clone( $repo_details, $repo_remote_details );\n   }\n}\n\n\nsub RemoveTargetInDir($$)\n{\n   my $target = shift;\n   my $chdir  = shift;\n\n   s/\\/\\/*/\\//g, s/\\/*$// for ( my $sane_target = $target );    #remove multiple slashes, and ending slashes, dots\n\n   if ( $sane_target && $chdir && -d $chdir )\n   {\n      eval\n      {\n         RunInDir( cd => $chdir, child => sub { SysExec( \"rm\", \"-rf\", $sane_target ); } );\n      };\n   }\n}\n\nsub EmitArchiveAccessInstructions($)\n{\n   my $archive_names = shift;\n\n   if ( -f \"/etc/redhat-release\" )\n   {\n      return <<EOM_DUMP;\n#########################################\n# INSTRUCTIONS TO ACCESS FROM CLIENT BOX\n#########################################\n\nsudo bash -s <<\"EOM_SCRIPT\"\ncat > /etc/yum.repos.d/zimbra-packages.repo <<EOM\n@{[\n   join(\"\\n\",\n      map {\n\"[$_]\nname=Zimbra Package Archive ($_)\nbaseurl=$CFG{DEPLOY_URL_PREFIX}/archives/$_/$CFG{PKG_OS_TAG}/\nenabled=1\ngpgcheck=0\nprotect=0\"\n      }\n      @$archive_names\n   )]}\nEOM\nyum clean all\nEOM_SCRIPT\nEOM_DUMP\n   }\n   else\n   {\n      return <<EOM_DUMP;\n#########################################\n# INSTRUCTIONS TO ACCESS FROM CLIENT BOX\n#########################################\n\nsudo bash -s <<\"EOM_SCRIPT\"\ncat > /etc/apt/sources.list.d/zimbra-packages.list << EOM\n@{[\n   join(\"\\n\",\n      map {\n\"deb [trusted=yes] $CFG{DEPLOY_URL_PREFIX}/archives/$_/$CFG{PKG_OS_TAG} ./ # Zimbra Package Archive ($_)\"\n      }\n      @$archive_names\n   )]}\nEOM\napt-get update\nEOM_SCRIPT\nEOM_DUMP\n   }\n}\n\n\nsub Build($)\n{\n   my $repo_list = shift;\n\n   my @ALL_BUILDS = @{ LoadBuilds($repo_list) };\n\n   my $tool_attributes = {\n      ant => [\n         \"-Ddebug=$CFG{BUILD_DEBUG_FLAG}\",\n         \"-Dis-production=$CFG{BUILD_PROD_FLAG}\",\n         \"-Dzimbra.buildinfo.platform=$CFG{BUILD_OS}\",\n         \"-Dzimbra.buildinfo.pkg_os_tag=$CFG{PKG_OS_TAG}\",\n         \"-Dzimbra.buildinfo.version=$CFG{BUILD_RELEASE_NO}_$CFG{BUILD_RELEASE_CANDIDATE}_$CFG{BUILD_NO}\",\n         \"-Dzimbra.buildinfo.revision=$CFG{BUILD_REVISION_NORMALIZED}\",\n         \"-Dzimbra.buildinfo.type=$CFG{BUILD_TYPE}\",\n         \"-Dzimbra.buildinfo.release=$CFG{BUILD_TS}\",\n         \"-Dzimbra.buildinfo.date=$CFG{BUILD_TS}\",\n         \"-Dzimbra.buildinfo.host=$CFG{BUILD_HOSTNAME}\",\n         \"-Dzimbra.buildinfo.buildnum=$CFG{BUILD_NO}\",\n      ],\n      make => [\n         \"debug=$CFG{BUILD_DEBUG_FLAG}\",\n         \"is-production=$CFG{BUILD_PROD_FLAG}\",\n         \"zimbra.buildinfo.platform=$CFG{BUILD_OS}\",\n         \"zimbra.buildinfo.pkg_os_tag=$CFG{PKG_OS_TAG}\",\n         \"zimbra.buildinfo.version=$CFG{BUILD_RELEASE_NO}_$CFG{BUILD_RELEASE_CANDIDATE}_$CFG{BUILD_NO}\",\n         \"zimbra.buildinfo.revision=$CFG{BUILD_REVISION_NORMALIZED}\",\n         \"zimbra.buildinfo.type=$CFG{BUILD_TYPE}\",\n         \"zimbra.buildinfo.release=$CFG{BUILD_TS}\",\n         \"zimbra.buildinfo.date=$CFG{BUILD_TS}\",\n         \"zimbra.buildinfo.host=$CFG{BUILD_HOSTNAME}\",\n         \"zimbra.buildinfo.buildnum=$CFG{BUILD_NO}\",\n      ],\n      mvn => [\n      ],\n   };\n\n   push @{ $tool_attributes->{ant} },\n       ref $CFG{ANT_OPTIONS} eq 'ARRAY' ? @{ $CFG{ANT_OPTIONS} } : ($CFG{ANT_OPTIONS})\n       if defined $CFG{ANT_OPTIONS};\n     \n   push( @{ $tool_attributes->{mvn} }, $CFG{MVN_OPTIONS} )\n       if ( $CFG{MVN_OPTIONS} );\n\n   my $cnt = 0;\n   for my $build_info (@ALL_BUILDS)\n   {\n      ++$cnt;\n\n      if ( my $dir = $build_info->{dir} )\n      {\n         my $target_dir = \"$CFG{BUILD_DIR}/$dir\";\n\n         next\n           unless ( !defined $ENV{ENV_BUILD_INCLUDE} || grep { $dir =~ /$_/ } split( \",\", $ENV{ENV_BUILD_INCLUDE} ) );\n\n         RemoveTargetInDir( $dir, $CFG{BUILD_DIR} )\n           if ( ( $ENV{ENV_FORCE_REBUILD} && grep { $dir =~ /$_/ } split( \",\", $ENV{ENV_FORCE_REBUILD} ) ) );\n\n         print \"=========================================================================================================\\n\";\n         print color('blue') . \"BUILDING: $dir ($cnt of \" . scalar(@ALL_BUILDS) . \")\" . color('reset') . \"\\n\";\n         print \"\\n\";\n\n         if ( $ENV{ENV_RESUME_FLAG} && -f \"$target_dir/.built.$CFG{BUILD_TS}\" )\n         {\n            print color('yellow') . \"SKIPPING... [TO REBUILD REMOVE '$target_dir']\" . color('reset') . \"\\n\";\n            print \"=========================================================================================================\\n\";\n            print \"\\n\";\n         }\n         else\n         {\n            unlink glob \"$target_dir/.built.*\";\n\n            RunInDir(\n               cd    => $dir,\n               child => sub {\n\n                  my $abs_dir = Cwd::abs_path();\n\n                  if ( my $tool_seq = $build_info->{tool_seq} || [ \"ant\", \"mvn\", \"make\" ] )\n                  {\n                     for my $tool (@$tool_seq)\n                     {\n                        if ( my $targets = $build_info->{ $tool . \"_targets\" } )    #Known values are: ant_targets, mvn_targets, make_targets\n                        {\n                           eval { SysExec( $tool, \"clean\" ) if ( !$ENV{ENV_SKIP_CLEAN_FLAG} ); };\n\n                           SysExec( $tool, @{ $tool_attributes->{$tool} || [] }, @$targets );\n                        }\n                     }\n                  }\n\n                  if ( my $stage_cmd = $build_info->{stage_cmd} )\n                  {\n                     &$stage_cmd\n                  }\n\n                  if ( my $packages_path = TranslateToPackagePath( $build_info->{deploy_pkg_into} ) )\n                  {\n                     SysExec( \"mkdir\", \"-p\", $packages_path );\n                     SysExec( \"rsync\", \"-av\", \"build/dist/$CFG{PKG_OS_TAG}/\", \"$packages_path/\" );\n                  }\n\n                  if ( !exists $build_info->{partial} )\n                  {\n                     SysExec( \"mkdir\", \"-p\", \"$target_dir\" );\n                     SysExec( \"touch\", \"$target_dir/.built.$CFG{BUILD_TS}\" );\n                  }\n               },\n            );\n\n            print \"\\n\";\n            print \"=========================================================================================================\\n\";\n            print \"\\n\";\n         }\n      }\n   }\n\n   RunInDir(\n      cd    => \"$GLOBAL_PATH_TO_SCRIPT_DIR\",\n      child => sub {\n         SysExec( \"rsync\", \"-az\", \"--delete\", \".\", \"$CFG{BUILD_DIR}/zm-build\" );\n         SysExec( \"mkdir\", \"-p\", \"$CFG{BUILD_DIR}/zm-build/$CFG{BUILD_ARCH}\" );\n\n         my @ALL_PACKAGES = ();\n         push( @ALL_PACKAGES, @{ EvalFile(\"instructions/$CFG{BUILD_TYPE}_package_list.pl\") } );\n         push( @ALL_PACKAGES, \"zcs-bundle\" )\n           if ( !$CFG{DISABLE_TAR} );\n\n         for my $package_script (@ALL_PACKAGES)\n         {\n            if ( !defined $ENV{ENV_PACKAGE_INCLUDE} || grep { $package_script =~ /$_/ } split( \",\", $ENV{ENV_PACKAGE_INCLUDE} ) )\n            {\n               SysExec(\n                  \"  releaseNo='$CFG{BUILD_RELEASE_NO}' \\\\\n                     releaseCandidate='$CFG{BUILD_RELEASE_CANDIDATE}' \\\\\n                     branch='$CFG{BUILD_RELEASE}-$CFG{BUILD_RELEASE_NO_SHORT}' \\\\\n                     buildNo='$CFG{BUILD_NO}' \\\\\n                     os='$CFG{BUILD_OS}' \\\\\n                     PKG_OS_TAG='$CFG{PKG_OS_TAG}' \\\\\n                     buildType='$CFG{BUILD_TYPE}' \\\\\n                     repoDir='$CFG{BUILD_DIR}' \\\\\n                     arch='$CFG{BUILD_ARCH}' \\\\\n                     buildTimeStamp='$CFG{BUILD_TS}' \\\\\n                     buildLogFile='$CFG{BUILD_DIR}/logs/build.log' \\\\\n                     zimbraThirdPartyServer='$CFG{BUILD_THIRDPARTY_SERVER}' \\\\\n                        bash $GLOBAL_PATH_TO_SCRIPT_DIR/instructions/bundling-scripts/$package_script.sh\n                  \"\n               );\n\n               if ( $CFG{DISABLE_BUNDLE} )    # move created packages out of the tar for independent deployment in archive.\n               {\n                  my $alt_dest_pkg_dir = TranslateToPackagePath(\"bundle\");\n\n                  SysExec( \"mkdir\", \"-p\", $alt_dest_pkg_dir );\n                  SysExec( \"rsync\", \"-av\", \"--remove-source-files\", \"$CFG{BUILD_DIR}/zm-build/$CFG{BUILD_ARCH}/\", \"$alt_dest_pkg_dir/\" );\n               }\n            }\n         }\n      },\n   );\n}\n\n\nsub Deploy()\n{\n   print \"\\n\";\n   print \"=========================================================================================================\\n\";\n   print color('blue') . \"DEPLOYING ARTIFACTS\" . color('reset') . \"\\n\";\n   print \"\\n\";\n   print \"\\n\";\n\n   my $destination_dir = \"$CFG{BUILD_DESTINATION_BASE_DIR}/$CFG{DESTINATION_NAME}\";\n\n   SysExec( \"mkdir\", \"-p\", \"$destination_dir/archives\" );\n\n   my @archive_names = map { basename($_) } grep { -d $_ && $_ !~ m/\\/bundle$/ } glob(\"$CFG{BUILD_DIR}/zm-packages/*\");\n\n   foreach my $archive_name (@archive_names)\n   {\n      SysExec( \"rsync\", \"-av\", \"--delete\", \"$CFG{BUILD_DIR}/zm-packages/$archive_name/\", \"$destination_dir/archives/$archive_name\" );\n\n      if ( -f \"/etc/redhat-release\" )\n      {\n         if ( !$CFG{LOCAL_DEPLOY} || DetectPrerequisite( \"createrepo\", \"\", 1 ) )\n         {\n            SysExec(\"cd '$destination_dir/archives/$archive_name/$CFG{PKG_OS_TAG}' && createrepo '.'\");\n         }\n      }\n      else\n      {\n         if ( !$CFG{LOCAL_DEPLOY} || DetectPrerequisite( \"dpkg-scanpackages\", \"\", 1 ) )\n         {\n            SysExec(\"cd '$destination_dir/archives/$archive_name/$CFG{PKG_OS_TAG}' && dpkg-scanpackages '.' /dev/null > Packages\");\n         }\n      }\n   }\n\n   EchoToFile( \"$destination_dir/archive-access-$CFG{PKG_OS_TAG}.txt\", EmitArchiveAccessInstructions( \\@archive_names ) );\n\n   SysExec(\"cp $CFG{BUILD_DIR}/zm-build/zcs-*.$CFG{BUILD_TS}.tgz $destination_dir/\")\n     if ( !$CFG{DISABLE_TAR} );\n\n   if ( $CFG{LOCAL_DEPLOY} )\n   {\n      if ( !-f \"/etc/nginx/conf.d/zimbra-pkg-archives-host.conf\" || !`pgrep -f -P1 '[n]ginx'` )\n      {\n         print \"\\n\";\n         print \"=========================================================================================================\\n\";\n         print <<EOM_DUMP;\n@{[color('bold white')]}\n############################################\n# INSTRUCTIONS TO SETUP NGINX PACKAGES HOST\n############################################\n@{[color('reset')]}\n# You might need to resolve network, firewall, selinux, permissions issues appropriately before proceeding:\n\n# sudo sed -i -e s/^SELINUX=enforcing/SELINUX=permissive/ /etc/selinux/config\n# sudo setenforce permissive\n# sudo systemctl stop firewalld\n# sudo ufw disable\n@{[color('yellow')]}\nsudo bash -s <<\"EOM_SCRIPT\"\n[ -f /etc/redhat-release ] && ( yum install -y epel-release && yum install -y nginx && service nginx start )\n[ -f /etc/redhat-release ] || ( apt-get -y install nginx && service nginx start )\ntee /etc/nginx/conf.d/zimbra-pkg-archives-host.conf <<EOM\nserver {\n  listen 8008;\n  location / {\n     root $CFG{BUILD_DESTINATION_BASE_DIR};\n     autoindex on;\n  }\n}\nEOM\nservice httpd stop 2>/dev/null\nservice nginx restart\nservice nginx status\nEOM_SCRIPT\n@{[color('reset')]}\nEOM_DUMP\n      }\n   }\n\n   print \"\\n\";\n   print \"=========================================================================================================\\n\";\n   print \"\\n\";\n}\n\n\nsub GetNewBuildNo()\n{\n   my $line = 1000;\n\n   my $file = \"$GLOBAL_PATH_TO_SCRIPT_DIR/.build.number\";\n\n   if ( -f $file )\n   {\n      open( FD1, \"<\", $file );\n      $line = <FD1>;\n      close(FD1);\n\n      $line += 1;\n   }\n\n   open( FD2, \">\", $file );\n   printf( FD2 \"%s\\n\", $line );\n   close(FD2);\n\n   return $line;\n}\n\nsub GetNewBuildTs()\n{\n   chomp( my $x = `date +'%Y%m%d%H%M%S'` );\n\n   return $x;\n}\n\n\nsub GetBuildOS()    # FIXME - use standard mechanism\n{\n   our $detected_os = undef;\n\n   sub detect_os\n   {\n      chomp( $detected_os = `$GLOBAL_PATH_TO_SCRIPT_DIR/rpmconf/Build/get_plat_tag.sh` )\n        if ( !$detected_os );\n\n      return $detected_os\n        if ($detected_os);\n\n      Die(\"Unknown OS\");\n   }\n\n   return detect_os();\n}\n\nsub GetBuildArch()\n{\n   my $b_os = $CFG{BUILD_OS};\n\n   return \"amd64\"\n     if ( $b_os =~ /UBUNTU[0-9]+_64/ );\n\n   return \"x86_64\"\n     if ( $b_os =~ /RHEL[0-9]+_64/ || $b_os =~ /CENTOS[0-9]+_64/ );\n\n   Die(\"Could not determine BUILD_ARCH\");\n}\n\nsub GetPkgOsTag()\n{\n   my $b_os = $CFG{BUILD_OS};\n\n   return \"u$1\"\n     if ( $b_os =~ /UBUNTU([0-9]+)_/ );\n\n   return \"r$1\"\n     if ( $b_os =~ /RHEL([0-9]+)_/ || $b_os =~ /CENTOS([0-9]+)_/ );\n\n   Die(\"Could not determine PKG_OS_TAG\");\n}\n\n\n##############################################################################################\n\nsub Clone($$)\n{\n   my $repo_details        = shift;\n   my $repo_remote_details = shift;\n\n   my $repo_name       = $repo_details->{name};\n   my $repo_branch_csv = $CFG{GIT_OVERRIDES}->{\"$repo_name.branch\"} || $repo_details->{branch} || $CFG{GIT_DEFAULT_BRANCH} || \"develop\";\n   my $repo_tag_csv    = $CFG{GIT_OVERRIDES}->{\"$repo_name.tag\"} || $repo_details->{tag} || $CFG{GIT_DEFAULT_TAG} if ( $CFG{GIT_OVERRIDES}->{\"$repo_name.tag\"} || !$CFG{GIT_OVERRIDES}->{\"$repo_name.branch\"} );\n   my $repo_remote     = $CFG{GIT_OVERRIDES}->{\"$repo_name.remote\"} || $repo_details->{remote} || $CFG{GIT_DEFAULT_REMOTE} || \"gh-zm\";\n   my $repo_url_prefix = $CFG{GIT_OVERRIDES}->{\"$repo_remote.url-prefix\"} || $repo_remote_details->{$repo_remote}->{'url-prefix'} || Die( \"unresolved url-prefix for remote='$repo_remote'\", \"\" );\n   my $repo_name_suffix     = $CFG{GIT_OVERRIDES}->{\"$repo_name.repo_name_suffix\"} || $repo_details->{repo_name_suffix} || $CFG{GIT_DEFAULT_REPO_NAME_SUFFIX};\n\n   $repo_url_prefix =~ s,/*$,,;\n\n   my $repo_dir = \"$CFG{BUILD_SOURCES_BASE_DIR}/$repo_name\";\n   my $repo_source = $repo_url_prefix . \"/\" .\n                  ($repo_name_suffix ? \"$repo_name$repo_name_suffix.git\" : \"$repo_name.git\");\n\n   if ( !-d $repo_dir )\n   {\n      my $s = 0;\n      foreach my $minus_b_arg ( split( /,/, $repo_tag_csv ? $repo_tag_csv : $repo_branch_csv ) )\n      {\n         my $r = SysExec(\"git\", \"ls-remote\",\n                $repo_tag_csv ? \"--tags\" : \"--heads\",\n                $repo_source,\n                \"$minus_b_arg\");\n         if ( $r->{success} && \"@{$r->{out}}\" =~ /$minus_b_arg$/ )\n         {\n            my @clone_cmd_args = ( \"git\", \"clone\" );\n\n            push( @clone_cmd_args, \"--depth=1\" ) if ( not $ENV{ENV_GIT_FULL_CLONE} and $repo_name ne \"zm-mailbox\");\n            push( @clone_cmd_args, \"-b\", $minus_b_arg );\n            push( @clone_cmd_args, $repo_source, \"$repo_dir\");\n            print \"\\n\";\n            my $r = SysExec(@clone_cmd_args);\n            if ( $r->{success} )\n            {\n               $s++;\n               last;\n            }\n         }\n      }\n\n      Die(\"Clone Attempts Failed\")\n        if ( !$s );\n\n      RemoveTargetInDir( $repo_name, $CFG{BUILD_DIR} );\n   }\n   else\n   {\n      if ( !defined $ENV{ENV_GIT_UPDATE_INCLUDE} || grep { $repo_name =~ /$_/ } split( \",\", $ENV{ENV_GIT_UPDATE_INCLUDE} ) )\n      {\n         if ($repo_tag_csv)\n         {\n            RunInDir(\n               cd    => $repo_dir,\n               child => sub {\n\n                  my $s = 0;\n                  foreach my $minus_b_arg ( split( /,/, $repo_tag_csv ) )\n                  {\n                     print \"\\n\";\n                     my $r = SysExec( \"git\", \"checkout\", $minus_b_arg );\n                     if ( $r->{success} )\n                     {\n                        $s++;\n                        last;\n                     }\n                  }\n\n                  Die(\"Clone Attempts Failed\")\n                    if ( !$s );\n               },\n            );\n\n            RemoveTargetInDir( $repo_name, $CFG{BUILD_DIR} );\n         }\n         else\n         {\n            print \"\\n\";\n            RunInDir(\n               cd    => $repo_dir,\n               child => sub {\n                  my $z = SysExec( \"git\", \"pull\", \"--ff-only\" );\n\n                  if ( \"@{$z->{out}}\" !~ /Already up-to-date/ )\n                  {\n                     RemoveTargetInDir( $repo_name, $CFG{BUILD_DIR} );\n                  }\n               },\n            );\n         }\n      }\n   }\n}\n\nsub SysExec(@)\n{\n   my $options = shift\n     if ( @_ && ref( $_[0] ) eq \"HASH\" );\n\n   $options->{continue_on_error} ||= 0;\n   $options->{verbose}           ||= 1;\n\n   my $cmd_str = \"@_\";\n\n   if ( $options->{verbose} )\n   {\n      print color('green') . \"#: pwd=@{[Cwd::getcwd()]}\" . color('reset') . \"\\n\";\n      print color('green') . \"#: $cmd_str\" . color('reset') . \"\\n\";\n   }\n\n   $! = 0;\n   my ( $success, $error_message, $full_buf, $stdout_buf, $stderr_buf ) = run( command => \\@_, verbose => 1 );\n\n   Die( \"cmd='$cmd_str'\", $error_message )\n     if ( !$success && !$options->{continue_on_error} );\n\n   return { msg => $error_message, out => $stdout_buf, err => $stderr_buf, success => $success };\n}\n\n\nsub LoadProperties($)\n{\n   my $f = shift;\n\n   my $x = SlurpFile($f);\n\n   my @cfg_kvs =\n     map { $_ =~ s/^\\s+|\\s+$//g; $_ }    # trim\n     map { split( /=/, $_, 2 ) }         # split around =\n     map { $_ =~ s/#.*$//g; $_ }         # strip comments\n     grep { $_ !~ /^\\s*#/ }              # ignore comments\n     grep { $_ !~ /^\\s*$/ }              # ignore empty lines\n     @$x;\n\n   my %ret_hash = ();\n   for ( my $e = 0 ; $e < scalar @cfg_kvs ; $e += 2 )\n   {\n      my $probe_key = $cfg_kvs[$e];\n      my $probe_val = $cfg_kvs[ $e + 1 ];\n\n      if ( $probe_key =~ /^%(.*)/ )\n      {\n         my @val_kv_pair = split( /=/, $probe_val, 2 );\n\n         $ret_hash{$1}{ $val_kv_pair[0] } = $val_kv_pair[1];\n      }\n      else\n      {\n         $ret_hash{$probe_key} = $probe_val;\n      }\n   }\n\n   return \\%ret_hash;\n}\n\n\nsub SlurpFile($)\n{\n   my $f = shift;\n\n   open( FD, \"<\", \"$f\" ) || Die( \"In open for read\", \"file='$f'\" );\n\n   chomp( my @x = <FD> );\n   close(FD);\n\n   return \\@x;\n}\n\n\nsub EchoToFile($$)\n{\n   my $f = shift;\n   my $w = shift;\n\n   open( FD, \">\", \"$f\" ) || Die( \"In open for write\", \"file='$f'\" );\n   print FD $w . \"\\n\";\n   close(FD);\n}\n\n\nsub DetectPrerequisite($;$$)\n{\n   my $util_name       = shift;\n   my $additional_path = shift || \"\";\n   my $warn_only       = shift || 0;\n\n   chomp( my $detected_util = `PATH=\"$additional_path:\\$PATH\" \\\\which \"$util_name\" 2>/dev/null | sed -e 's,//*,/,g'` );\n\n   return $detected_util\n     if ($detected_util);\n\n   Die(\n      \"Prerequisite '$util_name' missing in PATH\"\n        . \"\\nTry: \"\n        . \"\\n   [ -f /etc/redhat-release ] && sudo yum install perl-Data-Dumper perl-IPC-Cmd gcc-c++ java-1.8.0-openjdk ant ant-junit ruby maven wget rpm-build createrepo\"\n        . \"\\n   [ -f /etc/redhat-release ] || sudo apt-get install software-properties-common openjdk-8-jdk ant ant-optional ruby git maven build-essential\",\n      \"\",\n      $warn_only\n   );\n}\n\n\nsub RunInDir(%)\n{\n   my %args  = (@_);\n   my $chdir = $args{cd};\n   my $child = $args{child};\n\n   my $child_pid = fork();\n\n   Die(\"FAILURE while forking\")\n     if ( !defined $child_pid );\n\n   if ( $child_pid != 0 )    # parent\n   {\n      while ( waitpid( $child_pid, 0 ) == -1 ) { }\n\n      Die( \"child $child_pid died\", einfo($?) )\n        if ( $? != 0 );\n   }\n   else\n   {\n      Die( \"chdir to '$chdir' failed\", einfo($?) )\n        if ( $chdir && !chdir($chdir) );\n\n      $! = 0;\n      &$child;\n      exit(0);\n   }\n}\n\nsub einfo()\n{\n   my @SIG_NAME = split( / /, $Config{sig_name} );\n\n   return \"ret=\" . ( $? >> 8 ) . ( ( $? & 127 ) ? \", sig=SIG\" . $SIG_NAME[ $? & 127 ] : \"\" );\n}\n\nsub Die($;$$)\n{\n   my $msg       = shift;\n   my $info      = shift || \"\";\n   my $warn_only = shift || 0;\n\n   my $err = \"$!\";\n\n   print \"\\n\" if ( !$warn_only );\n   print \"\\n\";\n   print \"=========================================================================================================\\n\";\n   print color('red') . \"FAILURE MSG\" . color('reset') . \" : $msg\\n\"  if ( !$warn_only );\n   print color('red') . \"WARNING MSG\" . color('reset') . \" : $msg\\n\"  if ($warn_only);\n   print color('red') . \"SYSTEM ERR \" . color('reset') . \" : $err\\n\"  if ($err);\n   print color('red') . \"EXTRA INFO \" . color('reset') . \" : $info\\n\" if ($info);\n   print \"\\n\";\n   print \"=========================================================================================================\\n\";\n\n   if ( !$warn_only )\n   {\n      print color('red');\n      print \"--Stack Trace-- ($$)\\n\";\n      my $i = 1;\n\n      while ( ( my @call_details = ( caller( $i++ ) ) ) )\n      {\n         print $call_details[1] . \":\" . $call_details[2] . \" called from \" . $call_details[3] . \"\\n\";\n      }\n      print color('reset');\n      print \"\\n\";\n      print \"=========================================================================================================\\n\";\n\n      die \"END\"\n   }\n}\n\nsub NormalizeBuildRevision {\n    my ($val) = @_;\n    return $val unless defined $val;\n\n    if ($CFG{PKG_OS_TAG} =~ /^r/) {\n        return $val if $val =~ /^[\\w]+$/;\n        $val =~ s/[~-]/_/g;\n        $val =~ s/_+/_/g;\n        $val =~ s/^_//;\n        $val =~ s/_$//;\n    }\n\n    return $val;\n}\n\n##############################################################################################\n\nsub main()\n{\n   InitGlobalBuildVars();\n\n   my $all_repos = LoadRepos();\n\n   Prepare();\n\n   Checkout($all_repos);\n\n   if ( !$CFG{STOP_AFTER_CHECKOUT} )\n   {\n      Build($all_repos);\n\n      Deploy();\n   }\n}\n\nmain();\n\n##############################################################################################\n"
  },
  {
    "path": "config.build.in",
    "content": "# Example config:\n# - please change as appropriate.\n# - command line overrides the config.\n\nBUILD_RELEASE           = JUDASPRIEST\nBUILD_RELEASE_NO        = 8.8.0\nBUILD_RELEASE_CANDIDATE = GA\nBUILD_TYPE              = FOSS\nBUILD_THIRDPARTY_SERVER = zdev-vm008.eng.zimbra.com\n\n# Example of GIT_OVERRIDES (hash)\n# %GIT_OVERRIDES          = myremote.url-prefix=ssh://git@stash.corp.synacor.com:7999/~user/zm-mailbox.git\n# %GIT_OVERRIDES          = zm-mailbox.branch=dev\n# %GIT_OVERRIDES          = zm-mailbox.remote=myremote\n# %GIT_OVERRIDES          = zm-mailbox.tag=judaspriest-872    # .tag always overrides .branch\n"
  },
  {
    "path": "instructions/.gitignore",
    "content": "NETWORK_*.pl\n"
  },
  {
    "path": "instructions/FOSS_package_list.pl",
    "content": "@ENTRIES = (\n   \"zimbra-core\",\n   \"zimbra-ldap\",\n   \"zimbra-logger\",\n   \"zimbra-mta\",\n   \"zimbra-dnscache\",\n   \"zimbra-snmp\",\n   \"zimbra-store\",\n   \"zimbra-apache\",\n   \"zimbra-spell\",\n   \"zimbra-proxy\",\n   \"zimbra-imapd\",\n);\n"
  },
  {
    "path": "instructions/FOSS_remote_list.pl",
    "content": "@ENTRIES = (\n   \"gh-zm\" => { 'url-prefix' => \"https://github.com/Zimbra\", },\n   \"gh-ks\" => { 'url-prefix' => \"https://github.com/kohlschutter\", },\n);\n"
  },
  {
    "path": "instructions/FOSS_repo_list.pl",
    "content": "@ENTRIES = (\n   { name => \"ant-1.7.0-ziputil-patched\",            },\n   { name => \"ant-tar-patched\",                      },\n   { name => \"ical4j-0.9.16-patched\",                },\n   { name => \"junixsocket\",                         tag    => \"junixsocket-parent-2.0.4\", remote => \"gh-ks\",},\n   { name => \"nekohtml-1.9.13\",                      },\n   { name => \"java-html-sanitizer-release-20190610.1\",},\n   { name => \"antisamy\",                             },\n   { name => \"zm-admin-console\",                     },\n   { name => \"zm-admin-help-common\",                 },\n   { name => \"zm-ajax\",                              },\n   { name => \"zm-admin-ajax\",                        },\n   { name => \"zm-amavis\",                            },\n   { name => \"zm-aspell\",                            },\n   { name => \"zm-bulkprovision-admin-zimlet\",        },\n   { name => \"zm-bulkprovision-store\",               },\n   { name => \"zm-certificate-manager-admin-zimlet\",  },\n   { name => \"zm-certificate-manager-store\",         },\n   { name => \"zm-charset\",                           },\n   { name => \"zm-clam-scanner-store\",                },\n   { name => \"zm-core-utils\",                        },\n   { name => \"zm-db-conf\",                           },\n   { name => \"zm-dnscache\",                          },\n   { name => \"zm-downloads\",                         },\n   { name => \"zm-freshclam\",                         },\n   { name => \"zm-helptooltip-zimlet\",                },\n   { name => \"zm-jetty-conf\",                        },\n   { name => \"zm-jython\",                            },\n   { name => \"zm-launcher\",                          },\n   { name => \"zm-ldap-utilities\",                    },\n   { name => \"zm-ldap-utils-store\",                  },\n   { name => \"zm-licenses\",                          },\n   { name => \"zm-mailbox\",                           },\n   { name => \"zm-migration-tools\",                   },\n   { name => \"zm-mta\",                               },\n   { name => \"zm-nginx-conf\",                        },\n   { name => \"zm-nginx-lookup-store\",                },\n   { name => \"zm-openid-consumer-store\",             },\n   { name => \"zm-pkg-tool\",                          },\n   { name => \"zm-postfix\",                           },\n   { name => \"zm-proxy-config-admin-zimlet\",         },\n   { name => \"zm-ssdb-ephemeral-store\",              },\n   { name => \"zm-taglib\",                            },\n      # zm-timezones repo can be removed and made independent of zm-zextras\n      # zm-timezones cannot be done unless the packages from it are pushed to public repo\n      # zm-timezones is already excluded in CircleCI builds via --exclude-git-repo=...\n   { name => \"zm-timezones\",                         },\n   { name => \"zm-versioncheck-admin-zimlet\",         },\n   { name => \"zm-versioncheck-store\",                },\n   { name => \"zm-versioncheck-utilities\",            },\n   { name => \"zm-viewmail-admin-zimlet\",             },\n   { name => \"zm-web-client\",                        },\n   { name => \"zm-webclient-portal-example\",          },\n   { name => \"zm-zcs\",                               },\n   { name => \"zm-zcs-lib\",                           },\n   { name => \"zm-zimlets\",                           },\n   { name => \"zm-oauth-social\",                      },\n   { name => \"zm-gql\",\t\t                     },\n);\n"
  },
  {
    "path": "instructions/FOSS_staging_list.pl",
    "content": "@ENTRIES = (\n   {\n      \"dir\"             => \"zm-mailbox\",\n      \"ant_targets\"     => [\"pkg-after-plough-through-tests\"],\n      \"deploy_pkg_into\" => \"bundle\",\n      \"stage_cmd\"       => sub {\n         SysExec(\"mkdir -p                                 $CFG{BUILD_DIR}/zm-mailbox/store-conf/\");\n         SysExec(\"rsync -az store-conf/conf                $CFG{BUILD_DIR}/zm-mailbox/store-conf/\");\n         SysExec(\"install -T -D store/build/dist/versions-init.sql $CFG{BUILD_DIR}/zm-mailbox/store/build/dist/versions-init.sql\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-mailbox/store\",\n      \"ant_targets\" => [\"publish-store-test\", \"test\", \"coverage\", \"sonar-scan\"],\n      \"stage_cmd\"   => undef,\n   },\n   {\n      # This repo can be removed and made independent of zm-zextras\n      # This cannot be done unless the packages from zm-timezones are pushed to public repo\n      # This is already excluded in CircleCI builds\n      \"dir\"             => \"zm-timezones\",\n      \"ant_targets\"     => [\"pkg\", \"sonar-scan\"],\n      \"deploy_pkg_into\" => \"bundle\",\n   },\n   {\n      \"dir\"         => \"junixsocket/junixsocket-native\",\n      \"mvn_targets\" => [\"package\"],\n      \"stage_cmd\"   => sub {\n         SysExec(\"mkdir -p $CFG{BUILD_DIR}/junixsocket/junixsocket-native/build\");\n         SysExec(\"cp -f target/nar/junixsocket-native-*/lib/*/jni/libjunixsocket-native-*.so $CFG{BUILD_DIR}/junixsocket/junixsocket-native/build/\");\n         SysExec(\"cp -f target/junixsocket-native-*.nar  $CFG{BUILD_DIR}/junixsocket/junixsocket-native/build/\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-taglib\",\n      \"ant_targets\" => [\"publish-local\", \"sonar-scan\"],\n      \"stage_cmd\"   => sub {\n         SysExec(\"mkdir -p $CFG{BUILD_DIR}/zm-taglib/build\");\n         SysExec(\"cp -f build/zm-taglib*.jar  $CFG{BUILD_DIR}/zm-taglib/build/\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-charset\",\n      \"ant_targets\" => [\"publish-local\", \"sonar-scan\"],\n      \"stage_cmd\"   => undef,\n   },\n   {\n      \"dir\"         => \"zm-ldap-utilities\",\n      \"ant_targets\" => [\"build-dist\"],\n      \"stage_cmd\"   => sub {\n         SysExec(\"(cd .. && rsync -az --relative zm-ldap-utilities/build/dist $CFG{BUILD_DIR}/)\");\n         SysExec(\"(cd .. && rsync -az --relative zm-ldap-utilities/src/ldap/migration $CFG{BUILD_DIR}/)\");\n         SysExec(\"(cd .. && rsync -az --relative zm-ldap-utilities/conf $CFG{BUILD_DIR}/)\");\n         SysExec(\"(cd .. && rsync -az --relative zm-ldap-utilities/src/libexec $CFG{BUILD_DIR}/)\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-ajax\",\n      \"ant_targets\" => [\"publish-local\", \"sonar-scan\"],\n      \"stage_cmd\"   => undef,\n   },\n   {\n      \"dir\"         => \"zm-admin-ajax\",\n      \"ant_targets\" => [\"publish-local\", \"sonar-scan\"],\n      \"stage_cmd\"   => undef,\n   },\n   {\n      \"dir\"         => \"zm-ssdb-ephemeral-store\",\n      \"ant_targets\" => [\"publish-local\", \"test\", \"coverage\", \"sonar-scan\"],\n      \"stage_cmd\"   => sub {\n         SysExec(\"mkdir -p $CFG{BUILD_DIR}/zm-ssdb-ephemeral-store/build/dist\");\n         SysExec(\"cp -f build/zm-ssdb-ephemeral-store*.jar $CFG{BUILD_DIR}/zm-ssdb-ephemeral-store/build/dist\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-openid-consumer-store\",\n      \"ant_targets\" => [\"dist-package\", \"test\", \"coverage\", \"sonar-scan\"],\n      \"stage_cmd\"   => sub {\n         SysExec(\"mkdir -p $CFG{BUILD_DIR}/zm-openid-consumer-store/build/dist\");\n         SysExec(\"cp -f -r build/dist $CFG{BUILD_DIR}/zm-openid-consumer-store/build/\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-clam-scanner-store\",\n      \"ant_targets\" => [\"publish-local\", \"test\", \"coverage\", \"sonar-scan\"],\n      \"stage_cmd\"   => sub {\n         SysExec(\"mkdir -p $CFG{BUILD_DIR}/zm-clam-scanner-store/build/dist\");\n         SysExec(\"cp -f -rp build/zm-clam-scanner-store-*.jar $CFG{BUILD_DIR}/zm-clam-scanner-store/build/dist\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-licenses\",\n      \"ant_targets\" => undef,\n      \"stage_cmd\"   => sub {\n         SysExec(\"mkdir -p $CFG{BUILD_DIR}/zm-licenses\");\n         SysExec(\"(cd .. && rsync -az --relative zm-licenses/ $CFG{BUILD_DIR}/)\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-nginx-lookup-store\",\n      \"ant_targets\" => [\"publish-local\", \"test\", \"coverage\", \"sonar-scan\"],\n      \"stage_cmd\"   => sub {\n         SysExec(\"mkdir -p $CFG{BUILD_DIR}/zm-nginx-lookup-store/build/dist\");\n         SysExec(\"cp -f -rp build/zm-nginx-lookup-store-*.jar $CFG{BUILD_DIR}/zm-nginx-lookup-store/build/dist\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-versioncheck-admin-zimlet\",\n      \"ant_targets\" => [\"package-zimlet\"],\n      \"stage_cmd\"   => sub {\n         SysExec(\"mkdir -p $CFG{BUILD_DIR}/zm-versioncheck-admin-zimlet/build/zimlet\");\n         SysExec(\"cp -f build/zimlet/*.zip $CFG{BUILD_DIR}/zm-versioncheck-admin-zimlet/build/zimlet\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-bulkprovision-admin-zimlet\",\n      \"ant_targets\" => [\"package-zimlet\"],\n      \"stage_cmd\"   => sub {\n         SysExec(\"mkdir -p $CFG{BUILD_DIR}/zm-bulkprovision-admin-zimlet/build/zimlet\");\n         SysExec(\"cp -f build/zimlet/*.zip $CFG{BUILD_DIR}/zm-bulkprovision-admin-zimlet/build/zimlet\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-certificate-manager-admin-zimlet\",\n      \"ant_targets\" => [\"package-zimlet\"],\n      \"stage_cmd\"   => sub {\n         SysExec(\"mkdir -p $CFG{BUILD_DIR}/zm-certificate-manager-admin-zimlet/build/zimlet\");\n         SysExec(\"cp -f build/zimlet/*.zip $CFG{BUILD_DIR}/zm-certificate-manager-admin-zimlet/build/zimlet\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-proxy-config-admin-zimlet\",\n      \"ant_targets\" => [\"package-zimlet\"],\n      \"stage_cmd\"   => sub {\n         SysExec(\"mkdir -p $CFG{BUILD_DIR}/zm-proxy-config-admin-zimlet/build/zimlet\");\n         SysExec(\"cp -f build/zimlet/*.zip $CFG{BUILD_DIR}/zm-proxy-config-admin-zimlet/build/zimlet\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-helptooltip-zimlet\",\n      \"ant_targets\" => [\"package-zimlet\"],\n      \"stage_cmd\"   => sub {\n         SysExec(\"mkdir -p $CFG{BUILD_DIR}/zm-helptooltip-zimlet/build/zimlet\");\n         SysExec(\"cp -f build/zimlet/*.zip $CFG{BUILD_DIR}/zm-helptooltip-zimlet/build/zimlet\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-viewmail-admin-zimlet\",\n      \"ant_targets\" => [\"package-zimlet\"],\n      \"stage_cmd\"   => sub {\n         SysExec(\"mkdir -p $CFG{BUILD_DIR}/zm-viewmail-admin-zimlet/build/zimlet\");\n         SysExec(\"cp -f build/zimlet/*.zip $CFG{BUILD_DIR}/zm-viewmail-admin-zimlet/build/zimlet\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-zimlets\",\n      \"ant_targets\" => [ \"package-zimlets\", \"jar\", \"sonar-scan\" ],\n      \"stage_cmd\"   => sub {\n         SysExec(\"mkdir -p $CFG{BUILD_DIR}/zm-zimlets/conf\");\n         SysExec(\"cp -f conf/zimbra.tld $CFG{BUILD_DIR}/zm-zimlets/conf\");\n         SysExec(\"cp -f conf/web.xml.production $CFG{BUILD_DIR}/zm-zimlets/conf\");\n         SysExec(\"mkdir -p $CFG{BUILD_DIR}/zm-zimlets/build/dist/zimlets\");\n         SysExec(\"cp -f build/dist/zimlets/*.zip $CFG{BUILD_DIR}/zm-zimlets/build/dist/zimlets\");\n         SysExec(\"mkdir -p $CFG{BUILD_DIR}/zm-zimlets/build/dist\");\n         SysExec(\"cp -f build/dist/lib/zimlettaglib.jar $CFG{BUILD_DIR}/zm-zimlets/build/dist/zimlettaglib.jar\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-web-client\",\n      \"ant_targets\"     => [\"pkg\"],\n      \"deploy_pkg_into\" => \"bundle\",\n   },\n   {\n      \"dir\"         => \"zm-admin-help-common\",\n      \"ant_targets\" => undef,\n      \"stage_cmd\"   => sub {\n         SysExec(\"cp -f -r ../zm-admin-help-common $CFG{BUILD_DIR}\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-versioncheck-utilities\",\n      \"ant_targets\" => undef,\n      \"stage_cmd\"   => sub {\n         SysExec(\"(cd .. && rsync -az --relative zm-versioncheck-utilities/src/libexec/zmcheckversion $CFG{BUILD_DIR}/)\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-webclient-portal-example\",\n      \"ant_targets\" => undef,\n      \"stage_cmd\"   => sub {\n         SysExec(\"cp -f -r ../zm-webclient-portal-example $CFG{BUILD_DIR}\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-downloads\",\n      \"ant_targets\" => undef,\n      \"stage_cmd\"   => sub {\n         SysExec(\"(cd .. && rsync -az --relative --exclude '.git' zm-downloads $CFG{BUILD_DIR}/)\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-db-conf\",\n      \"ant_targets\" => undef,\n      \"stage_cmd\"   => sub {\n         SysExec(\"(cd .. && rsync -az --relative zm-db-conf/src/db/migration $CFG{BUILD_DIR}/)\");\n         SysExec(\"(cd .. && rsync -az --relative zm-db-conf/src/db/mysql     $CFG{BUILD_DIR}/)\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-admin-console\",\n      \"ant_targets\" => [\"pkg\"],\n      \"deploy_pkg_into\" => \"bundle\",\n   },\n   {\n      \"dir\"         => \"zm-aspell\",\n      \"ant_targets\" => undef,\n      \"stage_cmd\"   => sub {\n         SysExec(\"cp -f -r ../zm-aspell $CFG{BUILD_DIR}\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-dnscache\",\n      \"ant_targets\" => undef,\n      \"stage_cmd\"   => sub {\n         SysExec(\"cp -f -r ../zm-dnscache $CFG{BUILD_DIR}\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-amavis\",\n      \"ant_targets\" => undef,\n      \"stage_cmd\"   => sub {\n         SysExec(\"cp -f -r ../zm-amavis $CFG{BUILD_DIR}\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-nginx-conf\",\n      \"ant_targets\" => undef,\n      \"stage_cmd\"   => sub {\n         SysExec(\"cp -f -r ../zm-nginx-conf $CFG{BUILD_DIR}\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-postfix\",\n      \"ant_targets\" => undef,\n      \"stage_cmd\"   => sub {\n         SysExec(\"cp -f -r ../zm-postfix $CFG{BUILD_DIR}\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-core-utils\",\n      \"ant_targets\" => undef,\n      \"stage_cmd\"   => sub {\n         SysExec(\"cp -f -r ../zm-core-utils $CFG{BUILD_DIR}\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-migration-tools\",\n      \"ant_targets\" => undef,\n      \"stage_cmd\"   => sub {\n         SysExec(\"cp -f -r ../zm-migration-tools $CFG{BUILD_DIR}\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-bulkprovision-store\",\n      \"ant_targets\" => [\"jar\", \"sonar-scan\"],\n      \"stage_cmd\"   => sub {\n         SysExec(\"mkdir -p $CFG{BUILD_DIR}/zm-bulkprovision-store\");\n         SysExec(\"cp -f -r ../zm-bulkprovision-store/build $CFG{BUILD_DIR}/zm-bulkprovision-store\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-certificate-manager-store\",\n      \"ant_targets\" => [\"jar\", \"sonar-scan\"],\n      \"stage_cmd\"   => sub {\n         SysExec(\"mkdir -p $CFG{BUILD_DIR}/zm-certificate-manager-store\");\n         SysExec(\"cp -f -r ../zm-certificate-manager-store/build $CFG{BUILD_DIR}/zm-certificate-manager-store\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-versioncheck-store\",\n      \"ant_targets\" => [\"jar\", \"sonar-scan\"],\n      \"stage_cmd\"   => sub {\n         SysExec(\"mkdir -p $CFG{BUILD_DIR}/zm-versioncheck-store\");\n         SysExec(\"cp -f -r ../zm-versioncheck-store/build $CFG{BUILD_DIR}/zm-versioncheck-store\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-ldap-utils-store\",\n      \"ant_targets\" => [\"jar\", \"sonar-scan\"],\n      \"stage_cmd\"   => sub {\n         SysExec(\"mkdir -p $CFG{BUILD_DIR}/zm-ldap-utils-store\");\n         SysExec(\"cp -f -r ../zm-ldap-utils-store/build $CFG{BUILD_DIR}/zm-ldap-utils-store\");\n      },\n   },\n   {\n      \"dir\"         => \"ant-1.7.0-ziputil-patched\",\n      \"ant_targets\" => [\"jar\", \"sonar-scan\"],\n      \"stage_cmd\"   => undef,\n   },\n   {\n      \"dir\"         => \"ant-tar-patched\",\n      \"ant_targets\" => [\"jar\", \"sonar-scan\"],\n      \"stage_cmd\"   => undef,\n   },\n   {\n      \"dir\"         => \"nekohtml-1.9.13\",\n      \"ant_targets\" => [\"jar\", \"sonar-scan\"],\n      \"stage_cmd\"   => undef,\n   },\n   {\n      \"dir\"         => \"java-html-sanitizer-release-20190610.1\",\n      \"ant_targets\" => [\"jar\", \"sonar-scan\"],\n      \"stage_cmd\"   => undef,\n   },\n   {\n      \"dir\"         => \"antisamy\",\n      \"ant_targets\" => [\"jar\", \"sonar-scan\"],\n      \"stage_cmd\"   => undef,\n   },\n   {\n      \"dir\"         => \"ical4j-0.9.16-patched\",\n      \"ant_targets\" => [ \"clean-compile\", \"package\", \"sonar-scan\" ],\n      \"stage_cmd\"   => undef,\n   },\n   {\n      \"dir\"         => \"zm-zcs-lib\",\n      \"ant_targets\" => [\"dist\", \"pkg\"],\n      \"stage_cmd\"   => sub {\n         SysExec(\"(cd .. && rsync -az --relative zm-zcs-lib $CFG{BUILD_DIR}/)\");\n      },\n      \"deploy_pkg_into\" => \"bundle\",\n   },\n   {\n      \"dir\"         => \"zm-jython\",\n      \"ant_targets\" => undef,\n      \"stage_cmd\"   => sub {\n         SysExec(\"(cd .. && rsync -az --relative zm-jython $CFG{BUILD_DIR}/)\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-mta\",\n      \"ant_targets\" => undef,\n      \"stage_cmd\"   => sub {\n         SysExec(\"(cd .. && rsync -az --relative zm-mta $CFG{BUILD_DIR}/)\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-freshclam\",\n      \"ant_targets\" => undef,\n      \"stage_cmd\"   => sub {\n         SysExec(\"(cd .. && rsync -az --relative zm-freshclam $CFG{BUILD_DIR}/)\");\n      },\n   },\n   {\n      \"dir\"          => \"zm-launcher\",\n      \"make_targets\" => [\"JAVA_BINARY=/opt/zimbra/common/bin/java\"],\n      \"stage_cmd\"    => sub {\n         SysExec(\"mkdir -p $CFG{BUILD_DIR}/zm-launcher/build/dist\");\n         SysExec(\"cp -f build/zmmailboxd* $CFG{BUILD_DIR}/zm-launcher/build/dist\");\n      },\n   },\n   {\n      \"dir\"         => \"zm-jetty-conf\",\n      \"ant_targets\" => undef,\n      \"stage_cmd\"   => sub {\n         SysExec(\"cp -f -r ../zm-jetty-conf $CFG{BUILD_DIR}\");\n      },\n   },\n   \n   {\n      \"dir\"         => \"zm-oauth-social\",\n      \"ant_targets\" => [\"publish-local\", \"oauth-social-common-jar\", \"oauth-social-jar\", \"test\", \"coverage\", \"sonar-scan\"],\n      \"stage_cmd\"   => sub {\n         SysExec(\"mkdir -p $CFG{BUILD_DIR}/zm-oauth-social/build/dist\");\n         SysExec(\"cp -f -rp build/zm-oauth-social*.jar $CFG{BUILD_DIR}/zm-oauth-social/build/dist\");\n      },\n   },\n   \n   {\n      \"dir\"         => \"zm-gql\",\n      \"ant_targets\" => [\"publish-local\", \"test\", \"coverage\", \"sonar-scan\"],\n      \"stage_cmd\"   => sub {\n         SysExec(\"mkdir -p $CFG{BUILD_DIR}/zm-gql/build/dist\");\n         SysExec(\"cp -f -rp build/zm-gql-*.jar $CFG{BUILD_DIR}/zm-gql/build/dist\");\n      },\n   },\n);\n"
  },
  {
    "path": "instructions/bundling-scripts/.gitignore",
    "content": "zimbra-archiving.sh\nzimbra-convertd.sh\n"
  },
  {
    "path": "instructions/bundling-scripts/utils.sh",
    "content": "#!/bin/bash\n\nCopy()\n{\n   if [ $# -ne 2 ]\n   then\n      echo \"Usage: Copy <file1> <file2>\" 1>&2\n      exit 1;\n   fi\n\n   local src_file=\"$1\"; shift;\n   local dest_file=\"$1\"; shift;\n\n   mkdir -p \"$(dirname \"$dest_file\")\"\n\n   cp -f \"$src_file\" \"$dest_file\"\n}\n\nCpy2()\n{\n   if [ $# -ne 2 ]\n   then\n      echo \"Usage: Cpy2 <file1> <dir>\" 1>&2\n      exit 1;\n   fi\n\n   local src_file=\"$1\"; shift;\n   local dest_dir=\"$1\"; shift;\n\n   mkdir -p \"$dest_dir\"\n\n   cp -f \"$src_file\" \"$dest_dir\"\n}\n\n\nCreatePackage()\n{\n    if [ $# -ne 1 ]\n    then\n      echo \"Usage: CreatePackage <os-name>\" 1>&2\n      exit 1\n    fi\n\n    if [[ $1 == UBUNTU* ]]\n    then\n        CreateDebianPackage\n    elif [[ $1 == RHEL* ]]\n    then\n        CreateRhelPackage\n    else\n        echo \"OS not supported. Run using UBUNTU or RHEL system. \"\n        exit 1\n    fi\n\n    if [ $? -ne 0 ]; then\n        echo -e \"\\t### ${currentPackage} package building failed ###\" >> ${buildLogFile}\n    else\n        echo -e \"\\t*** ${currentPackage} package successfully created ***\" >> ${buildLogFile}\n    fi\n\n}\n\n"
  },
  {
    "path": "instructions/bundling-scripts/zcs-bundle.sh",
    "content": "#!/bin/bash\n#\n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n\ncd ${repoDir}/zm-build\n\nif [ \"${buildType}\" = \"NETWORK\" ]\nthen\n   ZCS_REL=zcs-${buildType}-${releaseNo}_${releaseCandidate}_${buildNo}.${os}.${buildTimeStamp}\nelse\n   ZCS_REL=zcs-${releaseNo}_${releaseCandidate}_${buildNo}.${os}.${buildTimeStamp}\nfi\n\nmkdir -p $ZCS_REL/bin\nmkdir -p $ZCS_REL/data\nmkdir -p $ZCS_REL/docs/en_US\nmkdir -p $ZCS_REL/lib/jars\nmkdir -p $ZCS_REL/packages\nmkdir -p $ZCS_REL/util/modules\n\ncp -f ${repoDir}/zm-build/RE/README.txt                                                 ${ZCS_REL}/\ncp -f ${repoDir}/zm-build/rpmconf/Build/checkLicense.pl                                 ${ZCS_REL}/bin\ncp -f ${repoDir}/zm-build/rpmconf/Build/checkService.pl                                 ${ZCS_REL}/bin\ncp -f ${repoDir}/zm-build/rpmconf/Build/get_plat_tag.sh                                 ${ZCS_REL}/bin\ncp -f ${repoDir}/zm-build/rpmconf/Build/zmValidateLdap.pl                               ${ZCS_REL}/bin\ncp -f ${repoDir}/zm-build/rpmconf/Install/Util/addUser.sh                               ${ZCS_REL}/util\ncp -f ${repoDir}/zm-build/rpmconf/Install/Util/globals.sh                               ${ZCS_REL}/util\ncp -f ${repoDir}/zm-build/rpmconf/Install/Util/modules/getconfig.sh                     ${ZCS_REL}/util/modules\ncp -f ${repoDir}/zm-build/rpmconf/Install/Util/modules/packages.sh                      ${ZCS_REL}/util/modules\ncp -f ${repoDir}/zm-build/rpmconf/Install/Util/modules/postinstall.sh                   ${ZCS_REL}/util/modules\ncp -f ${repoDir}/zm-build/rpmconf/Install/Util/utilfunc.sh                              ${ZCS_REL}/util\ncp -f ${repoDir}/zm-build/rpmconf/Install/install.sh                                    ${ZCS_REL}/\ncp -f ${repoDir}/zm-core-utils/src/libexec/zmdbintegrityreport                          ${ZCS_REL}/bin\ncp -f ${repoDir}/zm-mailbox/store/build/dist/versions-init.sql                          ${ZCS_REL}/data\n\n# all local packages to bundle\ncp -f ${repoDir}/zm-build/${arch}/*.*                                                   ${ZCS_REL}/packages\n\nfor pkgf in ${repoDir}/zm-packages/bundle/*/*.{rpm,deb,changes}\ndo\n   if ! [[ \"$pkgf\" =~ src.rpm$ ]]\n   then\n      [ -f \"$pkgf\" ] && cp -f \"$pkgf\"                                                   ${ZCS_REL}/packages\n   fi\ndone\n\nif [ -f \"/etc/redhat-release\" ]\nthen\n   if \\which createrepo 2>&-\n   then\n      ( cd ${ZCS_REL}/packages && createrepo . ) # Create index of packages\n   fi\nelse\n   if \\which dpkg-scanpackages 2>&-\n   then\n      ( cd ${ZCS_REL}/packages && dpkg-scanpackages . /dev/null > Packages ) # Create index of packages\n   fi\nfi\n\nchmod 755 ${ZCS_REL}/bin/checkService.pl\nchmod 755 ${ZCS_REL}/bin/checkLicense.pl\nchmod 755 ${ZCS_REL}/bin/zmValidateLdap.pl\nchmod 755 ${ZCS_REL}/bin/zmdbintegrityreport\nchmod 755 ${ZCS_REL}/install.sh\n\ncp -f ${repoDir}/zm-admin-help-common/WebRoot/help/en_US/admin/pdf/*.pdf                ${ZCS_REL}/docs/en_US\ncp -f ${repoDir}/zm-admin-help-common/WebRoot/help/en_US/admin/txt/readme_binary.txt    ${ZCS_REL}/readme_binary_en_US.txt\n\nif [ \"${buildType}\" = \"NETWORK\" ]\nthen\n   cp -f ${repoDir}/zm-admin-help-network/WebRoot/help/en_US/admin/pdf/*.pdf               ${ZCS_REL}/docs/en_US\n   cp -f ${repoDir}/zm-admin-help-network/WebRoot/help/en_US/admin/txt/readme_binary.txt   ${ZCS_REL}/readme_binary_en_US.txt\n\n   cp -f ${repoDir}/zm-backup-store/build/dist/backup-version-init.sql                     ${ZCS_REL}/data\n   cp -f ${repoDir}/zm-license-tools/build/zm-license-tools-*.jar                          ${ZCS_REL}/lib/jars/zimbra-license-tools.jar\n\n   cp -f ${repoDir}/zm-network-licenses/thirdparty/oracle_jdk_eula.txt                     ${ZCS_REL}/docs/oracle_jdk_eula.txt\n   cp -f ${repoDir}/zm-network-licenses/zimbra/zimbra_network_eula.txt                     ${ZCS_REL}/docs/zimbra_network_eula.txt\n\n   cp -f ${repoDir}/zm-network-build/rpmconf/Install/Util/modules/postinstall.sh           ${ZCS_REL}/util/modules\n   cp -f ${repoDir}/zm-network-build/rpmconf/Util/checkValidBackup                         ${ZCS_REL}/bin/checkValidBackup\n\n   chmod 755 ${ZCS_REL}/bin/checkValidBackup\nelse\n   cp -f ${repoDir}/zm-licenses/zimbra/zcl.txt                                                        ${ZCS_REL}/docs\nfi\n\n##########################################\n\nif [ \"${buildType}\" == \"NETWORK\" ]\nthen\n   echo \"NETWORK\" > ${ZCS_REL}/.BUILD_TYPE\nelse\n   echo \"FOSS\" > ${ZCS_REL}/.BUILD_TYPE\nfi\n\necho \"${buildNo}\"          > ${ZCS_REL}/.BUILD_NUM\necho \"${os}\"               > ${ZCS_REL}/.BUILD_PLATFORM\necho \"${releaseNo}\"        > ${ZCS_REL}/.BUILD_RELEASE_NO\necho \"${releaseCandidate}\" > ${ZCS_REL}/.BUILD_RELEASE_CANDIDATE\necho \"${buildTimeStamp}\"   > ${ZCS_REL}/.BUILD_TIME_STAMP\n\n##########################################\n\ntar czf ${ZCS_REL}.tgz  ${ZCS_REL}\n\necho \"ZCS build completed: ${repoDir}/zm-build/${ZCS_REL}.tgz\"\n"
  },
  {
    "path": "instructions/bundling-scripts/zimbra-apache.sh",
    "content": "#!/bin/bash\n#\n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n\n# Shell script to create zimbra apache package\n\n\n#-------------------- Configuration ---------------------------\n\n    currentScript=`basename $0 | cut -d \".\" -f 1`                          # zimbra-apache\n    currentPackage=`echo ${currentScript}build | cut -d \"-\" -f 2` # apachebuild\n\n\n#-------------------- Build Package ---------------------------\n\nmain()\n{\n    echo -e \"\\tCreate package directories\" >> ${buildLogFile}\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf\n\n    echo -e \"\\tCopy package files\" >> ${buildLogFile}\n    cp ${repoDir}/zm-aspell/conf/httpd.conf ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/httpd.conf\n    cp ${repoDir}/zm-aspell/conf/php.ini ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/php.ini\n\n    CreatePackage \"${os}\"\n}\n\n#-------------------- Util Functions ---------------------------\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"$0\")\" && pwd)\"\n\nsource \"$SCRIPT_DIR/utils.sh\"\n\nCreateDebianPackage()\n{\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/DEBIAN\n    echo -e \"\\tCreate debian package\" >> ${buildLogFile}\n    (cd ${repoDir}/zm-build/${currentPackage}; find . -type f ! -regex '.*?debian-binary.*' ! -regex '.*?DEBIAN.*' -print0 | xargs -0 md5sum | sed -e 's| \\./| |' \\\n        > ${repoDir}/zm-build/${currentPackage}/DEBIAN/md5sums)\n    cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.deb | sed -e \"s/@@VERSION@@/${releaseNo}.${releaseCandidate}.${buildNo}.${os/_/.}/\" -e \"s/@@branch@@/${buildTimeStamp}/\" -e \"s/@@ARCH@@/${arch}/\" \\\n        > ${repoDir}/zm-build/${currentPackage}/DEBIAN/control\n    (cd ${repoDir}/zm-build/${currentPackage}; dpkg -b ${repoDir}/zm-build/${currentPackage} ${repoDir}/zm-build/${arch})\n\n}\n\nCreateRhelPackage()\n{\n  cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.spec | \\\n  sed -e \"s/@@VERSION@@/${releaseNo}_${releaseCandidate}_${buildNo}.${os} /\" \\\n      -e \"s/@@RELEASE@@/${buildTimeStamp}/\" \\\n      -e \"s/^Copyright:/Copyright:/\" > ${repoDir}/zm-build/${currentScript}.spec\n  echo \"%attr(755, zimbra, zimbra) /opt/zimbra/conf\" >> ${repoDir}/zm-build/${currentScript}.spec\n  echo \"%attr(644, zimbra, zimbra) /opt/zimbra/conf/*\" >> ${repoDir}/zm-build/${currentScript}.spec\n  echo \"\" >> ${repoDir}/zm-build/${currentScript}.spec\n  echo \"%clean\" >> ${repoDir}/zm-build/${currentScript}.spec\n  (cd ${repoDir}/zm-build/${currentPackage}; \\\n  rpmbuild --target ${arch} --define '_rpmdir ../' --buildroot=${repoDir}/zm-build/${currentPackage} -bb ${repoDir}/zm-build/${currentScript}.spec )\n}\n\n############################################################################\nmain \"$@\"\n"
  },
  {
    "path": "instructions/bundling-scripts/zimbra-core.sh",
    "content": "#!/bin/bash\n#\n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n\n# Shell script to create zimbra core package\n\n\n#-------------------- Configuration ---------------------------\n\ncurrentScript=\"$(basename \"$0\" | cut -d \".\" -f 1)\"               # zimbra-core\ncurrentPackage=\"$(echo ${currentScript}build | cut -d \"-\" -f 2)\" # corebuild\n\n#-------------------- Util Functions ---------------------------\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"$0\")\" && pwd)\"\n\nsource \"$SCRIPT_DIR/utils.sh\"\n\nCreateDebianPackage()\n{\n   echo -e \"\\tCreate debian package\" >> ${buildLogFile}\n\n   mkdir -p \"${repoDir}/zm-build/${currentPackage}/DEBIAN\";\n\n   cat ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post > ${repoDir}/zm-build/${currentPackage}/DEBIAN/postinst\n   cat ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.pre  > ${repoDir}/zm-build/${currentPackage}/DEBIAN/preinst\n\n   chmod 555 ${repoDir}/zm-build/${currentPackage}/DEBIAN/preinst\n   chmod 555 ${repoDir}/zm-build/${currentPackage}/DEBIAN/postinst\n\n   (\n      set -e;\n      cd ${repoDir}/zm-build/${currentPackage}\n      find . -type f -print0 \\\n         | xargs -0 md5sum \\\n         | grep -v -w \"DEBIAN/.*\" \\\n         | sed -e \"s@ [.][/]@ @\" \\\n         | sort \\\n   ) > ${repoDir}/zm-build/${currentPackage}/DEBIAN/md5sums\n\n   (\n      set -e;\n      MORE_DEPENDS=\", zimbra-timezone-data (>= 1.0.1+1510156506-1.$PKG_OS_TAG) $(find ${repoDir}/zm-packages/ -name \\*.deb \\\n                         | xargs -n1 basename \\\n                         | sed -e 's/_[0-9].*//' \\\n                         | grep -e zimbra-common- \\\n                         | sed '1s/^/, /; :a; {N;s/\\n/, /;ba}')\";\n\n      cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.deb \\\n         | sed -e \"s/@@VERSION@@/${releaseNo}.${releaseCandidate}.${buildNo}.${os/_/.}/\" \\\n               -e \"s/@@branch@@/${buildTimeStamp}/\" \\\n               -e \"s/@@ARCH@@/${arch}/\" \\\n               -e \"s/@@MORE_DEPENDS@@/${MORE_DEPENDS}/\" \\\n               -e \"/^%post$/ r ${currentScript}.post\"\n   ) > ${repoDir}/zm-build/${currentPackage}/DEBIAN/control\n\n   (\n      set -e;\n      cd ${repoDir}/zm-build/${currentPackage}\n      dpkg -b ${repoDir}/zm-build/${currentPackage} ${repoDir}/zm-build/${arch}\n   )\n}\n\nCreateRhelPackage()\n{\n    MORE_DEPENDS=\", zimbra-timezone-data >= 1.0.1+1510156506-1.$PKG_OS_TAG $(find ${repoDir}/zm-packages/ -name \\*.rpm \\\n                       | xargs -n1 basename \\\n                       | sed -e 's/-[0-9].*//' \\\n                       | grep -e zimbra-common- \\\n                       | sed '1s/^/, /; :a; {N;s/\\n/, /;ba}')\";\n\n    cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.spec | \\\n    \tsed -e \"s/@@VERSION@@/${releaseNo}_${releaseCandidate}_${buildNo}.${os}/\" \\\n            \t-e \"s/@@RELEASE@@/${buildTimeStamp}/\" \\\n                -e \"s/@@MORE_DEPENDS@@/${MORE_DEPENDS}/\" \\\n            \t-e \"/^%pre$/ r ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.pre\" \\\n            \t-e \"/Best email money can buy/ a Network edition\" \\\n            \t-e \"/^%post$/ r ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post\" > ${repoDir}/zm-build/${currentScript}.spec\n    (cd ${repoDir}/zm-build/corebuild; find opt -maxdepth 2 -type f -o -type l \\\n    \t| sed -e 's|^|%attr(-, zimbra, zimbra) /|' >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec )\n    echo \"%attr(440, root, root) /etc/sudoers.d/01_zimbra\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(440, root, root) /etc/sudoers.d/02_zimbra-core\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(755, root, root) /opt/zimbra/bin\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(755, zimbra, zimbra) /opt/zimbra/docs\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(444, zimbra, zimbra) /opt/zimbra/docs/*\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n\n    if [ \"${buildType}\" == \"NETWORK\" ]\n    then\n      echo \"%attr(755, zimbra, zimbra) /opt/zimbra/docs/rebranding\" >> \\\n         ${repoDir}/zm-build/${currentScript}.spec\n      echo \"%attr(444, zimbra, zimbra) /opt/zimbra/docs/rebranding/*\" >> \\\n         ${repoDir}/zm-build/${currentScript}.spec\n    fi\n\n    echo \"%attr(755, root, root) /opt/zimbra/contrib\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(755, root, root) /opt/zimbra/libexec\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(755, zimbra, zimbra) /opt/zimbra/logger\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(755, zimbra, zimbra) /opt/zimbra/conf\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(644, zimbra, zimbra) /opt/zimbra/conf/*\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(755, zimbra, zimbra) /opt/zimbra/conf/externaldirsync\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(644, zimbra, zimbra) /opt/zimbra/conf/externaldirsync/*\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(755, zimbra, zimbra) /opt/zimbra/conf/sasl2\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(644, zimbra, zimbra) /opt/zimbra/conf/sasl2/*\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(755, zimbra, zimbra) /opt/zimbra/conf/zmconfigd\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(644, zimbra, zimbra) /opt/zimbra/conf/zmconfigd/*\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(-, zimbra, zimbra) /opt/zimbra/db\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(-, root, root) /opt/zimbra/lib\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(-, zimbra, zimbra) /opt/zimbra/conf/crontabs\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(-, root, root) /opt/zimbra/common/lib/jylibs\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(-, root, root) /opt/zimbra/common/lib/perl5/Zimbra\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(755, zimbra, zimbra) /opt/zimbra/logger/db/work\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"\" >> ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%clean\" >> ${repoDir}/zm-build/${currentScript}.spec\n    (cd ${repoDir}/zm-build/${currentPackage}; \\\n    \trpmbuild --target ${arch} --define '_rpmdir ../' --buildroot=${repoDir}/zm-build/${currentPackage} -bb ${repoDir}/zm-build/${currentScript}.spec )\n}\n\n#-------------------- main packaging ---------------------------\n\nmain()\n{\n   set -e\n\n   Copy ${repoDir}/zm-build/rpmconf/Env/sudoers.d/01_zimbra                                         ${repoDir}/zm-build/${currentPackage}/etc/sudoers.d/01_zimbra\n   Copy ${repoDir}/zm-build/rpmconf/Env/sudoers.d/02_zimbra-core                                    ${repoDir}/zm-build/${currentPackage}/etc/sudoers.d/02_zimbra-core\n\n   Copy ${repoDir}/zm-amavis/conf/amavisd.conf.in                                                   ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/amavisd.conf.in\n   Copy ${repoDir}/zm-amavis/conf/amavisd/amavisd-custom.conf                                       ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/amavisd-custom.conf\n   Copy ${repoDir}/zm-amavis/conf/dspam.conf.in                                                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/dspam.conf.in\n\n   Copy ${repoDir}/zm-build/lib/Zimbra/DB/DB.pm                                                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/DB/DB.pm\n   Copy ${repoDir}/zm-build/lib/Zimbra/LDAP.pm                                                      ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/LDAP.pm\n   Copy ${repoDir}/zm-build/lib/Zimbra/LocalConfig.pm                                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/LocalConfig.pm\n   Copy ${repoDir}/zm-build/lib/Zimbra/Mon/Logger.pm                                                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/Mon/Logger.pm\n   Copy ${repoDir}/zm-build/lib/Zimbra/Mon/LoggerSchema.pm                                          ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/Mon/LoggerSchema.pm\n   Copy ${repoDir}/zm-build/lib/Zimbra/Mon/Zmstat.pm                                                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/Mon/Zmstat.pm\n   Copy ${repoDir}/zm-build/lib/Zimbra/SMTP.pm                                                      ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/SMTP.pm\n   Copy ${repoDir}/zm-build/lib/Zimbra/SOAP/Soap.pm                                                 ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/SOAP/Soap.pm\n   Copy ${repoDir}/zm-build/lib/Zimbra/SOAP/Soap11.pm                                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/SOAP/Soap11.pm\n   Copy ${repoDir}/zm-build/lib/Zimbra/SOAP/Soap12.pm                                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/SOAP/Soap12.pm\n   Copy ${repoDir}/zm-build/lib/Zimbra/SOAP/XmlDoc.pm                                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/SOAP/XmlDoc.pm\n   Copy ${repoDir}/zm-build/lib/Zimbra/SOAP/XmlElement.pm                                           ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/SOAP/XmlElement.pm\n   Copy ${repoDir}/zm-build/lib/Zimbra/Util/Common.pm                                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/Util/Common.pm\n   Copy ${repoDir}/zm-build/lib/Zimbra/Util/LDAP.pm                                                 ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/Util/LDAP.pm\n   Copy ${repoDir}/zm-build/lib/Zimbra/Util/Timezone.pm                                             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/Util/Timezone.pm\n   Copy ${repoDir}/zm-build/lib/Zimbra/ZmClient.pm                                                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/ZmClient.pm\n\n   Copy ${repoDir}/zm-build/rpmconf/Build/get_plat_tag.sh                                           ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/get_plat_tag.sh\n   Copy ${repoDir}/zm-build/rpmconf/Build/get_plat_tag.sh                                           ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/installer/bin/get_plat_tag.sh\n   Copy ${repoDir}/zm-build/rpmconf/Conf/auditswatchrc                                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/auditswatchrc.in\n   Copy ${repoDir}/zm-build/rpmconf/Conf/logswatchrc                                                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/logswatchrc\n   Copy ${repoDir}/zm-build/rpmconf/Conf/swatchrc                                                   ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/swatchrc.in\n   Copy ${repoDir}/zm-build/rpmconf/Conf/zmssl.cnf.in                                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/zmssl.cnf.in\n   Copy ${repoDir}/zm-build/rpmconf/Env/crontabs/crontab                                            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/crontabs/crontab\n   Copy ${repoDir}/zm-build/rpmconf/Env/crontabs/crontab.ldap                                       ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/crontabs/crontab.ldap\n   Copy ${repoDir}/zm-build/rpmconf/Env/crontabs/crontab.logger                                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/crontabs/crontab.logger\n   Copy ${repoDir}/zm-build/rpmconf/Env/crontabs/crontab.mta                                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/crontabs/crontab.mta\n   Copy ${repoDir}/zm-build/rpmconf/Env/crontabs/crontab.store                                      ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/crontabs/crontab.store\n   Copy ${repoDir}/zm-build/rpmconf/Env/zimbra.bash_profile                                         ${repoDir}/zm-build/${currentPackage}/opt/zimbra/.bash_profile\n   Copy ${repoDir}/zm-build/rpmconf/Env/zimbra.bashrc                                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/.bashrc\n   Copy ${repoDir}/zm-build/rpmconf/Env/zimbra.exrc                                                 ${repoDir}/zm-build/${currentPackage}/opt/zimbra/.exrc\n   Copy ${repoDir}/zm-build/rpmconf/Env/zimbra.ldaprc                                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/.ldaprc\n   Copy ${repoDir}/zm-build/rpmconf/Env/zimbra.platform                                             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/.platform\n   Copy ${repoDir}/zm-build/rpmconf/Env/zimbra.viminfo                                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/.viminfo\n   Copy ${repoDir}/zm-build/rpmconf/Img/connection_failed.gif                                       ${repoDir}/zm-build/${currentPackage}/opt/zimbra/logger/db/work/connection_failed.gif\n   Copy ${repoDir}/zm-build/rpmconf/Img/data_not_available.gif                                      ${repoDir}/zm-build/${currentPackage}/opt/zimbra/logger/db/work/data_not_available.gif\n   Copy ${repoDir}/zm-build/rpmconf/Install/Util/addUser.sh                                         ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/addUser.sh\n   Copy ${repoDir}/zm-build/rpmconf/Install/Util/addUser.sh                                         ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/installer/util/addUser.sh\n   Copy ${repoDir}/zm-build/rpmconf/Install/Util/globals.sh                                         ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/installer/util/globals.sh\n   Copy ${repoDir}/zm-build/rpmconf/Install/Util/modules/getconfig.sh                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/installer/util/modules/getconfig.sh\n   Copy ${repoDir}/zm-build/rpmconf/Install/Util/modules/packages.sh                                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/installer/util/modules/packages.sh\n   Copy ${repoDir}/zm-build/rpmconf/Install/Util/modules/postinstall.sh                             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/installer/util/modules/postinstall.sh\n   Copy ${repoDir}/zm-build/rpmconf/Install/Util/utilfunc.sh                                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/installer/util/utilfunc.sh\n   Copy ${repoDir}/zm-build/rpmconf/Install/install.sh                                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/installer/install.sh\n   Copy ${repoDir}/zm-build/rpmconf/Install/postinstall.pm                                          ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/postinstall.pm\n   Copy ${repoDir}/zm-build/rpmconf/Install/preinstall.pm                                           ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/preinstall.pm\n   Copy ${repoDir}/zm-build/rpmconf/Install/zmsetup.pl                                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmsetup.pl\n   Copy ${repoDir}/zm-build/rpmconf/Upgrade/zmupgrade.pm                                            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmupgrade.pm\n\n   Copy ${repoDir}/zm-core-utils/conf/dhparam.pem.zcs                                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/dhparam.pem.zcs\n   Copy ${repoDir}/zm-core-utils/conf/zmlogrotate                                                   ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/zmlogrotate\n   Copy ${repoDir}/zm-core-utils/src/bin/antispam-mysql                                             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/antispam-mysql\n   Copy ${repoDir}/zm-core-utils/src/bin/antispam-mysql.server                                      ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/antispam-mysql.server\n   Copy ${repoDir}/zm-core-utils/src/bin/antispam-mysqladmin                                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/antispam-mysqladmin\n   Copy ${repoDir}/zm-core-utils/src/bin/ldap.production                                            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/ldap\n   Copy ${repoDir}/zm-core-utils/src/bin/mysql                                                      ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/mysql\n   Copy ${repoDir}/zm-core-utils/src/bin/mysql.server                                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/mysql.server\n   Copy ${repoDir}/zm-core-utils/src/bin/mysqladmin                                                 ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/mysqladmin\n   Copy ${repoDir}/zm-core-utils/src/bin/postconf                                                   ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/postconf\n   Copy ${repoDir}/zm-core-utils/src/bin/postfix                                                    ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/postfix\n   Copy ${repoDir}/zm-core-utils/src/bin/qshape                                                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/qshape\n   Copy ${repoDir}/zm-core-utils/src/bin/zmaccts                                                    ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmaccts\n   Copy ${repoDir}/zm-core-utils/src/bin/zmamavisdctl                                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmamavisdctl\n   Copy ${repoDir}/zm-core-utils/src/bin/zmantispamctl                                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmantispamctl\n   Copy ${repoDir}/zm-core-utils/src/bin/zmantispamdbpasswd                                         ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmantispamdbpasswd\n   Copy ${repoDir}/zm-core-utils/src/bin/zmantivirusctl                                             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmantivirusctl\n   Copy ${repoDir}/zm-core-utils/src/bin/zmapachectl                                                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmapachectl\n   Copy ${repoDir}/zm-core-utils/src/bin/zmarchivectl                                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmarchivectl\n   Copy ${repoDir}/zm-core-utils/src/bin/zmauditswatchctl                                           ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmauditswatchctl\n   Copy ${repoDir}/zm-core-utils/src/bin/zmblobchk                                                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmblobchk\n   Copy ${repoDir}/zm-core-utils/src/bin/zmcaldebug                                                 ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmcaldebug\n   Copy ${repoDir}/zm-core-utils/src/bin/zmcbpadmin                                                 ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmcbpadmin\n   Copy ${repoDir}/zm-core-utils/src/bin/zmcbpolicydctl                                             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmcbpolicydctl\n   Copy ${repoDir}/zm-core-utils/src/bin/zmcertmgr                                                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmcertmgr\n   Copy ${repoDir}/zm-core-utils/src/bin/zmclamdctl                                                 ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmclamdctl\n   Copy ${repoDir}/zm-core-utils/src/bin/zmconfigdctl                                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmconfigdctl\n   Copy ${repoDir}/zm-core-utils/src/bin/zmcontactbackup                                            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmcontactbackup\n   Copy ${repoDir}/zm-core-utils/src/bin/zmcontrol                                                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmcontrol\n   Copy ${repoDir}/zm-core-utils/src/bin/zmdedupe                                                   ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmdedupe\n   Copy ${repoDir}/zm-core-utils/src/bin/zmdhparam                                                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmdhparam\n   Copy ${repoDir}/zm-core-utils/src/bin/zmdnscachectl                                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmdnscachectl\n   Copy ${repoDir}/zm-core-utils/src/bin/zmdumpenv                                                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmdumpenv\n   Copy ${repoDir}/zm-core-utils/src/bin/zmfixcalendtime                                            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmfixcalendtime\n   Copy ${repoDir}/zm-core-utils/src/bin/zmfixcalprio                                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmfixcalprio\n   Copy ${repoDir}/zm-core-utils/src/bin/zmfreshclamctl                                             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmfreshclamctl\n   Copy ${repoDir}/zm-core-utils/src/bin/zmgsautil                                                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmgsautil\n   Copy ${repoDir}/zm-core-utils/src/bin/zmhostname                                                 ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmhostname\n   Copy ${repoDir}/zm-core-utils/src/bin/zminnotop                                                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zminnotop\n   Copy ${repoDir}/zm-core-utils/src/bin/zmitemdatafile                                             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmitemdatafile\n   Copy ${repoDir}/zm-core-utils/src/bin/zmjava                                                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmjava\n   Copy ${repoDir}/zm-core-utils/src/bin/zmjavaext                                                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmjavaext\n   Copy ${repoDir}/zm-core-utils/src/bin/zmldappasswd                                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmldappasswd\n   Copy ${repoDir}/zm-core-utils/src/bin/zmldapupgrade                                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmldapupgrade\n   Copy ${repoDir}/zm-core-utils/src/bin/zmlmtpinject                                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmlmtpinject\n   Copy ${repoDir}/zm-core-utils/src/bin/zmlocalconfig                                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmlocalconfig\n   Copy ${repoDir}/zm-core-utils/src/bin/zmloggerctl                                                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmloggerctl\n   Copy ${repoDir}/zm-core-utils/src/bin/zmloggerhostmap                                            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmloggerhostmap\n   Copy ${repoDir}/zm-core-utils/src/bin/zmlogswatchctl                                             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmlogswatchctl\n   Copy ${repoDir}/zm-core-utils/src/bin/zmmailbox                                                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmmailbox\n   Copy ${repoDir}/zm-core-utils/src/bin/zmmailboxdctl                                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmmailboxdctl\n   Copy ${repoDir}/zm-core-utils/src/bin/zmmemcachedctl                                             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmmemcachedctl\n   Copy ${repoDir}/zm-core-utils/src/bin/zmmetadump                                                 ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmmetadump\n   Copy ${repoDir}/zm-core-utils/src/bin/zmmigrateattrs                                             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmmigrateattrs\n   Copy ${repoDir}/zm-core-utils/src/bin/zmmilterctl                                                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmmilterctl\n   Copy ${repoDir}/zm-core-utils/src/bin/zmmtactl                                                   ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmmtactl\n   Copy ${repoDir}/zm-core-utils/src/bin/zmmypasswd                                                 ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmmypasswd\n   Copy ${repoDir}/zm-core-utils/src/bin/zmmysqlstatus                                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmmysqlstatus\n   Copy ${repoDir}/zm-core-utils/src/bin/zmmytop                                                    ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmmytop\n   Copy ${repoDir}/zm-core-utils/src/bin/zmopendkimctl                                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmopendkimctl\n   Copy ${repoDir}/zm-core-utils/src/bin/zmplayredo                                                 ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmplayredo\n   Copy ${repoDir}/zm-core-utils/src/bin/zmprov                                                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmprov\n   Copy ${repoDir}/zm-core-utils/src/bin/zmproxyconf                                                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmproxyconf\n   Copy ${repoDir}/zm-core-utils/src/bin/zmproxyctl                                                 ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmproxyctl\n   Copy ${repoDir}/zm-core-utils/src/bin/zmpython                                                   ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmpython\n   Copy ${repoDir}/zm-core-utils/src/bin/zmredodump                                                 ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmredodump\n   Copy ${repoDir}/zm-core-utils/src/bin/zmsaslauthdctl                                             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmsaslauthdctl\n   Copy ${repoDir}/zm-core-utils/src/bin/zmshutil                                                   ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmshutil\n   Copy ${repoDir}/zm-core-utils/src/bin/zmskindeploy                                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmskindeploy\n   Copy ${repoDir}/zm-core-utils/src/bin/zmsoap                                                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmsoap\n   Copy ${repoDir}/zm-core-utils/src/bin/zmspellctl                                                 ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmspellctl\n   Copy ${repoDir}/zm-core-utils/src/bin/zmsshkeygen                                                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmsshkeygen\n   Copy ${repoDir}/zm-core-utils/src/bin/zmstat-chart                                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmstat-chart\n   Copy ${repoDir}/zm-core-utils/src/bin/zmstat-chart-config                                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmstat-chart-config\n   Copy ${repoDir}/zm-core-utils/src/bin/zmstatctl                                                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmstatctl\n   Copy ${repoDir}/zm-core-utils/src/bin/zmstorectl                                                 ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmstorectl\n   Copy ${repoDir}/zm-core-utils/src/bin/zmswatchctl                                                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmswatchctl\n   Copy ${repoDir}/zm-core-utils/src/bin/zms3config                                                 ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zms3config\n   Copy ${repoDir}/zm-core-utils/src/bin/zmthrdump                                                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmthrdump\n   Copy ${repoDir}/zm-core-utils/src/bin/zmtlsctl                                                   ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmtlsctl\n   Copy ${repoDir}/zm-core-utils/src/bin/zmtotp                                                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmtotp\n   Copy ${repoDir}/zm-core-utils/src/bin/zmtrainsa                                                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmtrainsa\n   Copy ${repoDir}/zm-core-utils/src/bin/zmtzupdate                                                 ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmtzupdate\n   Copy ${repoDir}/zm-core-utils/src/bin/zmupdateauthkeys                                           ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmupdateauthkeys\n   Copy ${repoDir}/zm-core-utils/src/bin/zmvolume                                                   ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmvolume\n   Copy ${repoDir}/zm-core-utils/src/bin/zmzimletctl                                                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmzimletctl\n   Copy ${repoDir}/zm-core-utils/src/bin/zmonlyofficectl                                            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmonlyofficectl\n   Copy ${repoDir}/zm-core-utils/src/bin/zmrabbitmqctl                                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmrabbitmqctl\n   Copy ${repoDir}/zm-core-utils/src/bin/zmonlyofficeinstall                                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmonlyofficeinstall\n   Copy ${repoDir}/zm-core-utils/src/bin/zmlicensectl                                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmlicensectl\n   Copy ${repoDir}/zm-core-utils/src/bin/zmacl                                                      ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmacl\n   Copy ${repoDir}/zm-core-utils/src/contrib/zmfetchercfg                                           ${repoDir}/zm-build/${currentPackage}/opt/zimbra/contrib/zmfetchercfg\n   Copy ${repoDir}/zm-core-utils/src/libexec/600.zimbra                                             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/600.zimbra\n   Copy ${repoDir}/zm-core-utils/src/libexec/client_usage_report.py                                 ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/client_usage_report.py\n   Copy ${repoDir}/zm-core-utils/src/libexec/configrewrite                                          ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/configrewrite\n   Copy ${repoDir}/zm-core-utils/src/libexec/icalmig                                                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/icalmig\n   Copy ${repoDir}/zm-core-utils/src/libexec/libreoffice-installer.sh                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/libreoffice-installer.sh\n   Copy ${repoDir}/zm-core-utils/src/libexec/zcs                                                    ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zcs\n   Copy ${repoDir}/zm-core-utils/src/libexec/zimbra                                                 ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zimbra\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmaltermimeconfig                                      ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmaltermimeconfig\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmantispamdbinit                                       ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmantispamdbinit\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmantispammycnf                                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmantispammycnf\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmcbpolicydinit                                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmcbpolicydinit\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmcheckduplicatemysqld                                 ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmcheckduplicatemysqld\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmcheckexpiredcerts                                    ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmcheckexpiredcerts\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmcleantmp                                             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmcleantmp\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmclientcertmgr                                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmclientcertmgr\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmcompresslogs                                         ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmcompresslogs\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmcomputequotausage                                    ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmcomputequotausage\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmconfigd                                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmconfigd\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmcpustat                                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmcpustat\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmdailyreport                                          ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmdailyreport\n   Copy ${repoDir}/zm-core-utils/src/bin/zmpasswordexpiryreminder                                   ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmpasswordexpiryreminder\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmdbintegrityreport                                    ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmdbintegrityreport\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmdiaglog                                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmdiaglog\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmdkimkeyutil                                          ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmdkimkeyutil\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmdnscachealign                                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmdnscachealign\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmdomaincertmgr                                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmdomaincertmgr\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmexplainslow                                          ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmexplainslow\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmexplainsql                                           ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmexplainsql\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmextractsql                                           ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmextractsql\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmfixperms                                             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmfixperms\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmfixreminder                                          ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmfixreminder\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmgenentitlement                                       ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmgenentitlement\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmgsaupdate                                            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmgsaupdate\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmhspreport                                            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmhspreport\n   Copy ${repoDir}/zm-core-utils/src/libexec/zminiutil                                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zminiutil\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmiostat                                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmiostat\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmiptool                                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmiptool\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmjavawatch                                            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmjavawatch\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmjettyenablelogging                                   ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmjettyenablelogging\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmjsprecompile                                         ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmjsprecompile\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmlogger                                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmlogger\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmloggerinit                                           ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmloggerinit\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmlogprocess                                           ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmlogprocess\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmmsgtrace                                             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmmsgtrace\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmmtainit                                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmmtainit\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmmtastatus                                            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmmtastatus\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmmycnf                                                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmmycnf\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmmyinit                                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmmyinit\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmnotifyinstall                                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmnotifyinstall\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmpostfixpolicyd                                       ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmpostfixpolicyd\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmproxyconfgen                                         ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmproxyconfgen\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmproxyconfig                                          ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmproxyconfig\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmproxypurge                                           ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmproxypurge\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmqaction                                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmqaction\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmqstat                                                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmqstat\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmqueuelog                                             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmqueuelog\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmrc                                                   ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmrc\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmrcd                                                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmrcd\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmresetmysqlpassword                                   ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmresetmysqlpassword\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmrrdfetch                                             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmrrdfetch\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmsacompile                                            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmsacompile\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmsaupdate                                             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmsaupdate\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmserverips                                            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmserverips\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmsetservername                                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmsetservername\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmsnmpinit                                             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmsnmpinit\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmspamextract                                          ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmspamextract\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmstat-allprocs                                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmstat-allprocs\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmstat-cleanup                                         ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmstat-cleanup\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmstat-convertd                                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmstat-convertd\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmstat-cpu                                             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmstat-cpu\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmstat-df                                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmstat-df\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmstat-fd                                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmstat-fd\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmstat-io                                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmstat-io\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmstat-mtaqueue                                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmstat-mtaqueue\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmstat-mysql                                           ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmstat-mysql\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmstat-nginx                                           ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmstat-nginx\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmstat-proc                                            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmstat-proc\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmstat-vm                                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmstat-vm\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmstatuslog                                            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmstatuslog\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmsyslogsetup                                          ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmsyslogsetup\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmthreadcpu                                            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmthreadcpu\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmunbound                                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmunbound\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmupdatedownload                                       ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmupdatedownload\n   Copy ${repoDir}/zm-core-utils/src/libexec/zmupdatezco                                            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmupdatezco\n   Copy ${repoDir}/zm-core-utils/src/perl/migrate20131014-removezca.pl                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20131014-removezca.pl\n\n   Copy ${repoDir}/zm-db-conf/src/db/migration/Migrate.pm                                           ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/Migrate.pm\n   Copy ${repoDir}/zm-db-conf/src/db/migration/clearArchivedFlag.pl                                 ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/clearArchivedFlag.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/fixConversationCounts.pl                             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/fixConversationCounts.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/fixZeroChangeIdItems.pl                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/fixZeroChangeIdItems.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/fixup20080410-SetRsvpTrue.pl                         ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/fixup20080410-SetRsvpTrue.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate-ComboUpdater.pl                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate-ComboUpdater.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050517-AddUnreadColumn.pl                   ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050517-AddUnreadColumn.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050531-RemoveCascadingDeletes.pl            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050531-RemoveCascadingDeletes.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050609-AddDateIndex.pl                      ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050609-AddDateIndex.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050628-ShrinkSyncColumns.pl                 ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050628-ShrinkSyncColumns.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050701-SchemaCleanup.pl                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050701-SchemaCleanup.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050721-MailItemIndexes.pl                   ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050721-MailItemIndexes.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050727-RemoveTypeInvite.pl                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050727-RemoveTypeInvite.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050727a-Volume.pl                           ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050727a-Volume.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050804-SpamToJunk.pl                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050804-SpamToJunk.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050809-AddConfig.pl                         ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050809-AddConfig.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050811-WipeAppointments.pl                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050811-WipeAppointments.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050818-TagsFlagsIndexes.pl                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050818-TagsFlagsIndexes.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050822-TrackChangeDate.pl                   ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050822-TrackChangeDate.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050824-AddMailTransport.sh                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050824-AddMailTransport.sh\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050824a-Volume.pl                           ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050824a-Volume.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050831-SecondaryMsgVolume.pl                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050831-SecondaryMsgVolume.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050916-Volume.pl                            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050916-Volume.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050920-CompressionThreshold.pl              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050920-CompressionThreshold.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050927-DropRedologSequence.pl               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050927-DropRedologSequence.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20051021-UniqueVolume.pl                      ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20051021-UniqueVolume.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20060120-Appointment.pl                       ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20060120-Appointment.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20060412-NotebookFolder.pl                    ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20060412-NotebookFolder.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20060515-AddImapId.pl                         ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20060515-AddImapId.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20060518-EmailedContactsFolder.pl             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20060518-EmailedContactsFolder.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20060708-FlagCalendarFolder.pl                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20060708-FlagCalendarFolder.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20060803-CreateMailboxMetadata.pl             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20060803-CreateMailboxMetadata.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20060807-WikiDigestFixup.sh                   ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20060807-WikiDigestFixup.sh\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20060810-PersistFolderCounts.pl               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20060810-PersistFolderCounts.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20060911-MailboxGroup.pl                      ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20060911-MailboxGroup.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20060929-TypedTombstones.pl                   ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20060929-TypedTombstones.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20061101-IMFolder.pl                          ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20061101-IMFolder.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20061117-TasksFolder.pl                       ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20061117-TasksFolder.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20061120-AddNameColumn.pl                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20061120-AddNameColumn.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20061204-CreatePop3MessageTable.pl            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20061204-CreatePop3MessageTable.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20061205-UniqueAppointmentIndex.pl            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20061205-UniqueAppointmentIndex.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20061212-RepairMutableIndexIds.pl             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20061212-RepairMutableIndexIds.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20061221-RecalculateFolderSizes.pl            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20061221-RecalculateFolderSizes.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070302-NullContactVolumeId.pl               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070302-NullContactVolumeId.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070306-Pop3MessageUid.pl                    ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070306-Pop3MessageUid.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070606-WidenMetadata.pl                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070606-WidenMetadata.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070614-BriefcaseFolder.pl                   ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070614-BriefcaseFolder.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070627-BackupTime.pl                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070627-BackupTime.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070629-IMTables.pl                          ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070629-IMTables.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070630-LastSoapAccess.pl                    ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070630-LastSoapAccess.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070703-ScheduledTask.pl                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070703-ScheduledTask.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070706-DeletedAccount.pl                    ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070706-DeletedAccount.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070713-NullContactBlobDigest.pl             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070713-NullContactBlobDigest.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070725-CreateRevisionTable.pl               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070725-CreateRevisionTable.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070726-ImapDataSource.pl                    ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070726-ImapDataSource.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070809-Signatures.pl                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070809-Signatures.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070921-ImapDataSourceUidValidity.pl         ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070921-ImapDataSourceUidValidity.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070928-ScheduledTaskIndex.pl                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070928-ScheduledTaskIndex.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20071128-AccountId.pl                         ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20071128-AccountId.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20071202-DeleteSignatures.pl                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20071202-DeleteSignatures.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20071204-deleteOldLDAPUsers.pl                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20071204-deleteOldLDAPUsers.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20071206-WidenSizeColumns.pl                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20071206-WidenSizeColumns.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20080130-ImapFlags.pl                         ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20080130-ImapFlags.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20080213-IndexDeferredColumn.pl               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20080213-IndexDeferredColumn.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20080909-DataSourceItemTable.pl               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20080909-DataSourceItemTable.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20080930-MucService.pl                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20080930-MucService.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20090315-MobileDevices.pl                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20090315-MobileDevices.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20090406-DataSourceItemTable.pl               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20090406-DataSourceItemTable.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20090430-highestindexed.pl                    ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20090430-highestindexed.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20100106-MobileDevices.pl                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20100106-MobileDevices.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20100913-Mysql51.pl                           ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20100913-Mysql51.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20100926-Dumpster.pl                          ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20100926-Dumpster.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20101123-MobileDevices.pl                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20101123-MobileDevices.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20110314-MobileDevices.pl                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20110314-MobileDevices.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20110330-RecipientsColumn.pl                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20110330-RecipientsColumn.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20110705-PendingAclPush.pl                    ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20110705-PendingAclPush.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20110810-TagTable.pl                          ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20110810-TagTable.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20110928-MobileDevices.pl                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20110928-MobileDevices.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20110929-VersionColumn.pl                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20110929-VersionColumn.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20111005-ItemIdCheckpoint.pl                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20111005-ItemIdCheckpoint.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20120125-uuidAndDigest.pl                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20120125-uuidAndDigest.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20120222-LastPurgeAtColumn.pl                 ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20120222-LastPurgeAtColumn.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20120229-DropIMTables.pl                      ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20120229-DropIMTables.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20120319-Name255Chars.pl                      ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20120319-Name255Chars.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20120410-BlobLocator.pl                       ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20120410-BlobLocator.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20120611_7to8_bundle.pl                       ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20120611_7to8_bundle.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20121009-VolumeBlobs.pl                       ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20121009-VolumeBlobs.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20130226_alwayson.pl                          ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20130226_alwayson.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20130227-UpgradeCBPolicyDSchema.sql           ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20130227-UpgradeCBPolicyDSchema.sql\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20130606-UpdateCBPolicydSchema.sql            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20130606-UpdateCBPolicydSchema.sql\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20130819-UpgradeQuotasTable.sql               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20130819-UpgradeQuotasTable.sql\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20140319-MailItemPrevFolders.pl               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20140319-MailItemPrevFolders.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20140328-EnforceTableCharset.pl               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20140328-EnforceTableCharset.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20140624-DropMysqlIndexes.pl                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20140624-DropMysqlIndexes.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20150401-ZmgDevices.pl                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20150401-ZmgDevices.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20150515-DataSourcePurgeTables.pl             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20150515-DataSourcePurgeTables.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20150623-ZmgDevices.pl                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20150623-ZmgDevices.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20150702-ZmgDevices.pl                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20150702-ZmgDevices.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20170301-ZimbraChat.pl                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20170301-ZimbraChat.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20180301-ZimbraChat.pl                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20180301-ZimbraChat.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20190401-ZimbraChat.pl                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20190401-ZimbraChat.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20190611-ZimbraChat.pl                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20190611-ZimbraChat.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20210506-BriefcaseApi.pl                      ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20210506-BriefcaseApi.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20200625-MobileDevices.pl                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20200625-MobileDevices.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20210319-MobileDevices.pl                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20210319-MobileDevices.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20210809-UnsubscribeFolder.pl                 ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20210809-UnsubscribeFolder.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20220525-Volume.pl                            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20220525-Volume.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20220721-AddMdmUpdateTimestamp.pl             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20220721-AddMdmUpdateTimestamp.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20220729-FilesShareWithMeFolder.pl            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20220729-FilesShareWithMeFolder.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20230224-UpdateOnlyOffice-7.2.1.pl            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20230224-UpdateOnlyOffice-7.2.1.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrateAmavisLdap20050810.pl                         ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateAmavisLdap20050810.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrateClearSpamFlag.pl                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateClearSpamFlag.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrateLargeMetadata.pl                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateLargeMetadata.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrateLogger1-index.pl                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateLogger1-index.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrateLogger2-config.pl                             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateLogger2-config.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrateLogger3-diskindex.pl                          ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateLogger3-diskindex.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrateLogger4-loghostname.pl                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateLogger4-loghostname.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrateLogger5-qid.pl                                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateLogger5-qid.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrateLogger6-qid.pl                                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateLogger6-qid.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrateMailItemTimestamps.pl                         ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateMailItemTimestamps.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migratePreWidenSizeColumns.pl                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migratePreWidenSizeColumns.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrateRemoveMailboxId.pl                            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateRemoveMailboxId.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrateRemoveTagIndexes.pl                           ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateRemoveTagIndexes.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrateRenameIdentifiers.pl                          ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateRenameIdentifiers.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrateSyncSequence.pl                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateSyncSequence.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrateToSplitTables.pl                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateToSplitTables.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/migrateUpdateAppointment.pl                          ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateUpdateAppointment.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/optimizeMboxgroups.pl                                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/optimizeMboxgroups.pl\n   Copy ${repoDir}/zm-db-conf/src/db/migration/zmdbupgrade.pl                                       ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/zmdbupgrade.pl\n   Copy ${repoDir}/zm-db-conf/src/db/mysql/create_database.sql                                      ${repoDir}/zm-build/${currentPackage}/opt/zimbra/db/create_database.sql\n   Copy ${repoDir}/zm-db-conf/src/db/mysql/db.sql                                                   ${repoDir}/zm-build/${currentPackage}/opt/zimbra/db/db.sql\n\n   Copy ${repoDir}/zm-freshclam/freshclam.conf.in                                                   ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/freshclam.conf.in\n\n   Copy ${repoDir}/zm-jython/jylibs/commands.py                                                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/jylibs/commands.py\n   Copy ${repoDir}/zm-jython/jylibs/conf.py                                                         ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/jylibs/conf.py\n   Copy ${repoDir}/zm-jython/jylibs/config.py                                                       ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/jylibs/config.py\n   Copy ${repoDir}/zm-jython/jylibs/globalconfig.py                                                 ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/jylibs/globalconfig.py\n   Copy ${repoDir}/zm-jython/jylibs/ldap.py                                                         ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/jylibs/ldap.py\n   Copy ${repoDir}/zm-jython/jylibs/listener.py                                                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/jylibs/listener.py\n   Copy ${repoDir}/zm-jython/jylibs/localconfig.py                                                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/jylibs/localconfig.py\n   Copy ${repoDir}/zm-jython/jylibs/logmsg.py                                                       ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/jylibs/logmsg.py\n   Copy ${repoDir}/zm-jython/jylibs/miscconfig.py                                                   ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/jylibs/miscconfig.py\n   Copy ${repoDir}/zm-jython/jylibs/mtaconfig.py                                                    ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/jylibs/mtaconfig.py\n   Copy ${repoDir}/zm-jython/jylibs/serverconfig.py                                                 ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/jylibs/serverconfig.py\n   Copy ${repoDir}/zm-jython/jylibs/state.py                                                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/jylibs/state.py\n\n   Copy ${repoDir}/zm-launcher/build/dist/zmmailboxdmgr                                             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmmailboxdmgr\n   Copy ${repoDir}/zm-launcher/build/dist/zmmailboxdmgr.unrestricted                                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmmailboxdmgr.unrestricted \n\n   Copy ${repoDir}/zm-ldap-utilities/conf/externaldirsync/Exchange2000.xml                          ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/externaldirsync/Exchange2000.xml\n   Copy ${repoDir}/zm-ldap-utilities/conf/externaldirsync/Exchange2003.xml                          ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/externaldirsync/Exchange2003.xml\n   Copy ${repoDir}/zm-ldap-utilities/conf/externaldirsync/Exchange5.5.xml                           ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/externaldirsync/Exchange5.5.xml\n   Copy ${repoDir}/zm-ldap-utilities/conf/externaldirsync/domino.xml                                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/externaldirsync/domino.xml\n   Copy ${repoDir}/zm-ldap-utilities/conf/externaldirsync/novellGroupWise.xml                       ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/externaldirsync/novellGroupWise.xml\n   Copy ${repoDir}/zm-ldap-utilities/conf/externaldirsync/openldap.xml                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/externaldirsync/openldap.xml\n   Copy ${repoDir}/zm-ldap-utilities/conf/freshclam.conf.in                                         ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/freshclam.conf.in\n   Copy ${repoDir}/zm-ldap-utilities/conf/zmconfigd.cf                                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/zmconfigd.cf\n   Copy ${repoDir}/zm-ldap-utilities/conf/zmconfigd.log4j.properties                                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/zmconfigd.log4j.properties\n   Copy ${repoDir}/zm-ldap-utilities/src/ldap/migration/migrate20110615-AddDynlist.pl               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20110615-AddDynlist.pl\n   Copy ${repoDir}/zm-ldap-utilities/src/ldap/migration/migrate20110721-AddUnique.pl                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20110721-AddUnique.pl\n   Copy ${repoDir}/zm-ldap-utilities/src/ldap/migration/migrate20111019-UniqueZimbraId.pl           ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20111019-UniqueZimbraId.pl\n   Copy ${repoDir}/zm-ldap-utilities/src/ldap/migration/migrate20120210-AddSearchNoOp.pl            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20120210-AddSearchNoOp.pl\n   Copy ${repoDir}/zm-ldap-utilities/src/ldap/migration/migrate20120507-UniqueDKIMSelector.pl       ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20120507-UniqueDKIMSelector.pl\n   Copy ${repoDir}/zm-ldap-utilities/src/ldap/migration/migrate20140728-AddSSHA512.pl               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20140728-AddSSHA512.pl\n   Copy ${repoDir}/zm-ldap-utilities/src/ldap/migration/migrate20141022-AddTLSBits.pl               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20141022-AddTLSBits.pl\n   Copy ${repoDir}/zm-ldap-utilities/src/ldap/migration/migrate20150930-AddSyncpovSessionlog.pl     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20150930-AddSyncpovSessionlog.pl\n   Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmldapanon                                         ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmldapanon\n   Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmldapapplyldif                                    ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmldapapplyldif\n   Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmldapenable-mmr                                   ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmldapenable-mmr\n   Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmldapenablereplica                                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmldapenablereplica\n   Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmldapinit                                         ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmldapinit\n   Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmldapmmrtool                                      ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmldapmmrtool\n   Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmldapmonitordb                                    ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmldapmonitordb\n   Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmldappromote-replica-mmr                          ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmldappromote-replica-mmr\n   Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmldapreplicatool                                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmldapreplicatool\n   Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmldapschema                                       ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmldapschema\n   Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmldapupdateldif                                   ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmldapupdateldif\n   Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmreplchk                                          ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmreplchk\n   Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmslapadd                                          ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmslapadd\n   Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmslapcat                                          ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmslapcat\n   Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmslapd                                            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmslapd\n   Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmslapindex                                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmslapindex\n   Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmstat-ldap                                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmstat-ldap\n\n   Copy ${repoDir}/zm-licenses/zimbra/ypl-full.txt                                                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/YPL.txt\n   Copy ${repoDir}/zm-licenses/zimbra/zpl-full.txt                                                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/ZPL.txt\n\n   Copy ${repoDir}/zm-migration-tools/ReadMe.txt                                                    ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/zmztozmig.txt\n\n   Copy ${repoDir}/zm-mta/cbpolicyd.conf.in                                                         ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/cbpolicyd.conf.in\n   Copy ${repoDir}/zm-mta/clamd.conf.in                                                             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/clamd.conf.in\n   Copy ${repoDir}/zm-mta/opendkim-localnets.conf.in                                                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/opendkim-localnets.conf.in\n   Copy ${repoDir}/zm-mta/opendkim.conf.in                                                          ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/opendkim.conf.in\n   Copy ${repoDir}/zm-mta/postfix_header_checks.in                                                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/postfix_header_checks.in\n   Copy ${repoDir}/zm-mta/postfix_sasl_smtpd.conf                                                   ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/sasl2/smtpd.conf.in\n   Copy ${repoDir}/zm-mta/salocal.cf.in                                                             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/salocal.cf.in\n   Copy ${repoDir}/zm-mta/saslauthd.conf.in                                                         ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/saslauthd.conf.in\n   Copy ${repoDir}/zm-mta/zmconfigd/postfix_content_filter.cf                                       ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/zmconfigd/postfix_content_filter.cf\n   Copy ${repoDir}/zm-mta/zmconfigd/smtpd_end_of_data_restrictions.cf                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/zmconfigd/smtpd_end_of_data_restrictions.cf\n   Copy ${repoDir}/zm-mta/zmconfigd/smtpd_recipient_restrictions.cf                                 ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/zmconfigd/smtpd_recipient_restrictions.cf\n   Copy ${repoDir}/zm-mta/zmconfigd/smtpd_relay_restrictions.cf                                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/zmconfigd/smtpd_relay_restrictions.cf\n   Copy ${repoDir}/zm-mta/zmconfigd/smtpd_sender_login_maps.cf                                      ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/zmconfigd/smtpd_sender_login_maps.cf\n   Copy ${repoDir}/zm-mta/zmconfigd/smtpd_sender_restrictions.cf                                    ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/zmconfigd/smtpd_sender_restrictions.cf\n\n   Cpy2 ${repoDir}/junixsocket/junixsocket-native/build/junixsocket-native-*.nar                    ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/\n   Cpy2 ${repoDir}/junixsocket/junixsocket-native/build/libjunixsocket-native-*.so                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/\n\n   Copy ${repoDir}/zm-bulkprovision-store/build/dist/commons-csv-1.2.jar                            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/com_zimbra_bulkprovision/commons-csv-1.2.jar\n   Copy ${repoDir}/zm-bulkprovision-store/build/dist/zm-bulkprovision-store*.jar                    ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/com_zimbra_bulkprovision/com_zimbra_bulkprovision.jar\n\n   Copy ${repoDir}/zm-certificate-manager-store/build/zm-certificate-manager-store*.jar             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/com_zimbra_cert_manager/com_zimbra_cert_manager.jar \n\n\n   # Copy SSDB Ephemeral storage extension + dependencies\n   Cpy2 ${repoDir}/zm-ssdb-ephemeral-store/build/dist/zm-ssdb-ephemeral-store*.jar                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/com_zimbra_ssdb_ephemeral_store/\n   Cpy2 ${repoDir}/zm-zcs-lib/build/dist/jedis-2.9.0.jar                                            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/com_zimbra_ssdb_ephemeral_store/\n   Cpy2 ${repoDir}/zm-zcs-lib/build/dist/commons-pool2-2.4.2.jar                                    ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/com_zimbra_ssdb_ephemeral_store/\n\n   if [ \"${buildType}\" == \"NETWORK\" ]\n   then\n      Copy ${repoDir}/zm-backup-store/docs/backup.txt                                                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/backup.txt\n      Copy ${repoDir}/zm-backup-store/docs/mailboxMove.txt                                             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/mailboxMove.txt\n      Copy ${repoDir}/zm-backup-store/docs/soapbackup.txt                                              ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/soapbackup.txt\n      Copy ${repoDir}/zm-backup-store/docs/xml-meta.txt                                                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/xml-meta.txt\n      Copy ${repoDir}/zm-backup-store/build/dist/backup-version-init.sql                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/db/backup-version-init.sql\n\n      Copy ${repoDir}/zm-backup-utilities/src/bin/zmbackup                                             ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmbackup\n      Copy ${repoDir}/zm-backup-utilities/src/bin/zmbackupabort                                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmbackupabort\n      Copy ${repoDir}/zm-backup-utilities/src/bin/zmbackupquery                                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmbackupquery\n      Copy ${repoDir}/zm-backup-utilities/src/bin/zmmboxmove                                           ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmmboxmove\n      Copy ${repoDir}/zm-backup-utilities/src/bin/zmmboxmovequery                                      ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmmboxmovequery\n      Copy ${repoDir}/zm-backup-utilities/src/bin/zmpurgeoldmbox                                       ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmpurgeoldmbox\n      Copy ${repoDir}/zm-backup-utilities/src/bin/zmrestore                                            ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmrestore\n      Copy ${repoDir}/zm-backup-utilities/src/bin/zmrestoreldap                                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmrestoreldap\n      Copy ${repoDir}/zm-backup-utilities/src/bin/zmrestoreoffline                                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmrestoreoffline\n      Copy ${repoDir}/zm-backup-utilities/src/bin/zmschedulebackup                                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmschedulebackup\n      Copy ${repoDir}/zm-backup-utilities/src/db/backup_schema.sql                                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/db/backup_schema.sql\n      Copy ${repoDir}/zm-backup-utilities/src/libexec/zmbackupldap                                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmbackupldap\n      Copy ${repoDir}/zm-backup-utilities/src/libexec/zmbackupqueryldap                                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmbackupqueryldap\n\n      Copy ${repoDir}/zm-convertd-native/conf/convertd.log4j.properties                                ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/convertd.log4j.properties\n      Copy ${repoDir}/zm-convertd-native/src/bin/zmconvertctl                                          ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmconvertctl\n      Copy ${repoDir}/zm-convertd-native/src/libexec/zmconvertdmod                                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmconvertdmod\n\n      Copy ${repoDir}/zm-hsm/docs/soap-admin.txt                                                       ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/hsm-soap-admin.txt\n\n      Copy ${repoDir}/zm-network-build/rpmconf/Install/Util/modules/postinstall.sh                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/installer/util/modules/postinstall.sh\n      Copy ${repoDir}/zm-network-build/rpmconf/Install/postinstall.pm                                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/postinstall.pm\n      Copy ${repoDir}/zm-network-build/rpmconf/Install/preinstall.pm                                   ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/preinstall.pm\n\n      Copy ${repoDir}/zm-network-licenses/thirdparty/oracle_jdk_eula.txt                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/oracle_jdk_eula.txt\n\n      Copy ${repoDir}/zm-postfixjournal/build/dist/postjournal                                         ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/postjournal\n\n      Copy ${repoDir}/zm-rebranding-docs/docs/rebranding/DE_Rebranding_directions.txt                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/rebranding/DE_Rebranding_directions.txt\n      Copy ${repoDir}/zm-rebranding-docs/docs/rebranding/ES_Rebranding_directions.txt                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/rebranding/ES_Rebranding_directions.txt\n      Copy ${repoDir}/zm-rebranding-docs/docs/rebranding/FR_Rebranding_directions.txt                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/rebranding/FR_Rebranding_directions.txt\n      Copy ${repoDir}/zm-rebranding-docs/docs/rebranding/IT_Rebranding_directions.txt                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/rebranding/IT_Rebranding_directions.txt\n      Copy ${repoDir}/zm-rebranding-docs/docs/rebranding/JA_Rebranding_directions.txt                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/rebranding/JA_Rebranding_directions.txt\n      Copy ${repoDir}/zm-rebranding-docs/docs/rebranding/NL_Rebranding_directions.txt                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/rebranding/NL_Rebranding_directions.txt\n      Copy ${repoDir}/zm-rebranding-docs/docs/rebranding/RU_Rebranding_directions.txt                  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/rebranding/RU_Rebranding_directions.txt\n      Copy ${repoDir}/zm-rebranding-docs/docs/rebranding/en_US_Rebranding_directions.txt               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/rebranding/en_US_Rebranding_directions.txt\n      Copy ${repoDir}/zm-rebranding-docs/docs/rebranding/pt_BR_Rebranding_directions.txt               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/rebranding/pt_BR_Rebranding_directions.txt\n      Copy ${repoDir}/zm-rebranding-docs/docs/rebranding/zh_CN_Rebranding_directions.txt               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/rebranding/zh_CN_Rebranding_directions.txt\n      Copy ${repoDir}/zm-rebranding-docs/docs/rebranding/zh_HK_Rebranding_directions.txt               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/rebranding/zh_HK_Rebranding_directions.txt\n\n      Copy ${repoDir}/zm-twofactorauth-store/docs/twofactorauth.md                                     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/twofactorauth.md\n\n      Copy ${repoDir}/zm-vmware-appmonitor/build/dist/libexec/vmware-appmonitor                        ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/vmware-appmonitor\n      Copy ${repoDir}/zm-vmware-appmonitor/build/dist/lib/libappmonitorlib.so                          ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/libappmonitorlib.so\n\n      Copy ${repoDir}/zm-voice-store/docs/ZimbraVoice-Extension.txt                                    ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/ZimbraVoice-Extension.txt\n      Copy ${repoDir}/zm-voice-store/docs/soap-voice-admin.txt                                         ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/soap-voice-admin.txt\n      Copy ${repoDir}/zm-voice-store/docs/soap-voice.txt                                               ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/soap-voice.txt\n   fi\n\n   CreatePackage \"${os}\"\n}\n\n############################################################################\nmain \"$@\"\n"
  },
  {
    "path": "instructions/bundling-scripts/zimbra-dnscache.sh",
    "content": "#!/bin/bash\n#\n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n\n# Shell script to create zimbra dnscache package\n\n\n#-------------------- Configuration ---------------------------\n\n    currentScript=`basename $0 | cut -d \".\" -f 1`                          # zimbra-dnscache\n    currentPackage=`echo ${currentScript}build | cut -d \"-\" -f 2` # dnscachebuild\n\n\n#-------------------- Build Package ---------------------------\nmain()\n{\n    echo -e \"\\tCreate package directories\" >> ${buildLogFile}\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/etc/sudoers.d\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/data/dns/ca\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/data/dns/trust\n\n    CreatePackage \"${os}\"\n}\n\n#-------------------- Util Functions ---------------------------\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"$0\")\" && pwd)\"\n\nsource \"$SCRIPT_DIR/utils.sh\"\n\nCreateDebianPackage()\n{\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/DEBIAN\n    cat ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post >> ${repoDir}/zm-build/${currentPackage}/DEBIAN/postinst\n    chmod 555 ${repoDir}/zm-build/${currentPackage}/DEBIAN/*\n\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/etc/resolvconf/update.d\n    cp ${repoDir}/zm-dnscache/conf/dns/zimbra-unbound ${repoDir}/zm-build/${currentPackage}/etc/resolvconf/update.d\n    cp ${repoDir}/zm-build/rpmconf/Env/sudoers.d/02_${currentScript}.deb ${repoDir}/zm-build/${currentPackage}/etc/sudoers.d/02_${currentScript}\n\n    echo -e \"\\tCreate debian package\" >> ${buildLogFile}\n    (cd ${repoDir}/zm-build/${currentPackage}; find . -type f ! -regex '.*.hg.*' ! -regex '.*?debian-binary.*' ! -regex '.*?DEBIAN.*' -print0 | xargs -0 md5sum | sed -e 's| \\./| |' \\\n        > ${repoDir}/zm-build/${currentPackage}/DEBIAN/md5sums)\n    cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.deb | sed -e \"s/@@VERSION@@/${releaseNo}.${releaseCandidate}.${buildNo}.${os/_/.}/\" \\\n        -e \"s/@@branch@@/${buildTimeStamp}/\" -e \"s/@@ARCH@@/${arch}/\" -e \"s/^Copyright:/Copyright:/\" -e \"/^%post$/ r ${currentPackage}.post\" \\\n        > ${repoDir}/zm-build/${currentPackage}/DEBIAN/control\n    (cd ${repoDir}/zm-build/${currentPackage}; dpkg -b ${repoDir}/zm-build/${currentPackage} ${repoDir}/zm-build/${arch})\n\n}\n\nCreateRhelPackage()\n{\n    cp ${repoDir}/zm-build/rpmconf/Env/sudoers.d/02_${currentScript}.rpm ${repoDir}/zm-build/${currentPackage}/etc/sudoers.d/02_${currentScript}\n\n    cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.spec | \\\n        sed -e \"s/@@VERSION@@/${releaseNo}_${releaseCandidate}_${buildNo}.${os}/\" \\\n            -e \"s/@@RELEASE@@/${buildTimeStamp}/\" \\\n            -e \"s/^Copyright:/Copyright:/\" \\\n            -e \"/^%post$/ r ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post\" > ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(-, zimbra, zimbra) /opt/zimbra/data/dns\" >> \\\n        ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(440, root, root) /etc/sudoers.d/02_zimbra-dnscache\" >> \\\n        ${repoDir}/zm-build/${currentScript}.spec\n    (cd ${repoDir}/zm-build/${currentPackage}; \\\n        rpmbuild --target ${arch} --define '_rpmdir ../' --buildroot=${repoDir}/zm-build/${currentPackage} -bb ${repoDir}/zm-build/${currentScript}.spec )\n}\n\n############################################################################\nmain \"$@\""
  },
  {
    "path": "instructions/bundling-scripts/zimbra-imapd.sh",
    "content": "#!/bin/bash\n#\n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2017 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.  # You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n\n# Shell script to create zimbra-imapd package\n\n\n#-------------------- Configuration ---------------------------\n\n    currentScript=`basename $0 | cut -d \".\" -f 1`                          # zimbra-imapd\n    currentPackage=`echo ${currentScript}build | cut -d \"-\" -f 2`          # imapbuild\n\n\n#-------------------- Build Package ---------------------------\nmain()\n{\n    echo -e \"\\tCreate package directories\" >> ${buildLogFile}\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/jars\n\n\n    echo -e \"\\tCopy package files\" >> ${buildLogFile}\n    cp ${repoDir}/zm-core-utils/src/bin/zmimapdctl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmimapdctl\n    cp ${repoDir}/zm-zcs-lib/build/dist/oauth-1.4.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/jars/oauth-1.4.jar\n    cp ${repoDir}/zm-mailbox/store-conf/conf/imapd.log4j.properties ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/imapd.log4j.properties\n    CreatePackage \"${os}\"\n}\n\n#-------------------- Util Functions ---------------------------\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"$0\")\" && pwd)\"\n\nsource \"$SCRIPT_DIR/utils.sh\"\n\nCreateDebianPackage()\n{\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/DEBIAN\n    cat ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post >> ${repoDir}/zm-build/${currentPackage}/DEBIAN/postinst\n    chmod 555 ${repoDir}/zm-build/${currentPackage}/DEBIAN/*\n\n    echo -e \"\\tCreate debian package\" >> ${buildLogFile}\n    (cd ${repoDir}/zm-build/${currentPackage}; find . -type f ! -regex '.*?debian-binary.*' ! -regex '.*?DEBIAN.*' -print0 | xargs -0 md5sum | sed -e 's| \\./| |' \\\n        > ${repoDir}/zm-build/${currentPackage}/DEBIAN/md5sums)\n    cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.deb | sed -e \"s/@@VERSION@@/${releaseNo}.${releaseCandidate}.${buildNo}.${os/_/.}/\" -e \"s/@@branch@@/${buildTimeStamp}/\" -e \"s/@@ARCH@@/${arch}/\" \\\n        > ${repoDir}/zm-build/${currentPackage}/DEBIAN/control\n    (cd ${repoDir}/zm-build/${currentPackage}; dpkg -b ${repoDir}/zm-build/${currentPackage} ${repoDir}/zm-build/${arch})\n\n}\n\nCreateRhelPackage()\n{\n    cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.spec | \\\n        sed -e \"s/@@VERSION@@/${releaseNo}_${releaseCandidate}_${buildNo}.${os}/\" \\\n        -e \"s/@@RELEASE@@/${buildTimeStamp}/\" \\\n        -e \"s/^Copyright:/Copyright:/\" \\\n        > ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(-, root, root) /opt/zimbra/bin/zmimapdctl\" >> \\\n        ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(-, root, root) /opt/zimbra/lib/jars/oauth-1.4.jar\" >> \\\n        ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(755, zimbra, zimbra) /opt/zimbra/conf/imapd.log4j.properties\" >> \\\n        ${repoDir}/zm-build/${currentScript}.spec\n    echo \"\" >> ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%clean\" >> ${repoDir}/zm-build/${currentScript}.spec\n    (cd ${repoDir}/zm-build/${currentPackage}; \\\n        rpmbuild --target ${arch} --define '_rpmdir ../' --buildroot=${repoDir}/zm-build/${currentPackage} -bb ${repoDir}/zm-build/${currentScript}.spec )\n}\n\n############################################################################\nmain \"$@\"\n"
  },
  {
    "path": "instructions/bundling-scripts/zimbra-ldap.sh",
    "content": "#!/bin/bash\n#\n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n\n# Shell script to create zimbra ldap package\n\n\n#-------------------- Configuration ---------------------------\n\n    currentScript=`basename $0 | cut -d \".\" -f 1`                          # zimbra-ldap\n    currentPackage=`echo ${currentScript}build | cut -d \"-\" -f 2` # ldapbuild\n\n    ldapSchemaDir=${repoDir}/zm-ldap-utilities/build/dist\n\n\n#-------------------- Build Package ---------------------------\nmain()\n{\n    echo -e \"\\tCreate package directories\" >> ${buildLogFile}\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/etc/openldap/zimbra\n\n    echo -e \"\\tCopy package files\" >> ${buildLogFile}\n    cp -rf ${ldapSchemaDir}/*  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/etc/openldap/zimbra\n    if [ \"${buildType}\" == \"NETWORK\" ]\n    then\n      cp -f ${repoDir}/zm-convertd-native/conf/ldap/zimbra_mimehandlers.ldif ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/etc/openldap/zimbra/convertd_mimehandlers.ldif\n    fi\n\n    CreatePackage \"${os}\"\n}\n\n#-------------------- Util Functions ---------------------------\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"$0\")\" && pwd)\"\n\nsource \"$SCRIPT_DIR/utils.sh\"\n\nCreateDebianPackage()\n{\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/DEBIAN\n    cat ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post >> ${repoDir}/zm-build/${currentPackage}/DEBIAN/postinst\n    chmod 555 ${repoDir}/zm-build/${currentPackage}/DEBIAN/*\n\n    echo -e \"\\tCreate debian package\" >> ${buildLogFile}\n    (cd ${repoDir}/zm-build/${currentPackage}; find . -type f ! -regex '.*?debian-binary.*' ! -regex '.*?DEBIAN.*' -print0 | xargs -0 md5sum | sed -e 's| \\./| |' \\\n        > ${repoDir}/zm-build/${currentPackage}/DEBIAN/md5sums)\n    cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.deb | sed -e \"s/@@VERSION@@/${releaseNo}.${releaseCandidate}.${buildNo}.${os/_/.}/\" -e \"s/@@branch@@/${buildTimeStamp}/\" -e \"s/@@ARCH@@/${arch}/\" \\\n        > ${repoDir}/zm-build/${currentPackage}/DEBIAN/control\n    (cd ${repoDir}/zm-build/${currentPackage}; dpkg -b ${repoDir}/zm-build/${currentPackage} ${repoDir}/zm-build/${arch})\n\n}\n\nCreateRhelPackage()\n{\n    cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.spec | \\\n        sed -e \"s/@@VERSION@@/${releaseNo}_${releaseCandidate}_${buildNo}.${os}/\" \\\n            -e \"s/@@RELEASE@@/${buildTimeStamp}/\" \\\n            -e \"s/^Copyright:/Copyright:/\" \\\n            -e \"/^%post$/ r ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post\" >  ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(-, root, root) /opt/zimbra/common/etc/openldap/zimbra\" >> \\\n        ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(-, root, root) /opt/zimbra/common/etc/openldap/zimbra/*\" >> \\\n        ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(-, root, root) /opt/zimbra/common/etc/openldap/zimbra/config\" >> \\\n        ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(-, root, root) /opt/zimbra/common/etc/openldap/zimbra/config/*\" >> \\\n        ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(-, root, root) /opt/zimbra/common/etc/openldap/zimbra/config/cn=config\" >> \\\n        ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(-, root, root) /opt/zimbra/common/etc/openldap/zimbra/config/cn=config/*\" >> \\\n        ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(-, root, root) /opt/zimbra/common/etc/openldap/zimbra/config/cn=config/olcDatabase={2}mdb\" >> \\\n        ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(-, root, root) /opt/zimbra/common/etc/openldap/zimbra/schema\" >> \\\n        ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(-, root, root) /opt/zimbra/common/etc/openldap/zimbra/schema/*\" >> \\\n        ${repoDir}/zm-build/${currentScript}.spec\n    echo \"\" >> ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%clean\" >> ${repoDir}/zm-build/${currentScript}.spec\n    (cd ${repoDir}/zm-build/${currentPackage}; \\\n        rpmbuild --target ${arch} --define '_rpmdir ../' --buildroot=${repoDir}/zm-build/${currentPackage} -bb ${repoDir}/zm-build/${currentScript}.spec )\n}\n\n############################################################################\nmain \"$@\"\n"
  },
  {
    "path": "instructions/bundling-scripts/zimbra-logger.sh",
    "content": "#!/bin/bash\n#\n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n\n# Shell script to create zimbra logger package\n\n\n#-------------------- Configuration ---------------------------\n\n    currentScript=`basename $0 | cut -d \".\" -f 1`                          # zimbra-logger\n    currentPackage=`echo ${currentScript}build | cut -d \"-\" -f 2` # loggerbuild\n\n\n#-------------------- Build Package ---------------------------\nmain()\n{\n    echo -e \"\\tCreate package directories...\" >> ${buildLogFile}\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/logger/db/data\n\n    CreatePackage \"${os}\"\n}\n\n#-------------------- Util Functions ---------------------------\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"$0\")\" && pwd)\"\n\nsource \"$SCRIPT_DIR/utils.sh\"\n\nCreateDebianPackage()\n{\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/DEBIAN\n    echo -e \"\\tCopy package files...\" >> ${buildLogFile}\n    cat ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post >> ${repoDir}/zm-build/${currentPackage}/DEBIAN/postinst\n    chmod 555 ${repoDir}/zm-build/${currentPackage}/DEBIAN/*\n\n    echo -e \"\\tCreate debian package...\" >> ${buildLogFile}\n    cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.deb | sed -e \"s/@@VERSION@@/${releaseNo}.${releaseCandidate}.${buildNo}.${os/_/.}/\" -e \"s/@@branch@@/${buildTimeStamp}/\" -e \"s/@@ARCH@@/${arch}/\" \\\n        > ${repoDir}/zm-build/${currentPackage}/DEBIAN/control\n    (cd ${repoDir}/zm-build/${currentPackage}; dpkg -b ${repoDir}/zm-build/${currentPackage} ${repoDir}/zm-build/${arch})\n\n}\n\nCreateRhelPackage()\n{\n    cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.spec | \\\n    \tsed -e \"s/@@VERSION@@/${releaseNo}_${releaseCandidate}_${buildNo}.${os}/\" \\\n            \t-e \"s/@@RELEASE@@/${buildTimeStamp}/\" \\\n            \t-e \"s/^Copyright:/Copyright:/\" \\\n            \t-e \"/^%post$/ r ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post\" > ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(755, zimbra, zimbra) /opt/zimbra/logger\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(755, zimbra, zimbra) /opt/zimbra/logger/db\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(755, zimbra, zimbra) /opt/zimbra/logger/db/data\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"\" >> ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%clean\" >> ${repoDir}/zm-build/${currentScript}.spec\n    (cd ${repoDir}/zm-build/${currentPackage}; \\\n    \trpmbuild --target ${arch} --define '_rpmdir ../' --buildroot=${repoDir}/zm-build/${currentPackage} -bb ${repoDir}/zm-build/${currentScript}.spec )\n}\n\n############################################################################\nmain \"$@\""
  },
  {
    "path": "instructions/bundling-scripts/zimbra-mta.sh",
    "content": "#!/bin/bash\n#\n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n\n# Shell script to create zimbra mta package\n\n\n#-------------------- Configuration ---------------------------\n\n    currentScript=`basename $0 | cut -d \".\" -f 1`                          # zimbra-mta\n    currentPackage=`echo ${currentScript}build | cut -d \"-\" -f 2` # mtabuild\n\n\n#-------------------- Build Package ---------------------------\nmain()\n{\n    echo -e \"\\tCreate package directories\" >> ${buildLogFile}\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/etc/sudoers.d\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/conf\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/data/amavisd/mysql\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/data/altermime\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/data/cbpolicyd/db\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/data/clamav\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/data/opendkim\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/data/postfix\n\n\n    echo -e \"\\tCopy package files\" >> ${buildLogFile}\n    cp ${repoDir}/zm-build/rpmconf/Env/sudoers.d/02_${currentScript} ${repoDir}/zm-build/${currentPackage}/etc/sudoers.d/02_${currentScript}\n    cp ${repoDir}/zm-postfix/conf/postfix/master.cf.in ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/conf/master.cf.in\n    cp ${repoDir}/zm-postfix/conf/postfix/tag_as_foreign.re.in ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/conf/tag_as_foreign.re.in\n    cp ${repoDir}/zm-postfix/conf/postfix/tag_as_originating.re.in ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/conf/tag_as_originating.re.in\n    cp -f ${repoDir}/zm-amavis/conf/amavisd/mysql/antispamdb.sql ${repoDir}/zm-build/${currentPackage}/opt/zimbra/data/amavisd/mysql/antispamdb.sql\n\n    CreatePackage \"${os}\"\n}\n\n#-------------------- Util Functions ---------------------------\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"$0\")\" && pwd)\"\n\nsource \"$SCRIPT_DIR/utils.sh\"\n\nCreateDebianPackage()\n{\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/DEBIAN\n    cat ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post >> ${repoDir}/zm-build/${currentPackage}/DEBIAN/postinst\n    chmod 555 ${repoDir}/zm-build/${currentPackage}/DEBIAN/*\n\n    echo -e \"\\tCreate debian package\" >> ${buildLogFile}\n    (cd ${repoDir}/zm-build/${currentPackage}; find . -type f ! -regex '.*opt/zimbra/postfix-.*/conf/master.cf' ! -regex '.*.hg.*' ! -regex '.*?debian-binary.*' ! -regex '.*?DEBIAN.*' -print0 | \\\n        xargs -0 md5sum | sed -e 's| \\./| |' > ${repoDir}/zm-build/${currentPackage}/DEBIAN/md5sums)\n    cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.deb | sed -e \"s/@@VERSION@@/${releaseNo}.${releaseCandidate}.${buildNo}.${os/_/.}/\" -e \"s/@@branch@@/${buildTimeStamp}/\" \\\n        -e \"s/@@ARCH@@/${arch}/\" -e \"s/@@ARCH@@/amd64/\" -e \"s/^Copyright:/Copyright:/\" -e \"/^%post$/ r ${currentScript}.post\" > ${repoDir}/zm-build/${currentPackage}/DEBIAN/control\n    (cd ${repoDir}/zm-build/${currentPackage}; dpkg -b ${repoDir}/zm-build/${currentPackage} ${repoDir}/zm-build/${arch})\n\n}\n\nCreateRhelPackage()\n{\n    cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.spec | \\\n        sed -e \"s/@@VERSION@@/${releaseNo}_${releaseCandidate}_${buildNo}.${os}/\" \\\n            -e \"s/@@RELEASE@@/${buildTimeStamp}/\" \\\n            -e \"s/@@MTA_PROVIDES@@/smtpdaemon/\" \\\n            -e \"s/^Copyright:/Copyright:/\" \\\n            -e \"/^%post$/ r ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post\" > ${repoDir}/zm-build/${currentScript}.spec\n    (cd ${repoDir}/zm-build/mtabuild; find opt -maxdepth 2 -type f -o -type l \\\n        | sed -e 's|^|%attr(-, zimbra, zimbra) /|' >> \\\n        ${repoDir}/zm-build/${currentScript}.spec )\n    echo \"%attr(440, root, root) /etc/sudoers.d/02_zimbra-mta\" >> \\\n        ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(-, zimbra, zimbra) /opt/zimbra/common/conf/master.cf.in\" >> \\\n        ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(-, zimbra, zimbra) /opt/zimbra/common/conf/tag_as_foreign.re.in\" >> \\\n        ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(-, zimbra, zimbra) /opt/zimbra/common/conf/tag_as_originating.re.in\" >> \\\n        ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(-, zimbra, zimbra) /opt/zimbra/data/amavisd\" >> \\\n        ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(-, zimbra, zimbra) /opt/zimbra/data/clamav\" >> \\\n        ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(-, zimbra, zimbra) /opt/zimbra/data/cbpolicyd\" >> \\\n        ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(-, zimbra, zimbra) /opt/zimbra/data/opendkim\" >> \\\n        ${repoDir}/zm-build/${currentScript}.spec\n    (cd ${repoDir}/zm-build/${currentPackage}; \\\n        rpmbuild --target ${arch} --define '_rpmdir ../' --buildroot=${repoDir}/zm-build/${currentPackage} -bb ${repoDir}/zm-build/${currentScript}.spec )\n}\n\n############################################################################\nmain \"$@\"\n"
  },
  {
    "path": "instructions/bundling-scripts/zimbra-proxy.sh",
    "content": "#!/bin/bash\n#\n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n\n# Shell script to create zimbra proxy package\n\n\n#-------------------- Configuration ---------------------------\n\n    currentScript=`basename $0 | cut -d \".\" -f 1`                          # zimbra-proxy\n    currentPackage=`echo ${currentScript}build | cut -d \"-\" -f 2` # proxybuild\n\n\n#-------------------- Build Package ---------------------------\nmain()\n{\n    echo -e \"\\tCreate package directories\" >> ${buildLogFile}\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/nginx/includes\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/nginx/templates\n\n\n    echo -e \"\\tCopy package files\" >> ${buildLogFile}\n    cp ${repoDir}/zm-nginx-conf/conf/nginx/* ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/nginx/templates/\n\n    CreatePackage \"${os}\"\n}\n\n#-------------------- Util Functions ---------------------------\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"$0\")\" && pwd)\"\n\nsource \"$SCRIPT_DIR/utils.sh\"\n\nCreateDebianPackage()\n{\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/DEBIAN\n    cat ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post >> ${repoDir}/zm-build/${currentPackage}/DEBIAN/postinst\n    chmod 555 ${repoDir}/zm-build/${currentPackage}/DEBIAN/*\n\n    echo -e \"\\tCreate debian package\" >> ${buildLogFile}\n    (cd ${repoDir}/zm-build/${currentPackage}; find . -type f ! -regex \".*?debian-binary.*\" ! -regex \".*?DEBIAN.*\" -print0 | xargs -0 md5sum | sed -e \"s| \\./| |\" \\\n        > ${repoDir}/zm-build/${currentPackage}/DEBIAN/md5sums)\n    cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.deb | sed -e \"s/@@VERSION@@/${releaseNo}.${releaseCandidate}.${buildNo}.${os/_/.}/\" -e \"s/@@branch@@/${buildTimeStamp}/\" -e \"s/@@ARCH@@/${arch}/\" \\\n        > ${repoDir}/zm-build/${currentPackage}/DEBIAN/control\n    (cd ${repoDir}/zm-build/${currentPackage}; dpkg -b ${repoDir}/zm-build/${currentPackage} ${repoDir}/zm-build/${arch} )\n\n}\n\nCreateRhelPackage()\n{\n    cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.spec | \\\n        sed -e \"s/@@VERSION@@/${releaseNo}_${releaseCandidate}_${buildNo}.${os}/\" \\\n               -e \"s/@@RELEASE@@/${buildTimeStamp}/\" \\\n               -e \"s/^Copyright:/Copyright:/\" \\\n               -e \"/^%post$/ r ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post\" > ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(755, zimbra, zimbra) /opt/zimbra/conf/nginx\" >> \\\n        ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(644, zimbra, zimbra) /opt/zimbra/conf/nginx/*\" >> \\\n        ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(755, zimbra, zimbra) /opt/zimbra/conf/nginx/includes\" >> \\\n        ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(755, zimbra, zimbra) /opt/zimbra/conf/nginx/templates\" >> \\\n        ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(644, zimbra, zimbra) /opt/zimbra/conf/nginx/templates/*\" >> \\\n        ${repoDir}/zm-build/${currentScript}.spec\n    echo \"\" >> ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%clean\" >> ${repoDir}/zm-build/${currentScript}.spec\n    (cd ${repoDir}/zm-build/${currentPackage}; \\\n    rpmbuild --target ${arch} --define '_rpmdir ../' --buildroot=${repoDir}/zm-build/${currentPackage} -bb ${repoDir}/zm-build/${currentScript}.spec )\n}\n\n############################################################################\nmain \"$@\""
  },
  {
    "path": "instructions/bundling-scripts/zimbra-snmp.sh",
    "content": "#!/bin/bash\n#\n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n\n# Shell script to create zimbra snmp package\n\n\n#-------------------- Configuration ---------------------------\n\n    currentScript=`basename $0 | cut -d \".\" -f 1`                          # zimbra-snmp\n    currentPackage=`echo ${currentScript}build | cut -d \"-\" -f 2` # snmpbuild\n\n\n#-------------------- Build Package ---------------------------\nmain()\n{\n    echo -e \"\\tCreate package directories\" >> ${buildLogFile}\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/data/snmp/persist\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/data/snmp/state\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/conf\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/share/snmp/mibs\n\n\n    echo -e \"\\tCopy package files\" >> ${buildLogFile}\n    cp ${repoDir}/zm-build/rpmconf/Conf/snmp.conf ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/conf/snmp.conf\n    cp ${repoDir}/zm-build/rpmconf/Conf/snmpd.conf.in ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/snmpd.conf.in\n    cp ${repoDir}/zm-build/rpmconf/Conf/snmp.conf ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/share/snmp/snmp.conf\n    cp ${repoDir}/zm-build/rpmconf/Conf/mibs/*mib ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/share/snmp/mibs\n\n    CreatePackage \"${os}\"\n}\n\n#-------------------- Util Functions ---------------------------\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"$0\")\" && pwd)\"\n\nsource \"$SCRIPT_DIR/utils.sh\"\n\nCreateDebianPackage()\n{\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/DEBIAN\n    cat ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post >> ${repoDir}/zm-build/${currentPackage}/DEBIAN/postinst\n    chmod 555 ${repoDir}/zm-build/${currentPackage}/DEBIAN/*\n\n    echo -e \"\\tCreate debian package\" >> ${buildLogFile}\n    (cd ${repoDir}/zm-build/${currentPackage}; find . -type f ! -regex '.*.hg.*' ! -regex '.*?debian-binary.*' ! -regex '.*?DEBIAN.*' -print0 | xargs -0 md5sum | sed -e 's| \\./| |' \\\n        > ${repoDir}/zm-build/${currentPackage}/DEBIAN/md5sums)\n    cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.deb | sed -e \"s/@@VERSION@@/${releaseNo}.${releaseCandidate}.${buildNo}.${os/_/.}/\" -e \"s/@@branch@@/${buildTimeStamp}/\" -e \"s/@@ARCH@@/${arch}/\" \\\n        > ${repoDir}/zm-build/${currentPackage}/DEBIAN/control\n    (cd ${repoDir}/zm-build/${currentPackage}; dpkg -b ${repoDir}/zm-build/${currentPackage} ${repoDir}/zm-build/${arch})\n\n}\n\nCreateRhelPackage()\n{\n    cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.spec | \\\n    \tsed -e \"s/@@VERSION@@/${releaseNo}_${releaseCandidate}_${buildNo}.${os}/\" \\\n    \t-e \"s/@@RELEASE@@/${buildTimeStamp}/\" \\\n    \t-e \"s/^Copyright:/Copyright:/\" \\\n    \t> ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(755, zimbra, zimbra) /opt/zimbra/data/snmp\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(755, zimbra, zimbra) /opt/zimbra/conf\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(644, zimbra, zimbra) /opt/zimbra/conf/*\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(775, root, zimbra) /opt/zimbra/common/conf\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(644, root, root) /opt/zimbra/common/conf/snmp.conf\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(755, root, root) /opt/zimbra/common/share/snmp\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(644, root, root) /opt/zimbra/common/share/snmp/snmp.conf\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(755, root, root) /opt/zimbra/common/share/snmp/mibs\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(644, root, root) /opt/zimbra/common/share/snmp/mibs/zimbra.mib\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(644, root, root) /opt/zimbra/common/share/snmp/mibs/zimbra_traps.mib\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"\" >> ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%clean\" >> ${repoDir}/zm-build/${currentScript}.spec\n    (cd ${repoDir}/zm-build/${currentPackage}; \\\n    \trpmbuild --target ${arch} --define '_rpmdir ../' --buildroot=${repoDir}/zm-build/${currentPackage} -bb ${repoDir}/zm-build/${currentScript}.spec )\n\n}\n\n\n############################################################################\nmain \"$@\"\n"
  },
  {
    "path": "instructions/bundling-scripts/zimbra-spell.sh",
    "content": "#!/bin/bash\n#\n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n\n# Shell script to create zimbra spell package\n\n\n#-------------------- Configuration ---------------------------\n\n    currentScript=`basename $0 | cut -d \".\" -f 1`                          # zimbra-spell\n    currentPackage=`echo ${currentScript}build | cut -d \"-\" -f 2` # spellbuild\n\n\n#-------------------- Build Package ---------------------------\nmain()\n{\n    echo -e \"\\tCreate package directories\" >> ${buildLogFile}\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/data/httpd/htdocs\n\n\n    echo -e \"\\tCopy package files\" >> ${buildLogFile}\n    cp ${repoDir}/zm-aspell/src/php/aspell.php ${repoDir}/zm-build/${currentPackage}/opt/zimbra/data/httpd/htdocs/aspell.php\n\n    CreatePackage \"${os}\"\n}\n\n#-------------------- Util Functions ---------------------------\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"$0\")\" && pwd)\"\n\nsource \"$SCRIPT_DIR/utils.sh\"\n\nCreateDebianPackage()\n{\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/DEBIAN\n    cat ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post >> ${repoDir}/zm-build/${currentPackage}/DEBIAN/postinst\n    chmod 555 ${repoDir}/zm-build/${currentPackage}/DEBIAN/*\n\n    echo -e \"\\tCreate debian package\" >> ${buildLogFile}\n    (cd ${repoDir}/zm-build/${currentPackage}; find . -type f ! -regex '.*?debian-binary.*' ! -regex '.*?DEBIAN.*' -print0 | xargs -0 md5sum | sed -e 's| \\./| |' \\\n        > ${repoDir}/zm-build/${currentPackage}/DEBIAN/md5sums)\n    cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.deb | sed -e \"s/@@VERSION@@/${releaseNo}.${releaseCandidate}.${buildNo}.${os/_/.}/\" -e \"s/@@branch@@/${buildTimeStamp}/\" -e \"s/@@ARCH@@/${arch}/\" \\\n        > ${repoDir}/zm-build/${currentPackage}/DEBIAN/control\n    (cd ${repoDir}/zm-build/${currentPackage}; dpkg -b ${repoDir}/zm-build/${currentPackage} ${repoDir}/zm-build/${arch})\n\n}\n\nCreateRhelPackage()\n{\n    cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.spec | \\\n    \tsed -e \"s/@@VERSION@@/${releaseNo}_${releaseCandidate}_${buildNo}.${os}/\" \\\n    \t-e \"s/@@RELEASE@@/${buildTimeStamp}/\" \\\n    \t-e \"s/^Copyright:/Copyright:/\" \\\n    \t> ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(-, root, root) /opt/zimbra/data/httpd/htdocs/aspell.php\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"\" >> ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%clean\" >> ${repoDir}/zm-build/${currentScript}.spec\n    (cd ${repoDir}/zm-build/${currentPackage}; \\\n    \trpmbuild --target ${arch} --define '_rpmdir ../' --buildroot=${repoDir}/zm-build/${currentPackage} -bb ${repoDir}/zm-build/${currentScript}.spec )\n}\n\n############################################################################\nmain \"$@\""
  },
  {
    "path": "instructions/bundling-scripts/zimbra-store.sh",
    "content": "#!/bin/bash\n#\n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n\n# Shell script to create zimbra store package\n\nset -e\n\n#-------------------- Configuration ---------------------------\n\n    currentScript=`basename $0 | cut -d \".\" -f 1`                          # zimbra-store\n    currentPackage=`echo ${currentScript}build | cut -d \"-\" -f 2` # storebuild\n\n#-------------------- Build Package ---------------------------\nmain()\n{\n    echo -e \"\\tCreate package directories\" >> ${buildLogFile}\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/etc/sudoers.d\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/templates\n\n    echo -e \"\\tCopy package files\" >> ${buildLogFile}\n\n    echo -e \"\\tCopy etc files\" >> ${buildLogFile}\n    cp ${repoDir}/zm-build/rpmconf/Env/sudoers.d/02_${currentScript} ${repoDir}/zm-build/${currentPackage}/etc/sudoers.d/02_${currentScript}\n\n    echo -e \"\\tCopy bin files of /opt/zimbra/\" >> ${buildLogFile}\n\n    if [ \"${buildType}\" == \"NETWORK\" ]\n    then\n       cp -f ${repoDir}/zm-hsm-store/src/bin/zmmoveblobs ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmmoveblobs\n       cp -f ${repoDir}/zm-hsm/src/bin/zmhsm ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmhsm\n       cp -f ${repoDir}/zm-hsm/src/bin/zmschedulesmpolicy ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmschedulesmpolicy\n       cp -f ${repoDir}/zm-archive-utils/src/bin/zmarchiveconfig ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmarchiveconfig\n       cp -f ${repoDir}/zm-archive-utils/src/bin/zmarchivesearch ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmarchivesearch\n       cp -f ${repoDir}/zm-sync-tools/src/bin/zmsyncreverseproxy ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmsyncreverseproxy\n       cp -f ${repoDir}/zm-sync-store/src/bin/zmdevicesstats ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmdevicesstats\n       cp -f ${repoDir}/zm-sync-store/src/bin/zmgdcutil ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmgdcutil\n       cp -f ${repoDir}/zm-sync-store/src/bin/zmmdmmailschedule ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmmdmmailschedule\n    fi\n\n\n    cp -f ${repoDir}/zm-migration-tools/zmztozmig.conf ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/zmztozmig.conf\n\n    cp -f ${repoDir}/zm-mailbox/store-conf/conf/owasp_policy.xml ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/owasp_policy.xml\n    cp -f ${repoDir}/zm-mailbox/store-conf/conf/antisamy.xml ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/antisamy.xml\n    cp -f ${repoDir}/zm-mailbox/store-conf/conf/custom-mimetypes.xml ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/custom-mimetypes.xml\n\n    echo -e \"\\tCopy extensions-extra files of /opt/zimbra/\" >> ${buildLogFile}\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/extensions-extra/openidconsumer\n    cp -rf ${repoDir}/zm-openid-consumer-store/build/dist/. ${repoDir}/zm-build/${currentPackage}/opt/zimbra/extensions-extra/openidconsumer\n    rm -rf ${repoDir}/zm-build/${currentPackage}/opt/zimbra/extensions-extra/openidconsumer/extensions-extra\n\n\n    if [ \"${buildType}\" == \"NETWORK\" ]\n    then\n       echo -e \"\\tCopy extensions-network-extra files of /op/zimbra/\" >> ${buildLogFile}\n       mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/extensions-network-extra\n       cp -rf ${repoDir}/zm-saml-consumer-store/build/dist/saml ${repoDir}/zm-build/${currentPackage}/opt/zimbra/extensions-network-extra/\n    fi\n\n    echo -e \"\\tCopy lib files of /opt/zimbra/\" >> ${buildLogFile}\n\n    echo -e \"\\t\\tCopy ext files of /opt/zimbra/lib/\" >> ${buildLogFile}\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/jars\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/mitel\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/clamscanner\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/twofactorauth\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/nginx-lookup\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/openidconsumer\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbra-license\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbra-freebusy\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbraadminversioncheck\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbraldaputils\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zm-oauth-social\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zm-gql\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext-common\n\n    if [ \"${buildType}\" == \"NETWORK\" ]\n    then\n      mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/backup\n      mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbra-archive\n      mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/voice\n      mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/mitel\n      mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/cisco\n      mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbrasync\n      mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/network\n      mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/com_zimbra_oo\n      mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/convertd\n      mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbrahsm\n      mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/smime\n      mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zm-doc-server-ext\n\n      cp -f ${repoDir}/zm-backup-store/build/dist/zm-backup-store.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/backup/zimbrabackup.jar\n      cp -f ${repoDir}/zm-backup-store/build/dist/rocksdbjni-8.1.1.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/backup/rocksdbjni-8.1.1.jar\n      cp -f ${repoDir}/zm-backup-store/build/dist/zstd-jni-1.5.5-9.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/backup/zstd-jni-1.5.5-9.jar\n      cp -f ${repoDir}/zm-archive-store/build/dist/*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbra-archive/zimbra-archive.jar\n      cp -rf ${repoDir}/zm-voice-store/build/dist/zm-voice-store.jar  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/voice/zimbravoice.jar\n      cp -rf ${repoDir}/zm-voice-mitel-store/build/dist/zm-voice-mitel-store.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/mitel\n      cp -rf ${repoDir}/zm-voice-cisco-store/build/dist/zm-voice-cisco-store.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/cisco\n      cp -rf ${repoDir}/zm-sync-common/build/dist/*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbrasync\n      cp -rf ${repoDir}/zm-sync-store/build/dist/*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbrasync\n      cp -rf ${repoDir}/zm-sync-tools/build/dist/*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbrasync\n      cp -f ${repoDir}/zm-openoffice-store/build/dist/*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/com_zimbra_oo\n      mv ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/com_zimbra_oo/zm-openoffice-store.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/com_zimbra_oo/com_zimbra_oo.jar\n      cp -rf ${repoDir}/zm-convertd-store/build/dist/*jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/convertd\n      cp -f ${repoDir}/zm-twofactorauth-store/build/dist/zm-twofactorauth-store*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/twofactorauth/zimbratwofactorauth.jar\n      cp -f ${repoDir}/zm-hsm-store/build/zimbrahsm.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbrahsm/zimbrahsm.jar\n      cp -f ${repoDir}/zm-store-managers/build/zm-store-managers*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbrahsm/zm-store-managers.jar\n      cp -f ${repoDir}/zm-freebusy-provider-store/build/zimbra-freebusyprovider.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbra-freebusy/zimbra-freebusyprovider.jar\n      cp -rf ${repoDir}/zm-smime-store/build/dist/*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/smime\n      cp -f ${repoDir}/zm-network-gql/build/dist/zm-network-gql*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zm-gql/zmnetworkgql.jar\n      cp -f ${repoDir}/zm-zcs-lib/build/dist/tika-app-1.24.1.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/convertd/\n      cp -rf ${repoDir}/zm-doc-server-ext/build/dist/*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zm-doc-server-ext\n    fi\n\n    cp -f ${repoDir}/zm-clam-scanner-store/build/dist/zm-clam-scanner-store*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/clamscanner/clamscanner.jar\n    cp -f ${repoDir}/zm-nginx-lookup-store/build/dist/zm-nginx-lookup-store*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/nginx-lookup/nginx-lookup.jar\n    cp -f ${repoDir}/zm-openid-consumer-store/build/dist/guice*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/openidconsumer/\n    cp -f ${repoDir}/zm-versioncheck-store/build/zm-versioncheck-store*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbraadminversioncheck/zimbraadminversioncheck.jar\n    cp -f ${repoDir}/zm-ldap-utils-store/build/zm-ldap-utils-*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbraldaputils/zimbraldaputils.jar\n    \n    cp -f ${repoDir}/zm-oauth-social/build/dist/zm-oauth-social.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zm-oauth-social/zmoauthsocial.jar\n    cp -f ${repoDir}/zm-oauth-social/build/dist/zm-oauth-social-common.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext-common/zm-oauth-social-common.jar\n    \n    cp -f ${repoDir}/zm-zcs-lib/build/dist/java-jwt-3.2.0.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zm-oauth-social/\n    cp -f ${repoDir}/zm-gql/build/dist/zm-gql*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zm-gql/zmgql.jar\n\n#-------------------- Get wars content (service.war, zimbra.war and zimbraAdmin.war) ---------------------------\n\n    echo \"\\t\\t++++++++++ service.war content ++++++++++\" >> ${buildLogFile}\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/webapps/service/WEB-INF/lib\n    cp ${repoDir}/zm-zimlets/conf/zimbra.tld ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/webapps/service/WEB-INF\n    cp ${repoDir}/zm-taglib/build/zm-taglib*.jar         ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/webapps/service/WEB-INF/lib\n    cp ${repoDir}/zm-zimlets/build/dist/zimlettaglib.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/webapps/service/WEB-INF/lib\n\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/webapps/zimbra\n\n    if [ \"${buildType}\" == \"NETWORK\" ]\n    then\n      echo \"\\t\\t***** css, public and t content *****\" >> ${buildLogFile}\n      mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/webapps/zimbra/css\n      mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/webapps/zimbra/public\n    fi\n\n    echo \"\\t\\t***** portals example content *****\" >> ${buildLogFile}\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/webapps/zimbra/portals/example\n    cp -rf ${repoDir}/zm-webclient-portal-example/example ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/webapps/zimbra/portals\n\n    echo \"\\t\\t***** robots.txt content *****\" >> ${buildLogFile}\n    cp -f ${repoDir}/zm-aspell/conf/robots.txt ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/webapps/zimbra/robots.txt\n\n    echo \"\\t\\t***** downloads content *****\" >> ${buildLogFile}\n    downloadsDir=${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/webapps/zimbra/downloads\n    mkdir -p ${downloadsDir}\n    cp -rf ${repoDir}/zm-downloads/. ${downloadsDir}\n\n    if [ \"${buildType}\" == \"NETWORK\" ]\n    then\n        set -e\n        cd ${downloadsDir}\n        # wget -r -nd --no-parent --reject-regex=\"/backup/\" --reject \"index.*\" http://${zimbraThirdPartyServer}/ZimbraThirdParty/zco-migration-builds/current/\n        # zimbraThirdPartyServer Could be S3 bucket name.\n        rclone copy -v ${zimbraThirdPartyServer}/ZimbraThirdParty/zco-migration-builds/current/ ./\n    fi\n\n    echo \"\\t\\t***** help content *****\" >> ${buildLogFile}\n    rsync -a ${repoDir}/zm-admin-help-common/WebRoot/help ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/webapps/zimbraAdmin/\n\n    if [ \"${buildType}\" == \"NETWORK\" ]\n    then\n       rsync -a ${repoDir}/zm-admin-help-network/WebRoot/help ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/webapps/zimbraAdmin/\n    fi\n\n    if [ \"${buildType}\" == \"NETWORK\" ]\n    then\n      echo -e \"\\t\\tCopy ext-common files of /opt/zimbra/lib/\" >> ${buildLogFile}\n      mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext-common\n      cp -f ${repoDir}/zm-zcs-lib/build/dist/bcpkix-jdk15on-1.64.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext-common/\n      cp -f ${repoDir}/zm-zcs-lib/build/dist/bcmail-jdk15on-1.64.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext-common/\n      cp -f ${repoDir}/zm-zcs-lib/build/dist/bcprov-jdk15on-1.64.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext-common/\n      cp -f ${repoDir}/zm-zcs-lib/build/dist/saaj-impl-1.5.1.jar     ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext-common/\n    fi\n\n    cp -f ${repoDir}/zm-migration-tools/src/libexec/zmztozmig ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec\n    cp -f ${repoDir}/zm-migration-tools/src/libexec/zmcleaniplanetics ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec\n    cp -f ${repoDir}/zm-versioncheck-utilities/src/libexec/zmcheckversion ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec\n\n    echo -e \"\\tCopy log files of /opt/zimbra/\" >> ${buildLogFile}\n     mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/log\n     cp -f ${repoDir}/zm-build/rpmconf/Conf/hotspot_compiler ${repoDir}/zm-build/${currentPackage}/opt/zimbra/log/.hotspot_compiler\n\n    echo -e \"\\tCopy zimlets files of /opt/zimbra/\" >> ${buildLogFile}\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/zimlets\n    zimletsArray=( \"zm-versioncheck-admin-zimlet\" \\\n                   \"zm-bulkprovision-admin-zimlet\" \\\n                   \"zm-certificate-manager-admin-zimlet\" \\\n                   \"zm-proxy-config-admin-zimlet\" \\\n                   \"zm-helptooltip-zimlet\" \\\n                   \"zm-viewmail-admin-zimlet\" )\n    for i in \"${zimletsArray[@]}\"\n    do\n        cp ${repoDir}/${i}/build/zimlet/*.zip ${repoDir}/zm-build/${currentPackage}/opt/zimbra/zimlets\n    done\n\n    cp -f ${repoDir}/zm-zimlets/build/dist/zimlets/*.zip ${repoDir}/zm-build/${currentPackage}/opt/zimbra/zimlets\n\n    if [ \"${buildType}\" == \"NETWORK\" ]\n    then\n      echo -e \"\\tCopy zimlets-network files of /opt/zimbra/\" >> ${buildLogFile}\n      mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/zimlets-network\n      adminZimlets=( \"zm-license-admin-zimlet\" \\\n                     \"zm-backup-restore-admin-zimlet\" \\\n                     \"zm-convertd-admin-zimlet\" \\\n                     \"zm-delegated-admin-zimlet\" \\\n                     \"zm-hsm-admin-zimlet\" \\\n                     \"zm-smime-cert-admin-zimlet\" \\\n                     \"zm-2fa-admin-zimlet\" \\\n                     \"zm-ucconfig-admin-zimlet\" \\\n                     \"zm-securemail-zimlet\" \\\n                     \"zm-mobile-sync-admin-zimlet\" )\n      for i in \"${adminZimlets[@]}\"\n      do\n         cp ${repoDir}/${i}/build/zimlet/*.zip ${repoDir}/zm-build/${currentPackage}/opt/zimbra/zimlets-network\n      done\n\n      adminUcZimlets=( \"cisco\" \"mitel\" \"voiceprefs\" )\n      for i in \"${adminUcZimlets[@]}\"\n      do\n         cp ${repoDir}/zm-uc-admin-zimlets/${i}/build/zimlet/*.zip ${repoDir}/zm-build/${currentPackage}/opt/zimbra/zimlets-network\n      done\n    fi\n\n    echo \"\\t\\t***** Building jetty/common/ *****\" >> ${buildLogFile}\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/common/endorsed\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/common/lib\n\n\n   mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/temp\n   touch ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/temp/.emptyfile\n\n     echo -e \"\\tCreate jetty conf\" >> ${buildLogFile}\n     mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/etc\n     mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/modules\n     mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/start.d\n\n    cp -f ${repoDir}/zm-jetty-conf/conf/jetty/jettyrc  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/etc/\n    cp -f ${repoDir}/zm-jetty-conf/conf/jetty/zimbra.policy.example ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/etc/\n    cp -f ${repoDir}/zm-jetty-conf/conf/jetty/jetty.xml.production ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/etc/jetty.xml.in\n    cp -f ${repoDir}/zm-jetty-conf/conf/jetty/webdefault.xml.production ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/etc/webdefault.xml\n    cp -f ${repoDir}/zm-jetty-conf/conf/jetty/jetty-setuid.xml ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/etc/jetty-setuid.xml\n    cp -f ${repoDir}/zm-jetty-conf/conf/jetty/spnego/etc/spnego.properties ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/etc/spnego.properties.in\n    cp -f ${repoDir}/zm-jetty-conf/conf/jetty/spnego/etc/spnego.conf ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/etc/spnego.conf.in\n    cp -f ${repoDir}/zm-jetty-conf/conf/jetty/spnego/etc/krb5.ini ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/etc/krb5.ini.in\n    cp -f ${repoDir}/zm-jetty-conf/conf/jetty/modules/*.mod  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/modules\n    cp -f ${repoDir}/zm-jetty-conf/conf/jetty/modules/*.mod.in ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/modules\n    cp -f ${repoDir}/zm-jetty-conf/conf/jetty/start.d/*.ini.in   ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/start.d\n    cp -f ${repoDir}/zm-jetty-conf/conf/jetty/modules/npn/*.mod  ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/modules/npn\n    cp -f ${repoDir}/zm-jetty-conf/conf/jetty/jetty-logging.properties ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/etc/\n\n    cp -f ${repoDir}/zm-zimlets/conf/web.xml.production ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/etc/zimlet.web.xml.in\n\n    CreatePackage \"${os}\"\n}\n\n#-------------------- Util Functions ---------------------------\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"$0\")\" && pwd)\"\n\nsource \"$SCRIPT_DIR/utils.sh\"\n\nCreateDebianPackage()\n{\n    mkdir -p ${repoDir}/zm-build/${currentPackage}/DEBIAN\n    cat ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.pre >> ${repoDir}/zm-build/${currentPackage}/DEBIAN/preinst\n    cat ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post >> ${repoDir}/zm-build/${currentPackage}/DEBIAN/postinst\n    chmod 555 ${repoDir}/zm-build/${currentPackage}/DEBIAN/*\n\n    echo -e \"\\tCreate debian package\" >> ${buildLogFile}\n    (cd ${repoDir}/zm-build/${currentPackage}; find . -type f ! -regex '.*jetty_base/webapps/zimbra/WEB-INF/jetty-env.xml' ! \\\n        -regex '.*jetty_base/webapps/zimbraAdmin/WEB-INF/jetty-env.xml' ! -regex '.*jetty_base/modules/setuid.mod' ! \\\n        -regex '.*jetty_base/etc/krb5.ini' ! -regex '.*jetty_base/etc/spnego.properties' ! -regex '.*jetty_base/etc/jetty.xml' ! \\\n        -regex '.*jetty_base/etc/spnego.conf' ! -regex '.*jetty_base/webapps/zimbraAdmin/WEB-INF/web.xml' ! \\\n        -regex '.*jetty_base/webapps/zimbra/WEB-INF/web.xml' ! -regex '.*jetty_base/webapps/service/WEB-INF/web.xml' ! \\\n        -regex '.*jetty_base/work/.*' ! -regex '.*.hg.*' ! -regex '.*?debian-binary.*' ! -regex '.*?DEBIAN.*' -print0 | xargs -0 md5sum | \\sed -e 's| \\./| |' \\\n        > ${repoDir}/zm-build/${currentPackage}/DEBIAN/md5sums)\n\n    (\n      set -e\n      MORE_DEPENDS=\"$(find ${repoDir}/zm-packages/ -name \\*.deb \\\n                         | xargs -n1 basename \\\n                         | sed -e 's/_[0-9].*//' \\\n                         | grep -e zimbra-mbox- \\\n                         | sed '1s/^/, /; :a; {N;s/\\n/, /;ba}')\";\n\n      cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.deb \\\n         | sed -e \"s/@@VERSION@@/${releaseNo}.${releaseCandidate}.${buildNo}.${os/_/.}/\" \\\n               -e \"s/@@branch@@/${buildTimeStamp}/\" \\\n               -e \"s/@@ARCH@@/${arch}/\" \\\n               -e \"s/@@MORE_DEPENDS@@/${MORE_DEPENDS}/\" \\\n               -e \"s/@@PKG_OS_TAG@@/${PKG_OS_TAG}/\" \\\n               -e \"/^%post$/ r ${currentScript}.post\"\n    ) > ${repoDir}/zm-build/${currentPackage}/DEBIAN/control\n\n    (cd ${repoDir}/zm-build/${currentPackage}; dpkg -b ${repoDir}/zm-build/${currentPackage} ${repoDir}/zm-build/${arch})\n\n}\n\nCreateRhelPackage()\n{\n    MORE_DEPENDS=\"$(find ${repoDir}/zm-packages/ -name \\*.rpm \\\n                       | xargs -n1 basename \\\n                       | sed -e 's/-[0-9].*//' \\\n                       | grep -e zimbra-mbox- \\\n                       | sed '1s/^/, /; :a; {N;s/\\n/, /;ba}')\";\n\n    cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.spec | \\\n    \tsed -e \"s/@@VERSION@@/${releaseNo}_${releaseCandidate}_${buildNo}.${os}/\" \\\n            \t-e \"s/@@RELEASE@@/${buildTimeStamp}/\" \\\n                -e \"s/@@MORE_DEPENDS@@/${MORE_DEPENDS}/\" \\\n                -e \"s/@@PKG_OS_TAG@@/${PKG_OS_TAG}/\" \\\n            \t-e \"/^%pre$/ r ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.pre\" \\\n            \t-e \"/^%post$/ r ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post\" > ${repoDir}/zm-build/${currentScript}.spec\n\n    echo \"%attr(-, root, root) /opt/zimbra/lib\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(440, root, root) /etc/sudoers.d/02_zimbra-store\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(755, zimbra, zimbra) /opt/zimbra/conf\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(644, zimbra, zimbra) /opt/zimbra/conf/*\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(-, zimbra, zimbra) /opt/zimbra/log\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(-, zimbra, zimbra) /opt/zimbra/zimlets\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(-, zimbra, zimbra) /opt/zimbra/extensions-extra\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n\n   if [ \"${buildType}\" == \"NETWORK\" ]\n   then\n      echo \"%attr(-, zimbra, zimbra) /opt/zimbra/zimlets-network\" >> \\\n         ${repoDir}/zm-build/${currentScript}.spec\n      echo \"%attr(-, zimbra, zimbra) /opt/zimbra/extensions-network-extra\" >> \\\n         ${repoDir}/zm-build/${currentScript}.spec\n   fi\n\n    echo \"%attr(755, root, root) /opt/zimbra/bin\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(755, root, root) /opt/zimbra/libexec\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"%attr(-, zimbra, zimbra) /opt/zimbra/jetty_base\" >> \\\n    \t${repoDir}/zm-build/${currentScript}.spec\n    echo \"\" >> ${repoDir}/zm-build/${currentScript}.spec\n    echo \"%clean\" >> ${repoDir}/zm-build/${currentScript}.spec\n    (cd ${repoDir}/zm-build/${currentPackage}; \\\n    rpmbuild --target ${arch} --define '_rpmdir ../' --buildroot=${repoDir}/zm-build/${currentPackage} -bb ${repoDir}/zm-build/${currentScript}.spec )\n}\n############################################################################\nmain \"$@\"\n"
  },
  {
    "path": "lib/Zimbra/DB/DB.pm",
    "content": "# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2005, 2007, 2009, 2010, 2013, 2014, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n# \npackage Zimbra::DB::DB;\n\nuse strict;\n\n#############\n\nmy $MYSQL = \"mysql\";\nmy $DB_USER = \"zimbra\";\nmy $DB_PASSWORD = \"zimbra\";\nmy $database = \"zimbra\";\nmy $ZMLOCALCONFIG = \"/opt/zimbra/bin/zmlocalconfig\";\n\nif ($^O !~ /MSWin/i) {\n    $DB_PASSWORD = `$ZMLOCALCONFIG -s -m nokey zimbra_mysql_password`;\n    chomp $DB_PASSWORD;\n    $DB_USER = `$ZMLOCALCONFIG -m nokey zimbra_mysql_user`;\n    chomp $DB_USER;\n    $MYSQL = \"/opt/zimbra/bin/mysql\";\n}\n\nsub getDatabase() {\n    return $database;\n}\n\nsub setDatabase($) {\n    $database = shift();\n}\n\nsub getMailboxIds() {\n    return runSql(\"SELECT id FROM mailbox ORDER BY id\");\n}\n\nsub runSql(@) {\n    my ($script, $logSql) = @_;\n\n    if (! defined($logSql)) {\n\t$logSql = 1;\n    }\n\n    # Write the last script to a text file for debugging\n    # open(LASTSCRIPT, \">lastScript.sql\") || die \"Could not open lastScript.sql\";\n    # print(LASTSCRIPT $script);\n    # close(LASTSCRIPT);\n\n    if ($logSql) {\n\tZimbra::DB::DB::log($script);\n    }\n\n    # Run the mysql command and redirect output to a temp file\n    my $tempFile = \"/tmp/mysql.out.$$\";\n    my $command = \"$MYSQL --user=$DB_USER --password=$DB_PASSWORD \" .\n        \"--database=$database --batch --skip-column-names\";\n    open(MYSQL, \"| $command > $tempFile\") || die \"Unable to run $command\";\n    print(MYSQL $script);\n    close(MYSQL);\n\n    if ($? != 0) {\n        die \"Error while running '$command'.\";\n    }\n\n    # Process output\n    open(OUTPUT, $tempFile) || die \"Could not open $tempFile\";\n    my @output;\n    while (<OUTPUT>) {\n        s/\\s+$//;\n        push(@output, $_);\n    }\n\n    unlink($tempFile);\n    return @output;\n}\n\nsub log\n{\n    print scalar(localtime()), \": \", @_, \"\\n\";\n}\n\n1;\n"
  },
  {
    "path": "lib/Zimbra/LDAP.pm",
    "content": "package Zimbra::LDAP;\n\nuse strict;\nuse warnings;\n\nuse Zimbra::LocalConfig;\nuse Net::LDAP;\n\nmy $ERROR;\nmy $TLSVERIFY = \"require\";               # \"none\"\nmy $CAPATH    = \"/opt/zimbra/conf/ca\";\n\n=head1 NAME\n\nZimbra::LDAP - Access to Zimbra LDAP directory\n\n=head1 SYNOPSIS\n\n  my $zl     = Zimbra::LDAP->new;\n  my $global = $zl->global;\n  my $server = $zl->server('mail.zimbra.com');\n  my $admin  = $zl->mail('admin@mail.zimbra.com');\n  \n  print $global->get_value(\"zimbraSmtpHostname\") , \"\\n\";\n  print $server->get_value(\"zimbraSmtpHostname\") , \"\\n\";\n  print $admin->get_value(\"cn\") , \"\\n\";\n  \n  \n  # when default settings are not what you need\n  use Zimbra::LocalConfig;\n  use Zimbra::LDAP;\n   \n  my $zlc = Zimbra::LocalConfig->new( file => \"some non-default file\" )\n    ;    # when working with multiple environments create multiple objects\n  my $zl = Zimbra::LDAP->new(\n      dn       => $zlc->get('my local config dn'),          # grab from config\n      password => $zlc->get('my local config password'),    # grab from config\n      config => $zlc,                  # pass in custom local config\n      url    => $zlc->get('my url')    # grab from config\n  );\n\n\n=head1 DESCRIPTION\n\nPerl API for interacting with the Zimbra LDAP server.\n\n=head1 CONSTRUCTOR\n\n=head2 new\n\nCreates new instance of Zimbra::LDAP.\n\nNew supports passing in the following values:\n\n=over\n\n=item url\n\n=item dn\n\n=item password\n\n=item config\n\n=back\n\nSee each of the above methods for more details about each value.\n\n  my $zl = Zimbra::LDAP->new;\n  my $zl = Zimbra::LDAP->new( dn => \"my dn\", password => \"my dn password\" );\n\n=cut\n\nsub new {\n    my $class = shift;\n    my %args  = @_;\n    my $self  = {};\n    bless $self, $class;\n\n    foreach my $key ( keys %args ) {\n        if ( $self->can($key) ) {\n            unless ( $self->$key( $args{$key} ) ) {\n                return;\n            }\n        }\n    }\n\n    return unless ( $self->config );\n    return unless ( $self->ldap );\n    return $self;\n}\n\n=head1 PROPERTIES\n\n=head2 error\n\nReturns last error message.\n\n  print Zimbra::LDAP->error, \"\\n\";\n  print $zl->error,          \"\\n\";\n\n=cut\n\nsub error {\n    $ERROR = $_[1] if ($#_);\n    return $ERROR;\n}\n\n=head2 config\n\nReturns the Zimbra::LocalConfig object.\n\n  print $zl->config->get(\"ldap_url\"), \"\\n\";\n\n=cut\n\nsub config {\n    $_[0]->{_config} = $_[1] if ($#_);    # allow new to assign value\n    unless ( exists( $_[0]->{_config} ) ) {\n        unless ( $_[0]->{_config} = Zimbra::LocalConfig->new ) {\n            $_[0]->error(\n                \"Zimbra::LocalConfig error: \" . Zimbra::LocalConfig->error );\n            return;\n        }\n    }\n    return $_[0]->{_config};\n}\n\n=head2 dn\n\nReturns the local config zimbra_ldap_userdn or the dn value passed during new.\n\n  print $zl->dn, \"\\n\";\n\n=cut\n\nsub dn {\n    $_[0]->{_dn} = $_[1] if ($#_);    # allow new to assign value\n    $_[0]->{_dn} = $_[0]->config->get(\"zimbra_ldap_userdn\")\n      unless ( exists( $_[0]->{_dn} ) );    # assign default dn;\n    return $_[0]->{_dn};\n}\n\n=head2 password\n\nReturns the local config zimbra_ldap_password or the password value passed during new.\n\n  print $zl->password, \"\\n\";\n\n=cut\n\nsub password {\n    $_[0]->{_password} = $_[1] if ($#_);    # allow new to assign value\n    $_[0]->{_password} = $_[0]->config->get(\"zimbra_ldap_password\")\n      unless ( exists( $_[0]->{_password} ) );    # assign default password;\n    return $_[0]->{_password};\n}\n\n=head2 url\n\nReturns the local config ldap_url or the value url value passed during new.\n\n  print $zl->url, \"\\n\";\n\n=cut\n\nsub url {\n    $_[0]->{_url} = $_[1] if ($#_);                  # allow new to assign value\n    $_[0]->{_url} = $_[0]->config->get(\"ldap_url\")\n      unless ( exists( $_[0]->{_url} ) );            # assign default url;\n    return $_[0]->{_url};\n}\n\n=head2 ldap\n\nReturns the Net::LDAP object.\n\n  my $result = $zl->ldap->search(...);\n\n=cut\n\nsub ldap {\n    unless ( exists( $_[0]->{_ldap} ) ) {\n        if ( my $ldapurl = $_[0]->url ) {\n            my $servers = [ split( / /, $ldapurl ) ];\n\n            # connect to ldap server\n            unless ( $_[0]->{_ldap} = Net::LDAP->new($servers) ) {\n                delete( $_[0]->{_ldap} );\n                $_[0]->error( \"Failed to connect to LDAP (\"\n                      . join( \" \", @$servers ) . \"):\"\n                      . $@ );\n                return;\n            }\n\n       #print \"LDAP Host: \",$_[0]->{_ldap}->host,\" \",$_[0]->{_ldap}->scheme,\" \",\n       #     $_[0]->config->get(\"ldap_starttls_supported\"),\"\\n\";\n       # start TLS if desired\n            if ( $_[0]->{_ldap}->scheme !~ /^ldaps$/i ) {\n                if ( $_[0]->config->get(\"ldap_starttls_supported\") ) {\n                    my $mesg = $_[0]->{_ldap}->start_tls(\n                        verify => $TLSVERIFY,\n                        capath => $CAPATH\n                    );\n                    if ( $mesg->code ) {\n                        $_[0]->error( \"start tls failed: \" . $mesg->error );\n                        return;\n                    }\n                }\n            }\n\n            # bind ldap\n            my $mesg =\n              $_[0]->{_ldap}->bind( $_[0]->dn, password => $_[0]->password );\n            if ( $mesg->code ) {\n                $_[0]->error( \"bind failed: \" . $mesg->error );\n                return;\n            }\n        }\n        else {\n            $_[0]->error(\"ldap_url not defined in localconfig\");\n            return;\n        }\n    }\n    return $_[0]->{_ldap};\n}\n\n=head2 global\n\nReturns Net::LDAP::Entry for the Zimbra global config LDAP entry.\n\n  print $zl->global->get_value(\"zimbraSmtpHostname\"), \"\\n\";\n\n=cut\n\nsub global {\n    unless ( exists( $_[0]->{_global} ) ) {\n        $_[0]->{_global} = $_[0]->searchsingle(\n            scope  => \"base\",\n            base   => \"cn=config,cn=zimbra\",\n            filter => \"cn=config\"\n        );\n    }\n    return $_[0]->{_global};\n}\n\n=head1 METHODS\n\n=head2 mail\n\nReturns Net::LDAP::Entry for the passed mail address.\n\n  my $admin=$zl->mail('admin@mail.zimbra.com');\n\n=cut\n\nsub mail {\n    my $self = shift;\n    my $mail = shift;\n    return $self->searchsingle( filter => \"(mail=$mail)\" );\n}\n\n=head2 searchsingle\n\nPasses all arguments to Net::LDAP search method and checks that we only get one result and returns that specific Net::LDAP::Entry value.\n\n  my $mail = $zl->searchsingle( filter => \"(mail=$mail)\" );\n  unless ($mail) {\n      print $zl->error, \"\\n\";\n  }\n\n=cut\n\nsub searchsingle {\n    my ( $self, %args ) = @_;\n    my $mesg  = $self->ldap->search(%args);\n    my $count = $mesg->count;\n    if ( $count != 1 ) {\n        $self->error(\"$count matches for '$args{filter}'\");\n        return;\n    }\n    return $mesg->entry(0);\n}\n\n=head2 server\n\nReturns Net::LDAP::Entry for the passed server name.\n\n  my $server = $zl->server('mail.zimbra.com');\n\n=cut\n\nsub server {\n    my $self = shift;\n    my $host = shift;\n    return $self->searchsingle(\n        base   => \"cn=servers,cn=zimbra\",\n        filter => \"(cn=$host)\"\n    );\n}\n\n=head1 SEE ALSO\n\nL<Zimbra::LocalConfig>, L<Net::LDAP>\n\n=cut\n\n1;\n"
  },
  {
    "path": "lib/Zimbra/LocalConfig.pm",
    "content": "package Zimbra::LocalConfig;\n\nuse strict;\nuse warnings;\n\nuse XML::Simple;\n\nmy $ERROR;\n\n=head1 NAME\n\nZimbra::LocalConfig - Read access to all Zimbra local config values\n\n=head1 SYNOPSIS\n\n  use Zimbra::LocalConfig;\n  my $zlc = Zimbra::LocalConfig->new;\n  print $zlc->get('ldap_url'), \"\\n\";\n\n=head1 DESCRIPTION\n\nPerl API for accessing zimbra local config values.\n\n=head1 CONSTRUCTOR\n\n=head2 new\n\nCreates new instance of Zimbra::LocalConfig.\n\n  my $zlc = Zimbra::LocalConfig->new;\n  my $zlc = Zimbra::LocalConfig->new(file=>\"my zimbra config xml file\");\n\n=cut\n\nsub new {\n    my $class = shift;\n    my %args  = @_;\n    my $self  = {};\n\n    bless $self, $class;\n\n    foreach my $key ( keys %args ) {\n        if ( $self->can($key) ) {\n            unless ( $self->$key( $args{$key} ) ) {\n                return;\n            }\n        }\n    }\n\n    return unless ( $self->xml );\n    return $self;\n}\n\n=head1 PROPERTIES\n\n=head2 error\n\nReturns last error message.\n\n  print Zimbra::LocalConfig->error, \"\\n\";\n  print $zlc->error,                \"\\n\";\n\n=cut\n\nsub error {\n    $ERROR = $_[1] if ($#_);\n    return $ERROR;\n}\n\n=head2 file\n\nReturns the local config file name. Defaults to:\n\n/opt/zimbra/conf/localconfig.xml\n\n  print $zlc->file, \"\\n\";\n\n=cut\n\nsub file {\n    $_[0]->{_file} = $_[1] if ($#_);    # allow new to assign value\n    $_[0]->{_file} = \"/opt/zimbra/conf/localconfig.xml\"\n      unless ( exists( $_[0]->{_file} ) );    # assign default file;\n    return $_[0]->{_file};\n}\n\n=head2 xml\n\nReturns HASH representation of XML file.\n\n\n  print $zlc->xml->{key}{ldap_url}, \"\\n\";\n\n=cut\n\nsub xml {\n    $_[0]->{_xml} = $_[1] if ($#_);    # allow new to assign value\n    unless ( exists( $_[0]->{_xml} ) ) {\n        unless ( $_[0]->{_xml} = XMLin( $_[0]->file ) ) {\n            $_[0]->error( \"failed to open \" . $_[0]->file . \": \" . $@ );\n            return;\n        }\n    }\n    return $_[0]->{_xml};\n}\n\n=head1 METHODS\n\n=head2 get\n\nGet passed local config value.\n\n  my $ldapurl = $zlc->get('ldap_url');\n\n=cut\n\nsub get {\n    if ( exists( $_[0]->xml->{key}{ $_[1] } ) ) {\n        return $_[0]->xml->{key}{ $_[1] }{value};\n    }\n    else {\n        return;\n    }\n}\n\n=head1 SEE ALSO\n\nL<XML::Simple>\n\n=cut\n\n1;\n"
  },
  {
    "path": "lib/Zimbra/Mon/Logger.pm",
    "content": "# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2013, 2014, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n# \n#!/usr/bin/perl\n\npackage Zimbra::Mon::Logger;\n\nuse strict;\n\nuse Sys::Syslog qw(:DEFAULT setlogsock);;\nuse Data::UUID;\n\nrequire Exporter;\n\nmy @ISA = qw(Exporter);\n\nmy $ident=\"zimbramon\";\nmy $facility=\"local0\";\nmy $stats_facility = \"local1\";\n\nmy @EXPORT = qw (Log);\n\nour %loglevels = ('debug' => 0, 'info' => 1, 'err' => 3, 'crit' => 4);\n\nmy $LOG_LEVEL = $loglevels{'info'};\nmy $ug = new Data::UUID;\n\nsub Log\n{\n\tmy ($level,$msg) = (@_);\n\tif ($loglevels{$level} >= $LOG_LEVEL) {\n\t\t# native is a better choice but unix provide a consistent output\n\t\t# across multiple nodes that makes parsing easier\n\t\tsetlogsock('unix');\n\t\teval { openlog($ident, \"pid,ndelay,nowait,nofatal\", $facility); };\n\t\treturn if ($@);\n\t\tif (length($msg) <= 800) {\n\t\t\t syslog($level, \"$$:$level: $msg\");\n\t\t} else {\n\t\t\tmy $last_uuid = undef;\n\t\t\tmy $m = $msg;\n\t\t\tdo {\n\t\t\t\tmy $substring = substr $m, 0, 800;\n\t\t\t\t$m = substr $m, 800;\n\t\t\t\tif (defined $last_uuid) {\n\t\t\t\t\t$substring = \":::${last_uuid}:::${substring}\";\n\t\t\t\t}\n\t\t\t\t$last_uuid = $ug->to_string($ug->create());\n\t\t\t\tsyslog($level, \"$$:$level: ${substring}:::${last_uuid}:::\");\n\t\t\t} while (length($m) > 800);\n\t\t\tsyslog($level, \":::${last_uuid}:::${m}\");\n\t\t\t\n\t\t}\n\t\tif ($::DEBUG) {\n\t\t\tprint STDERR scalar localtime().\":$$:$level: $msg\\n\";\n\t\t}\n\t\tcloselog();\n\t}\n}\n\nsub LogStats\n{\n\tmy ($level,$msg) = (@_);\n\tif ($loglevels{$level} >= $LOG_LEVEL) {\n\t\tsetlogsock('unix');\n\t\teval { openlog($ident, \"pid,ndelay,nowait,nofatal\", $stats_facility);};\n\t\treturn if ($@);\n\t\tif (length($msg) <= 800) {\n\t\t\t syslog($level, \"$$:$level: $msg\");\n\t\t} else {\n\t\t\tmy $last_uuid = undef;\n\t\t\tmy $m = $msg;\n\t\t\tdo {\n\t\t\t\tmy $substring = substr $m, 0, 800;\n\t\t\t\t$m = substr $m, 800;\n\t\t\t\tif (defined $last_uuid) {\n\t\t\t\t\t$substring = \":::${last_uuid}:::${substring}\";\n\t\t\t\t}\n\t\t\t\t$last_uuid = $ug->to_string($ug->create());\n\t\t\t\tsyslog($level, \"$$:$level: ${substring}:::${last_uuid}:::\");\n\t\t\t} while (length($m) > 800);\n\t\t\tsyslog($level, \":::${last_uuid}:::${m}\");\n\t\t\t\n\t\t}\n\t\tif ($::DEBUG) {\n\t\t\tprint STDERR scalar localtime().\":$$:$level: $msg\\n\";\n\t\t}\n\t\tcloselog();\n\t}\n}\n\n\n1\n\n"
  },
  {
    "path": "lib/Zimbra/Mon/LoggerSchema.pm",
    "content": "# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2009, 2010, 2013, 2014, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n# \npackage Zimbra::Mon::LoggerSchema;\nuse strict;\n\nrequire Exporter;\nour @ISA = qw(Exporter);\nour @EXPORT = qw(@LOGGER_SCHEMA_UPGRADE);\n\n\nour @LOGGER_SCHEMA_UPGRADE = (\n    # version 0, schema version\n    [ q{\n    \tCREATE TABLE config (\n    \t    version INTEGER NOT NULL UNIQUE\n    \t)\n      },\n      q{\n        INSERT INTO config VALUES (0);\n      }\n    ],\n    # version 1, column mapping\n    [ q{\n    \tCREATE TABLE rrd_column_type (\n    \t    csv_file     varchar(255) not null,\n    \t    col_name     varchar(255) not null,\n    \t    -- G-AUGE, C-OUNTER, A-BSOLUTE or D-ERIVED\n    \t    col_type     char(1) not null,\n    \t    col_interval integer,\n    \t    CONSTRAINT unqcoltype UNIQUE (csv_file, col_name)\n    \t)\n      },\n      # sqlite's version of multiple insert\n      #\n      # by default, all columns will have an interval of 30s\n      # and type of GAUGE (i.e. columns not in this table)\n      q{\n      \tINSERT INTO rrd_column_type\n      \t          select 'mailboxd.csv', 'gc_minor_ms',    'C', 30\n      \tunion all select 'mailboxd.csv', 'gc_minor_count', 'C', 30\n      \tunion all select 'mailboxd.csv', 'gc_major_ms',    'C', 30\n      \tunion all select 'mailboxd.csv', 'gc_major_count', 'C', 30\n      \tunion all select 'mysql.csv',    'Slow_queries',   'C', 30\n      \tunion all select 'mysql.csv',    'Opened_tables',  'C', 30\n      \tunion all select 'df.csv',       'disk_pct_used',  'G', 600\n      \tunion all select 'df.csv',       'disk_use',       'G', 600\n      \tunion all select 'df.csv',       'disk_space',     'G', 600\n      \tunion all select 'zmmtastats',   'clam_events',    'A', 300\n      \tunion all select 'zmmtastats',   'sendmail_events','A', 300\n      \tunion all select 'zmmtastats',   'filter_count',   'A', 300\n      \tunion all select 'zmmtastats',   'filter_virus',   'A', 300\n      \tunion all select 'zmmtastats',   'filter_spam',    'A', 300\n      \tunion all select 'zmmtastats',   'filter_misc',    'A', 300\n      \tunion all select 'zmmtastats',   'mta_count',      'A', 300\n      \tunion all select 'zmmtastats',   'mta_volume',     'A', 300\n      },\n      q{\n      \tUPDATE config SET version = 1\n      }\n    ],\n    # version 2, column globs\n    [ q{\n    \t UPDATE rrd_column_type SET col_interval = 60 WHERE csv_file = 'mailboxd.csv'\n      },\n      q{\n      \tINSERT INTO rrd_column_type\n      \t          select 'mailboxd.csv', '*',    'G', 60\n      \tunion all select 'zmstatuslog',  '*',    'G', 120\n      },\n      q{\n      \tUPDATE config SET version = 2\n      }\n    ],\n    # version 3, counter types\n    [ q{\n    \tALTER table rrd_column_type ADD COLUMN col_unit varchar(64)\n      },\n      q{\n      \tUPDATE rrd_column_type SET col_unit = '% time', col_interval = 60\n      \t WHERE col_name IN ('gc_minor_ms', 'gc_major_ms')\n      },\n      q{\n      \tUPDATE rrd_column_type SET col_unit = 'times/second', col_interval = 60\n      \t WHERE col_name IN ('gc_minor_count', 'gc_major_count')\n      },\n      q{\n      \tUPDATE rrd_column_type SET col_unit = 'queries/s'\n      \t WHERE col_name = 'Slow_queries'\n      },\n      q{\n      \tUPDATE rrd_column_type SET col_unit = 'opens/s'\n      \t WHERE col_name = 'Opened_tables'\n      },\n      q{\n      \tUPDATE rrd_column_type SET col_unit = 'bytes'\n      \t WHERE col_name IN ('disk_use', 'disk_space')\n      },\n      q{\n      \tUPDATE rrd_column_type SET col_unit = 'events/s'\n      \t WHERE col_name IN ('clam_events', 'sendmail_events')\n      },\n      q{\n      \tUPDATE rrd_column_type SET col_unit = 'filter/s'\n      \t WHERE col_name IN ('filter_count', 'filter_misc', 'filter_virus', 'filter_spam')\n      },\n      q{\n      \tUPDATE rrd_column_type SET col_unit = 'msgs/s'\n      \t WHERE col_name = 'mta_count'\n      },\n      q{\n      \tUPDATE rrd_column_type SET col_unit = 'bytes/s'\n      \t WHERE col_name = 'mta_volume'\n      },\n      q{\n      \tINSERT INTO rrd_column_type select 'mysql.csv',  '*', 'G', 30, null\n      },\n      q{\n      \tINSERT INTO rrd_column_type\n      \t          select 'mtaqueue.csv', 'requests',          'G', 30, 'msgs'\n      \tunion all select 'fd.csv',       'fd_count',          'G', 30, 'fd'\n      \tunion all select 'cpu.csv',      '*',                 'G', 30, '% cpu'\n      \tunion all select 'vmstat.csv',   'pageins',           'G', 30, 'KB/s'\n      \tunion all select 'vmstat.csv',   'si',                'G', 30, 'KB/s'\n      \tunion all select 'vmstat.csv',   'pageout',           'G', 30, 'KB/s'\n      \tunion all select 'vmstat.csv',   'so',                'G', 30, 'KB/s'\n      \tunion all select 'vmstat.csv',   'free',              'G', 30, 'KB'\n      \tunion all select 'vmstat.csv',   'active',            'G', 30, 'KB'\n      \tunion all select 'vmstat.csv',   'inac',              'G', 30, 'KB'\n      \tunion all select 'vmstat.csv',   'Active',            'G', 30, 'KB'\n      \tunion all select 'vmstat.csv',   'Inactive',          'G', 30, 'KB'\n      \tunion all select 'vmstat.csv',   'cache',             'G', 30, 'KB'\n      \tunion all select 'vmstat.csv',   'cs',                'G', 30, 'cs/s'\n      \tunion all select 'vmstat.csv',   'r',                 'G', 30, 'run-q'\n      \tunion all select 'vmstat.csv',   'b',                 'G', 30, 'io-q'\n      \tunion all select 'vmstat.csv',   'loadavg',           'G', 30, null\n      \tunion all select 'soap.csv',     'exec_count',        'A', 30, 'calls/s'\n      \tunion all select 'soap.csv',     'exec_ms_avg',       'G', 30, null\n      \tunion all select 'mailboxd.csv', 'mbox_add_msg_count','A', 30, 'add/s'\n      \tunion all select 'mailboxd.csv', 'soap_count',        'A', 30, 'op/s'\n      \tunion all select 'mailboxd.csv', 'imap_count',        'A', 30, 'op/s'\n      \tunion all select 'mailboxd.csv', 'pop_count',         'A', 30, 'op/s'\n      \tunion all select 'mailboxd.csv', 'mbox_msg_cache',    'G', 30, 'cache hit %'\n      \tunion all select 'mailboxd.csv', 'mbox_item_cache',   'G', 30, 'cache hit %'\n      \tunion all select 'convertd.csv', 'cputime',           'G', 30, 'seconds/100'\n      \tunion all select 'convertd.csv', 'stime',             'G', 30, 'seconds/100'\n      \tunion all select 'convertd.csv', 'utime',             'G', 30, 'seconds/100'\n      \tunion all select 'convertd.csv', 'rss',               'G', 30, 'KB'\n      \tunion all select 'allprocs.csv', 'cputime',           'G', 30, 'seconds'\n      \tunion all select 'nginx.csv',    'cputime',           'G', 30, 'seconds/100'\n      \tunion all select 'nginx.csv',    'stime',             'G', 30, 'seconds/100'\n      \tunion all select 'nginx.csv',    'utime',             'G', 30, 'seconds/100'\n      \tunion all select 'nginx.csv',    'rss',               'G', 30, 'KB'\n      },\n      q{\n      \tUPDATE config SET version = 3\n      },\n    ],\n    [\n      q{\n      \tDELETE FROM rrds WHERE csv_file = 'allprocs.csv';\n      },\n      q{\n      \tUPDATE config SET version = 4\n      },\n    ],\n);\n\n1;\n"
  },
  {
    "path": "lib/Zimbra/Mon/Zmstat.pm",
    "content": "# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2007, 2008, 2009, 2010, 2013, 2014, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n# \n\npackage Zimbra::Mon::Zmstat;\n\nuse Exporter;\n@ISA = qw(Exporter);\n@EXPORT = qw(\n    zmstatInit getZimbraUser getZimbraServerHostname\n    getZmstatRoot getZmstatInterval\n    isLinux isMac\n    percent getTstamp getDate waitUntilNiceRoundSecond\n    getPidFileDir readPidFile createPidFile\n    getLogFilePath openLogFile rotateLogFile\n    readLine\n);\n\nuse strict;\nuse File::Basename;\nuse FileHandle;\n\nour %LC;\n\nsub getLocalConfig(;@) {\n    my @vars = @_;\n    my $dir = dirname($0);\n    my $cmd = \"/opt/zimbra/bin/zmlocalconfig -q -x\";\n    if (scalar(@vars) > 0) {\n        $cmd .= ' ' . join(' ', @vars);\n    }\n    open(LCH, \"$cmd |\") or die \"Unable to invoke $cmd: $!\";\n    my $line;\n    while (defined($line = <LCH>)) {\n        $line =~ s/[\\r\\n]*$//;  # Remove trailing CR/LFs.\n        my @fields = split(/\\s*=\\s*/, $line, 2);\n        $LC{$fields[0]} = $fields[1];\n    }\n    close(LCH);\n}\n\nsub userCheck() {\n    my $loggedIn = `id -un`;\n    chomp($loggedIn) if (defined($loggedIn));\n    my $expected = $LC{zimbra_user};\n    if ($loggedIn ne $expected) {\n        print STDERR \"Must be user $expected to run this command\\n\";\n        exit(1);\n    }\n}\n\nsub isLinux() {\n    return $^O =~ /linux/i;\n}\n\nsub isMac() {\n    return $^O =~ /darwin/i;\n}\n\nsub osCheck() {\n    if (!isLinux() && !isMac()) {\n        print \"zmstat is supported on Linux and Mac only\\n\";\n        exit(0);  # return success to calling script\n    }\n}\n\nsub zmstatInit() {\n    osCheck();\n    getLocalConfig('zimbra_user', 'zimbra_server_hostname',\n                   'zmstat_interval', 'zmstat_disk_interval');\n    userCheck();\n}\n\nsub getZimbraUser() {\n    return $LC{'zimbra_user'};\n}\n\nsub getZimbraServerHostname() {\n    return $LC{'zimbra_server_hostname'};\n}\n\nsub getZmstatRoot() {\n        return \"/opt/zimbra/zmstat\";\n}\n\nsub getZmstatInterval() {\n    my $n = $LC{'zmstat_interval'};\n    if (!defined($n) || $n + 0 < 1) {\n        $n = 30;\n    }\n    return $n;\n}\n\nsub percent($$) {\n    my ($val, $total) = @_;\n    return sprintf(\"%.1f\", $total > 0 ? $val * 100 / $total : 0);\n}\n\nsub getTstamp() {\n    my ($sec, $min, $hour, $mday, $mon, $year) =\n        localtime();\n    return sprintf(\"%02d/%02d/%04d %02d:%02d:%02d\",\n                   $mon + 1, $mday, $year + 1900,\n                   $hour, $min, $sec);\n}\n\nsub getDate() {\n    my ($sec, $min, $hour, $mday, $mon, $year) = localtime();\n    return sprintf(\"%04d-%02d-%02d\", $year + 1900, $mon + 1, $mday);\n}\n\nsub waitUntilNiceRoundSecond($) {\n    # Maximum interval allowed is 1 day (24 * 60 * 60 seconds)\n    my $maxInterval = 24 * 60 * 60;\n    my $interval = shift;\n    $interval %= $maxInterval;\n    $interval = $interval ? $interval : $maxInterval;\n    while (1) {\n        my ($sec, $min, $hour) = localtime();\n        my $t = $hour * 60 * 60 + $min * 60 + $sec;\n        my $howlong = $t % $interval;\n        last if ($howlong == 0);\n        select(undef, undef, undef, 0.05);\n    }\n    return time;\n}\n\nsub getPidFileDir() {\n    return getZmstatRoot() . \"/pid\";\n}\n\nsub readPidFile($) {\n    my $file = shift;\n    my $pid = undef;\n    if (open(PID, \"< $file\")) {\n        $pid = <PID>;\n        close(PID);\n        chomp($pid) if (defined($pid));\n    }\n    return $pid;\n}\n\n# Check pid file to see if this process is a duplicate.\n# If not, create the pid file.\nsub createPidFile($) {\n    my $name = shift;\n    my $zmstatDir = getZmstatRoot();\n    my $pidDir = getPidFileDir();\n    my $pidFile = \"$pidDir/$name\";\n    if (-e $pidFile) {\n        my $pid = readPidFile($pidFile);\n        if ($pid) {\n            if (kill(0, $pid)) {\n                # Already running.\n                print STDERR \"$name: Already running as pid $pid\\n\";\n                exit(0);\n            }\n            unlink($pidFile);\n        }\n    }\n    if (! -e $zmstatDir) {\n        die \"$zmstatDir does not exist\";\n    }\n    if (! -e $pidDir) {\n        mkdir($pidDir, 0755);\n    }\n    open(PID, \"> $pidFile\") || die \"Unable to create pid file $pidFile: $!\";\n    print PID \"$$\\n\";\n    close(PID);\n}\n\nsub getLogFilePath($) {\n    my $fname = shift;\n    return getZmstatRoot() . \"/$fname\";\n}\n\nsub openLogFile($;$) {\n    my ($logfile, $heading) = @_;\n    my $fh = new FileHandle;\n    if (defined($logfile) && $logfile ne '' && $logfile ne '-') {\n        my $dir = File::Basename::dirname($logfile);\n        if (! -e $dir) {\n            mkdir($dir, 0755) || die \"Unable to create log directory $dir: $!\";\n            my (undef,undef,$uid,$gid) = getpwnam('zimbra');\n            chown $uid,$gid,$dir;\n        }\n        if (-f $logfile) { # check for stale data\n        \tmy $stale = 0;\n        \tmy $date = \"\";\n        \tmy $today = getDate();\n        \t$fh->open(\"<$logfile\") || die \"Unable to read existing logfile: $!\";\n        \twhile (<$fh>) {\n        \t\tif (/^(\\d{2})\\/(\\d{2})\\/(\\d{4})/o) {\n        \t\t\t$date = \"$3-$1-$2\";\n        \t\t}\n        \t}\n        \t$stale = 1 if $date ne $today;\n        \tif ($stale) {\n        \t\tprint STDERR \"$logfile was stale ($date) pre-rotating\\n\";\n        \t\treturn rotateLogFile($fh, $logfile, $heading, $date);\n        \t}\n        \t$fh->close();\n        }\n        $fh->open(\">> $logfile\") || die \"Unable to open log file $logfile: $!\";\n    } else {\n        $fh = *STDOUT;\n    }\n    if ($heading) {\n        $fh->print($heading);\n        $fh->print(\"\\n\");\n        $fh->flush();\n    }\n    return $fh;\n}\n\nsub rotateLogFile($$;$$) {\n    my ($fh, $logfile, $heading, $date) = @_;\n    my ($name, $path) = File::Basename::fileparse($logfile);\n    if (!defined($date)) {\n        $date = getDate();\n    }\n    my $rotatedir = \"$path/$date\";\n    mkdir($rotatedir, 0755);\n    if (! -d $rotatedir) {\n        die \"Unable to create log rotation directory $rotatedir\";\n    }\n    my (undef,undef,$uid,$gid) = getpwnam('zimbra');\n    chown $uid,$gid,$rotatedir;\n    $fh->close() if defined $fh;\n\n    my $rotatefile = \"$rotatedir/$name\";\n\n    # If previous .gz is there, unzip it.\n    my $rotateGz = \"$rotatefile.gz\";\n    if (-e $rotateGz) {\n    \tif (-e $rotatefile) {\n    \t    unlink($rotatefile);\n    \t}\n    \tsystem(\"gzip -d $rotateGz\");\n    }\n\n    # Rename or concatenate, with gzip.\n    if (! -e $rotatefile) {\n        my $rc = system(\"cat $logfile | gzip -c > $rotateGz\");\n        $rc >>= 8;\n        if ($rc) {\n        \tdie \"Unable to move $logfile to $rotateGz\";\n        }\n        unlink($logfile);\n    } else {\n        my $rc = system(\"cat $rotatefile $logfile | gzip -c > $rotateGz\");\n        $rc >>= 8;\n        if ($rc) {\n            die \"Unable to concatenate $logfile and $rotatefile to $rotateGz\";\n        }\n        unlink($rotatefile, $logfile);\n    }\n\n    return openLogFile($logfile, $heading);\n}\n\nsub readLine($$) {\n    my ($rh, $skip_empty) = @_;\n    my $line = '';\n    while ($line eq '') {\n        $line = <$rh>;\n        return if (!defined($line));  # EOF\n        chomp($line);\n        last if (!$skip_empty);\n    }\n    return $line;\n}\n\n1;\n"
  },
  {
    "path": "lib/Zimbra/SMTP.pm",
    "content": "package Zimbra::SMTP;\n\nuse strict;\nuse warnings;\n\nuse Zimbra::LDAP;\nuse Net::SMTP;\nuse Net::DNS;\n\nmy $ERROR;\n\n=head1 NAME\n\nZimbra::SMTP - Access to Zimbra SMTP mail servers\n\n=head1 SYNOPSIS\n\n  my $zs = Zimbra::SMTP->new;\n  $zs->send(\n      to      => 'abc@zimbra.com',\n      from    => 'xyz@zimbra.com',\n      subject => 'testing',\n      message => 'test'\n  );\n\n=head1 DESCRIPTION\n\nPerl API for sending SMTP messages through Zimbra MTA.\n\n=head1 CONSTRUCTOR\n\n=head2 new\n\nCreates new instance of Zimbra::SMTP.\n\n  my $zs = Zimbra::SMTP->new;\n\n=cut\n\nsub new {\n    my $class = shift;\n    my $self  = {};\n    bless $self, $class;\n    return unless ( $self->ldap );\n    return $self;\n}\n\n=head1 PROPERTIES\n\n=head2 error\n\nReturns last error message.\n\n  print Zimbra::SMTP->error, \"\\n\";\n  print $zs->error,          \"\\n\";\n\n=cut\n\nsub error {\n    $ERROR = $_[1] if ($#_);\n    return $ERROR;\n}\n\n=head2 ldap\n\nReturns the Zimbra::LDAP object.\n\n  print $zs->ldap->config->get(\"ldap_url\"), \"\\n\";\n\n=cut\n\nsub ldap {\n    unless ( exists( $_[0]->{_ldap} ) ) {\n        unless ( $_[0]->{_ldap} = Zimbra::LDAP->new ) {\n            $_[0]->error( \"failed to connect to LDAP: \" . Zimbra::LDAP->error );\n            return;\n        }\n    }\n    return $_[0]->{_ldap};\n}\n\n=head2 smtp\n\nReturns the Net::SMTP object.\n\nWe try to find the most appropriate MTA to use with Net::SMTP in this order:\n\n=over\n\n=item servers zimbra ldap zimbraSmtpHostname and zimbraSmtpPort\n\n=item global zimbra ldap zimbraSmtpHostname and zimbraSmtpPort\n\n=item localhost port 25\n\n=item DNS MX record for destination domain\n\n=back\n\n  print $zs->smtp->domain, \"\\n\";\n\n=cut\n\nsub smtp {\n    unless ( exists( $_[0]->{_smtp} ) ) {\n\n        foreach my $try ( \"_server\", \"_global\", \"_local\", \"_domain\" ) {\n            my ( $server, $port ) = $_[0]->$try( $_[1] );\n            if ( $_[0]->{_smtp} =\n                Net::SMTP->new( Host => $server, Port => $port, Timeout => 10 )\n              )\n            {\n                #print \"SMTP \", $try, \" \", $server, \" \", $port, \"\\n\";\n                return $_[0]->{_smtp};\n            }\n        }\n        delete( $_[0]->{_smtp} );\n        $_[0]->error(\"failed to find available SMTP server\");\n        return;\n    }\n    return $_[0]->{_smtp};\n}\n\nsub _server {\n    my $ls =\n      $_[0]->ldap->server( $_[0]->ldap->config->get(\"zimbra_server_hostname\") );\n    my $server = $ls->get_value(\"zimbraSmtpHostname\");\n    my $port = $ls->get_value(\"zimbraSmtpPort\") || 25;\n    return $server, $port;\n}\n\nsub _global {\n    return $_[0]->ldap->global->get_value(\"zimbraSmtpHostname\"),\n      $_[0]->ldap->global->get_value(\"zimbraSmtpPort\") || 25;\n}\n\nsub _local {\n    return \"localhost\", 25;\n}\n\nsub _domain {\n    my $server = undef;\n    my $dns    = new Net::DNS::Resolver;\n    if ( my $mx = $dns->query( $_[1], 'MX' ) ) {\n        if ( my $rr = ( $mx->answer )[0] ) {\n            $server = $rr->exchange;\n        }\n    }\n    return $server, 25;\n}\n\n=head1 METHODS\n\n=head2 send\n\nSend email message using smtp.\n\nSend support the following named arguments:\n\n=over\n\n=item to\n\nSpecifies e-mail address to send message to.\n\n=item from\n\nSpecifies e-mail address the message is from.\n\n=item subject\n\nSpecifies e-mail subject.\n\n=item message\n\nSpecifies e-mail content.\n\n=back\n\n  $zs->send(\n      to      => 'abc@zimbra.com',\n      from    => 'xyz@zimbra.com',\n      subject => 'testing',\n      message => 'test'\n  );\n\n=cut\n\nsub send {\n    my ( $self, %args ) = @_;\n    my $domain = $args{to};\n    $domain =~ s/^[^\\@]+\\@//;\n    unless ( $self->smtp($domain) ) {\n        return;\n    }\n    if ( $self->smtp ) {\n        $self->smtp->mail( $args{from} );\n        $self->smtp->to( $args{to} );\n        my @message = \"To: $args{to}\\n\";\n        push( @message, \"From: $args{from}\\n\" );\n        push( @message, \"Subject: \", $args{subject}, \"\\n\" )\n          if ( exists( $args{subject} ) );\n        push( @message, \"\\n\" );\n        push( @message, $args{message}, \"\\n\" ) if ( exists( $args{message} ) );\n        $self->smtp->data(@message);\n        return 1;\n    }\n    return;\n}\n\n=head2 SEE ALSO\n\nL<Zimbra::LDAP>, L<Net::SMTP>, L<Net::DNS>\n\n=cut\n\n1;\n"
  },
  {
    "path": "lib/Zimbra/SOAP/Soap.pm",
    "content": "# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2004, 2005, 2007, 2009, 2010, 2013, 2014, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n# \npackage Zimbra::SOAP::Soap;\n\nuse strict;\nuse warnings;\n\nuse XML::Parser;\n\nuse LWP::UserAgent;\nuse Zimbra::SOAP::XmlElement;\nuse Zimbra::SOAP::Soap12;\nuse Zimbra::SOAP::Soap11;\n\n#use overload '\"\"' => \\&to_string;\n\nBEGIN {\n    use Exporter   ();\n    our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);\n\n    # set the version for version checking\n    $VERSION     = 1.00;\n    @ISA         = qw(Exporter);\n    @EXPORT      = qw();\n    %EXPORT_TAGS = ( );     # eg: TAG => [ qw!name1 name2! ],\n\n    # your exported package globals go here,\n    # as well as any optionally exported functions\n    @EXPORT_OK   = qw();\n}\n\nour @EXPORT_OK;\n\nour $Soap12 = new Zimbra::SOAP::Soap12;\nour $Soap11 = new Zimbra::SOAP::Soap11;\n\n#\n# given a XmlElement, wrap it in a SOAP envelope and return the envelope\n#\n\nsub soapEnvelope {\n    die \"must override\";\n}\n\n#\n# Return Content-Type header\n#\n\nsub getContentType() {\n    die \"must override\";\n}\n\n#\n# Return the namespace String\n#\n\nsub getNamespace {\n    die \"must override\";\n}\n\n#\n# Return charset encoding for converting from bytes/strings\n#\n\nsub getCharSet {\n    return \"UTF-8\";\n}\n\n#\n# Convert a SOAP message in a String to bytes\n#\n\nsub convertToBytes {\n    die \"not implemented yet\";\n}\n\n#\n# Convert a SOAP message in bytes to a String \n#\n\nsub convertToString {\n    die \"not implemented yet\";\n}\n\n#\n# return the first child in the soap body\n#\n\nsub getElement {\n    die \"must override\";\n}\n\n#\n# Returns true if this element represents a SOAP fault\n#\n\nsub isFault {\n    die \"must override\";\n}\n\n#\n# Returns true if this soap envelope has a SOAP fault as the\n# first child of its body.     \n#\n\nsub hasFault {\n    my ($self, $e) = @_;\n    return $self->isFault($e->child(0));\n}\n\n#\n# determine if given element is Soap11 or Soap12 envelope,\n# and returns the Soap11 or Soap12 instance, or undef if neither.\n#\n\nsub determineProtocol {\n    my $e = shift;\n    return undef unless $e->name() eq \"Envelope\";\n    return $Soap12 if ($e->ns() eq $Soap12->getNamespace());\n    return $Soap11 if ($e->ns() eq $Soap11->getNamespace());\n    return undef;\n}\n\n#\n# Whether or not to include a HTTP SOAPActionHeader. (Gag)\n#\n\nsub hasSOAPActionHeader {\n    die \"must override\";\n}\n\n#\n# returns the version as a string (e.g, \"1.1\" or \"1.2\")\n#\n\nsub getVersion {\n    die \"must override\";\n}\n\n#\nsub toString {\n    my $self = shift;\n    return \"SOAP \".$self->getVersion();\n}\n\nsub zimbraContext {\n        my ($self, $authtoken) = @_;\n        my $context = new Zimbra::SOAP::XmlElement(\"context\", \"urn:zimbra\");\n        my $auth = new Zimbra::SOAP::XmlElement(\"authToken\");\n        $auth->content($authtoken);\n        $context->add_child($auth);\n        return $context;                \n}\n\n# simple invoke method for now, this will get replaced\n\nsub invoke {\n    my ($self, $uri, $doc, $context, $timeout) = @_;\n\n    my $env = $self->soapEnvelope($doc, $context);\n    my $soap = $env->to_string();\n    #print \"REQUEST:\\n\" . $env->to_string('pretty') . \"\\n\";\n    my $ua = new LWP::UserAgent();\n    if (defined($timeout) && $timeout > 0) {\n        $ua->timeout($timeout);  # timeout in seconds\n    }\n    my $req = new HTTP::Request(POST=> $uri);\n\n    $req->content_type($self->getContentType());\n    $req->content_length(length($soap));\n    if ($self->hasSOAPActionHeader()) {\n        $req->header(\"SOAPAction\" => $uri);\n    }\n    $req->add_content($soap);\n    my $res = $ua->request($req);\n    if (!defined($res)) {\n        print STDERR \"No response from server\\n\";\n        return undef;\n    }\n\n    my $xml = undef;\n    eval {\n        $xml = Zimbra::SOAP::XmlElement::parse($res->content);\n    };\n    if (!defined($xml)) {\n        # Check for network/HTTP error after trying XML parse because\n        # a SOAP fault comes back with HTTP 500 status.\n        if ($res->is_error()) {\n            print STDERR\n                \"SOAP request failed: code=\" . $res->code() .\n                \", error=\" . $res->message() . \"\\n\";\n        } else {\n            # We have legitimate XML parse error.\n            print STDERR\n                \"Unable to parse SOAP response: \" . $res->content() . \"\\n\";\n        }\n        return undef;\n    }\n    my $rsoap = determineProtocol($xml);\n    if (!defined($rsoap)) {\n        print STDERR \"Unable to determine SOAP protocol\\n\";\n        return undef;\n    } elsif ($rsoap != $self) {\n        print STDERR \"Unexpected SOAP version in response\\n\";\n        return undef;\n    }\n\n    my $resp = $self->getElement($xml);\n    #print \"RESPONSE:\\n\" . $resp->to_string('pretty') . \"\\n\" if defined($resp);\n\n    if ($self->isFault($resp)) {\n        my $faultParsed = 0;\n        my $reason = $resp->find_child('Reason');\n        if (defined($reason)) {\n            my $text = $reason->find_child('Text');\n            if (defined($text)) {\n                print STDERR\n                    \"Received SOAP fault: \" . $text->content() . \"\\n\";\n                $faultParsed = 1;\n            }\n        }\n        if (!$faultParsed) {\n            print STDERR\n                \"Received SOAP fault: \" . $resp->to_string('pretty') . \"\\n\";\n        }\n        return undef;\n    }\n\n    return $resp;\n}\n\n1;\n"
  },
  {
    "path": "lib/Zimbra/SOAP/Soap11.pm",
    "content": "# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2004, 2005, 2007, 2009, 2010, 2013, 2014, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n# \npackage Zimbra::SOAP::Soap11;\n\nuse strict;\nuse warnings;\n\nuse XML::Parser;\nuse Zimbra::SOAP::XmlElement;\n\n#use overload '\"\"' => \\&to_string;\n\nBEGIN {\n    use Exporter   ();\n    our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);\n\n    # set the version for version checking\n    $VERSION     = 1.00;\n    @ISA         = qw(Exporter Zimbra::SOAP::Soap);\n    @EXPORT      = qw();\n    %EXPORT_TAGS = ( );     # eg: TAG => [ qw!name1 name2! ],\n\n    # your exported package globals go here,\n    # as well as any optionally exported functions\n    @EXPORT_OK   = qw();\n}\n\nour @EXPORT_OK;\n\nour $NS = \"http://schemas.xmlsoap.org/soap/envelope/\";\n\nsub new {\n    my $type = shift;\n    my $self = {};\n    bless $self, $type;\n    return $self;\n}\n\n#\n# given a XmlElement, wrap it in a SOAP envelope and return the envelope\n#\n\nsub soapEnvelope {\n    my $self = shift;\n    my $e = shift;\n    my $context = shift;\n    my $env = new Zimbra::SOAP::XmlElement(\"Envelope\", $NS);\n    if ($context) {\n\t    my $header= new Zimbra::SOAP::XmlElement(\"Header\", $NS);\n\t    $header->add_child($context);\n\t    $env->add_child($header);\n    }    \n    my $body = new Zimbra::SOAP::XmlElement(\"Body\", $NS);\n    $body->add_child($e);\n    $env->add_child($body);\n    return $env;\n}\n\nsub getContentType() {\n    return \"text/xml; charset=utf-8\"\n}\n\n#\n# Return the namespace String\n#\n\nsub getNamespace {\n    return $NS;\n}\n\n#\n# return the first child in the soap body\n#\n\nsub getElement {\n    my ($self, $e) = @_;\n\n    die \"getElement was not passed a Soap Envelope\" unless\n\t($e->name() eq 'Envelope') && ($e->ns() eq $NS);\n\n    my $body = $e->find_child('Body');\n    die \"getElement unable to find Soap Body\" unless defined $body;\n\n    return $body->child(0);\n}\n\n#\n# Returns true if this element represents a SOAP fault\n#\n\nsub isFault {\n    my ($self, $e) = @_;\n    return \n\t($e->name() eq 'Fault') &&\n\t($e->ns() eq $NS);\n}\n\n#\n# Whether or not to include a HTTP SOAPActionHeader. (Gag)\n#\n\nsub hasSOAPActionHeader {\n    return 1;\n}\n\n#\n# returns the version as a string (e.g, \"1.1\" or \"1.2\")\n#\n\nsub getVersion {\n    return \"1.1\";\n}\n\n1;\n"
  },
  {
    "path": "lib/Zimbra/SOAP/Soap12.pm",
    "content": "# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2004, 2005, 2007, 2009, 2010, 2013, 2014, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n# \npackage Zimbra::SOAP::Soap12;\n\nuse strict;\nuse warnings;\n\nuse XML::Parser;\nuse Zimbra::SOAP::XmlElement;\n\n#use overload '\"\"' => \\&to_string;\n\nBEGIN {\n    use Exporter   ();\n    our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);\n\n    # set the version for version checking\n    $VERSION     = 1.00;\n    @ISA         = qw(Exporter Zimbra::SOAP::Soap);\n    @EXPORT      = qw();\n    %EXPORT_TAGS = ( );     # eg: TAG => [ qw!name1 name2! ],\n\n    # your exported package globals go here,\n    # as well as any optionally exported functions\n    @EXPORT_OK   = qw();\n}\n\nour @EXPORT_OK;\n\nour $NS = \"http://www.w3.org/2003/05/soap-envelope\";\n\nsub new {\n    my $type = shift;\n    my $self = {};\n    bless $self, $type;\n    return $self;\n}\n\n#\n# given a XmlElement, wrap it in a SOAP envelope and return the envelope\n#\n\nsub soapEnvelope {\n    my $self = shift;\n    my $e = shift;\n    my $context = shift;\n    my $env = new Zimbra::SOAP::XmlElement(\"Envelope\", $NS);\n    if ($context) {\n\t    my $header= new Zimbra::SOAP::XmlElement(\"Header\", $NS);\n\t    $header->add_child($context);\n\t    $env->add_child($header);\n    }\n    my $body = new Zimbra::SOAP::XmlElement(\"Body\", $NS);\n    $body->add_child($e);\n    $env->add_child($body);\n    return $env;\n}\n\nsub getContentType() {\n    return \"application/soap+xml; charset=utf-8\";\n}\n\n#\n# Return the namespace String\n#\n\nsub getNamespace {\n    return $NS;\n}\n\n#\n# return the first child in the soap body\n#\n\nsub getElement {\n    my ($self, $e) = @_;\n\n    die \"getElement was not passed a Soap Envelope\" unless\n\t($e->name() eq 'Envelope') && ($e->ns() eq $NS);\n\n    my $body = $e->find_child('Body');\n    die \"getElement unable to find Soap Body\" unless defined $body;\n\n    return $body->child(0);\n}\n\n#\n# Returns true if this element represents a SOAP fault\n#\n\nsub isFault {\n    my ($self, $e) = @_;\n    return \n\t($e->name() eq 'Fault') &&\n\t($e->ns() eq $NS);\n}\n\n#\n# Whether or not to include a HTTP SOAPActionHeader. (Gag)\n#\n\nsub hasSOAPActionHeader {\n    return 0;\n}\n\n#\n# returns the version as a string (e.g, \"1.1\" or \"1.2\")\n#\n\nsub getVersion {\n    return \"1.2\";\n}\n\n1;\n"
  },
  {
    "path": "lib/Zimbra/SOAP/XmlDoc.pm",
    "content": "# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2004, 2005, 2007, 2009, 2010, 2013, 2014, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n# \npackage Zimbra::SOAP::XmlDoc;\n\nuse strict;\nuse warnings;\nuse Zimbra::SOAP::XmlElement;\n\nBEGIN {\n    use Exporter   ();\n    our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);\n\n    # set the version for version checking\n    $VERSION     = 1.00;\n    @ISA         = qw(Exporter);\n    @EXPORT      = qw();\n    %EXPORT_TAGS = ( );     # eg: TAG => [ qw!name1 name2! ],\n\n    # your exported package globals go here,\n    # as well as any optionally exported functions\n    @EXPORT_OK   = qw();\n}\n\nour @EXPORT_OK;\n\nsub new {\n    my $type = shift;\n    my $self = {};\n    bless $self, $type;\n    return $self;\n}\n\nsub to_string {\n    my $self = shift;\n    return $self->{'root'}->to_string(@_);\n}\n \nsub start {\n    my $self = shift;\n    my $name = shift;\n    my $ns = shift;\n    my $element = new Zimbra::SOAP::XmlElement($name, $ns);\n    if (@_) {\n\tmy $attrs = shift;\n\t$element->attrs($attrs) if defined($attrs);\n    }\n    if (@_) {\n\t$element->content(shift);\n    }\n    if (!defined($self->{'root'})) {\n\t$self->{'root'} = $element;\n    } else {\n\tmy $s = $self->{'stack'};\n\tmy $parent = @{$s}[$#{$s}];\n\t$parent->add_child($element);\n    }\n    push(@{$self->{'stack'}}, $element);\n    return $self;\n}\n\nsub current {\n    my $self = shift;\n    my $s = $self->{'stack'};\n    my $e = @{$s}[$#{$s}] || die \"not in an element\";\n    return $e;\n}\n\nsub end {\n    my $self = shift;\n    my $s = $self->{'stack'};\n    my $e = @{$s}[$#{$s}] || die \"not in an element\";\n    if (@_) {\n\tmy $name = shift;\n\tmy $aname = $e->name;\n\tif ($name ne $aname) {\n\t    die \"name mismatch in end. expecting($name), actual($aname)\";\n\t}\n    }\n    pop(@{$self->{'stack'}});\n }\n\nsub add {\n    my ($self, $name, $ns, $attrs, $text) = @_;\n    $self->start($name, $ns, $attrs);\n    $self->current->append_content($text) if defined($text);\n    $self->end;\n}\n\nsub root {\n    my $self = shift;\n    return $self->{'root'};\n}\n\n1;\n\n__END__\n"
  },
  {
    "path": "lib/Zimbra/SOAP/XmlElement.pm",
    "content": "# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2004, 2005, 2007, 2009, 2010, 2013, 2014, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n# \npackage Zimbra::SOAP::XmlElement;\n\nuse strict;\nuse warnings;\n\nuse XML::Parser;\n\n#use overload '\"\"' => \\&to_string;\n\nBEGIN {\n    use Exporter   ();\n    our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);\n\n    # set the version for version checking\n    $VERSION     = 1.00;\n    @ISA         = qw(Exporter);\n    @EXPORT      = qw();\n    %EXPORT_TAGS = ( );     # eg: TAG => [ qw!name1 name2! ],\n\n    # your exported package globals go here,\n    # as well as any optionally exported functions\n    @EXPORT_OK   = qw();\n}\n\nour @EXPORT_OK;\n\n# \n# parses XML into a hash of hashes, where 'name' is the name\n# of the tag, 'ns' is the namespace URI,\n# 'attrs' is a hash of the attributes, 'children'\n# is an array of the child elements, and 'content' is all of \n# the textual content.\n# \n# for example:\n# \n# <wkdc:getTokensRequest xmlns:wkdc=\"http://stanford.edu/wkdc\">\n#    <requesterCredential type=\"krb5\">\n#               {base64-krb5-mk-req-data}\n#    </requesterCredential>\n#   <tokens>\n#     <token type=\"service\" id=\"0\"/>\n#   </tokens>\n# </wkdc:getTokensRequest>\n# \n# will parse into:\n# \n# $tree = {\n#   'name' => 'getTokensRequest',\n#   'ns' => 'http://stanford.edu/wkdc',\n#   'attrs' => {},\n#   'children' => [\n#       {\n#         'name' => 'requesterCredential',\n#         'attrs' => { 'type' => 'krb5' },\n#         'content' => '   {base64-krb5-mk-req-data}  '\n#       },\n#       {\n#          'name' => 'tokens',\n#          'attrs' => {},\n#          'children' => [\n#             {\n#               'name' => 'token',\n#               'attrs' => { 'id' => 0, 'type' => 'service'},\n#               'content' => '     '\n#             }\n#          ]\n#       }\n#   ]\n#   'content' => '      '\n# };\n#\n# note that all the whitespace in the document will get left\n# in. It should be trim'd if needed.\n#\n\nsub parse {\n    my $xml = shift;\n    my $parser = new XML::Parser(Namespaces => 1,\n\t\t\t\t Handlers => {\n\t\t\t\t     Start => \\&XPStart,\n\t\t\t\t     End => \\&XPEnd,\n\t\t\t\t     Char => \\&XPChar,\n\t\t\t\t     Init => \\&XPInit,\n\t\t\t\t     Final => \\&XPFinal\n\t\t\t\t     });\n    return $parser->parse($xml);\n}\n\n# creates a new element with the specified name and namespace\nsub new {\n    my $type = shift;\n    my ($name, $ns) = @_;\n    my $self = { 'attrs' => {}, 'children' => []};\n    bless $self, $type;\n    $self->name($name) if defined $name;\n    $self->ns($ns) if defined $ns;\n\n    return $self;\n}\n\n# returns the name of this element\nsub name {\n    my $self = shift;\n    $self->{'name'} = shift if @_;\n    return $self->{'name'};\n}\n\n\n# returns the URI of the namespace of this element\nsub ns {\n    my $self = shift;\n    $self->{'ns'} = shift if @_;\n    return $self->{'ns'};\n}\n\n# returns the content\nsub content {\n    my $self = shift;\n    $self->{'content'} = shift if @_;\n    return $self->{'content'};\n}\n\n# returns the content with leading and trailing whitespace removed\nsub content_trimmed {\n    my $self = shift;\n    my $c = $self->{'content'};\n    $c =~ s/^\\s*(.*)\\s*$/$1/;\n    return $c; \n}\n\n# apppend the given string to the content\nsub append_content {\n    my $self = shift;\n    $self->{'content'} .= shift if @_;\n}\n\n# returns (and sets new if specified) the hash ref containing attrs\nsub attrs {\n    my $self = shift;\n    $self->{'attrs'} = shift if @_;\n    return $self->{'attrs'};\n}\n\n# returns true if this element has any attrs\nsub has_attrs {\n    my $self = shift;\n    return %{$self->{'attrs'}};\n}\n\n# returns (and sets new if specified) attribute\nsub attr {\n    my $self = shift;\n    my $name = shift;\n    $self->{'attrs'}{$name} = shift if @_;\n    return $self->{'attrs'}{$name};\n}\n\n# returns (and sets new if specified) child array ref\nsub children {\n    my $self = shift;\n    $self->{'children'} = shift if @_;\n    return $self->{'children'};\n}\n\n# returns true if this element has any children\nsub has_children {\n    my $self = shift;\n    return $#{$self->{'children'}} != -1;\n}\n\n# returns the number of children\nsub num_children {\n    my $self = shift;\n    return $#{$self->{'children'}} + 1;\n}\n\n# return the child at the specified index\nsub child {\n    my ($self, $index) = @_;\n    return $self->{'children'}->[$index];\n}\n\n# this will only find the first child with the given name\nsub  find_child {\n    my $self = shift;\n    my $name = shift;\n    foreach my $child (@{$self->children}) {\n\treturn $child if ($child->name() eq $name);\n    }\n    return undef;\n}\n\n# add a new child\nsub add_child {\n    my $self = shift;\n    push @{$self->{'children'}}, shift;\n}\n\n# escape any special XML characters\nsub escape {\n    my $v = shift;\n    $$v =~ s/&/&amp;/sg;\n    $$v =~ s/</&lt;/sg;\n    $$v =~ s/>/&gt;/sg;\n    $$v =~ s/\\\"/&quot;/sg;\n    $$v =~ s/\\'/&apos;/sg;\n}\n\nsub recursive_to_string {\n    my ($e, $ctxt) = @_;\n\n    my $pretty = $ctxt->{'pretty'};\n    my $level = $ctxt->{'level'};\n    my $out = $ctxt->{'out'};\n\n    my $name = $e->name();\n    my $ns_uri = $e->ns();\n    my $xmlns;\n\n    if (defined $ns_uri) {\n\tmy $prefix = get_ns_prefix($ctxt, $ns_uri);\n\tif (!defined($prefix)) {\n\t    $prefix = new_ns_prefix($ctxt, $ns_uri);\n\t    $xmlns = \"xmlns:$prefix=\\\"$ns_uri\\\"\";\n\t }\n\t$name = \"$prefix:$name\";\n    }\n\n    my $closed = 0;\n    my $cont = 0;\n    $$out .= ' ' x $level if $pretty;\n    $$out .= \"<$name\";\n    while (my($attr,$val) = each(%{$e->attrs})) {\n\tescape(\\$val);\n\t$$out .= \" $attr=\\\"$val\\\"\";\n    }\n    $$out .= \" $xmlns\" if $xmlns;\n\n    my $child;\n\n    if (defined($e->content)) {\n\tif (!$closed) {\n\t    $$out .= \">\";\n\t    $closed=1;\n\t}\n\t$cont = 1;\n\tmy $c = $e->content;\n\tescape(\\$c);\n\t$$out .= $c;\n    }\n\n    foreach $child (@{$e->children}) {\n\t    if (!$closed) {\n\t\t$$out .= \">\";\n\t\t$$out .= \"\\n\" if $pretty;\n\t\t$closed=1;\n\t    }\n\t    $ctxt->{'level'} += 2;\n\t    recursive_to_string($child, $ctxt);\n\t    $ctxt->{'level'} = $level;\n\t}\n    \n    if ($closed) {\n\t$$out .= ' ' x $level if $pretty && !$cont;\n\t$$out .= \"</$name>\";\n\t$$out .= \"\\n\" if $pretty;\n    } else {\n\t$$out .= \"/>\";\n\t$$out .= \"\\n\" if $pretty;\n    }\n}\n\n# returns the prefix of the specified URI\nsub get_ns_prefix {\n    my ($ctxt, $uri) = @_;\n    my $pre = $ctxt->{'ns'}->{$uri};\n    return $pre;\n}\n\n# create a new prefix for the specified URI\nsub new_ns_prefix {\n    my ($ctxt, $uri) = @_;\n    chomp $uri if ($uri =~ m!/$!);\n    #my ($pre) = ($uri =~ m!.*/([a-zA-z][a-zA-Z0-9]{1,4})!);\n    #if (defined $ctxt->{$pre}) {\n\tmy $pre = \"ns\" . $ctxt->{'nscounter'}++;\n    #} else {\n\t#$ctxt->{$pre} = 1;\n    #}\n\n    $ctxt->{'ns'}->{$uri} = $pre;\n    return $pre;\n}\n\n# convert this element to a string\nsub to_string {\n    my $self = shift;\n    my $pretty = shift;\n    my $output = \"\";\n    my $ctxt = {pretty => $pretty, \n\t\tout => \\$output, \n\t\tlevel => 0,\n\t\tnscounter => 0,\n\t\tns => {}\n\t    };\n    recursive_to_string($self, $ctxt);\n    return $output;\n}\n\n# XML::Parser Init handler\nsub XPInit {\n  my $expat = shift;\n  $expat->{'Doc'} = {};\n  $expat->{'Stack'} = [];\n  $expat->{'Cur'} = undef;\n}\n\n# XML::Parser Start handler\nsub XPStart {\n  my $expat = shift;\n  my $tag = shift;\n\n  my $element = new Zimbra::SOAP::XmlElement($tag, $expat->namespace($tag));\n\n  if ($#_ >= 0) {\n      $element->attrs({@_});\n  }\n\n  my $cur = $expat->{'Cur'};\n  \n  if (defined $cur) {\n      $cur->add_child($element);\n      push @{$expat->{'Stack'}}, $cur;\n  } else {\n      $expat->{'Doc'} = $element;\n  }\n  $expat->{'Cur'} = $element;\n}\n\n# XML::Parser End handler\nsub XPEnd {\n  my $expat = shift;\n  my $tag = shift;\n  $expat->{'Cur'} = pop @{ $expat->{'Stack'}};\n}\n\n# XML::Parser Char handler\nsub XPChar {\n  my $expat = shift;\n  my $text = shift;\n  my $e = $expat->{'Cur'};\n  $e->append_content($text);\n}\n\n# XML::Parser Final handler\nsub XPFinal {\n  my $expat = shift;\n  delete $expat->{'Cur'};\n  delete $expat->{'Stack'};\n  $expat->{'Doc'};\n}\n\n1;\n"
  },
  {
    "path": "lib/Zimbra/Util/Common.pm",
    "content": "#!/usr/bin/perl\n# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2006, 2007, 2009, 2010, 2012, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n\npackage Zimbra::Util::Common; \nuse strict;\n\n\n# Zimbra Specfic library locations\nuse lib \"/opt/zimbra/common/lib/perl5\";\nuse lib \"/opt/zimbra/common/lib/perl5/Zimbra/SOAP\";\nuse lib \"/opt/zimbra/common/lib/perl5/Zimbra/Mon\";\nuse lib \"/opt/zimbra/common/lib/perl5/Zimbra/DB\";\nforeach my $arch (qw(i386 x86_64 i486 i586 i686 darwin)) {\n  foreach my $type (qw(linux-thread-multi linux-gnu-thread-multi linux thread-multi thread-multi-2level)) {\n    my $dir = \"/opt/zimbra/common/lib/perl5/${arch}-${type}\";\n    unshift(@INC, \"$dir\") \n      if (-d \"$dir\");\n  }\n}\n\n1\n"
  },
  {
    "path": "lib/Zimbra/Util/LDAP.pm",
    "content": "#!/usr/bin/perl\n# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n\npackage Zimbra::Util::LDAP; \nuse strict;\nuse Net::LDAP;\n\nsub doLdap() {\n  my $self=shift;\n  my ($key, $value) = @_;\n  my $is_master = $main::config{ldap_is_master};\n  my $pw = $main::config{ldap_root_password};\n  my $rc=0;\n  my $real_master=0;\n  my ($dn,$ldap_key);\n  my $ldap = Net::LDAP->new('ldapi://%2fopt%2fzimbra%2fdata%2fldap%2fstate%2frun%2fldapi/') or die \"$@\";\n  my $mesg = $ldap->bind(\"cn=config\", password=>\"$pw\");\n  if($mesg->code) {\n    main::logMsg(2,\"LDAP: Failed to bind\");\n\t$ldap->unbind;\n    return 1;\n  }\n  if (lc($is_master) eq \"true\") {\n    $mesg = $ldap->search(\n                          base=> \"cn=accesslog\",\n                          filter=>\"(objectClass=*)\",\n                          scope => \"base\",\n                          attrs => ['1.1'],\n                   );\n    my @entries=$mesg->entries;\n    my $size = @entries;\n    if ($size > 0 ) {\n      $real_master = 1;\n    }\n  }\n  if ($key =~ /^ldap_common_/) {\n    if ($key eq \"ldap_common_loglevel\") {\n      $ldap_key=\"olcLogLevel\";\n    } elsif ($key eq \"ldap_common_threads\") {\n      $ldap_key=\"olcThreads\";\n    } elsif ($key eq \"ldap_common_toolthreads\") {\n      $ldap_key=\"olcToolThreads\";\n    } elsif ($key eq \"ldap_common_require_tls\") {\n      $ldap_key=\"olcSecurity\";\n      chomp($value);\n      $value=\"ssf=$value\";\n    } elsif ($key eq \"ldap_common_writetimeout\") {\n      $ldap_key=\"olcWriteTimeout\";\n    } else {\n      main::logMsg(2,\"LDAP common: Unknown key: $key\");\n      $rc=1;\n    }\n    $dn=\"cn=config\";\n  } elsif ($key =~ /^ldap_db_/) {\n    if ($real_master) {\n      $dn=\"olcDatabase={3}mdb,cn=config\";\n    } else {\n      $dn=\"olcDatabase={2}mdb,cn=config\";\n    }\n    if ($key eq \"ldap_db_checkpoint\") {\n      $ldap_key=\"olcDbCheckpoint\";\n    } elsif ($key eq \"ldap_db_maxsize\") {\n      $ldap_key=\"olcDbMaxsize\";\n    } else {\n      main::logMsg(2,\"LDAP db: Unknown key: $key\");\n      $rc=1;\n    }\n  } elsif ($key =~ /ldap_access/) {\n    if ($real_master) {\n      $dn=\"olcDatabase={2}mdb,cn=config\";\n      if ($key eq \"ldap_accesslog_checkpoint\") {\n        $ldap_key=\"olcDbCheckpoint\";\n      } elsif ($key eq \"ldap_accesslog_maxsize\") {\n        $ldap_key=\"olcDbMaxsize\";\n      } else {\n        main::logMsg(2,\"LDAP accesslog: Unknown key: $key\");\n        $rc=1;\n      }\n    }\n  } elsif ($key =~ /ldap_overlay/) {\n    if ($real_master) {\n      if ($key =~ /ldap_overlay_syncprov/) {\n        $dn=\"olcOverlay={0}syncprov,olcDatabase={3}mdb,cn=config\";\n        if ($key eq \"ldap_overlay_syncprov_checkpoint\") {\n          $ldap_key=\"olcSpCheckpoint\";\n        } else {\n          main::logMsg(2,\"LDAP overlay syncprov: Unknown key: $key\");\n          $rc=1;\n        }\n      } elsif ($key =~ /ldap_overlay_accesslog/) {\n        $dn=\"olcOverlay={1}accesslog,olcDatabase={3}mdb,cn=config\";\n        if ($key eq \"ldap_overlay_accesslog_logpurge\") {\n          $ldap_key=\"olcAccessLogPurge\";\n        } else {\n          main::logMsg(2,\"LDAP overlay accesslog: Unknown key: $key\");\n          $rc=1;\n        }\n      } else {\n        main::logMsg(2,\"LDAP overlay: Unknown key: $key\");\n        $rc=1;\n      }\n    }\n  } else {\n    main::logMsg(2,\"LDAP: Unknown key: $key\");\n    $rc=1;\n  }\n\n  if ($rc) { $ldap->unbind; return $rc; }\n\n  if (!$real_master && ($key =~ /ldap_access/ || $key =~ /ldap_overlay/)) {\n    main::logMsg(2,\"LDAP: Trying to modify key: $key when not a master\");\n    $ldap->unbind;\n    return 0;\n  }\n\n  my $entry;\n  if ($real_master && $key =~ /ldap_overlay_syncprov/) {\n    # Obtain real syncprov overlay DN\n    $mesg=$ldap->search(base=>\"olcDatabase={3}mdb,cn=config\",\n                  scope=>\"sub\",\n                  filter=>'(objectClass=olcSyncProvConfig)',\n                  attrs=>[ \"1.1\" ],\n                 );\n    $entry=$mesg->entry(0);\n    $dn=$entry->dn();\n  }\n\n  if ($real_master && $key =~ /ldap_overlay_accesslog/) {\n    # Obtain real syncprov overlay DN\n    $mesg=$ldap->search(base=>\"olcDatabase={3}mdb,cn=config\",\n                  scope=>\"sub\",\n                  filter=>'(objectClass=olcAccessLogConfig)',\n                  attrs=>[ \"1.1\" ],\n                 );\n    $entry=$mesg->entry(0);\n    $dn=$entry->dn();\n  }\n\n  $mesg=$ldap->search(base=>$dn,\n                  scope=>\"base\",\n                  filter=>'objectClass=*',\n                  attrs=>[ \"$ldap_key\" ],\n                 );\n  $entry=$mesg->entry(0);\n  my $orig_value = $entry->get_value(\"$ldap_key\");\n\n  if ($orig_value ne $value) {\n    main::logMsg(3,\"LDAP: Changing key: $key\");\n    $mesg = $ldap->modify(\n           $dn,\n           replace=>{$ldap_key=>\"$value\"},\n    );\n    if ($mesg->code) {\n      main::logMsg(2,\"LDAP key change failed: \".$mesg->code());\n      $rc=1;\n    }\n  }\n  \n  $ldap->unbind;\n  return $rc;\n}\n\n1;\n"
  },
  {
    "path": "lib/Zimbra/Util/Timezone.pm",
    "content": "package Zimbra::Util::Timezone;\nuse strict;\nour %TIMEZONES;\nour $_PARSED=0;\n\nsub new {\n  my $class = shift;\n  my $tzname = shift;\n  my $self = { tzname => $tzname, tzid=>undef, primary=>undef };\n  bless $self, $class;\n  $TIMEZONES{$self} = $self;\n}\n \nsub tzname {\n  my $self = shift;\n  if (@_) {\n    $self->{tzname} = shift;\n  } else {\n    $self->{tzname};\n  }\n}\nsub tzid {\n  my $self = shift;\n  if (@_) {\n    $self->{tzid} = shift;\n  } else {\n    $self->{tzid};\n  }\n}\nsub tzalias {\n  my $self = shift;\n  if (@_) {\n    $self->{tzalias} = shift if ($self->{tzalias} eq \"\");\n  } else {\n    $self->{tzalias};\n  }\n}\n\nsub primary {\n  my $self = shift;\n  if (@_) {\n    $self->{primary} = shift;\n  } else {\n    $self->{primary};\n  }\n}\n\nsub parse {\n  my $self = shift;\n  my $file = shift;\n  return if ($_PARSED == 1);\n  $file=\"/opt/zimbra/conf/timezones.ics\" if ($file eq \"\");\n  open(FILE, \"$file\") or return undef;\n  my $tz;\n  while (<FILE>) {\n    $tz = $self->new if (/BEGIN:VTIMEZONE/);\n    $tz->tzid($1) if (/TZID:(.+)/);\n    $tz->tzname($1) if (/TZNAME:(.+)/);\n    $tz->primary(1) if (/X-ZIMBRA-TZ-PRIMARY:TRUE/);\n    next if (/END:VTIMEZONE/);\n  }\n  close(FILE);\n  $_PARSED=1;\n  return $tz;\n}\n\nsub gettzbyname {\n  my $self = shift;\n  my $name = shift;\n  foreach (sort values %TIMEZONES) {\n    return $_ if ($_->tzname eq $name && $_->primary == 1);\n  }\n  return undef;\n}\nsub gettzbyid {\n  my $self = shift;\n  my $name = shift;\n  foreach (sort values %TIMEZONES) {\n    return $_ if ($_->tzid eq $name && $_->primary == 1);\n  }\n  return undef;\n}\n\nsub dump {\n  my $self = shift;\n  my @tzs;\n  foreach (values %TIMEZONES) {\n    #next if ($_->tzname eq \"\");\n    push(@tzs, $_->tzid) if ($_->primary == 1);\n  }\n  return @tzs;\n}\n\n1;\n"
  },
  {
    "path": "lib/Zimbra/ZmClient.pm",
    "content": "#!/usr/bin/perl\n# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2010, 2012, 2013, 2014, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n# \n\npackage ZmClient;\n\nuse IPC::Open2;\nuse POSIX \":sys_wait_h\";\nuse IO::Handle;\nuse Net::HTTP;\nuse LWP::UserAgent;\nuse HTTP::Request;\n\n$SIG{CHLD} = 'IGNORE'; # PvZ ftw\n\nmy $zmprov_exe = '/opt/zimbra/bin/zmprov';\nmy %zmprov = ();\nmy %zmprovl = ();\nmy $zmmailbox_exe = '/opt/zimbra/bin/zmmailbox';\nmy %zmmailbox = ();\nmy %authTokens = ();\n\nsub init() {\n    $zmprov_exe = '/opt/zimbra/bin/zmprov';\n    %zmprov = ();\n    $zmmailbox_exe = '/opt/zimbra/bin/zmmailbox';\n    %zmmailbox = ();\n    %authTokens = ();\n}\n\nsub initZmprovSoap() {\n    my $buf;\n    return if (exists $zmprov{'pid'} && kill(0, $zmprov{'pid'}));\n    $zmprov{'pid'} = open2(\n            $zmprov{'in'}, $zmprov{'out'}, \"$zmprov_exe 2>&1 \") || die \"$!\";\n\n\teval {\n\t\tlocal $SIG{ALRM} = sub { die \"alarm\\n\" };\n\t\talarm(60); # avoid timeouts when mailstore is down\n\t\tdo { # this part, we can ignore\n\t\t\tsysread($zmprov{'in'}, $buf, 8192);\n\t\t} while ($buf !~ /^prov> $/osm);\n\t\talarm(0); \n\t};\n}\n\nsub initZmprovLdap() {\n    my $buf;\n    return if (exists $zmprovl{'pid'} && kill(0, $zmprovl{'pid'}));\n    $zmprovl{'pid'} = open2(\n            $zmprovl{'in'}, $zmprovl{'out'}, \"$zmprov_exe -l 2>&1 \") || die \"$!\";\n\n\teval {\n\t\tlocal $SIG{ALRM} = sub { die \"alarm\\n\" };\n\t\talarm(60); # avoid timeouts when ldap is down\n\t\tdo { # this part, we can ignore\n\t\t\tsysread($zmprovl{'in'}, $buf, 8192);\n\t\t} while ($buf !~ /^prov> $/osm);\n\t\talarm(0); \n\t};\n}\n\nsub initZmprov() {\n\tinitZmprovSoap();\n\tinitZmprovLdap();\n}\n\nsub sendZmprovRequestSoap($) {\n    my $cmd = shift @_;\n    my $buf;\n    initZmprovSoap unless (exists $zmprov{'pid'} && kill(0, $zmprov{'pid'}));\n    die \"zmprov not initialized\" if (!exists $zmprov{'out'});\n    $zmprov{'out'}->print($cmd . \"\\n\");\n    my @lines = ();\n    my $needs_join = 0;\n\n    do {\n        sysread($zmprov{'in'}, $buf, 8192);\n        my @newlines = split(/\\n/, $buf);\n\n        if ($needs_join) {\n            $lines[$#lines] .= shift @newlines if @newlines > 0;\n            $needs_join = 0;\n        }\n\n        $needs_join = 1 if ($buf !~ /\\n$/osm);\n\n        push(@lines, @newlines);\n    } while ($buf !~ /^prov> $/osm);\n    pop @lines if ($lines[$#lines] =~ /^prov> $/osm);\n    wantarray ? @lines : join(\"\\n\", @lines);\n}\n\nsub sendZmprovRequestLdap($) {\n    my $cmd = shift @_;\n    my $buf;\n    initZmprovLdap unless (exists $zmprovl{'pid'} && kill(0, $zmprovl{'pid'}));\n    die \"zmprovl not initialized\" if (!exists $zmprovl{'out'});\n    $zmprovl{'out'}->print($cmd . \"\\n\");\n    my @lines = ();\n    my $needs_join = 0;\n\n    do {\n        sysread($zmprovl{'in'}, $buf, 8192);\n        my @newlines = split(/\\n/, $buf);\n\n        if ($needs_join) {\n            $lines[$#lines] .= shift @newlines if @newlines > 0;\n            $needs_join = 0;\n        }\n\n        $needs_join = 1 if ($buf !~ /\\n$/osm);\n\n        push(@lines, @newlines);\n    } while ($buf !~ /^prov> $/osm);\n    pop @lines if ($lines[$#lines] =~ /^prov> $/osm);\n    wantarray ? @lines : join(\"\\n\", @lines);\n}\n\nsub sendZmprovRequest($) {\n\twaitpid (-1, WNOHANG);\n    my $cmd = shift @_;\n\tmy @lines;\n\tif ($cmd =~ m/^-l\\s+/) {\n\t\t$cmd =~ s/^-l\\s+//;\n\t\t@lines = sendZmprovRequestLdap($cmd);\n\t} else {\n\t\t@lines = sendZmprovRequestSoap($cmd);\n\t}\n    wantarray ? @lines : join(\"\\n\", @lines);\n}\n\n1;\n"
  },
  {
    "path": "rpmconf/Build/checkLicense.pl",
    "content": "#!/usr/bin/perl\n#\n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n#\nuse strict;\n\nuse lib qw(/opt/zimbra/common/lib/perl5 /opt/zimbra/zimbramon/lib);\nuse LWP::UserAgent;\nuse Getopt::Long;\nuse Net::LDAP;\nuse XML::Simple;\n\nsub valid_licensekey {\n\tmy ($licensekey) = @_;\n\treturn $licensekey =~ /^[A-Za-z0-9]{18,24}$/;\n}\n\nsub set_permissions {\n\tmy ($file) = @_;\n\tsystem(\"chown zimbra:zimbra $file\");\n\tsystem(\"chmod 644 $file\");\n}\n\nsub compare_versions {\n\tmy ($version1, $version2) = @_;\n\tmy @v1 = split /\\./, $version1;\n\tmy @v2 = split /\\./, $version2;\n\tfor my $i (0 .. $#v1) {\n\t\treturn -1 if !defined $v2[$i];\n\t\treturn 1  if $v1[$i] > $v2[$i];\n\t\treturn -1 if $v1[$i] < $v2[$i];\n\t}\n\treturn 0 if @v1 == @v2;\n\treturn 1 if @v1 > @v2;\n\treturn -1;\n}\nmy %options;\nmy ( $licensekey, $blah, $host );\n\nGetOptions(\n\t\\%options,\n\t\"upgradeVersion|uv=s\",\n\t\"currentVersion|cv=s\",\n\t\"internal\",\n\t\"help\"\n) or usage();\n\nsub usage {\n    print(\n        \"usage: checkLicense.pl -uv UPGRADEVERSION -cv CURRENTVERSION [-i]\\n\",\n        \"\\t-uv UPGRADEVERSION: Example: -uv 8.7.0\\n\",\n        \"\\t-cv CURRENTVERSION: Example: -cv 8.6.0\\n\",\n        \"\\t-i: Internal Zimbra usage\\n\",\n        \"\\t-h: Display this help message\\n\"\n    );\n    exit(0);\n}\n\nif ( $options{help} ) {\n    usage();\n}\n\nif ( $options{internal} ) {\n    $host = 'http://zimbra-stage-license.eng.zimbra.com';\n}\nelse {\n    $host = 'https://license.zimbra.com';\n}\n\nunless ( $options{upgradeVersion} && $options{currentVersion} ) {\n    myDie(3,\"ERROR: Both upgrade version and current version must be supplied.\\n\");\n}\n\nmy $localxml              = XMLin(\"/opt/zimbra/conf/localconfig.xml\");\nmy $ldap_master_url       = $localxml->{key}->{ldap_master_url}->{value};\nmy $master_ref            = [ split( \" \", $ldap_master_url ) ];\nmy $zimbra_admin_dn       = $localxml->{key}->{zimbra_ldap_userdn}->{value};\nmy $zimbra_admin_password = $localxml->{key}->{zimbra_ldap_password}->{value};\nchomp($zimbra_admin_password);\nmy $ldap_starttls_supported =\n  $localxml->{key}->{ldap_starttls_supported}->{value};\nmy $zimbra_require_interprocess_security =\n  $localxml->{key}->{zimbra_require_interprocess_security}->{value};\n\nmy $ldap = Net::LDAP->new($master_ref)\n  or myDie(4,\"Error connecting to LDAP server: $ldap_master_url\\n\");\nmy $mesg;\nif ( $ldap_master_url !~ /^ldaps/i ) {\n    if ($ldap_starttls_supported) {\n        $mesg = $ldap->start_tls(\n            verify => 'none',\n            capath => \"/opt/zimbra/conf/ca\",\n        ) or myDie(5,\"start_tls: $@\\n\");\n        $mesg->code && myDie(5,\"TLS: \", $mesg->error, \"\\n\");\n    }\n}\n$mesg = $ldap->bind( \"$zimbra_admin_dn\", password => \"$zimbra_admin_password\" );\n$mesg->code && myDie(6,\"Bind: \", $mesg->error, \"\\n\");\n$mesg = $ldap->search(\n    base   => \"cn=config,cn=zimbra\",\n    filter => \"(zimbraNetworkRealtimeLicense=*)\",\n    scope  => \"base\",\n    attrs  => [ 'zimbraNetworkRealtimeLicense'],\n);\n\nmy $size = $mesg->count;\nif (compare_versions($options{currentVersion}, '10.1.0') >= 0 && $size == 0) {\n\t$ldap->unbind();\n\tmyDie(2,\"Error: License key not detected\\n\");\n}\n\nmy $entry           = $mesg->entry(0);\nmy $licensekey = \"\";\nif ($entry) {\n\t$licensekey = $entry->get_value(\"zimbraNetworkRealtimeLicense\");\n}\nif (!defined($licensekey) || $licensekey eq '') {\n\tmy $license_file = \"/opt/zimbra/conf/ZCSLicensekey\";\n\tif (-e $license_file) {\n\t\tchomp($licensekey = qx(cat $license_file));\n\t} else {\n\t\tprint \"\\n\";\n\t\tprint \"Please enter the license key (an alphanumeric string of 18-24 characters without any special characters):\";\n\t\t$licensekey = <STDIN>;\n\t\tchomp($licensekey);\n\t\tif (!valid_licensekey($licensekey)) {\n\t\t\tmyDie(7,\"Error: Invalid license key entered \\n\");\n\t\t}\n\t\tsystem(\"echo \\\"$licensekey\\\" > $license_file\");\n\t\tset_permissions($license_file);\n\t}\n}\nmy $caf = '/opt/zimbra/zimbramon/lib/Mozilla/CA/cacert.pem';\nmy @lwpargs = -f $caf ? ( ssl_opts => { SSL_ca_file => $caf, SSL_ca_path => undef } ) : ();\nmy $browser = LWP::UserAgent->new(@lwpargs);\n$browser->env_proxy;\nmy $request = HTTP::Request->new(POST => \"$host/rest/v1/public/license/$licensekey/validate?version=$options{upgradeVersion}\");\n$request->header('Content-Type' => 'application/json');\nmy $response = $browser->request($request);\nif ( $response->is_success ) {\n\tmy $json_content = $response->content;\n\tmy ($status_code) = $json_content =~ /\"status\":\\s*(\\d+)/;\n\tif (defined $status_code && $status_code == 2000) {\n\t\tmy ($status_message) = $json_content =~ /\"statusMessage\":\\s*\"([^\"]*)\"/;\n\t\tmyDie(0, \"SUCCESS: \", $status_message, \"\\n\");\n\t} else {\n\t\tmyDie(1, \"ERROR: \", $response->content, \"\\n\");\n\n\t}\n} else {\n\tmyDie(1, \"ERROR: \", $response->content, \"\\n\");\n}\n\nsub myDie() {\n  my ($rc, @msg) = @_;\n  if (@msg) {\n    if ($rc != 0) {\n      warn (@msg);\n    } else {\n      print STDOUT @msg;\n    }\n  }\n  exit ($rc);\n}\n"
  },
  {
    "path": "rpmconf/Build/checkService.pl",
    "content": "#!/usr/bin/perl\n#\n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n#\nuse strict;\nuse lib qw(/opt/zimbra/common/lib/perl5 /opt/zimbra/zimbramon/lib);\nuse Getopt::Long;\nuse Net::LDAP;\nuse XML::Simple;\n\nmy %options;\n\nGetOptions( \\%options, \"service=s\", \"help\" ) or usage();\n\nsub usage {\n    print(\n        \"usage: checkService.pl -s SERVICE\\n\",\n        \"\\t-s SERVICE: Example: -s proxy\\n\",\n    );\n    exit(0);\n}\n\nif ( $options{help} ) {\n    usage();\n}\n\nunless ( $options{service} ) {\n    die(\"ERROR: No service supplied.\\n\");\n}\n\nmy $localxml              = XMLin(\"/opt/zimbra/conf/localconfig.xml\");\nmy $ldap_master_url       = $localxml->{key}->{ldap_master_url}->{value};\nmy $master_ref            = [ split( \" \", $ldap_master_url ) ];\nmy $zimbra_admin_dn       = $localxml->{key}->{zimbra_ldap_userdn}->{value};\nmy $zimbra_admin_password = $localxml->{key}->{zimbra_ldap_password}->{value};\nchomp($zimbra_admin_password);\nmy $ldap_starttls_supported =\n  $localxml->{key}->{ldap_starttls_supported}->{value};\nmy $zimbra_require_interprocess_security =\n  $localxml->{key}->{zimbra_require_interprocess_security}->{value};\n\nmy $ldap = Net::LDAP->new($master_ref)\n  or die \"Error connecting to LDAP server: $ldap_master_url\";\nmy $mesg;\nmy $global_mesg;\nif ( $ldap_master_url !~ /^ldaps/i ) {\n    if ($ldap_starttls_supported) {\n        $mesg = $ldap->start_tls(\n            verify => 'none',\n            capath => \"/opt/zimbra/conf/ca\",\n        ) or die \"start_tls: $@\";\n        $mesg->code && die \"TLS: \" . $mesg->error . \"\\n\";\n    }\n}\n$mesg = $ldap->bind( \"$zimbra_admin_dn\", password => \"$zimbra_admin_password\" );\n$mesg->code && die \"Bind: \" . $mesg->error . \"\\n\";\n$mesg = $ldap->search(\n    base   => \"cn=servers,cn=zimbra\",\n    filter => \"(zimbraServiceEnabled=$options{service})\",\n    attrs  => [\n        'zimbraServiceEnabled', 'zimbraReverseProxyMailEnabled',\n        'zimbraReverseProxyHttpEnabled'\n    ],\n);\n\nmy $size = $mesg->count;\nmy $found_http_proxy_true=0;\nmy $found_mail_proxy_true=0;\nmy $found_http_proxy_false=0;\nmy $found_mail_proxy_false=0;\nmy $total_servers;\n\nif ( $size == 0 ) {\n    $ldap->unbind();\n    print STDERR \"Error: $options{service} not enabled\\n\";\n    exit 2;\n}\nelse {\n    if ( $options{service} eq \"proxy\" ) {\n\t\t\t\t$global_mesg = $ldap->bind( \"$zimbra_admin_dn\", password => \"$zimbra_admin_password\" );\n\t\t\t\t$global_mesg->code && die \"Bind: \" . $global_mesg->error . \"\\n\";\n\t\t\t\t$global_mesg = $ldap->search(\n\t\t\t\t    base   => \"cn=config,cn=zimbra\",\n\t\t\t\t    filter => \"(|(zimbraReverseProxyMailEnabled=TRUE)(zimbraReverseProxyHttpEnabled=TRUE))\",\n\t\t\t\t    attrs  => [\n\t\t\t\t        'zimbraReverseProxyMailEnabled', 'zimbraReverseProxyHttpEnabled'\n\t\t\t\t    ],\n\t\t\t\t);\n\n\t\t\t\t# get globalconfig values of zimbraReverseProxyMailEnabled and zimbraReverseProxyHttpEnabled\n\t\t\t\tmy $global_size = $global_mesg->count;\n\t\t\t\tmy $global_zimbraReverseProxyMailEnabled;\n\t\t\t\tmy $global_zimbraReverseProxyHttpEnabled;\n\t\t\t\tif ($global_size != 0) {\n\t\t\t\t        foreach my $global_entry ( $global_mesg->entries ) {\n                    $global_zimbraReverseProxyMailEnabled=$global_entry->get_value(\"zimbraReverseProxyMailEnabled\");\n                    $global_zimbraReverseProxyHttpEnabled=$global_entry->get_value(\"zimbraReverseProxyHttpEnabled\");\n                  }\n\t\t\t\t}\n        foreach my $entry ( $mesg->entries ) {\n            $total_servers++;\n            if ( $entry->get_value(\"zimbraReverseProxyMailEnabled\") eq \"TRUE\" ) { $found_mail_proxy_true++; }\n            if ( $entry->get_value(\"zimbraReverseProxyMailEnabled\") eq \"FALSE\" ) { $found_mail_proxy_false++; }\n            if ( $entry->get_value(\"zimbraReverseProxyHttpEnabled\") eq \"TRUE\" ) { $found_http_proxy_true++; }\n            if ( $entry->get_value(\"zimbraReverseProxyHttpEnabled\") eq \"FALSE\" ) { $found_http_proxy_false++; }\n        }\n        if ((($found_mail_proxy_true < 1 && $global_zimbraReverseProxyMailEnabled eq \"FALSE\") && ($found_http_proxy_true < 1 && $global_zimbraReverseProxyHttpEnabled eq \"FALSE\")) || (($found_http_proxy_false eq $total_servers) || ($found_mail_proxy_false eq $total_servers))){\n                    print STDERR\n    \"Error: One or more proxies do not have zimbraReverseProxyMailEnabled and zimbraReverseProxyHttpEnabled set to TRUE. \\nIt is required to have at least one proxy with zimbraReverseProxyMailEnabled and at least one proxy with zimbraReverseProxyHttpEnabled for ZCS 8.7+\\n\";\n                    exit 3;\n    \t\t}\n    }\n}\n\n"
  },
  {
    "path": "rpmconf/Build/create_distribution.dist.sh",
    "content": "#!/bin/bash\n# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2013, 2014, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n# \n\nPKGDIR=$1\nTEMPLATE=$2\n\nget_size_from_pkg() {\n\tpkg=$1\n\tbpkg=`basename $pkg`\n\tNAME=`echo $bpkg | awk -F. '{print $1}'| sed -e 's/zimbra-//' -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`\n\tSIZE=`cat ${pkg}/Contents/Info.plist |  sed -ne '/IFPkgFlagInstalledSize/{n;p;}'| sed -ne '/integer/ s/<integer>//p' | sed -e 's/<\\/integer>//' -e 's/ //g' -e 's/\t//g'`\n}\n\nget_build_num() {\n\tDIR=`dirname $0`\n\tMAJOR=`cat $DIR/../../RE/MAJOR`\n\tMINOR=`cat $DIR/../../RE/MINOR`\n\tMICRO=`cat $DIR/../../RE/MICRO`\n\tBUILDNUM=`cat $DIR/../../RE/BUILD`\n}\n\nget_build_num\n\nfor i in ${PKGDIR}/*.pkg; do\n\tget_size_from_pkg $i\n\tVAR=${NAME}SIZE\n\teval $VAR=$SIZE\ndone\n\ncat $TEMPLATE | sed -e \"s/@@CORESIZE@@/$CORESIZE/g\" \\\n\t-e \"s/@@LDAPSIZE@@/$LDAPSIZE/g\" \\\n\t-e \"s/@@LOGGERSIZE@@/$LOGGERSIZE/g\" \\\n\t-e \"s/@@ARCHIVINGSIZE@@/$ARCHIVINGSIZE/g\" \\\n\t-e \"s/@@APACHESIZE@@/$APACHESIZE/g\" \\\n\t-e \"s/@@STORESIZE@@/$STORESIZE/g\" \\\n\t-e \"s/@@CONVERTDSIZE@@/$CONVERTDSIZE/g\" \\\n\t-e \"s/@@MEMCACHEDSIZE@@/$MEMCACHEDSIZE/g\" \\\n\t-e \"s/@@MTASIZE@@/$MTASIZE/g\" \\\n\t-e \"s/@@PROXYSIZE@@/$PROXYSIZE/g\" \\\n\t-e \"s/@@SNMPSIZE@@/$SNMPSIZE/g\" \\\n\t-e \"s/@@SPELLSIZE@@/$SPELLSIZE/g\" \\\n\t-e \"s/@@MAJOR@@/$MAJOR/g\" \\\n\t-e \"s/@@MINOR@@/$MINOR/g\" \\\n\t-e \"s/@@MICRO@@/$MICRO/g\" \\\n\t-e \"s/@@BUILDNUM@@/$BUILDNUM/g\" \n\n\n"
  },
  {
    "path": "rpmconf/Build/get_plat_tag.sh",
    "content": "#!/bin/bash\n#\n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n#\n\n\nif [ -f /etc/redhat-release ]; then\n   i=`uname -i`\n   if [[ \"x$i\" == \"xx86_64\" ]] || [[ \"x$i\" == \"xppc64\"* ]]; then\n        i=\"_64\"\n  else\n    i=\"\"\n  fi\n\n  grep \"Red Hat Enterprise Linux.*release 9\" /etc/redhat-release > /dev/null 2>&1\n  if [ $? = 0 ]; then\n    echo \"RHEL9${i}\"\n    exit 0\n  fi\n  grep \"Red Hat Enterprise Linux.*release 8\" /etc/redhat-release > /dev/null 2>&1\n  if [ $? = 0 ]; then\n    echo \"RHEL8${i}\"\n    exit 0\n  fi\n  grep \"Red Hat Enterprise Linux.*release 7\" /etc/redhat-release > /dev/null 2>&1\n  if [ $? = 0 ]; then\n    echo \"RHEL7${i}\"\n    exit 0\n  fi\n  grep \"Red Hat Enterprise Linux.*release 6\" /etc/redhat-release > /dev/null 2>&1\n  if [ $? = 0 ]; then\n    echo \"RHEL6${i}\"\n    exit 0\n  fi\n\n  grep \"CentOS Linux release 9\" /etc/redhat-release > /dev/null 2>&1\n  if [ $? = 0 ]; then\n    echo \"RHEL9${i}\"\n    exit 0\n  fi\n  grep \"CentOS Linux release 8\" /etc/redhat-release > /dev/null 2>&1\n  if [ $? = 0 ]; then\n    echo \"RHEL8${i}\"\n    exit 0\n  fi\n  grep \"CentOS Linux release 7\" /etc/redhat-release > /dev/null 2>&1\n  if [ $? = 0 ]; then\n    echo \"RHEL7${i}\"\n    exit 0\n  fi\n  grep \"CentOS release 6\" /etc/redhat-release > /dev/null 2>&1\n  if [ $? = 0 ]; then\n    echo \"RHEL6${i}\"\n    exit 0\n  fi\n\n  grep \"Rocky Linux release 9\" /etc/redhat-release > /dev/null 2>&1\n  if [ $? = 0 ]; then\n    echo \"RHEL9${i}\"\n    exit 0\n  fi\n  grep \"Rocky Linux release 8\" /etc/redhat-release > /dev/null 2>&1\n  if [ $? = 0 ]; then\n    echo \"RHEL8${i}\"\n    exit 0\n  fi\n\n  grep \"Scientific Linux release 9\" /etc/redhat-release > /dev/null 2>&1\n  if [ $? = 0 ]; then\n    echo \"RHEL9${i}\"\n    exit 0\n  fi\n  grep \"Scientific Linux release 8\" /etc/redhat-release > /dev/null 2>&1\n  if [ $? = 0 ]; then\n    echo \"RHEL8${i}\"\n    exit 0\n  fi\n  grep \"Scientific Linux release 7\" /etc/redhat-release > /dev/null 2>&1\n  if [ $? = 0 ]; then\n    echo \"RHEL7${i}\"\n    exit 0\n  fi\n  grep \"Scientific Linux release 6\" /etc/redhat-release > /dev/null 2>&1\n  if [ $? = 0 ]; then\n    echo \"RHEL6${i}\"\n    exit 0\n  fi\n\n  grep \"Fedora release 23\" /etc/redhat-release >/dev/null 2>&1\n  if [ $? = 0 ]; then\n    echo \"F23${i}\"\n    exit 0\n  fi\n  grep \"Fedora release 22\" /etc/redhat-release >/dev/null 2>&1\n  if [ $? = 0 ]; then\n    echo \"F22${i}\"\n    exit 0\n  fi\n\n  grep \"Red Hat Enterprise Linux.*release\" /etc/redhat-release > /dev/null 2>&1\n  if [ $? = 0 ]; then\n    echo \"RHELUNKNOWN${i}\"\n    exit 0\n  fi\n  grep \"CentOS release\" /etc/redhat-release > /dev/null 2>&1\n  if [ $? = 0 ]; then\n    echo \"CentOSUNKNOWN${i}\"\n    exit 0\n  fi\n  grep \"Rocky Linux release\" /etc/redhat-release > /dev/null 2>&1\n  if [ $? = 0 ]; then\n    echo \"RockyUNKNOWN${i}\"\n    exit 0\n  fi\n  grep \"Fedora Core release\" /etc/redhat-release > /dev/null 2>&1\n  if [ $? = 0 ]; then\n    echo \"FCUNKNOWN${i}\"\n    exit 0\n  fi\nfi\n\nif [ -f /etc/SuSE-release ]; then\n  i=`uname -i`\n   if [[ \"x$i\" == \"xx86_64\" ]] || [[ \"x$i\" == \"xppc64\"* ]]; then\n    i=\"_64\"\n  else\n    i=\"\"\n  fi\n\n  grep \"SUSE Linux Enterprise Server 11\" /etc/SuSE-release >/dev/null 2>&1\n  if [ $? = 0 ]; then\n    echo \"SLES11${i}\"\n    exit 0\n  fi\n  grep \"SUSE Linux Enterprise Server 10\" /etc/SuSE-release >/dev/null 2>&1\n  if [ $? = 0 ]; then\n    echo \"SLES10${i}\"\n    exit 0\n  fi\n  grep \"SUSE Linux Enterprise Server\" /etc/SuSE-release >/dev/null 2>&1\n  if [ $? = 0 ]; then\n    echo \"SLESUNKNOWN${i}\"\n    exit 0\n  fi\n  grep \"openSUSE\" /etc/SuSE-release > /dev/null 2>&1\n  if [ $? = 0 ]; then\n    echo \"openSUSEUNKNOWN${i}\"\n    exit 0\n  fi\nfi\n\nif [ -f /etc/lsb-release ]; then\n  LSB=\"lsb_release\"\n  i=`dpkg --print-architecture`\n  if [ \"x$i\" = \"xamd64\" ]; then\n    i=\"_64\"\n  else\n    i=\"\"\n  fi\n  RELEASE=$($LSB -s -c)\n  DISTRIBUTOR=$($LSB -s -i)\n  if [ \"$DISTRIBUTOR\" = \"Ubuntu\" ]; then\n    echo -n \"UBUNTU\"\n    if [ \"$RELEASE\" = \"precise\" ]; then\n      echo \"12${i}\"\n      exit 0\n    fi\n    if [ \"$RELEASE\" = \"trusty\" ]; then\n      echo \"14${i}\"\n      exit 0\n    fi\n    if [ \"$RELEASE\" = \"xenial\" ]; then\n      echo \"16${i}\"\n      exit 0\n    fi\n    if [ \"$RELEASE\" = \"bionic\" ]; then\n      echo \"18${i}\"\n      exit 0\n    fi\n    if [ \"$RELEASE\" = \"focal\" ]; then\n      echo \"20${i}\"\n      exit 0\n    fi\n    if [ \"$RELEASE\" = \"jammy\" ]; then\n      echo \"22${i}\"\n      exit 0\n    fi\n    if [ \"$RELEASE\" = \"noble\" ]; then\n      echo \"24${i}\"\n      exit 0\n    fi\n    echo \"UNKNOWN${i}\"\n    exit 0\n  fi\n  if [ \"$DISTRIBUTOR\" = \"Debian\" ]; then\n    echo -n \"DEBIAN\"\n    if [ \"$RELEASE\" = \"wheezy\" ]; then\n      echo \"7${i}\"\n      exit 0\n    fi\n    if [ \"$RELEASE\" = \"jessie\" ]; then\n      echo \"8${i}\"\n      exit 0\n    fi\n    if [ \"$RELEASE\" = \"stretch\" ]; then\n      echo \"9${i}\"\n      exit 0\n    fi\n    echo \"UNKNOWN${i}\"\n    exit 0\n  fi\n  if [ \"$DISTRIBUTOR\" = \"Univention\" ]; then\n    echo -n \"UCS\"\n    if [ \"$RELEASE\" = \"Vahr\" ]; then\n      echo \"4${i}\"\n      exit 0\n    fi\n    echo \"UNKNOWN${i}\"\n    exit 0\n  fi\nfi\n\nif [ -f /etc/debian_version ]; then\n  echo \"DEBIANUNKNOWN${i}\"\n  exit 0\nfi\n\nif [ -f /etc/mandriva-release ]; then\n  echo \"MANDRIVAUNKNOWN\"\n  exit 0\nfi\n\nif [ -f /etc/release ]; then\n  egrep 'Solaris 10.*X86' /etc/release > /dev/null 2>&1\n  if [ $? = 0 ]; then\n    echo \"SOLARISX86\"\n    exit 0\n  fi\n  echo \"SOLARISUNKNOWN\"\nfi\n\na=`uname -a | awk '{print $1}'`\np=`uname -p`\nif [ \"x$a\" = \"xDarwin\" ]; then\n  v=`sw_vers | grep ^ProductVersion | awk '{print $NF}' | awk -F. '{print $1\".\"$2}'`\n  if [ \"x$v\" = \"x10.4\" ]; then\n    if [ \"x$p\" = \"xi386\" ]; then\n      echo \"MACOSXx86\"\n      exit 0\n    fi\n\n    if [ \"x$p\" = \"xpowerpc\" ]; then\n      echo \"MACOSX\"\n      exit 0\n    fi\n  else\n    if [ \"x$p\" = \"xi386\" ]; then\n      p=x86\n    fi\n    echo \"MACOSX${p}_${v}\"\n    exit 0\n  fi\nfi\n\necho \"UNKNOWN${i}\"\nexit 1\n"
  },
  {
    "path": "rpmconf/Build/zmValidateLdap.pl",
    "content": "#!/usr/bin/perl\n#\n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n#\n# Must be run on a system where the ldap_url key is set to contain all of the\n# replicas, as that is how the script determines what replicas exist.\n\nuse strict;\nuse lib qw(/opt/zimbra/common/lib/perl5/ /opt/zimbra/zimbramon/lib);\nuse Net::LDAP;\nuse Getopt::Long;\n\nmy ( %c, %loaded, %options );\n\n$c{zmlocalconfig} = \"/opt/zimbra/bin/zmlocalconfig\";\nmy @verargs = qw (vmajor vminor vmicro umajor uminor umicro);\n\nmy $opts_good = GetOptions(\n    \"vmajor=i\" => \\$options{vmajor},\n    \"vminor=i\" => \\$options{vminor},\n    \"vmicro=i\" => \\$options{vmicro},\n    \"umajor=i\" => \\$options{umajor},\n    \"uminor=i\" => \\$options{uminor},\n    \"umicro=i\" => \\$options{umicro},\n    \"ldap\"     => \\$options{l},\n);\n\nif ( !$opts_good ) {\n    print \"Error: Invalid options.\\n\";\n    exit 1;\n}\n\nmy $ldap_is_master = getLocalConfig(\"ldap_is_master\");\nif ( lc($ldap_is_master) ne \"true\" ) {\n    foreach my $arg (@verargs) {\n        unless ( defined $options{$arg} ) {\n            print\n\"Error: All of current major.minor.micro and upgrade major.minor.micro must be provided.\\n\";\n            exit 1;\n        }\n    }\n}\n\nmy $ldap_master             = getLocalConfig(\"ldap_master_url\");\nmy $admin_user              = getLocalConfig(\"zimbra_ldap_userdn\");\nmy $admin_password          = getLocalConfig(\"zimbra_ldap_password\");\nmy $ldap_starttls_supported = getLocalConfig(\"ldap_starttls_supported\");\nmy $upgradeOK               = 1;\n\nmy ( $mesgp, $entry );\nmy @masters = split / /, $ldap_master;\nforeach my $master (@masters) {\n    my $ldapp;\n    chomp($master);\n    if ( $master =~ /^ldaps:/ ) {\n        $ldapp = Net::LDAP->new(\n            $master,\n            verify => 'require',\n            capath => '/opt/zimbra/conf/ca'\n        );\n    }\n    else {\n        if ( $ldapp = Net::LDAP->new($master) ) {\n            if ($ldap_starttls_supported) {\n                $mesgp = $ldapp->start_tls(\n                    verify => 'require',\n                    capath => \"/opt/zimbra/conf/ca\",\n                );\n                if ( $mesgp->code ) {\n                    print\n\"ERROR: Unable to connect via startTLS to master: $master\\n\";\n                    exit 1;\n                }\n            }\n        }\n    }\n    if ( !defined($ldapp) ) {\n        print \"ERROR: No LDAP connection.\\n\";\n        exit 1;\n    }\n    if ( lc($ldap_is_master) ne \"true\" ) {\n        $mesgp = $ldapp->bind( $admin_user, password => $admin_password );\n        if ( $mesgp->code ) {\n            print \"ERROR: Unable to bind as the Zimbra Admin LDAP user.\\n\";\n            $ldapp->unbind();\n            exit 3;\n        }\n        my $ldap_master_host = $ldapp->host();\n        $mesgp = $ldapp->search(\n            base   => \"cn=servers,cn=zimbra\",\n            filter => \"cn=$ldap_master_host\",\n            attrs  => [\n                'zimbraServerVersionMajor', 'zimbraServerVersionMinor',\n                'zimbraServerVersionMicro', 'zimbraServerVersionType',\n                'zimbraServerVersionBuild',\n            ]\n        );\n        if ( $mesgp->code ) {\n            print \"Search error: Unable to search master.\\n\";\n            exit 4;\n        }\n        my $size = $mesgp->count;\n        if ( $size != 1 ) {\n            print\n\"Size error: Invalid response from ldap master. Please verify cn=$ldap_master_host,cn=servers,cn=zimbra exists in ldap and is a master ldap server.\\n\";\n            exit 4;\n        }\n        my ( $lmMajor, $lmMinor, $lmMicro, $lmType );\n        my $entry = $mesgp->entry(0);\n        chomp( $lmMajor = $entry->get_value('zimbraServerVersionMajor') );\n        chomp( $lmMinor = $entry->get_value('zimbraServerVersionMinor') );\n        chomp( $lmMicro = $entry->get_value('zimbraServerVersionMicro') );\n        if ( $lmMajor eq \"\" ) {\n            $upgradeOK = 0;\n            $ldapp->unbind;\n        }\n        if (   ( $lmMajor != $options{umajor} )\n            || ( $lmMinor != $options{uminor} )\n            || ( $lmMicro != $options{umicro} ) )\n        {\n            $upgradeOK = 0;\n            $ldapp->unbind;\n        }\n    }\n}\n\nif ( !$upgradeOK ) {\n    print \"ERROR: One or more masters have not yet been upgraded.  Aborting.\\n\";\n    exit 5;\n}\n\nif ( $options{l} ) {\n    if (   -f '/opt/zimbra/data/ldap/mdb/db/data.mdb'\n        || -f '/opt/zimbra/data/ldap/hdb/db/id2entry.bdb' )\n    {\n        my $ldap_root_password = getLocalConfig(\"ldap_root_password\");\n        my $ldap;\n        if ( $options{vmajor} < 8\n            || ( $options{vmajor} == 8 && $options{vminor} == 0 ) )\n        {\n            $ldap = Net::LDAP->new(\n                'ldapi://%2fopt%2fzimbra%2fopenldap%2fvar%2frun%2fldapi/')\n              or die \"$@\";\n        }\n        else {\n            $ldap = Net::LDAP->new(\n                'ldapi://%2fopt%2fzimbra%2fdata%2fldap%2fstate%2frun%2fldapi/')\n              or die \"$@\";\n        }\n        my $mesg = $ldap->bind( \"cn=config\", password => $ldap_root_password );\n        if ( $mesg->code ) {\n            print \"ERROR: Unable to bind as root LDAP user.\\n\";\n            $ldap->unbind();\n            exit 2;\n        }\n        my $admin_user     = getLocalConfig(\"zimbra_ldap_userdn\");\n        my $admin_password = getLocalConfig(\"zimbra_ldap_password\");\n        $mesg = $ldap->bind( $admin_user, password => $admin_password );\n        if ( $mesg->code ) {\n            print \"ERROR: Unable to bind as Zimbra Admin LDAP user.\\n\";\n            $ldap->unbind();\n            exit 3;\n        }\n        $ldap->unbind();\n    }\n}\n\nsub getLocalConfig {\n    my ( $key, $force ) = @_;\n\n    return $loaded{lc}{$key}\n      if ( exists $loaded{lc}{$key} && !$force );\n    my $val = qx($c{zmlocalconfig} -x -s -m nokey ${key} 2> /dev/null);\n    chomp($val);\n    $loaded{lc}{$key} = $val;\n    return $val;\n}\n"
  },
  {
    "path": "rpmconf/Conf/auditswatchrc",
    "content": "\n# Failures for an ip:account pair\nwatchfor /\\[.*\\w+=(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3});.*\\]\\s+.*cmd=.*Auth; account=(.*?);.*error=authentication failed for .*/\n\texec /bin/echo \"IP:Acct failure threshold exceeded: $1 $2\"\n\tmail addresses=@@zimbra_swatch_notice_user@@,subject=\"ABUSE: IP:Acct threshold exceeded: $1 $2\"\n\tthreshold track_by=$1:$2,type=both,count=@@zimbra_swatch_ipacct_threshold@@,seconds=@@zimbra_swatch_threshold_seconds@@\n\tcontinue\n\n# Failures for a specific account\nwatchfor /\\[.*\\w+=(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3});.*\\]\\s+.*cmd=.*Auth; account=(.*?);.*error=authentication failed for .*/\n\texec /bin/echo \"Account failure threshold exceeded: $1 $2\"\n\tmail addresses=@@zimbra_swatch_notice_user@@,subject=\"ABUSE: Account threshold exceeded: $1 $2\"\n\tthreshold track_by=$2,type=both,count=@@zimbra_swatch_acct_threshold@@,seconds=@@zimbra_swatch_threshold_seconds@@\n\tcontinue\n\n# Failures from a specific IP\nwatchfor /\\[.*\\w+=(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3});.*\\]\\s+.*cmd=.*Auth; account=(.*?);.*error=authentication failed for .*/\n\tmail addresses=@@zimbra_swatch_notice_user@@,subject=\"ABUSE: IP threshold exceeded: $1 $2\"\n\texec /bin/echo \"IP failure threshold exceeded: $1 exceeded threshold on failure for $2\"\n\tthreshold track_by=$1,type=both,count=@@zimbra_swatch_ip_threshold@@,seconds=@@zimbra_swatch_threshold_seconds@@\n\tcontinue\n\t\n# All auth failures\nwatchfor /\\[.*\\w+=(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3});.*\\]\\s+.*cmd=.*Auth; account=(.*?);.*error=authentication failed for .*/\n\tmail addresses=@@zimbra_swatch_notice_user@@,subject=\"ABUSE: Excessive auth failures detected.\"\n\texec /bin/echo \"Excessive authentication failures detected.\"\n\tthreshold track_by=$1,type=both,count=@@zimbra_swatch_total_threshold@@,seconds=@@zimbra_swatch_threshold_seconds@@\n\tcontinue\n\t\n"
  },
  {
    "path": "rpmconf/Conf/hotspot_compiler",
    "content": "exclude com/zimbra/cs/session/SessionMap.putAndPrune\nexclude com/zimbra/cs/mailbox/MailItem.delete\nexclude org/apache/xerces/impl/XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch\n"
  },
  {
    "path": "rpmconf/Conf/logswatchrc",
    "content": "ignore /DEBUG/\nwatchfor /.*/\n\tpipe /opt/zimbra/libexec/zmlogger,MESSAGE=$_\\n,KEEP_OPEN=1\n"
  },
  {
    "path": "rpmconf/Conf/mibs/zimbra.mib",
    "content": "ZIMBRA-MIB DEFINITIONS ::= BEGIN\n\tIMPORTS\n\t\tenterprises\n\t\tFROM SNMPv2-SMI;\n\nzimbra OBJECT IDENTIFIER ::= { enterprises 666 }\n\nzmStatus OBJECT IDENTIFIER ::= { zimbra 1 }\n\nzmServiceName OBJECT-TYPE\n    SYNTAX      OCTET STRING (SIZE(1..32))\n    MAX-ACCESS  not-accessible\n    STATUS      current\n    DESCRIPTION\n        \"Service Name\"\n    ::= { zmStatus 0 }\n\nzmServiceStatus OBJECT-TYPE\n    SYNTAX      INTEGER\n    MAX-ACCESS  not-accessible\n    STATUS      current\n    DESCRIPTION\n        \"Service Status\"\n    ::= { zmStatus 1 }\n\n\nEND\n"
  },
  {
    "path": "rpmconf/Conf/mibs/zimbra_traps.mib",
    "content": "ZIMBRA-TRAP-MIB DEFINITIONS ::= BEGIN\n        IMPORTS zimbra FROM ZIMBRA-MIB;\n\nzmtraps OBJECT IDENTIFIER ::= { zimbra 0 }\n\nzmServiceStatusTrap NOTIFICATION-TYPE\n        STATUS current\n        DESCRIPTION \"Service Status Change\"\n        ::= { zmtraps 0 }\n\nEND               \n"
  },
  {
    "path": "rpmconf/Conf/snmp.conf",
    "content": "###########################################################################\n#\n# snmp.conf\n#\n#   - created by the snmpconf configuration program\n#\n###########################################################################\n# SECTION: Default Authentication Options\n#\n#   This section defines the default authentication\n#   information.  Setting these up properly in your\n#   ~/.snmp/snmp.conf file will greatly reduce the amount of\n#   command line arguments you need to type (especially for snmpv3).\n\n# defaultport: The default port number to use\n#   This token specifies the default port number you want packets to \n#   be sent to and received from.\n#   override: with -p on the command line.\n#   arguments: portnum\n\ndefaultport  162\n\n# defversion: The default snmp version number to use.\n#   override: with -v on the command line.\n#   arguments: 1|2c|3\n\ndefversion  2c\n\n# defcommunity: The default snmpv1 and snmpv2c community name to use when needed.\n#   If this is specified, you don't need to include the community\n#   name as an argument to the snmp applications.  \n#   override: with -c on the command line.\n#   arguments: communityname\n\ndefcommunity  zimbra\n\n\n\n###########################################################################\n# SECTION: Output style options\n#\n#   This section allows you to control how the output of the\n#   various commands will be formated\n\n# logtimestamp: Should timestamps be shown on the output\n#   arguments: (1|yes|true|0|no|false)\n\nlogtimestamp  1\n\n# printnumericoids: Print OIDs numericly or textually\n#   command line equivelent: -On\n#   arguments: (1|yes|true|0|no|false)\n\nprintnumericoids  0\n\n\n\n\n\n\n###########################################################################\n# SECTION: Textual mib parsing\n#\n#   This section controls the textual mib parser.  Textual\n#   mibs are parsed in order to convert OIDs, enumerated\n#   lists, and ... to and from textual representations\n#   and numerical representations.\n\n# mibdirs: Specifies directories to be searched for mibs.\n#   Adding a '+' sign to the front of the argument appends the new\n#   directory to the list of directories already being searched.\n#   arguments: [+]directory[:directory...]\n\nmibdirs  +/opt/zimbra/common/share/snmp/mibs\n"
  },
  {
    "path": "rpmconf/Conf/snmpd.conf.in",
    "content": "###########################################################################\n#\n# snmpd.conf\n#\n#   - created by the snmpconf configuration program\n#\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n###########################################################################\n# SECTION: Trap Destinations\n#\n#   Here we define who the agent will send traps to.\n\n# trapsink: A SNMPv1 trap receiver\n#   arguments: host [community] [portnum]\n\ntrapsink  @@SNMPHOST@@ zimbra \n\n# trap2sink: A SNMPv2c trap receiver\n#   arguments: host [community] [portnum]\n\ntrap2sink  @@SNMPHOST@@ zimbra \n\n# informsink: A SNMPv2c inform (acknowledged trap) receiver\n#   arguments: host [community] [portnum]\n\ninformsink  @@SNMPHOST@@ zimbra \n\n# trapcommunity: Default trap sink community to use\n#   arguments: community-string\n\ntrapcommunity  zimbra\n\n\n\n"
  },
  {
    "path": "rpmconf/Conf/swatchrc",
    "content": "perlcode 0 my %notifications=();\nperlcode 0 $notifications{smtp}=\"@@DOSMTPNOTIFICATIONS@@\";\nperlcode 0 $notifications{snmp}=\"@@DOSNMPNOTIFICATIONS@@\";\n\nperlcode 0 my $fr='@@ADMINEMAIL@@';\nperlcode 0 my $pwc='@@PHCEMAIL@@';\n\nperlcode 0 my $hostname=\"@@HOSTNAME@@\";\nperlcode 0 my $traphost=\"@@TRAPHOST@@\";\n\nperlcode 0 my $snmpargs=\"-v 2c -c zimbra $traphost ''\";\nperlcode 0 my $snmptrap=\"/opt/zimbra/common/bin/snmptrap $snmpargs\";\nperlcode 0 my $snmpsvctrap=\"ZIMBRA-TRAP-MIB::zmServiceStatusTrap\";\nperlcode 0 my $snmpsvcname=\"ZIMBRA-MIB::zmServiceName\";\nperlcode 0 my $snmpsvcstatus=\"ZIMBRA-MIB::zmServiceStatus\";\nperlcode 0 use Zimbra::SMTP;\n\nperlcode 0 my %statuses=('started'=>1,'stopped'=>0);\n\nperlcode 0 sub donotify {   my %args = (@_); if ($args{HOST} eq \"localhost\") {$args{HOST}=$hostname;}; if ($notifications{smtp}) { dosmtp(%args) if $args{SERVICE}; dodisksmtp(%args) if $args{DISK};}; if ($notifications{snmp}) {dosnmp(%args);};  }\n\nperlcode 0 sub dosmtp {   my %args = @_; if (my $smtp=Zimbra::SMTP->new) {unless($smtp->send(from=>$fr,to=>$pwc,subject=>\"Service $args{SERVICE} $args{STATUS} on $args{HOST}\",message=>$args{MESSAGE})){warn \"message send failed: \",$smtp->error}} else {warn \"failed new Zimbra::SMTP: \",Zimbra::SMTP->error} }\n\nperlcode 0 sub dodisksmtp {   my %args = (@_);  print \"SMTP notification: $args{MESSAGE}\\n\"; if (my $smtp=Zimbra::SMTP->new) {unless($smtp->send(from=>$fr,to=>$pwc,subject=>\"Disk $args{DISK} at $args{UTIL}\\% on $args{HOST}\",message=>$args{MESSAGE})){warn \"message send failed: \",$smtp->error}}else{warn \"failed new Zimbra::SMTP: \",Zimbra::SMTP->error}}\n\nperlcode 0 sub dosnmp {   my %args = (@_); print \"SNMP notification: $args{MESSAGE}\\n\"; `$snmptrap $snmpsvctrap $snmpsvcname s $args{SERVICE} $snmpsvcstatus i $statuses{$args{STATUS}}`; }\n\nignore /DEBUG/\n\nwatchfor /: Service status change: (\\S+) (.*) changed from stopped to running/\n\tdonotify SERVICE=$2,STATUS=started,HOST=$1\nwatchfor /: Service status change: (\\S+) (.*) changed from running to stopped/\n\tdonotify SERVICE=$2,STATUS=stopped,HOST=$1\n\nwatchfor /err: Disk warning: (\\S+) (\\S+) on device (\\S+) at (\\d+)/ \n        donotify DISK=$2,UTIL=$4,HOST=$1\nwatchfor /crit: Disk warning: (\\S+) (\\S+) on device (\\S+) at (\\d+)/ \n        donotify DISK=$2,UTIL=$4,HOST=$1\n"
  },
  {
    "path": "rpmconf/Conf/zmssl.cnf.in",
    "content": "#\n# OpenSSL example configuration file.\n# This is mostly being used for generation of certificate requests.\n#\n\n# This definition stops the following lines choking if HOME isn't\n# defined.\nHOME\t\t\t= /opt/zimbra/ssl\nRANDFILE\t\t= /opt/zimbra/ssl/.rnd\n\n# Extra OBJECT IDENTIFIER info:\n#oid_file\t\t= $ENV::HOME/.oid\noid_section\t\t= new_oids\n\n# To use this configuration file with the \"-extfile\" option of the\n# \"openssl x509\" utility, name here the section containing the\n# X.509v3 extensions to use:\n# extensions\t\t= \n# (Alternatively, use a configuration file that has only\n# X.509v3 extensions in its main [= default] section.)\n\n[ new_oids ]\n\n# We can add new OIDs in here for use by 'ca' and 'req'.\n# Add a simple OID like this:\n# testoid1=1.2.3.4\n# Or use config file substitution like this:\n# testoid2=${testoid1}.5.6\n\n####################################################################\n[ ca ]\ndefault_ca\t= CA_default\t\t# The default ca section\n\n####################################################################\n[ CA_default ]\n\ndir\t\t= /opt/zimbra/ssl/zimbra/ca\t\t# Where everything is kept\ncerts\t\t= $dir/certs\t\t# Where the issued certs are kept\ncrl_dir\t\t= $dir/crl\t\t# Where the issued crl are kept\ndatabase\t= $dir/index.txt\t# database index file.\n#unique_subject\t= no\t\t\t# Set to 'no' to allow creation of\n\t\t\t\t\t# several ctificates with same subject.\nnew_certs_dir\t= $dir/newcerts\t\t# default place for new certs.\n\ncertificate\t= $dir/cacert.pem \t# The CA certificate\nserial\t\t= /opt/zimbra/ssl/zimbra/ca/ca.srl \t\t# The current serial number\ncrl\t\t= $dir/crl.pem \t\t# The current CRL\nprivate_key\t= $dir/private/cakey.pem# The private key\nRANDFILE\t= $dir/private/.rand\t# private random number file\n\nx509_extensions\t= usr_cert\t\t# The extentions to add to the cert\n\n# Comment out the following two lines for the \"traditional\"\n# (and highly broken) format.\nname_opt \t= ca_default\t\t# Subject Name options\ncert_opt \t= ca_default\t\t# Certificate field options\n\n# Extension copying option: use with caution.\ncopy_extensions = copy\n\n# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs\n# so this is commented out by default to leave a V1 CRL.\n# crl_extensions\t= crl_ext\n\ndefault_days\t= 1825\t\t\t# how long to certify for\ndefault_crl_days= 30\t\t\t# how long before next CRL\ndefault_md\t= @@ssl_default_digest@@\t\t# which md to use.\npreserve\t= no\t\t\t# keep passed DN ordering\n\n# A few difference way of specifying how similar the request should look\n# For type CA, the listed attributes must be the same, and the optional\n# and supplied fields are just that :-)\npolicy\t\t= policy_match\n\n# For the CA policy\n[ policy_match ]\ncountryName\t\t= match\nstateOrProvinceName\t= match\norganizationName\t= match\norganizationalUnitName\t= optional\ncommonName\t\t= supplied\nemailAddress\t\t= optional\n\n# For the 'anything' policy\n# At this point in time, you must list all acceptable 'object'\n# types.\n[ policy_anything ]\ncountryName\t\t= optional\nstateOrProvinceName\t= optional\nlocalityName\t\t= optional\norganizationName\t= optional\norganizationalUnitName\t= optional\ncommonName\t\t= supplied\nemailAddress\t\t= optional\n\n####################################################################\n[ req ]\ndefault_bits\t\t= 1024\ndefault_keyfile \t= privkey.pem\ndistinguished_name\t= req_distinguished_name\nattributes\t\t= req_attributes\nx509_extensions\t= v3_ca\t# The extentions to add to the self signed cert\n\n# Passwords for private keys if not present they will be prompted for\n# input_password = secret\n# output_password = secret\n\n# This sets a mask for permitted string types. There are several options. \n# default: PrintableString, T61String, BMPString.\n# pkix\t : PrintableString, BMPString (PKIX recommendation before 2004)\n# utf8only: only UTF8Strings (PKIX recommendation after 2004).\n# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).\n# MASK:XXXX a literal mask value.\n# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings.\nstring_mask = utf8only\n\nreq_extensions = v3_req # The extensions to add to a certificate request\n\n[ req_distinguished_name ]\ncountryName\t\t\t= Country Name (2 letter code)\ncountryName_default\t\t= US\ncountryName_min\t\t\t= 2\ncountryName_max\t\t\t= 2\n\nstateOrProvinceName\t\t= State or Province Name (full name)\nstateOrProvinceName_default\t= N/A\n\nlocalityName\t\t\t= Locality Name (eg, city)\n\n0.organizationName\t\t= Organization Name (eg, company)\n0.organizationName_default\t= N/A\n\n# we can do this but it is not needed normally :-)\n#1.organizationName\t\t= Second Organization Name (eg, company)\n#1.organizationName_default\t= World Wide Web Pty Ltd\n\norganizationalUnitName\t\t= Organizational Unit Name (eg, section)\norganizationalUnitName_default\t= Zimbra Collaboration Suite\n\ncommonName\t\t\t= Common Name (e.g. server FQDN or YOUR name)\ncommonName_max\t\t\t= 64\ncommonName_default\t\t= @@HOSTNAME@@\n\nemailAddress\t\t\t= Email Address\nemailAddress_max\t\t= 64\n\n# SET-ex3\t\t\t= SET extension number 3\n\n[ req_attributes ]\nchallengePassword\t\t= A challenge password\nchallengePassword_min\t\t= 4\nchallengePassword_max\t\t= 20\n\nunstructuredName\t\t= An optional company name\n\n[ usr_cert ]\n\n# These extensions are added when 'ca' signs a request.\n\n# This goes against PKIX guidelines but some CAs do it and some software\n# requires this to avoid interpreting an end user certificate as a CA.\n\nbasicConstraints=CA:FALSE\n\n# Here are some examples of the usage of nsCertType. If it is omitted\n# the certificate can be used for anything *except* object signing.\n\n# This is OK for an SSL server.\n# nsCertType\t\t\t= server\n\n# For an object signing certificate this would be used.\n# nsCertType = objsign\n\n# For normal client use this is typical\n# nsCertType = client, email\n\n# and for everything including object signing:\n# nsCertType = client, email, objsign\n\n# This is typical in keyUsage for a client certificate.\n# keyUsage = nonRepudiation, digitalSignature, keyEncipherment\n\n# This will be displayed in Netscape's comment listbox.\nnsComment\t\t\t= \"OpenSSL Generated Certificate\"\n\n# PKIX recommendations harmless if included in all certificates.\nsubjectKeyIdentifier=hash\nauthorityKeyIdentifier=keyid,issuer:always\n\n# This stuff is for subjectAltName and issuerAltname.\n# Import the email address.\n# subjectAltName=email:copy\n# An alternative to produce certificates that aren't\n# deprecated according to PKIX.\n# subjectAltName=email:move\n\n# Copy subject details\n# issuerAltName=issuer:copy\n\n#nsCaRevocationUrl\t\t= http://www.domain.dom/ca-crl.pem\n#nsBaseUrl\n#nsRevocationUrl\n#nsRenewalUrl\n#nsCaPolicyUrl\n#nsSslServerName\n@@SUBJECT_ALT_NAMES@@\n\n[ v3_req ]\n\n# Extensions to add to a certificate request\n\nbasicConstraints = CA:FALSE\nkeyUsage = nonRepudiation, digitalSignature, keyEncipherment\n@@SUBJECT_ALT_NAMES@@\n\n[ v3_ca ]\n\n# Extensions for a typical CA\n\n# PKIX recommendation.\n\nsubjectKeyIdentifier=hash\n\nauthorityKeyIdentifier=keyid:always,issuer:always\n\n# This is what PKIX recommends but some broken software chokes on critical\n# extensions.\n#basicConstraints = critical,CA:true\n# So we do this instead.\nbasicConstraints = CA:true\n\n# Key usage: this is typical for a CA certificate. However since it will\n# prevent it being used as an test self-signed certificate it is best\n# left out by default.\n# keyUsage = cRLSign, keyCertSign\n\n# Some might want this also\n# nsCertType = sslCA, emailCA\n\n# Include email address in subject alt name: another PKIX recommendation\n# subjectAltName=email:copy\n# Copy issuer details\n# issuerAltName=issuer:copy\n@@SUBJECT_ALT_NAMES@@\n\n# DER hex encoding of an extension: beware experts only!\n# obj=DER:02:03\n# Where 'obj' is a standard or added object\n# You can even override a supported extension:\n# basicConstraints= critical, DER:30:03:01:01:FF\n\n[ crl_ext ]\n\n# CRL extensions.\n# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.\n\n# issuerAltName=issuer:copy\nauthorityKeyIdentifier=keyid:always,issuer:always\n\n"
  },
  {
    "path": "rpmconf/Ctl/zimbra.cf.in",
    "content": "# Order is important.\n#\n# APPLICATION name executable \"args\" mode \"label\"\n#\n# mode = \"normal\"\n#\n# SERVICE name \"label\" appname monitor_port control_syntax\n#\n# CONTROL_SYNTAX name cmd \"syntax\"\n# CONTROL_SYNTAX proto \"protocol-type\" (text, http, soap)\n#\n# commands: start, restart, stop, exit, drain, status\n#\tplus app specific stuff\n#\n# $nm, $ex, $args, $md, $label\n\n# exit_status_error_mappings \n# log_message_alerts \n#\n\nPORT 7777\n\nCONTROL_SYNTAX zimbrasyntax proto \"text\"\nCONTROL_SYNTAX zimbrasyntax start \"START\"\nCONTROL_SYNTAX zimbrasyntax restart \"RESTART\"\nCONTROL_SYNTAX zimbrasyntax stop \"STOP\"\nCONTROL_SYNTAX zimbrasyntax exit \"EXIT\"\nCONTROL_SYNTAX zimbrasyntax drain \"DRAIN\"\nCONTROL_SYNTAX zimbrasyntax status \"STATUS\"\nCONTROL_SYNTAX zimbrasyntax statuschange \"STATUSCHANGE\"\nCONTROL_SYNTAX zimbrasyntax events \"EVENTS\"\nCONTROL_SYNTAX zimbrasyntax addhost \"ADDHOST\"\nCONTROL_SYNTAX zimbrasyntax removehost \"REMOVEHOST\"\nCONTROL_SYNTAX zimbrasyntax shutdown \"SHUTDOWN\"\nCONTROL_SYNTAX zimbrasyntax reload \"RELOAD\"\nCONTROL_SYNTAX zimbrasyntax newfetchref \"NEWFETCHREF\"\nCONTROL_SYNTAX zimbrasyntax getfetchref \"GETFETCHREF\"\n"
  },
  {
    "path": "rpmconf/Ctl/zimbracore.cf",
    "content": "APPLICATION mysql test_server \"9999\" normal \"mysql server\"\n\nCONTROL_SYNTAX zimbrasyntax mysql_start \"/opt/zimbra/bin/mysql.server start\"\nCONTROL_SYNTAX zimbrasyntax mysql_stop \"/opt/zimbra/bin/mysql.server stop\"\nCONTROL_SYNTAX zimbrasyntax mysql_status \"/opt/zimbra/bin/mysqladmin status\"\n"
  },
  {
    "path": "rpmconf/Ctl/zimbraldap.cf",
    "content": "APPLICATION ldap test_server \"9999\" normal \"ldap server\"\n\nSERVICE ldap \"Zimbra Directory\" ldap \n\nCONTROL_SYNTAX zimbrasyntax ldap_start \"/opt/zimbra/bin/ldap start\"\nCONTROL_SYNTAX zimbrasyntax ldap_stop \"/opt/zimbra/bin/ldap stop\"\nCONTROL_SYNTAX zimbrasyntax ldap_status \"/opt/zimbra/bin/ldap status\"\n"
  },
  {
    "path": "rpmconf/Ctl/zimbralogger.cf",
    "content": "SERVICE logger \"Zimbra Mail Console\" logmysql,logswatch\n\nAPPLICATION logmysql test_server \"9999\" normal \"mysql server\"\n\nCONTROL_SYNTAX zimbrasyntax logmysql_start \"/opt/zimbra/bin/logmysql.server start\"\nCONTROL_SYNTAX zimbrasyntax logmysql_stop \"/opt/zimbra/bin/logmysql.server stop\"\nCONTROL_SYNTAX zimbrasyntax logmysql_status \"/opt/zimbra/bin/logmysqladmin status\"\n\nAPPLICATION logswatch test_server \"9999\" normal \"logger swatch daemon\"\n\nCONTROL_SYNTAX zimbrasyntax logswatch_start \"/opt/zimbra/bin/zmlogswatchctl start\"\nCONTROL_SYNTAX zimbrasyntax logswatch_stop \"/opt/zimbra/bin/zmlogswatchctl stop\"\nCONTROL_SYNTAX zimbrasyntax logswatch_status \"/opt/zimbra/bin/zmlogswatchctl status\"\n"
  },
  {
    "path": "rpmconf/Ctl/zimbramail.cf",
    "content": "SERVICE mailbox \"Zimbra Mail Console\" tomcat,mysql\n\nAPPLICATION tomcat test_server \"9999\" normal \"tomcat server\"\n\nCONTROL_SYNTAX zimbrasyntax tomcat_start \"/opt/zimbra/bin/tomcat start\"\nCONTROL_SYNTAX zimbrasyntax tomcat_stop \"/opt/zimbra/bin/tomcat stop\"\nCONTROL_SYNTAX zimbrasyntax tomcat_kill \"/opt/zimbra/bin/tomcat kill\"\nCONTROL_SYNTAX zimbrasyntax tomcat_status \"/opt/zimbra/bin/tomcat status\"\n\nAPPLICATION mysql test_server \"9999\" normal \"mysql server\"\n\nCONTROL_SYNTAX zimbrasyntax mysql_start \"/opt/zimbra/bin/mysql.server start\"\nCONTROL_SYNTAX zimbrasyntax mysql_stop \"/opt/zimbra/bin/mysql.server stop\"\nCONTROL_SYNTAX zimbrasyntax mysql_status \"/opt/zimbra/bin/mysqladmin status\"\n"
  },
  {
    "path": "rpmconf/Ctl/zimbramta.cf",
    "content": "SERVICE mta \"Zimbra MTA\" postfix,saslauthd,mtaconfig\n\nAPPLICATION postfix test_server \"9999\" normal \"Postfix mta\"\nCONTROL_SYNTAX zimbrasyntax postfix_start \"/opt/zimbra/bin/postfix start\"\nCONTROL_SYNTAX zimbrasyntax postfix_stop \"/opt/zimbra/bin/postfix stop\"\nCONTROL_SYNTAX zimbrasyntax postfix_status \"SMTP\"\n\nSERVICE antispam \"Zimbra MTA\" amavisd,mtaconfig\nSERVICE antivirus \"Zimbra MTA\" amavisd,clamd,mtaconfig\n\nAPPLICATION amavisd test_server \"9999\" normal \"Postfix mta\"\nCONTROL_SYNTAX zimbrasyntax amavisd_start \"/opt/zimbra/bin/zmamavisdctl start\"\nCONTROL_SYNTAX zimbrasyntax amavisd_stop \"/opt/zimbra/bin/zmamavisdctl stop\"\nCONTROL_SYNTAX zimbrasyntax amavisd_status \"/opt/zimbra/bin/zmamavisdctl status\"\n\nAPPLICATION clamd test_server \"9999\" normal \"Postfix mta\"\nCONTROL_SYNTAX zimbrasyntax clamd_start \"/opt/zimbra/bin/zmclamdctl start\"\nCONTROL_SYNTAX zimbrasyntax clamd_stop \"/opt/zimbra/bin/zmclamdctl stop\"\nCONTROL_SYNTAX zimbrasyntax clamd_status \"/opt/zimbra/bin/zmclamdctl status\"\n\nAPPLICATION mtaconfig test_server \"9999\" normal \"MTA Configuration Daemon\"\nCONTROL_SYNTAX zimbrasyntax mtaconfig_start \"/opt/zimbra/bin/zmmtaconfigctl start\"\nCONTROL_SYNTAX zimbrasyntax mtaconfig_stop \"/opt/zimbra/bin/zmmtaconfigctl stop\"\nCONTROL_SYNTAX zimbrasyntax mtaconfig_status \"/opt/zimbra/bin/zmmtaconfigctl status\"\n\nAPPLICATION saslauthd test_server \"9999\" normal \"SASL Auth Daemon\"\nCONTROL_SYNTAX zimbrasyntax saslauthd_start \"/opt/zimbra/bin/zmsaslauthdctl start\"\nCONTROL_SYNTAX zimbrasyntax saslauthd_stop \"/opt/zimbra/bin/zmsaslauthdctl stop\"\nCONTROL_SYNTAX zimbrasyntax saslauthd_status \"/opt/zimbra/bin/zmsaslauthdctl status\"\n"
  },
  {
    "path": "rpmconf/Ctl/zimbrasnmp.cf",
    "content": "# SNMP COMMANDS HERE\nAPPLICATION swatch test_server \"9999\" normal \"SNMP monitor\"\nSERVICE snmp \"Zimbra MTA\" swatch \n\nCONTROL_SYNTAX zimbrasyntax swatch_start \"/opt/zimbra/bin/zmswatchctl start\"\nCONTROL_SYNTAX zimbrasyntax swatch_stop \"/opt/zimbra/bin/zmswatchctl stop\"\nCONTROL_SYNTAX zimbrasyntax swatch_status \"/opt/zimbra/bin/zmswatchctl status\"\n\n"
  },
  {
    "path": "rpmconf/Env/crontabs/crontab",
    "content": "# ZIMBRASTART -- DO NOT EDIT ANYTHING BETWEEN THIS LINE AND ZIMBRAEND\nSHELL=/bin/bash\n#\n# Log pruning\n#\n30 2 * * * find /opt/zimbra/log/ ! -name 'zmsetup*.log' -type f -name '*.log?*' -mtime +8 -exec rm {} \\; > /dev/null 2>&1\n35 2 * * * find /opt/zimbra/log/ -type f -name '*.out.????????????' -mtime +8 -exec rm {} \\; > /dev/null 2>&1\n#\n# compress logs manually to avoid application pauses when \n# handled through the log4j thread\n#\n50 2 * * * /opt/zimbra/libexec/zmcompresslogs > /dev/null 2>&1\n#\n# tmp dir cleaning\n#\n40 2 * * * /opt/zimbra/libexec/zmcleantmp\n#\n# Status logging\n#\n*/2 * * * * /opt/zimbra/libexec/zmstatuslog > /dev/null 2>&1\n#*/10 * * * * /opt/zimbra/libexec/zmdisklog > /dev/null 2>&1\n#\n# SSL Certificate Expiration Checks\n#\n0 0 1 * * /opt/zimbra/libexec/zmcheckexpiredcerts -days 30 -email\n#\n# Backups\n#\n# BACKUP BEGIN\n# BACKUP END\n#\n# Storage Management\n#\n# STORAGE MANAGEMENT BEGIN\n# STORAGE MANAGEMENT END\n"
  },
  {
    "path": "rpmconf/Env/crontabs/crontab.ldap",
    "content": "#\n# crontab.ldap\n#\n# Monitor MDB database size\n*/30 * * * * /opt/zimbra/libexec/zmldapmonitordb > /dev/null 2>&1\n#\n"
  },
  {
    "path": "rpmconf/Env/crontabs/crontab.logger",
    "content": "#\n# crontab.logger\n#\n# process logs\n#\n00,10,20,30,40,50 * * * * /opt/zimbra/libexec/zmlogprocess > /tmp/logprocess.out 2>&1\n#\n# Graph generation\n#\n#10 * * * * /opt/zimbra/libexec/zmgengraphs >> /tmp/gengraphs.out 2>&1\n#\n# Daily reports\n#\n30 23 * * * /opt/zimbra/libexec/zmdailyreport -m\n"
  },
  {
    "path": "rpmconf/Env/crontabs/crontab.mta",
    "content": "#\n# crontab.mta\n#\n#\n# Queue logging\n#\n0,10,20,30,40,50 * * * * /opt/zimbra/libexec/zmqueuelog\n#\n# Spam training\n#\n0 22 * * * /opt/zimbra/bin/zmtrainsa >> /opt/zimbra/log/spamtrain.log 2>&1\n#\n# Spam training cleanup\n#\n45 23 * * * /opt/zimbra/bin/zmtrainsa --cleanup >> /opt/zimbra/log/spamtrain.log 2>&1\n#\n# Spam rule updates\n#\n45 0 * * * . /opt/zimbra/.bashrc; /opt/zimbra/libexec/zmsaupdate\n#\n# Spam Bayes auto-expiry\n#\n20 23 * * * /opt/zimbra/common/bin/sa-learn --dbpath /opt/zimbra/data/amavisd/.spamassassin --force-expire --sync > /dev/null 2>&1 \n# \n# Clean up amavisd/tmp\n#\n15 5,20 * * * find /opt/zimbra/data/amavisd/tmp -maxdepth 1 -type d -name 'amavis-*' -mtime +1 -exec rm -rf {} \\; > /dev/null 2>&1\n#\n# Clean up the quarantine dir\n#\n0 1 * * * find /opt/zimbra/data/amavisd/quarantine -type f -mtime +7 -exec rm -f {} \\; > /dev/null 2>&1\n#\n#\n#\n35 3 * * * /opt/zimbra/bin/zmcbpadmin --cleanup >/dev/null 2>&1\n\n"
  },
  {
    "path": "rpmconf/Env/crontabs/crontab.store",
    "content": "#\n# crontab.store\n#\n# Log pruning\n#\n30 2 * * * find /opt/zimbra/mailboxd/logs/ -type f -name \\*log\\* -mtime +8 -exec rm {} \\; > /dev/null 2>&1\n30 2 * * * find /opt/zimbra/log/ -type f -name stacktrace.\\* -mtime +8 -exec rm {} \\; > /dev/null 2>&1\n#\n# Report on any database inconsistencies\n#\n0 23 * * 7 /opt/zimbra/libexec/zmdbintegrityreport -m\n#\n# Monitor for multiple mysqld to prevent corruption\n#\n#*/5 * * * * /opt/zimbra/libexec/zmcheckduplicatemysqld -e > /dev/null 2>&1\n#\n# Check zimbraVersionCheckURL for new update. \n# Only runs if this server matches zimbraVersionCheckServer \n# Only executes on zimbraVersionCheckInterval. min 2h interval\n#\n18 */2 * * * /opt/zimbra/libexec/zmcheckversion -c >> /dev/null 2>&1\n#\n# Invoke \"ComputeAggregateQuotaUsageRequest\" periodically\n#\n15 2 * * *\t/opt/zimbra/libexec/zmcomputequotausage > /dev/null 2>&1\n#\n# Invoke \"client_usage_report.py\" periodically to process /opt/zimbra/log/access_log* files\n#\n55 1 * * *\t/opt/zimbra/libexec/client_usage_report.py > /dev/null 2>&1\n#\n# Run zmgsaupdate util to trickeSync galsync accounts\n#\n49 0 * * 7\t/opt/zimbra/libexec/zmgsaupdate > /dev/null 2>&1\n#\n# Password expiry reminders\n#\n0 0 * * * /opt/zimbra/bin/zmpasswordexpiryreminder\n"
  },
  {
    "path": "rpmconf/Env/sudoers.d/01_zimbra",
    "content": "Defaults:zimbra !requiretty\n"
  },
  {
    "path": "rpmconf/Env/sudoers.d/02_zimbra-core",
    "content": "%zimbra ALL=NOPASSWD:/opt/zimbra/libexec/zmstat-fd *\n"
  },
  {
    "path": "rpmconf/Env/sudoers.d/02_zimbra-dnscache.deb",
    "content": "%zimbra ALL=NOPASSWD:/opt/zimbra/libexec/zmunbound\n%zimbra ALL=NOPASSWD:/sbin/resolvconf *\n"
  },
  {
    "path": "rpmconf/Env/sudoers.d/02_zimbra-dnscache.rpm",
    "content": "%zimbra ALL=NOPASSWD:/opt/zimbra/libexec/zmunbound\n%zimbra ALL=NOPASSWD:/opt/zimbra/libexec/zmdnscachealign *\n%zimbra ALL=NOPASSWD:/sbin/resolvconf *\n"
  },
  {
    "path": "rpmconf/Env/sudoers.d/02_zimbra-mta",
    "content": "%zimbra ALL=NOPASSWD:/opt/zimbra/common/sbin/postfix\n%zimbra ALL=NOPASSWD:/opt/zimbra/common/sbin/postalias\n%zimbra ALL=NOPASSWD:/opt/zimbra/common/sbin/qshape.pl\n%zimbra ALL=NOPASSWD:/opt/zimbra/common/sbin/postconf\n%zimbra ALL=NOPASSWD:/opt/zimbra/common/sbin/postsuper\n%zimbra ALL=NOPASSWD:/opt/zimbra/common/sbin/postcat\n%zimbra ALL=NOPASSWD:/opt/zimbra/libexec/zmqstat\n%zimbra ALL=NOPASSWD:/opt/zimbra/libexec/zmmtastatus\n%zimbra ALL=NOPASSWD:/opt/zimbra/common/sbin/amavis-mc\n"
  },
  {
    "path": "rpmconf/Env/sudoers.d/02_zimbra-store",
    "content": "%zimbra ALL=NOPASSWD:/opt/zimbra/libexec/zmmailboxdmgr\n"
  },
  {
    "path": "rpmconf/Env/zimbra.bash_profile",
    "content": "# .bash_profile\numask 0027\n\n# Get the aliases and functions\nif [ -f ~/.bashrc ]; then\n        . ~/.bashrc\nfi\n\n# User specific environment and startup programs\n\n# this breaks unicode_start on vt consoles\n#BASH_ENV=$HOME/.bashrc\n#export BASH_ENV\n\nUSERNAME=\"zimbra\"\nexport USERNAME\n\nexport LANG=C\nexport LC_ALL=C\nunset CLASSPATH\nunset DYLD_LIBRARY_PATH\n"
  },
  {
    "path": "rpmconf/Env/zimbra.bashrc",
    "content": "# .bashrc\n\n# User specific aliases and functions\n\nalias rm='rm -i'\nalias cp='cp -i'\nalias mv='mv -i'\nalias h='history 40'\nalias j='jobs'\n\n# Source global definitions\nif [ -f /etc/bashrc ]; then\n\t. /etc/bashrc\nfi\n\nJAVA_HOME=/opt/zimbra/common/lib/jvm/java\nexport JAVA_HOME\n\nPATH=/opt/zimbra/bin:${JAVA_HOME}/bin:/opt/zimbra/common/bin:/opt/zimbra/common/sbin:/usr/sbin:${PATH}\nexport PATH\n\nunset LD_LIBRARY_PATH\n\nSNMPCONFPATH=/opt/zimbra/conf\nexport SNMPCONFPATH\n\neval `/usr/bin/perl -V:archname`\nPERLLIB=/opt/zimbra/common/lib/perl5/$archname:/opt/zimbra/common/lib/perl5\nexport PERLLIB\n\nPERL5LIB=$PERLLIB\nexport PERL5LIB\n\nJYTHONPATH=/opt/zimbra/common/lib/jylibs\nexport JYTHONPATH\n\nulimit -n 524288 > /dev/null 2>&1\numask 0027\n\nunset DISPLAY\n\nexport MANPATH=/opt/zimbra/common/share/man:${MANPATH}\n\nexport HISTTIMEFORMAT=\"%y%m%d %T \"\n\ncheck_license_expiry() {\n    local output json timestamp timestamp_no_z formatted_timestamp timestamp_epoch current_epoch remaining_days\n    local zm_license_cache=\"/opt/zimbra/log/.zm_license_cache\"\n    local cache_dir\n    cache_dir=\"$(dirname \"$zm_license_cache\")\"\n\n    if [ -f \"$zm_license_cache\" ] && [ \"$(date +%Y-%m-%d -r \"$zm_license_cache\")\" == \"$(date +%Y-%m-%d)\" ]; then\n        output=$(cat \"$zm_license_cache\")\n\telse\n\t\toutput=$(zmprov gcf zimbraNetworkRealtimeActivation 2>/dev/null) || return 0\n\t\tif [ -d \"$cache_dir\" ]; then\n\t\t\ttmp_cache=\"$zm_license_cache.$$\"\n\t\t\techo \"$output\" > \"$tmp_cache\" && mv -f \"$tmp_cache\" \"$zm_license_cache\"\n\t\tfi\n    fi\n\n    [ -z \"$output\" ] && return 0\n\n    json=${output#zimbraNetworkRealtimeActivation: }\n    [ -z \"$json\" ] && return 0\n\n    install_type=$(echo \"$json\" | grep -oP '\"InstallType\":\"\\K[^\"]+' 2>/dev/null)\n    [ -z \"$install_type\" ] && return 0\n\n    if [[ \"$install_type\" == \"trial\" || \"$install_type\" == \"perpetual\" || \"$install_type\" == \"perpetualOfflineLicense\" ]]; then\n        return 0\n    fi\n\n    timestamp=$(echo \"$json\" | grep -oP '\"ValidUntilTimestamp\":\"\\K[^\"]+' 2>/dev/null)\n    [ -z \"$timestamp\" ] && return 0\n\n    timestamp_no_z=\"${timestamp%Z}\"\n    formatted_timestamp=$(echo \"$timestamp_no_z\" | sed -E 's/([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})/\\1-\\2-\\3 \\4:\\5:\\6/')\n\n    timestamp_epoch=$(date -d \"$formatted_timestamp\" +%s 2>/dev/null)\n    [ -z \"$timestamp_epoch\" ] && return 0\n\n    current_epoch=$(date +%s 2>/dev/null)\n\n    if [ \"$timestamp_epoch\" -lt \"$current_epoch\" ]; then\n        remaining_days=-1\n    else\n        remaining_days=$(( ((timestamp_epoch - current_epoch) / 86400) + 1 ))\n    fi\n\n    if [ \"$remaining_days\" -eq -1 ]; then\n        echo -e \"\\e[31mLicense expiration alert: Your license is expired.\\e[0m\"\n    elif [ \"$remaining_days\" -le 60 ]; then\n        echo -e \"\\e[31mLicense expiration alert: Your license will expire in $remaining_days days.\\e[0m\"\n    fi\n}\n\n# Only run this in interactive shells and if the zmlicense exists\nif [[ $- == *i* && -f /opt/zimbra/bin/zmlicense ]]; then\n    check_license_expiry\nfi\n"
  },
  {
    "path": "rpmconf/Env/zimbra.exrc",
    "content": "set tabstop=4\nset shiftwidth=4\nset ai\nset nohlsearch\nset exrc\n"
  },
  {
    "path": "rpmconf/Env/zimbra.ldaprc",
    "content": "TLS_CACERTDIR /opt/zimbra/conf/ca\nTLS_REQCERT never\n"
  },
  {
    "path": "rpmconf/Env/zimbra.platform",
    "content": "@@BUILD_PLATFORM@@\n"
  },
  {
    "path": "rpmconf/Env/zimbra.viminfo",
    "content": ""
  },
  {
    "path": "rpmconf/Install/Util/addUser.sh",
    "content": "#!/bin/bash\n# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2005, 2007, 2009, 2010, 2013, 2014, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n# \n\nverifyExists() {\n\tEXISTS=0\n\tNM=`/usr/bin/nifind /$1/$2`\n\tif [ \"x$NM\" != \"x\" ]; then\n\t\tEXISTS=1\n\tfi\n}\n\nverifyAvailable() {\n\tverifyExists $1 $2\n\tif [ $EXISTS = 1 ]; then\n\t\techo \"$1 $2 already exists!\"\n\t\texit 1\n\tfi\n}\n\ngetNextGID() {\n\tGID=`/usr/bin/nireport / /groups gid | sort -n | tail -1`\n\tGID=`expr $GID + 1`\n}\n\ngetGIDByName() {\n\tIDS=`/usr/bin/niutil -read / /groups/$1 | egrep '^gid:' | sed -e 's/gid: //'`\n\tif [ \"x$IDS\" != \"x\" ]; then\n\t\tGID=$IDS\n\tfi\n}\n\ngetNextUID() {\n\tNUID=`/usr/bin/nireport / /users uid | sort -n | tail -1`\n\tNUID=`expr $NUID + 1`\n}\n\nwhile [ $# != 0 ]; do\n\tcase \"$1\" in \n\t\t-d)\n\t\t\tshift\n\t\t\thomedir=$1\n\t\t;;\n\t\t-g)\n\t\t\tshift\n\t\t\tmaingroup=$1\n\t\t;;\n\t\t-G)\n\t\t\tshift\n\t\t\tauxgroups=$1\n\t\t;;\n\t\t*)\n\t\t\tname=$1\n\t\t;;\n\tesac\n\tshift\n\ndone\n\nif [ \"x$name\" = \"x\" ]; then\n\techo \"You must specify a user name!\"\n\texit 1\nfi\n\nif [ \"x$maingroup\" = \"x\" ]; then\n\tmaingroup=$name\nfi\n\nauxgroups=`echo $auxgroups | sed -e 's/,/ /g'`\n\nverifyAvailable \"users\" $name\n\nfor g in $auxgroups; do\n\tverifyExists groups $g\n\tif [ $EXISTS = 0 ]; then\n\t\techo \"Auxiliary group $g not found!\"\n\t\texit 1\n\telse\n\t\t/usr/bin/niutil -mergeprop / /groups/$g users $name\n\tfi\ndone\n\nverifyExists groups $maingroup\nif [ $EXISTS = 1 ]; then\n\tgetGIDByName $maingroup\n\tcreategroup=0\nelse\n\tgetNextGID\n\tcreategroup=1\nfi\nmaingid=$GID\ngetNextUID \nmainuid=$NUID\n\necho \"Creating $name with UID $mainuid, GID $maingid\"\nif [ $creategroup = 1 ]; then\n\t/usr/bin/niutil -create / /groups/$maingroup\n\t/usr/bin/niutil -createprop / /groups/$maingroup gid $maingid\nfi\n/usr/bin/niutil -mergeprop / /groups/$maingroup users $name\n\nniutil -create / /users/$name\nniutil -createprop / /users/$name realname $name\nniutil -createprop / /users/$name uid $mainuid\nniutil -createprop / /users/$name gid ${maingid}\nniutil -createprop / /users/$name shell /bin/bash\n\nif [ x$homedir != \"x\" ]; then\n\tniutil -createprop / /users/$name home $homedir\nfi\n\nexit 0\n"
  },
  {
    "path": "rpmconf/Install/Util/globals.sh",
    "content": "#!/bin/bash\n# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n# \n\nLOGFILE=`mktemp -t install.log.XXXXXXXX 2> /dev/null` || { echo \"Failed to create tmpfile\"; exit 1; }\nif [ -e \"/tmp/install.log\" ]; then\n\trm \"/tmp/install.log\"\nfi\nln -sf \"$LOGFILE\" \"/tmp/install.log\"\nPLATFORM=`bin/get_plat_tag.sh`\n\nCORE_PACKAGES=\"zimbra-core\"\n\nPACKAGES=\"zimbra-ldap \\\nzimbra-logger \\\nzimbra-mta \\\nzimbra-dnscache \\\nzimbra-snmp \\\nzimbra-license-daemon \\\nzimbra-store \\\nzimbra-apache \\\nzimbra-spell \\\nzimbra-convertd \\\nzimbra-memcached \\\nzimbra-proxy \\\nzimbra-archiving \\\nzimbra-onlyoffice\"\n\nSERVICES=\"\"\n\nOPTIONAL_PACKAGES=\"zimbra-qatest \\\nzimbra-license-tools \\\nzimbra-license-extension \\\nzimbra-network-store\"\n\nZEXTRAS_PACKAGES=\"zimbra-connect \\\nzimbra-connect-modern \\\nzimbra-drive \\\nzimbra-drive-ng \\\nzimbra-drive-modern \\\nzimbra-docs \\\nzimbra-docs-modern \\\nzimbra-chat \\\nzimbra-talk \\\nzimbra-zimlet-auth \\\nzimbra-zimlet-briefcase-edit-lool \\\nzimbra-network-modules-ng\"\n\nDEPRECATED_PACKAGES_IN_10=\"zimbra-zimlet-restore-contacts \\\nzimbra-zimlet-duplicate-contacts\"\n\nMYDIR=\"$(CDPATH= cd \"$(dirname \"$0\")\" && pwd)\"\nif [ \"$(cat ${MYDIR}/.BUILD_TYPE)\" == \"NETWORK\" ]; then\n   OPTIONAL_PACKAGES=\"${OPTIONAL_PACKAGES} zimbra-modern-ui zimbra-modern-zimlets zimbra-zimlet-document-editor zimbra-zimlet-classic-document-editor zimbra-zimlet-classic-set-default-client zimbra-patch zimbra-mta-patch zimbra-proxy-patch zimbra-ldap-patch zimbra-onlyoffice-patch zimbra-lds-patch\"\nfi\n\nPACKAGE_DIR=\"$(CDPATH= cd \"$(dirname \"$0\")\" && pwd)/packages\"\n\nSAVEDIR=\"/opt/zimbra/.saveconfig\"\n\nif [ x$RESTORECONFIG = \"x\" ]; then\n\tRESTORECONFIG=$SAVEDIR\nfi\n\n#\n# Initial values\n#\n\nAUTOINSTALL=\"no\"\nINSTALLED=\"no\"\nINSTALLED_PACKAGES=\"\"\nREMOVE=\"no\"\nUPGRADE=\"no\"\nHOSTNAME=`hostname --fqdn`\nZIMBRAINTERNAL=no\necho $HOSTNAME | egrep -qe 'eng.synacor.com$|eng.zimbra.com$|lab.zimbra.com$|zimbradev.com$' > /dev/null 2>&1\nif [ $? = 0 ]; then\n\tZIMBRAINTERNAL=yes\nfi\n\nLDAPHOST=\"\"\nLDAPPORT=389\nfq=`isFQDN $HOSTNAME`\n\nif [ $fq = 0 ]; then\n\tHOSTNAME=\"\"\nfi\n\nSERVICEIP=`hostname -i`\n\nSMTPHOST=$HOSTNAME\nSNMPTRAPHOST=$HOSTNAME\nSMTPSOURCE=\"none\"\nSMTPDEST=\"none\"\nSNMPNOTIFY=\"0\"\nSMTPNOTIFY=\"0\"\nINSTALL_PACKAGES=\"zimbra-core\"\nSTARTSERVERS=\"yes\"\nLDAPROOTPW=\"\"\nLDAPZIMBRAPW=\"\"\nLDAPPOSTPW=\"\"\nLDAPREPPW=\"\"\nLDAPAMAVISPW=\"\"\nLDAPNGINXPW=\"\"\nif [ x\"$ZIMBRAINTERNAL\" = \"xno\" ]; then\n  CREATEDOMAIN=$(hostname -d) # May be empty\n  CREATEDOMAIN=${CREATEDOMAIN:-$HOSTNAME} # only go with fqdn if domain is empty\nelse\n  CREATEDOMAIN=$HOSTNAME\nfi\n\nCREATEADMIN=\"admin@${CREATEDOMAIN}\"\nCREATEADMINPASS=\"\"\nMODE=\"http\"\nALLOWSELFSIGNED=\"yes\"\nRUNAV=\"\"\nRUNSA=\"\"\nAVUSER=\"\"\nAVDOMAIN=\"\"\n"
  },
  {
    "path": "rpmconf/Install/Util/modules/getconfig.sh",
    "content": "#!/bin/bash\n# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2005, 2007, 2010, 2013, 2014, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n# \n\ngetConfigOptions() {\n\techo \"\"\n\techo \"Configuration section\"\n\tif [ $STORE_HERE = \"yes\" -a $POSTFIX_HERE = \"no\" ]; then\n\t\taskNonBlank \"Please enter the hostname for zimbraSmtpHostname\" \\\n\t\t\t\"$SMTPHOST\"\n\t\tSMTPHOST=$response\n\tfi\n\tif [ $STORE_HERE = \"yes\" ]; then\n\t\twhile :; do\n\t\t\taskNonBlank \"Enter web server mode (http, https, mixed, redirect)\" \"$MODE\"\n\t\t\tMODE=$response\n\t\t\tif [ $MODE = \"http\" -o $MODE = \"https\" -o $MODE = \"mixed\" -o $MODE = \"redirect\" ]; then\n\t\t\t\tbreak\n\t\t\telse\n\t\t\t\techo \"Please enter a valid mode\"\n\t\t\tfi\n\t\tdone\n\t\tif [ $ALLOWSELFSIGNED = \"true\" -o $ALLOWSELFSIGNED = \"yes\" ]; then\n\t\t\tALLOWSELFSIGNED=\"yes\"\n\t\telse\n\t\t\tALLOWSELFSIGNED=\"no\"\n\t\tfi\n\t\t# Hardcoding for bootstrap install. 20050725 MEM\n\t\tALLOWSELFSIGNED=\"true\"\n\n\tfi\n\n\tif [ $LDAP_HERE = \"yes\" ]; then\n\t\tLDAPHOST=$HOSTNAME\n\t\tLDAPPORT=389\n\t\tif [ $UPGRADE = \"no\" ]; then\n\t\t\tsu - zimbra -c \"zmlocalconfig -e -r startup_ldap_password\"\n\t\t\tLDAPROOTPW=`su - zimbra -c \"zmlocalconfig -s -m nokey startup_ldap_password\"`\n\t\t\taskNonBlank \"Enter the root ldap password for $LDAPHOST:\" \\\n\t\t\t\t\"$LDAPROOTPW\"\n\t\t\tLDAPROOTPW=$response\n\t\t\tsu - zimbra -c \"zmlocalconfig -e startup_ldap_password=''\"\n\t\tfi\n\telse\n\t\twhile :; do\n\n\t\t\taskNonBlank \"Please enter the hostname for the ldap server\" \"$LDAPHOST\"\n\t\t\tLDAPHOST=$response\n\t\t\taskInt \"Please enter the port for the ldap server\" \"$LDAPPORT\"\n\t\t\tLDAPPORT=$response\n\n\t\t\tif [ $LDAP_HERE = \"no\" -a $UPGRADE = \"no\" ]; then\n\t\t\t\taskNonBlank \"Enter the root ldap password for $LDAPHOST:\" \\\n\t\t\t\t\t\"$LDAPROOTPW\"\n\t\t\t\tLDAPROOTPW=$response\n\t\t\t\taskNonBlank \"Enter the zimbra admin ldap password for $LDAPHOST:\" \\\n\t\t\t\tLDAPZIMBRAPW=$response\n\t\t\tfi\n\n\t\t\tverifyLdapServer\n\t\t\t\n\t\t\tif [ $LDAPOK = \"yes\" ]; then\n\t\t\t\tbreak\n\t\t\tfi\n\t\tdone\n\n\tfi\n\n\tif [ $UPGRADE = \"no\" ]; then\n\n\t\tif [ $POSTFIX_HERE = \"yes\" ]; then\n\t\t\taskYN \"Enable Clam Anti-virus services?\" \"$RUNAV\"\n\t\t\tRUNAV=$response\n\t\t\tif [ $RUNAV = \"yes\" ]; then\n\t\t\t\tif [ \"x$AVUSER\" = \"x\" ]; then\n\t\t\t\t\tAVUSER=\"notify@${HOSTNAME}\"\n\t\t\t\tfi\n\t\t\t\taskNonBlank \"Notification address for AV alerts?\" \"$AVUSER\"\n\t\t\t\tAVUSER=$response\n\t\t\t\tAVDOMAIN=`echo $AVUSER | awk -F@ '{print $2}'`\n\t\t\tfi\n\t\t\taskYN \"Enable SpamAssassin anti-spam services?\" \"$RUNSA\"\n\t\t\tRUNSA=$response\n\t\tfi\n\n\t\tif [ $SNMP_HERE = \"yes\" ]; then\n\t\t\taskYN \"Notify via SNMP?\" \"$SNMPNOTIFY\"\n\t\t\tSNMPNOTIFY=$response\n\t\t\tif [ $SNMPNOTIFY = \"yes\" ]; then\n\t\t\t\taskNonBlank \"SNMP Trap host?\" \"$SNMPTRAPHOST\"\n\t\t\t\tSNMPTRAPHOST=$response\n\t\t\t\tSNMPNOTIFY=1\n\t\t\telse\n\t\t\t\tSNMPNOTIFY=0\n\t\t\tfi\n\t\t\taskYN \"Notify via SMTP?\" \"$SMTPNOTIFY\"\n\t\t\tSMTPNOTIFY=$response\n\t\t\tif [ $SMTPNOTIFY = \"yes\" ]; then\n\t\t\t\taskNonBlank \"SMTP Source email address?\" \"$SMTPSOURCE\"\n\t\t\t\tSMTPSOURCE=$response\n\t\t\t\taskNonBlank \"SMTP Destination email address?\" \"$SMTPDEST\"\n\t\t\t\tSMTPDEST=$response\n\t\t\t\tSMTPNOTIFY=1\n\t\t\telse\n\t\t\t\tSMTPNOTIFY=0\n\t\t\tfi\n\t\tfi\n\n\t\taskYN \"Create a domain?\" \"Y\"\n\t\tif [ $response = \"yes\" ]; then\n\t\t\taskNonBlank \"Enter domain to create:\" \"$CREATEDOMAIN\"\n\t\t\tCREATEDOMAIN=$response\n\t\t\twhile :; do\n\t\t\t\taskYN \"Create an admin account?\" \"Y\"\n\t\t\t\tif [ $response = \"yes\" ]; then\n\t\t\t\t\tCREATEADMIN=\"admin@${CREATEDOMAIN}\"\n\t\t\t\t\taskNonBlank \"Enter admin account to create:\" \"$CREATEADMIN\"\n\t\t\t\t\tCREATEADMIN=$response\n\t\t\t\t\twhile :; do\n\t\t\t\t\t\taskNonBlankNoEcho \"Enter admin password (min 6 chars):\" \"\"\n\t\t\t\t\t\tlen=`echo $response | wc -m`\n\t\t\t\t\t\t# Not sure why, but wc -m reports one too many\n\t\t\t\t\t\tif [ $len -gt 6 ]; then\n\t\t\t\t\t\t\tCREATEADMINPASS=$response\n\t\t\t\t\t\t\taskNonBlankNoEcho \"Re-enter admin password (min 6 chars):\" \"\"\n\t\t\t\t\t\t\tif [ $CREATEADMINPASS = $response ]; then\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\techo \"Passwords do not match!\"\n\t\t\t\t\t\t\tfi\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\techo \"Please enter a password 6 characters or longer\"\n\t\t\t\t\t\tfi\n\t\t\t\t\tdone\n\t\t\t\t\tadmindomain=`echo $CREATEADMIN | awk -F@ '{print $2}'`\n\t\t\t\t\tif [ x$admindomain = x$CREATEDOMAIN ]; then\n\t\t\t\t\t\tbreak\n\t\t\t\t\telse\n\t\t\t\t\t\techo \"You must create an admin account under the domain $CREATEDOMAIN\"\n\t\t\t\t\tfi\n\t\t\t\telse\n\t\t\t\t\tbreak\n\t\t\t\tfi\n\t\t\tdone\n\t\telse\n\t\t\tCREATEDOMAIN=\"\"\n\t\t\tCREATEADMIN=\"\"\n\t\t\tCREATEADMINPASS=\"\"\n\t\tfi\n\tfi\n\n}\n"
  },
  {
    "path": "rpmconf/Install/Util/modules/packages.sh",
    "content": "#!/bin/bash\n#\n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n#\n\ninstallPackages() {\n   echo\n   echo \"Beginning Installation - see $LOGFILE for details...\"\n   echo\n\n   pretty_display() {\n      local banner=$1; shift;\n      local pk=(\"$@\");\n      echo\n      echo \"$banner (${#pk[*]}):\" | tee -a $LOGFILE\n      local p;\n      for p in \"${pk[@]}\"\n      do\n         echo \"   $(basename $p)\" | tee -a $LOGFILE\n      done\n      echo -n \"      ...\";\n      echo >> $LOGFILE\n   }\n\n   gather_package_info()\n   {\n      local pkg=$1; shift;\n\n      if [ -z \"${gather_visit_flag[$pkg]}\" ]\n      then\n         echo \"gathering packgage info for: $pkg\" >> $LOGFILE\n\n         locatePackage $pkg\n\n         gather_visit_flag[$pkg]=1\n\n         if [ \"${global_pkg_loc[$pkg]}\" == \"local\" ]\n         then\n            local deps=( $(LocalPackageDepList \"${global_pkg_file[$pkg]}\") )\n            local dep\n            for dep in \"${deps[@]}\"\n            do\n               echo \"descending into dependency: $pkg (local) --deps-> $dep\" >> $LOGFILE\n               gather_package_info \"$dep\"\n            done\n\n            printf \"%48s %s\\n\" \"$pkg\" \"will be installed.\"\n\n            local_pkg_names+=( \"$pkg\" )\n            local_pkg_files+=( \"${global_pkg_file[$pkg]}\" )\n\n         elif [ \"${global_pkg_loc[$pkg]}\" == \"repo\" ]\n         then\n            local delay=0\n\n            if ! [[ \"$pkg\" =~ ^zimbra-.*-components$ ]]\n            then\n               local dep\n               for dep in $(RepoPackageDepList \"$pkg\")\n               do\n                  echo \"locating dependency: $pkg (remote) --deps-> $dep\" >> $LOGFILE\n                  locatePackage \"$dep\"\n                  if [ \"${global_pkg_loc[$dep]}\" == \"local\" ]\n                  then\n                     delay=1\n                  fi\n               done\n            fi\n\n            if [ \"$delay\" == \"1\" ]\n            then\n               printf \"%48s %s\\n\" \"$pkg\" \"will be downloaded and installed (later).\"\n               repo_pkg_names_delayed+=( \"$pkg\" )\n            else\n               printf \"%48s %s\\n\" \"$pkg\" \"will be downloaded and installed.\"\n               repo_pkg_names+=( \"$pkg\" )\n            fi\n\n         else\n            printf \"%48s %s\\n\" \"$pkg\" \"is missing.                                    ERROR\";\n            (( ++gather_dep_errors ))\n         fi\n\n         gather_visit_flag[$pkg]=2\n      fi\n   }\n\n   local -A gather_visit_flag=()\n   local gather_dep_errors=0\n   local repo_pkg_names_delayed=()\n   local repo_pkg_names=()\n   local local_pkg_names=()\n   local local_pkg_files=()\n\n   local PKG;\n   for PKG in $INSTALL_PACKAGES\n   do\n      gather_package_info $PKG;\n   done\n\n   if [ \"$gather_dep_errors\" -gt 0 ]\n   then\n      echo\n      echo \"Unable to find missing packages in repository. System is not modified.\"\n      exit 1\n   fi\n\n   if [ \"${#repo_pkg_names[@]}\" -gt 0 ]\n   then\n      # Download packages.\n      pretty_display \"Downloading packages\" \"${repo_pkg_names[@]}\";\n      $PACKAGEDOWNLOAD \"${repo_pkg_names[@]}\" >> $LOGFILE 2>&1\n      if [ $? -ne 0 ]; then\n         echo \"Unable to download packages from repository. System is not modified.\"\n         exit 1\n      fi\n      echo \"done\"\n   fi\n\n   if [ $UPGRADE = \"yes\" ]; then\n      if [ \"${ZM_CUR_MAJOR}\" -lt 8 ] || [ \"${ZM_CUR_MAJOR}\" -eq 8 -a \"${ZM_CUR_MINOR}\" -lt 7 ]; then\n         POST87UPGRADE=\"false\"\n      else\n         POST87UPGRADE=\"true\"\n      fi\n      if [ \"$FORCE_UPGRADE\" = \"yes\" -o \"$POST87UPGRADE\" = \"false\" ]; then\n         findUbuntuExternalPackageDependencies\n      fi\n      saveExistingConfig\n   fi\n\n   removeExistingInstall\n   installEPELRepo\n\n   if [ \"${#repo_pkg_names[@]}\" -gt 0 ]\n   then\n      pretty_display \"Installing repo packages\" \"${repo_pkg_names[@]}\";\n      $REPOINST \"${repo_pkg_names[@]}\" >>$LOGFILE 2>&1\n      if [ $? != 0 ]; then\n         pkgError\n      fi\n      echo \"done\"\n   fi\n\n   if [ \"${#local_pkg_files[@]}\" -gt 0 ]\n   then\n      pretty_display \"Installing local packages\" \"${local_pkg_names[@]}\";\n      $PACKAGEINST \"${local_pkg_files[@]}\" >> $LOGFILE 2>&1\n      if [ $? != 0 ]; then\n         pkgError\n      fi\n      echo \"done\"\n   fi\n\n   if [ \"${#repo_pkg_names_delayed[@]}\" -gt 0 ]\n   then\n      pretty_display \"Installing extra packages\" \"${repo_pkg_names_delayed[@]}\";\n      $REPOINST \"${repo_pkg_names_delayed[@]}\" >>$LOGFILE 2>&1\n      if [ $? != 0 ]; then\n         echo \"Unable to download extra packages from repository. Proceeding without this...\"\n         # not exiting on error\n      else\n         echo \"done\"\n      fi\n   fi\n\n   if [ $UPGRADE = \"yes\" ]; then\n      ST=\"UPGRADED\"\n   else\n      ST=\"INSTALLED\"\n   fi\n\n   D=`date +%s`\n   if [ \"$ISUBUNTU\" = \"true\" ] && [ ! -z \"$EXTPACKAGES\" ]; then\n      echo -n \"Re-installing $EXTPACKAGES ...\"\n      $REPOINST $EXTPACKAGES >> $LOGFILE 2>&1\n      if [ $? -ne 0 ]; then\n         echo \"Failed to install package[s] $EXTPACKAGES.\"\n         # not exiting on error\n      fi\n      echo \"done\"\n   fi\n\n   local pkg_n\n   for pkg_n in \"${local_pkg_names[@]}\" \"${repo_pkg_names[@]}\" \"${repo_pkg_names_delayed[@]}\"\n   do\n      echo \"${D}: $ST $(DumpFileDetailsFromPackage \"$pkg_n\")\" >> /opt/zimbra/.install_history\n   done\n\n   echo\n   echo \"Running Post Installation Configuration:\"\n}\n\npkgError() {\n   echo \"\"\n   echo \"ERROR: Unable to install required packages\"\n   if [ $UPGRADE = \"yes\" ]; then\n      echo \"WARNING: REMOTE PACKAGE INSTALLATION FAILED.\"\n      echo \"To proceed, review the instructions at:\"\n      echo \"https://wiki.zimbra.com/wiki/Recovering_from_upgrade_failure\"\n      echo \"Failure to follow the instructions on the wiki will result in complete data loss.\"\n   else\n      echo \"Fix the issues with remote package installation and rerun the installer\"\n   fi\n   exit 1\n}\n\ndeclare -A global_pkg_loc\ndeclare -A global_pkg_file\n\nlocatePackage() {\n   local package=\"$1\"; shift;\n\n   if [ -z \"${global_pkg_loc[$package]}\" ]\n   then\n      local check_file=\"$(echo \"$PACKAGE_DIR/$package\"[-_][0-9]*.\"$PACKAGEEXT\")\"\n      if [ -f \"$check_file\" ]\n      then\n         global_pkg_loc[$package]=\"local\"\n         global_pkg_file[$package]=$check_file\n      else\n         if grep -q -w -e \"^$package\" <(LocatePackageInRepo \"$package\")\n         then\n            global_pkg_loc[$package]=\"repo\"\n            global_pkg_file[$package]=\"\"\n         else\n            global_pkg_loc[$package]=\"unknown\"\n            global_pkg_file[$package]=\"\"\n         fi\n      fi\n   fi\n}\n\ncheckPackages() {\n   echo \"\"\n   echo \"Checking for installable packages\"\n   echo \"\"\n\n   AVAILABLE_PACKAGES=\"\"\n\n   local package\n   for package in $CORE_PACKAGES $PACKAGES $OPTIONAL_PACKAGES;\n   do\n      locatePackage $package\n      if [ \"${global_pkg_loc[$package]}\" == \"local\" ]\n      then\n         local file=${global_pkg_file[$package]}\n         if grep -q i386 <(echo $file)\n         then\n            PROC=\"i386\"\n         else\n            PROC=\"x86_64\"\n         fi\n\n         if [[ $PLATFORM == \"DEBIAN\"* || $PLATFORM == \"UBUNTU\"* ]]; then\n            LOCALPROC=`dpkg --print-architecture`\n            if [ x\"$LOCALPROC\" == \"xamd64\" ]; then\n               LOCALPROC=\"x86_64\"\n            fi\n         else\n            LOCALPROC=`uname -i`\n         fi\n\n         if [ x$LOCALPROC != x$PROC ]; then\n            echo \"Error: attempting to install $PROC packages on a $LOCALPROC OS.\"\n            echo \"Exiting...\"\n            echo \"\"\n            exit 1\n         fi\n\n         file_check=\"unverified\"\n         if [ x\"$PACKAGEVERIFY\" != \"x\" ]; then\n            if $PACKAGEVERIFY $file > /dev/null 2>&1\n            then\n               file_check=\"verified\";\n            else\n               echo \"Found $package locally, but package is not installable. (possibly corrupt)\"\n               echo \"Unable to continue. Please correct package corruption and rerun the installation.\"\n               exit 1\n            fi\n         fi\n\n         if ! grep -q -w -e \"$package\" <(echo \"$CORE_PACKAGES\")\n         then\n            AVAILABLE_PACKAGES=\"$AVAILABLE_PACKAGES $package\"\n         fi\n\n         printf \"%s\\n\" \"Found $package (local)\"\n\n      elif [ \"${global_pkg_loc[$package]}\" == \"repo\" ]\n      then\n         if ! grep -q -w -e \"$package\" <(echo \"$CORE_PACKAGES\")\n         then\n            AVAILABLE_PACKAGES=\"$AVAILABLE_PACKAGES $package\"\n         fi\n\n         printf \"%s\\n\" \"Found $package (repo)\"\n      else\n         if grep -q -w -e \"$package\" <(echo \"$CORE_PACKAGES\")\n         then\n            echo \"ERROR: Required Core package $package not found in $PACKAGE_DIR\"\n            echo \"Exiting\"\n            exit 1\n         fi\n      fi\n   done\n   echo \"\"\n}\n"
  },
  {
    "path": "rpmconf/Install/Util/modules/postinstall.sh",
    "content": "#!/bin/bash\n# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2005, 2007, 2008, 2009, 2010, 2012, 2013, 2014, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n# \n\npostInstallConfig() {\n\techo \"\"\n\techo \"Post installation configuration\"\n\techo \"\"\n\n\tchmod 755 /opt/zimbra\n\n\tif [ $UPGRADE = \"yes\" ]; then\n\t\t#restore old config, then overwrite...\n\t\trestoreExistingConfig\n\tfi\n\n\tif [ $UPGRADE = \"no\" -a $STORE_HERE = \"yes\" ]; then\n\t\techo -n \"Creating db...\"\n\t\trunAsZimbra \"/opt/zimbra/libexec/zmmyinit\"\n\t\techo \"done\"\n\tfi\n\n\tif [ $LOGGER_HERE = \"yes\" ]; then\n\t\tif [ ! -d \"/opt/zimbra/logger/db/data\" ]; then\n\t\t\techo -n \"Creating logger db...\"\n\t\t\trunAsZimbra \"/opt/zimbra/libexec/zmloggerinit\"\n\t\t\techo \"done\"\n\t\tfi\n\tfi\n\n\techo -n \"Setting the hostname to $HOSTNAME...\"\n\trunAsZimbra \"zmlocalconfig -e zimbra_server_hostname=${HOSTNAME}\"\n\techo \"done\"\n\n\techo -n \"Setting the LDAP host to $LDAPHOST...\"\n\trunAsZimbra \"zmlocalconfig -e ldap_host=$LDAPHOST\"\n\trunAsZimbra \"zmlocalconfig -e ldap_port=$LDAPPORT\"\n\techo \"done\"\n\n\tSERVERCREATED=\"no\"\n\tif [ $UPGRADE = \"no\" ]; then\n\t\tif [ $LDAP_HERE = \"yes\" ]; then\n\t\t\techo -n \"Initializing ldap...\"\n\t\t\trunAsZimbra \"/opt/zimbra/libexec/zmldapinit $LDAPROOTPW $LDAPZIMBRAPW\"\n\t\t\techo \"done\"\n\t\telse\n\t\t\t# set the ldap password in localconfig only\n\t\t\techo -n \"Setting the ldap passwords...\"\n\t\t\trunAsZimbra \"zmlocalconfig -f -e ldap_root_password=$LDAPROOTPW\"\n\t\t\trunAsZimbra \"zmlocalconfig -f -e zimbra_ldap_password=$LDAPZIMBRAPW\"\n\t\t\trunAsZimbra \"zmlocalconfig -f -e ldap_postfix_password=$LDAPPOSTPW\"\n\t\t\trunAsZimbra \"zmlocalconfig -f -e ldap_replication_password=$LDAPREPPW\"\n\t\t\trunAsZimbra \"zmlocalconfig -f -e ldap_amavis_password=$LDAPAMAVISPW\"\n\t\t\trunAsZimbra \"zmlocalconfig -f -e ldap_nginx_password=$LDAPNGINXPW\"\n\t\t\techo \"done\"\n\t\tfi\n\n\t\techo -n \"Creating server $HOSTNAME...\"\n\t\trunAsZimbra \"zmprov cs $HOSTNAME\"\n\t\tif [ $? = 0 ]; then\n\t\t\tSERVERCREATED=\"yes\"\n\t\tfi\n\t\techo \"done\"\n\n\t\tif [ x$CREATEDOMAIN != \"x\" ]; then\n\t\t\techo -n \"Creating domain $CREATEDOMAIN...\"\n\t\t\trunAsZimbra \"zmprov cd $CREATEDOMAIN\"\n\t\t\trunAsZimbra \"zmprov mcf zimbraDefaultDomainName $CREATEDOMAIN\"\n\t\t\techo \"done\"\n\t\t\tif [ x$CREATEADMIN != \"x\" ]; then\n\t\t\t\techo -n \"Creating admin account $CREATEADMIN...\"\n\t\t\t\trunAsZimbra \"zmprov ca $CREATEADMIN $CREATEADMINPASS zimbraIsAdminAccount TRUE\"\n\t\t\t\tLOCALHOSTNAME=`hostname --fqdn`\n\t\t\t\tif [ $LOCALHOSTNAME = $CREATEDOMAIN ]; then\n\t\t\t\t\trunAsZimbra \"zmprov aaa $CREATEADMIN postmaster@$HOSTNAME\"\n\t\t\t\tfi\n\t\t\t\techo \"done\"\n\t\t\tfi\n\t\tfi\n\telse\n\t\tif [ $LDAP_HERE = \"yes\" ]; then\n\t\t\techo -n \"Starting ldap...\"\n\t\t\trunAsZimbra \"ldap start\"\n\t\t\trunAsZimbra \"zmldapapplyldif\"\n\t\t\techo \"done\"\n\t\tfi\n\tfi\n\n\tif [ $LDAP_HERE = \"yes\" ]; then\n\t\tSERVICES=\"zimbraServiceInstalled ldap\"\n\tfi\n\n\tif [ $LOGGER_HERE = \"yes\" ]; then\n\t\tSERVICES=\"$SERVICES zimbraServiceInstalled logger\"\n\t\trunAsZimbra \"zmprov mcf zimbraLogHostname $HOSTNAME\"\n\tfi\n\n\tif [ $STORE_HERE = \"yes\" ]; then\n\t\tif [ $SERVERCREATED = \"yes\" ]; then\n\t\t\techo -n \"Setting smtp host to $SMTPHOST...\"\n\t\t\trunAsZimbra \"zmprov ms $HOSTNAME zimbraSmtpHostname $SMTPHOST\"\n\t\t\techo \"done\"\n\t\tfi\n\n\t\techo -n \"Adding $HOSTNAME to zimbraMailHostPool in default COS...\"\n\t\trunAsZimbra \"id=\\`zmprov gs $HOSTNAME | grep zimbraId | awk '{print \\$2}'\\`; for i in \\`zmprov gc default | grep zimbraMailHostPool | sed 's/zimbraMailHostPool: //'\\`; do host=\\\"\\$host zimbraMailHostPool \\$i\\\"; done; zmprov mc default \\$host zimbraMailHostPool \\$id\"\n\t\techo \"done\"\n\n\t\tSERVICES=\"$SERVICES zimbraServiceInstalled mailbox\"\n\tfi\n\n\tif [ $POSTFIX_HERE = \"yes\" ]; then\n\t\techo -n \"Initializing mta config...\"\n\t\trunAsZimbra \"/opt/zimbra/libexec/zmmtainit $LDAPHOST\"\n\t\techo \"done\"\n\n\t\t# zmprov isn't very friendly\n\n\t\tSERVICES=\"$SERVICES zimbraServiceInstalled mta\"\n\n\t\tif [ $RUNAV = \"yes\" ]; then\n\t\t\tSERVICES=\"$SERVICES zimbraServiceInstalled antivirus\"\n\t\t\trunAsZimbra \"zmlocalconfig -e av_notify_user=$AVUSER\"\n\t\t\trunAsZimbra \"zmlocalconfig -e av_notify_domain=$AVDOMAIN\"\n\t\tfi\n\t\tif [ $RUNSA = \"yes\" ]; then\n\t\t\tSERVICES=\"$SERVICES zimbraServiceInstalled antispam\"\n\t\tfi\n\tfi\n\n\tif [ $SNMP_HERE = \"yes\" ]; then\n\t\techo -n \"Configuring SNMP...\"\n\t\trunAsZimbra \"zmlocalconfig -e snmp_notify=$SNMPNOTIFY\"\n\t\trunAsZimbra \"zmlocalconfig -e smtp_notify=$SMTPNOTIFY\"\n\t\trunAsZimbra \\\n\t\t\t\"zmlocalconfig -e snmp_trap_host=$SNMPTRAPHOST\"\n\t\trunAsZimbra \"zmlocalconfig -e smtp_source=$SMTPSOURCE\"\n\t\trunAsZimbra \\\n\t\t\t\"zmlocalconfig -e smtp_destination=$SMTPDEST\"\n\t\trunAsZimbra \"zmsnmpinit\"\n\t\techo \"done\"\n\t\tSERVICES=\"$SERVICES zimbraServiceInstalled snmp\"\n\tfi\n\n\techo -n \"Setting services on $HOSTNAME...\"\n\trunAsZimbra \"zmprov -r ms $HOSTNAME $SERVICES\"\n\n\tENABLEDSERVICES=`echo $SERVICES | sed -e 's/zimbraServiceInstalled/zimbraServiceEnabled/g'`\n\trunAsZimbra \"zmprov -r ms $HOSTNAME $ENABLEDSERVICES\"\n\n\tLOCALSERVICES=`echo $SERVICES | sed -e 's/zimbraServiceInstalled //g'`\n\trunAsZimbra \"zmlocalconfig -e zimbra_services=\\\"$LOCALSERVICES\\\"\"\n\techo \"done\"\n\n\tif [ $STORE_HERE = \"yes\" -o $POSTFIX_HERE = \"yes\" ]; then\n\t\techo -n \"Setting up SSL...\"\n\t\trunAsZimbra \"zmcreatecert\"\n\t\tif [ $STORE_HERE = \"yes\" ]; then\n\t\t\trunAsZimbra \"zmcertinstall mailbox\"\n\t\t\trunAsZimbra \"zmtlsctl $MODE\"\n\t\tfi\n\t\tif [ $POSTFIX_HERE = \"yes\" ]; then\n\t\t\trunAsZimbra \"zmcertinstall mta /opt/zimbra/ssl/ssl/server/smtpd.crt /opt/zimbra/ssl/ssl/ca/ca.key\"\n\t\tfi\n\n\t\trunAsZimbra \"zmlocalconfig -e ssl_allow_untrusted_certs=$ALLOWSELFSIGNED\"\n\t\techo \"done\"\n\t\tif [ $UPGRADE = \"yes\" ]; then\n\t\t\trestoreCerts\n\t\tfi\n\tfi\n\n\tsetupCrontab\n}\n"
  },
  {
    "path": "rpmconf/Install/Util/utilfunc.sh",
    "content": "#!/bin/bash\n#\n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n#\n\ndisplayLicense() {\n  echo \"\"\n  echo \"\"\n  if [ -f ${MYDIR}/docs/zcl.txt ]; then\n    cat $MYDIR/docs/zcl.txt\n  elif [ -f ${MYDIR}/docs/zimbra_network_eula.txt ]; then\n    cat ${MYDIR}/docs/zimbra_network_eula.txt\n  fi\n  echo \"\"\n  echo \"\"\n  if [ x$DEFAULTFILE = \"x\" ]; then\n    askYN \"Do you agree with the terms of the software license agreement?\" \"N\"\n    if [ $response != \"yes\" ]; then\n      exit\n    fi\n  fi\n  echo \"\"\n}\n\nisFQDN() {\n  #fqdn is > 2 dots.  because I said so.\n  if [ x\"$1\" = \"x\" ]; then\n    echo 0\n    return\n  fi\n\n  NF=`echo $1 | awk -F. '{print NF}'`\n  if [ $NF -ge 2 ]; then\n    echo 1\n  else\n    echo 0\n  fi\n}\n\nverifyIPv6() {\n    IP=$1\n    BAD_IP=`echo $IP | awk -F: '{ RES=0; SHORT=0; LSHORT=0; if (NF > 8) { RES=1 } else { for (BLK = 1; BLK <= NF; BLK++) { if ($BLK !~ /^[0-9a-fA-F]$|^[0-9a-fA-F][0-9a-fA-F]$|^[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]$|^[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]$/) { if ($BLK == \"\") { if (SHORT > 0) { if ((BLK - LSHORT) != 1) { RES = 1 } } SHORT++; LSHORT = BLK } else { RES = 1 } } } } if ((NF == 3) && ($2 != \"\")) { RES = 1 } if (((SHORT > 2) && (NF != 3)) || ((SHORT == 2) && (!(($2 == \"\") || ($(NF-1) == \"\"))))) { RES = 1 } if ((NF - SHORT) > 6 ) { RES = 1 } if ((SHORT == 0) && (NF < 8)) { RES = 1 } print RES }'`\n    return ${BAD_IP}\n}\n\nverifyMixedIPv6() {\n    IP=$1\n    BAD_IP=`echo $IP | awk -F: '{ RES=0; SHORT=0; LSHORT=0; if (NF > 8) { RES=1 } else { for (BLK = 1; BLK <= NF; BLK++) { if ($BLK !~ /^[0-9a-fA-F]$|^[0-9a-fA-F][0-9a-fA-F]$|^[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]$|^[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]$/) { if ($BLK == \"\") { if (SHORT > 0) { if ((BLK - LSHORT) != 1) { RES = 1 } } SHORT++; LSHORT = BLK } else { RES = 1 } } } } if ((NF == 3) && ($2 != \"\")) { RES = 1 } if (((SHORT > 2) && (NF != 3)) || ((SHORT == 2) && (!(($2 == \"\") || ($(NF-1) == \"\"))))) { RES = 1 } if ((NF - SHORT) > 6 ) { RES = 1 } if ((SHORT == 0) && (NF < 6)) { RES = 1 } print RES }'`\n    return ${BAD_IP}\n}\n\nverifyIPv4() {\n    IP=$1\n    BAD_IP=0;\n    if [ \"`echo $IP | sed -ne 's/[0-9]//gp'`\" != \"...\" ]\n    then\n        BAD_IP=1\n    else\n        BAD_IP=`echo $IP | awk -F. 'BEGIN {BAD_OCTET=0} { for (OCTET = 1; OCTET <= 4; OCTET++) { if (($OCTET !~ /^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/) || ((OCTET == 1) && ($OCTET == \"0\"))) { BAD_OCTET=1 } } } END { print BAD_OCTET }'`\n    fi\n    return ${BAD_IP}\n}\n\nsaveConfig() {\n  FILE=$1\n\ncat > $FILE <<EOF\nREMOVE=$REMOVE\nUPGRADE=$UPGRADE\nHOSTNAME=$HOSTNAME\nSERVICEIP=$SERVICEIP\nLDAPHOST=$LDAPHOST\nLDAPPORT=$LDAPPORT\nSMTPHOST=$SMTPHOST\nSNMPTRAPHOST=$SNMPTRAPHOST\nSMTPSOURCE=$SMTPSOURCE\nSMTPDEST=$SMTPDEST\nSNMPNOTIFY=$SNMPNOTIFY\nSMTPNOTIFY=$SMTPNOTIFY\nSTARTSERVERS=$STARTSERVERS\nLDAPROOTPW=$LDAPROOTPW\nLDAPZIMBRAPW=$LDAPZIMBRAPW\nLDAPPOSTPW=$LDAPPOSTPW\nLDAPREPPW=$LDAPREPPW\nLDAPAMAVISPW=$LDAPAMAVISPW\nLDAPNGINXPW=$LDAPNGINXPW\nCREATEDOMAIN=$CREATEDOMAIN\nCREATEADMIN=$CREATEADMIN\nCREATEADMINPASS=$CREATEADMINPASS\nMODE=$MODE\nALLOWSELFSIGNED=$ALLOWSELFSIGNED\nRUNAV=$RUNAV\nRUNSA=$RUNSA\nAVUSER=$AVUSER\nAVDOMAIN=$AVDOMAIN\nINSTALL_PACKAGES=\"$INSTALL_PACKAGES\"\nINSTALL_WEBAPPS=\"$INSTALL_WEBAPPS\"\nUSE_ZIMBRA_PACKAGE_SERVER=$USE_ZIMBRA_PACKAGE_SERVER\nPACKAGE_SERVER=$PACKAGE_SERVER\nEOF\n\n}\n\nloadConfig() {\n  FILE=\"$1\"\n\n  if [ ! -f \"$FILE\" ]; then\n    echo \"\"\n    echo \"*** ERROR - can't find configuration file $FILE\"\n    echo \"\"\n    exit 1\n  fi\n  perl -pi -e 's/\\r//' \"$FILE\"\n  echo \"\"\n  echo -n \"Loading configuration data from $FILE...\"\n  source \"$FILE\"\n  echo \"done\"\n}\n\n# All ask functions take 2 args:\n#  Prompt\n#  Default (optional)\n\nask() {\n  PROMPT=$1\n  DEFAULT=$2\n\n  echo \"\"\n  echo -n \"$PROMPT [$DEFAULT] \"\n  read response\n\n  if [ -z $response ]; then\n    response=$DEFAULT\n  fi\n}\n\naskNonBlankNoEcho() {\n  PROMPT=$1\n  DEFAULT=$2\n\n  while [ 1 ]; do\n    stty -echo\n    ask \"$PROMPT\" \"$DEFAULT\"\n    stty echo\n    echo \"\"\n    if [ ! -z $response ]; then\n      break\n    fi\n    echo \"A non-blank answer is required\"\n  done\n}\n\naskNonBlank() {\n  PROMPT=$1\n  DEFAULT=$2\n\n  while [ 1 ]; do\n    ask \"$PROMPT\" \"$DEFAULT\"\n    if [ ! -z $response ]; then\n      break\n    fi\n    echo \"A non-blank answer is required\"\n  done\n}\n\naskYN() {\n  PROMPT=$1\n  DEFAULT=$2\n\n  if [ \"x$DEFAULT\" = \"xyes\" -o \"x$DEFAULT\" = \"xYes\" -o \"x$DEFAULT\" = \"xy\" -o \"x$DEFAULT\" = \"xY\" ]; then\n    DEFAULT=\"Y\"\n  else\n    DEFAULT=\"N\"\n  fi\n\n  while [ 1 ]; do\n    ask \"$PROMPT\" \"$DEFAULT\"\n    response=$(perl -e \"print lc(\\\"$response\\\");\")\n    if [ -z $response ]; then\n      :\n    else\n      if [ $response = \"yes\" -o $response = \"y\" ]; then\n        response=\"yes\"\n        break\n      else\n        if [ $response = \"no\" -o $response = \"n\" ]; then\n          response=\"no\"\n          break\n        fi\n      fi\n    fi\n    echo \"A Yes/No answer is required\"\n  done\n}\n\naskInt() {\n  PROMPT=$1\n  DEFAULT=$2\n\n  while [ 1 ]; do\n    ask \"$PROMPT\" \"$DEFAULT\"\n    if [ -z $response ]; then\n      :\n    else\n      expr $response + 5 > /dev/null 2>&1\n      if [ $? = 0 ]; then\n        break\n      fi\n    fi\n    echo \"A numeric answer is required\"\n  done\n}\n\naskInstallPkgYN() {\n  PROMPT=\"$1\"\n  REQUIRE_STORE=\"$2\"\n  YES_STORE_DEFAULT=\"$3\"\n  NO_STORE_DEFAULT=\"$4\"\n  if [ \"$STORE_SELECTED\" = \"yes\" ]; then\n    askYN \"$PROMPT\" \"$YES_STORE_DEFAULT\"\n  else\n    if [ \"$REQUIRE_STORE\" = \"yes\" ]; then\n      askYN \"$PROMPT\" \"$NO_STORE_DEFAULT\"\n    fi\n  fi\n}\n\nifStoreSelectedY() {\n  if [ \"$STORE_SELECTED\" = \"yes\" ]; then\n    response=\"yes\"\n  fi\n}\n\ncheckUser() {\n  user=$1\n  if [ x`whoami` != x$user ]; then\n    echo Error: must be run as $user user\n    exit 1\n  fi\n}\n\ncheckMySQLConfig() {\n  isInstalled zimbra-store\n  if [ x$PKGINSTALLED != \"x\" ]; then\n    if [ -f \"/opt/zimbra/conf/my.cnf\" ]; then\n      BIND_ADDR=`awk '{ if ( $1 ~ /^bind-address$/ ) { print $3 } }' /opt/zimbra/conf/my.cnf`\n      while [ \"${BIND_ADDR}x\" != \"127.0.0.1x\" -a \"${BIND_ADDR}x\" != \"localhostx\" ]; do\n        echo \"The MySQL bind address is currently not set to \\\"localhost\\\" or \\\"127.0.0.1\\\".  Due to a\"\n        echo \"MySQL bug (#61713), the MySQL bind address must be set to \\\"127.0.0.1\\\".  Please correct\"\n        echo \"the bind-address entry in the \\\"/opt/zimbra/conf/my.cnf\\\" file to proceed with the upgrade.\"\n        askYN \"Retry validation? (Y/N)?\" \"Y\"\n        if [ $response = \"no\" ]; then\n          break\n        fi\n        BIND_ADDR=`awk '{ if ( $1 ~ /^bind-address$/ ) { print $3 } }' /opt/zimbra/conf/my.cnf`\n      done\n      if [ \"${BIND_ADDR}x\" != \"127.0.0.1x\" -a \"${BIND_ADDR}x\" != \"localhostx\" ]; then\n        echo \"\"\n        echo \"It is recommended that the bind-address setting in the /opt/zimbra/conf/my.cnf file be set\"\n        echo \"to \\\"127.0.0.1\\\".  The current setting of \\\"${BIND_ADDR}\\\" is not supported within\"\n        echo \"ZCS and may cause the installation to fail.\"\n        askYN \"Proceed with installation? (Y/N)?\" \"N\"\n        if [ $response != \"yes\" ]; then\n          echo \"\"\n          echo \"Aborting installation\"\n          echo \"\"\n          exit 1\n        fi\n      fi\n    fi\n  fi\n}\n\ncheckDatabaseIntegrity() {\n\n\tisInstalled zimbra-store\n\tif [ x$PKGINSTALLED != \"x\" ]; then\n\t\tif [ -x \"bin/zmdbintegrityreport\" -a -x \"/opt/zimbra/bin/mysqladmin\" ]; then\n\t\t\twhile :; do\n\t\t\t\tif [ x$DEFAULTFILE = \"x\" ]; then\n\t\t\t\t\taskYN \"Do you want to verify message store database integrity?\" \"Y\"\n\t\t\t\t\tif [ $response = \"no\" ]; then\n\t\t\t\t\t\tbreak\n\t\t\t\t\tfi\n\t\t\t\telif [ x$VERIFYMSGDB != \"xyes\" ]; then\n\t\t\t\t\tbreak\n\t\t\t\tfi\n\t\t\t\techo \"Verifying integrity of message store databases.  This may take a while.\"\n\t\t\t\tsu - zimbra -c \"/opt/zimbra/bin/mysqladmin -s ping\" 2>/dev/null\n\t\t\t\tif [ $? != 0 ]; then\n\t\t\t\t\tsu - zimbra -c \"/opt/zimbra/bin/mysql.server start\" 2> /dev/null\n\t\t\t\t\tfor ((i = 0; i < 60; i++)) do\n\t\t\t\t\t\tsu - zimbra -c \"/opt/zimbra/bin/mysqladmin -s ping\" 2>/dev/null\n\t\t\t\t\t\tif [ $? = 0 ]; then\n\t\t\t\t\t\t\tSQLSTARTED=1\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\tfi\n\t\t\t\t\t\tsleep 2\n\t\t\t\t\tdone\n\t\t\t\tfi\n\t\t\t\tMAILBOXDBINTEGRITYOUTPUT=$(perl bin/zmdbintegrityreport -v -r 2>&1)\n\t\t\t\tMAILBOXDBINTEGRITYSTATUS=$?\n\t\t\t\techo \"$MAILBOXDBINTEGRITYOUTPUT\"\n\t\t\t\tif [ x\"$SQLSTARTED\" != \"x\" ]; then\n\t\t\t\t\tsu - zimbra -c \"/opt/zimbra/bin/mysqladmin -s ping\" 2>/dev/null\n\t\t\t\t\tif [ $? = 0 ]; then\n\t\t\t\t\t\tsu - zimbra -c \"/opt/zimbra/bin/mysql.server stop\" 2> /dev/null\n\t\t\t\t\t\tfor ((i = 0; i < 60; i++)) do\n\t\t\t\t\t\t\tsu - zimbra -c \"/opt/zimbra/bin/mysqladmin -s ping\" 2>/dev/null\n\t\t\t\t\t\t\tif [ $? != 0 ]; then\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\tfi\n\t\t\t\t\t\t\tsleep 2\n\t\t\t\t\t\tdone\n\t\t\t\t\tfi\n\t\t\t\tfi\n\t\t\t\tif [ $MAILBOXDBINTEGRITYSTATUS != 0 ]; then\n\t\t\t\t\tif echo \"$MAILBOXDBINTEGRITYOUTPUT\" | grep -q \"Database errors found\" && echo \"$MAILBOXDBINTEGRITYOUTPUT\" | grep -q \"Orphan accounts detected\"; then\n\t\t\t\t\t\texit $MAILBOXDBINTEGRITYSTATUS\n\t\t\t\t\telif echo \"$MAILBOXDBINTEGRITYOUTPUT\" | grep -q \"Database errors found\"; then\n\t\t\t\t\t\texit $MAILBOXDBINTEGRITYSTATUS\n\t\t\t\t\telif echo \"$MAILBOXDBINTEGRITYOUTPUT\" | grep -q \"Orphan accounts detected\"; then\n\t\t\t\t\t\techo \"Orphan accounts detected. Continuing with the upgrade.\"\n\t\t\t\t\tfi\n\t\t\t\tfi\n\t\t\t\tbreak\n\t\t\tdone\n\t\tfi\n\tfi\n}\n\ncheckRecentBackup() {\n\n  isInstalled zimbra-store\n  if [ x$PKGINSTALLED != \"x\" ]; then\n    if [ -x \"bin/checkValidBackup\" ]; then\n      echo \"Checking for a recent backup\"\n      `bin/checkValidBackup > /dev/null 2>&1`\n      if [ $? != 0 ]; then\n        echo \"WARNING: Unable to find a full system backup started within the last\"\n        echo \"24hrs.  It is recommended to perform a full system backup and\"\n        echo \"copy it to a safe location prior to performing an upgrade.\"\n        echo \"\"\n        if [ x$DEFAULTFILE = \"x\" ]; then\n          while :; do\n            askYN \"Do you wish to continue without a backup?\" \"N\"\n            if [ $response = \"no\" ]; then\n              askYN \"Exit?\" \"N\"\n              if [ $response = \"yes\" ]; then\n                echo \"Exiting.\"\n                exit 1\n              fi\n            else\n              break\n            fi\n          done\n        else\n          echo \"Automated install detected...continuing.\"\n        fi\n      fi\n    fi\n  fi\n}\n\ncheckCAKeyLength() {\n\tisInstalled \"zimbra-ldap\"\n\tif [ x$PKGINSTALLED != \"x\" ]; then\n\t\topenssl_cmd=\"\"\n\t\tkeyfile=\"/opt/zimbra/conf/ca/ca.key\"\n\t\tif [[ -x \"/opt/zimbra/common/bin/openssl\" ]]; then\n\t\t\topenssl_cmd=\"/opt/zimbra/common/bin/openssl\"\n\t\telse\n\t\t\topenssl_cmd=$(which openssl 2>/dev/null)\n\t\tfi\n\t\tif [[ -f \"$keyfile\" && -x \"$openssl_cmd\" ]]; then\n\t\t\techo \"Checking the keysize of $keyfile ...\"\n\t\t\tkey_length=$(\"$openssl_cmd\" rsa -in \"$keyfile\" -noout -text 2>/dev/null | grep -oP 'Private-Key: \\(\\K\\d+' | head -1)\n\t\t\tif [[ -n \"$key_length\" && \"$key_length\" -lt 2048 ]]; then\n\t\t\t\t echo \"$keyfile has a key size of $key_length bits. The minimum key size is 2048. Please fix it to proceed with the upgrade.\"\n\t\t\t\t exit 1\n\t\t\tfi\n\t\tfi\n\tfi\n}\n\ncheckUbuntuRelease() {\n  if [ -f \"/etc/lsb-release\" ]; then\n    . /etc/lsb-release\n  fi\n\n  if [ x\"$DEFAULTFILE\" != \"x\" ]; then\n    echo \"Automated install detected...continuing.\"\n    return\n  fi\n\n  if [ \"x$DISTRIB_ID\" = \"xUbuntu\" -a \"x$DISTRIB_RELEASE\" != \"x12.04\" -a \"x$DISTRIB_RELEASE\" != \"x14.04\" -a \"x$DISTRIB_RELEASE\" != \"x16.04\" -a \"x$DISTRIB_RELEASE\" != \"x18.04\" -a \"x$DISTRIB_RELEASE\" != \"x20.04\" -a \"x$DISTRIB_RELEASE\" != \"x22.04\" -a \"x$DISTRIB_RELEASE\" != \"x24.04\" ]; then\n    echo \"WARNING: ZCS is currently only supported on Ubuntu Server 12.04, 14.04, 16.04, 18.04, 20.04, 22.04 and 24.04 LTS.\"\n    echo \"You are attempting to install on $DISTRIB_DESCRIPTION which may not work.\"\n    echo \"Support will not be provided if you choose to continue.\"\n    echo \"\"\n    while :; do\n      askYN \"Do you wish to continue?\" \"N\"\n      if [ $response = \"no\" ]; then\n        askYN \"Exit?\" \"N\"\n        if [ $response = \"yes\" ]; then\n          echo \"Exiting.\"\n          exit 1\n        fi\n      else\n        break\n      fi\n    done\n  fi\n}\n\ncheckVersionDowngrade() {\n\n  if [ x\"${ZM_CUR_MAJOR}\" = \"x\" -o x\"${ZM_CUR_MINOR}\" = \"x\" -o x\"${ZM_CUR_MICRO}\" = \"x\" ]; then\n    return\n  fi\n\n  if [ x\"${ZM_INST_MAJOR}\" = \"x\" -o x\"${ZM_INST_MINOR}\" = \"x\" -o x\"${ZM_INST_MICRO}\" = \"x\" ]; then\n    return\n  fi\n\n  if [ ${ZM_CUR_MAJOR} -lt 7 ]; then\n\techo \"ERROR: You can only upgrade from ZCS 7.0 or later\"\n\texit 1\n  fi\n\n  ZM_CUR_VERSION=\"${ZM_CUR_MAJOR}.${ZM_CUR_MINOR}.${ZM_CUR_MICRO}\"\n  ZM_INST_VERSION=\"${ZM_INST_MAJOR}.${ZM_INST_MINOR}.${ZM_INST_MICRO}\"\n\n  DOWNGRADE=0\n  if [ ${ZM_CUR_MAJOR} -gt ${ZM_INST_MAJOR} ]; then\n    #echo \"$ZM_CUR_VERSION is newer then $ZM_INST_VERSION MAJOR\"\n    DOWNGRADE=1\n  elif [ ${ZM_CUR_MAJOR} -eq ${ZM_INST_MAJOR} ]; then\n    if [ ${ZM_CUR_MINOR} -gt ${ZM_INST_MINOR} ]; then\n      #echo \"$ZM_CUR_VERSION is newer then $ZM_INST_VERSION MINOR\"\n      DOWNGRADE=1\n    elif [ ${ZM_CUR_MINOR} -eq ${ZM_INST_MINOR} ]; then\n      if [ ${ZM_CUR_MICRO} -gt ${ZM_INST_MICRO} ]; then\n        #echo \"$ZM_CUR_VERSION is newer then $ZM_INST_VERSION MICRO\"\n        DOWNGRADE=1\n      fi\n    fi\n  fi\n\n  if [ $DOWNGRADE = 1 ]; then\n    echo \"Downgrading to version $ZM_INST_VERSION from $ZM_CUR_VERSION is not supported.\"\n    exit 1\n  else\n    echo \"ZCS upgrade from $ZM_CUR_VERSION to $ZM_INST_VERSION will be performed.\"\n  fi\n\n}\n\ncheckRequired() {\n\n  if [ -x \"/usr/bin/getent\" ]; then\n    if ! /usr/bin/getent hosts 127.0.0.1 | perl -ne 'if (! m|^\\d+\\.\\d+\\.\\d+\\.\\d+\\s+localhost\\s*| && ! m|^\\d+\\.\\d+\\.\\d+\\.\\d+\\s+localhost\\.localdomain\\s*|) { exit 11;}'; then\n      cat<<EOF\n\n  ERROR: Installation can not proceeed.  Please fix your /etc/hosts file\n  to contain:\n\n  127.0.0.1 localhost.localdomain localhost\n\n  Zimbra install grants mysql permissions only to localhost and\n  localhost.localdomain users.  But Fedora/RH installs leave lines such\n  as these in /etc/hosts:\n\n  127.0.0.1     myhost.mydomain.com myhost localhost.localdomain localhost\n\n  This causes MySQL to reject users coming from 127.0.0.1 as users from\n  myhost.mydomain.com.  You can read more details at:\n\n  http://bugs.mysql.com/bug.php?id=11822\n\nEOF\n      exit 1\n    fi\n\n    H_LINE=`sed -e 's/#.*//' /etc/hosts | awk '{ for (i = 2; i <=NF; i++) { if ($i ~ /^'$HOSTNAME'$/) { print $0; } } }'`\n    IP=`echo ${H_LINE} | awk '{ print $1 }'`\n    INVALID_IP=0\n\n    if [ \"`echo ${IP} | tr -d '[0-9a-fA-F:]'`\" = \"\" ]\n    then\n        verifyIPv6 ${IP}\n        if [ $? -ne 0 ]\n        then\n            INVALID_IP=1\n        fi\n    elif [ \"`echo ${IP} | tr -d '[0-9.]'`\" = \"\" ]\n    then\n        verifyIPv4 ${IP}\n        if [ $? -ne 0 ]\n        then\n            INVALID_IP=1\n        fi\n    elif [ \"`echo ${IP} | tr -d '[0-9a-fA-F:.]'`\" = \"\" ]\n    then\n        IPv6=`echo ${IP} | awk -F: '{printf(\"%s\", $1); for (i = 2; i < NF; i++) { printf(\":%s\", $i) }}'`\n        IPv4=`echo ${IP} | sed -ne 's/.*://p'`\n        verifyMixedIPv6 ${IPv6}\n        if [ $? -eq 0 ]\n        then\n            verifyIPv4 ${IPv4}\n            if [ $? -ne 0 ]\n            then\n                INVALID_IP=1\n            fi\n        else\n            INVALID_IP=1\n        fi\n    else\n        INVALID_IP=1\n    fi\n    if [ `echo ${H_LINE} | awk '{ print NF }'` -lt 2 -o ${INVALID_IP} -eq 1 ]\n    then\n        echo \"\"\n        echo \"  ERROR: Installation can not proceeed.  Please fix your /etc/hosts file\"\n        echo \"  to contain:\"\n        echo \"\"\n        echo \"  <ip> <FQHN> <HN>\"\n        echo \"\"\n        echo \"  Where <IP> is the ip address of the host, \"\n        echo \"  <FQHN> is the FULLY QUALIFIED host name, and\"\n        echo \"  <HN> is the (optional) hostname-only portion\"\n        echo \"\"\n        exit 1\n    fi\n  fi\n\n  GOOD=\"yes\"\n\n  # limitation of ext3\n  if [ -d \"/opt/zimbra/db/data\" ]; then\n    echo \"Checking current number of databases...\"\n    FS_TYPE=`df -T /opt/zimbra/db/data | awk '{ if (NR == 2) { print $2 } }'`\n    if [ \"${FS_TYPE}\"x = \"ext3\"x ]; then\n      DBCOUNT=`find /opt/zimbra/db/data -type d | wc -l | awk '{if ($NF-1 >= 31998) print $NF-1}'`\n      if [ x\"$DBCOUNT\" != \"x\" ]; then\n        echo \"You have $DBCOUNT databases on an ext3 FileSystem, which is at\"\n        echo \"or over the limit of 31998 databases. You will need to delete at\"\n        echo \"least one database prior to upgrading or your upgrade will fail.\"\n        echo \"/opt/zimbra/db/data/test is a good candidate for removal.\"\n        exit 1\n      fi\n    fi\n  fi\n\n  checkCAKeyLength\n  checkRecentBackup\n  checkDatabaseIntegrity\n}\n\n\ncheckRequiredSpace() {\n  # /tmp must have 100MB\n  # /opt/zimbra must have 5GB for fresh installs with zimbra-store\n  # /opt/zimbra must have 500MB for upgrades\n  GOOD=yes\n  echo \"Checking required space for zimbra-core\"\n  TMPKB=`df -Pk /tmp | tail -1 | awk '{print $4}'`\n  AVAIL=$(($TMPKB / 1024))\n  if [ $AVAIL -lt  100 ]; then\n    echo \"/tmp must have at least 100MB of availble space to install.\"\n    echo \"${AVAIL}MB is not enough space to install ZCS.\"\n    GOOD=no\n  fi\n  ZIMBRA=`df -Pk /opt/zimbra | tail -1 | awk '{print $4}'`\n  if [ $UPGRADE = \"yes\" ]; then\n    AVAIL=$(($ZIMBRA / 1024))\n    if [ $AVAIL -lt 500 ]; then\n      echo \"/opt/zimbra requires at least 500MB of space to upgrade.\"\n      echo \"${AVAIL}MB is not enough space to upgrade.\"\n      GOOD=no\n    fi\n  fi\n\n  isInstalled zimbra-store\n  isToBeInstalled zimbra-store\n  if [ \"x$PKGINSTALLED\" != \"x\" -o \"x$PKGTOBEINSTALLED\" != \"x\" ]; then\n    echo \"Checking space for zimbra-store\"\n    if [ $UPGRADE = \"no\" ]; then\n      AVAIL=$(($ZIMBRA / 1048576))\n      if [ $AVAIL -lt 5 ]; then\n        echo \"/opt/zimbra requires at least 5GB of space to install.\"\n        echo \"${AVAIL}GB is not enough space to install.\"\n        GOOD=no\n      fi\n    fi\n  fi\n  if [ $GOOD = \"no\" ]; then\n    if [ x\"$SKIPSPACECHECK\" != \"xyes\" ]; then\n      echo \"\"\n      echo \"Installation cancelled.\"\n      echo \"\"\n      exit 1\n    else\n      echo \"\"\n      echo \"Installation will continue by request.\"\n      echo \"\"\n    fi\n  fi\n}\n\ncheckStoreRequirements() {\n  if [[ $ONLYOFFICE_SELECTED == \"yes\" ]]; then\n\t  return\n  fi\n  echo \"Checking required packages for zimbra-store\"\n  GOOD=\"yes\"\n  if [ x\"$ZMTYPE_INSTALLABLE\" = \"xNETWORK\" ]; then\n    for i in $STORE_PACKAGES; do\n      #echo -n \"    $i...\"\n      isInstalled $i\n      if [ \"x$PKGINSTALLED\" != \"x\" ]; then\n        echo \"     FOUND: $PKGINSTALLED\"\n      else\n        if [[ $ONLYOFFICE_SELECTED == \"yes\" && $i == libreoffice* ]]; then\n          continue\n        fi\n        echo \"     MISSING: $i\"\n        GOOD=\"no\"\n      fi\n    done\n  fi\n\n  if [ $GOOD = \"no\" ]; then\n    echo \"\"\n    echo \"###WARNING###\"\n    echo \"\"\n    echo \"One or more suggested packages for zimbra-store are missing.\"\n    echo \"Some features may be disabled due to the missing package(s).\"\n    echo \"\"\n  else\n    echo \"zimbra-store package check complete.\"\n  fi\n\n\n}\n\ncheckExistingInstall() {\n\n  echo $PLATFORM | egrep -q \"UBUNTU|DEBIAN\"\n  if [ $? = 0 ]; then\n    if [ -L /opt -o -L /opt/zimbra ]; then\n      echo \"Installation cannot continue if either /opt or /opt/zimbra are symbolic links.\"\n      exit 1\n    fi\n  fi\n\n  echo \"Checking for existing installation...\"\n\n  for i in $OPTIONAL_PACKAGES; do\n    isInstalled $i\n    if [ x$PKGINSTALLED != \"x\" ]; then\n      echo \"    $i...FOUND $PKGINSTALLED\"\n      INSTALLED_PACKAGES=\"$INSTALLED_PACKAGES $i\"\n    elif [ x$i != \"xzimbra-qatest\" ]; then\n      echo \"    $i...NOT FOUND\"\n    fi\n  done\n\n\n  for i in $PACKAGES $CORE_PACKAGES; do\n    echo -n \"    $i...\"\n    isInstalled $i\n    if [ x\"$PKGINSTALLED\" != \"x\" ]; then\n      echo \"FOUND $PKGINSTALLED\"\n      if [ \"$i\" != \"zimbra-memcached\" ] && [ \"$i\" != \"zimbra-license-daemon\" ] && [ \"$i\" != \"zimbra-onlyoffice\" ]; then\n         INSTALLED=\"yes\"\n      fi\n      INSTALLED_PACKAGES=\"$INSTALLED_PACKAGES $i\"\n    else\n      if [ x$i = \"xzimbra-archiving\" ]; then\n        if [ -f \"/opt/zimbra/lib/ext/zimbra_xmbxsearch/zimbra_xmbxsearch.jar\" -a -f \"/opt/zimbra/zimlets-network/zimbra_xmbxsearch.zip\" ]; then\n          echo \"FOUND zimbra-cms\"\n          INSTALLED_PACKAGES=\"$INSTALLED_PACKAGES zimbra-archiving\"\n        else\n          echo \"NOT FOUND\"\n        fi\n      else\n         echo \"NOT FOUND\"\n      fi\n    fi\n  done\n\n  determineVersionType\n  if [ $INSTALLED = \"yes\" ]; then\n    verifyUpgrade\n    verifyNGModulesInstalled\n  fi\n  verifyLicenseActivationServer\n  verifyLicenseAvailable\n\n  if [ $INSTALLED != \"yes\" ]; then\n    checkUserInfo\n  fi\n}\n\ndetermineVersionType() {\n\n  isInstalled zimbra-core\n  if [ x\"$PKGINSTALLED\" != \"x\" ]; then\n    export ZMVERSION_CURRENT=`echo $PKGVERSION | sed s/^zimbra-core-//`\n    if [ -f \"/opt/zimbra/bin/zmbackupquery\" ]; then\n      ZMTYPE_CURRENT=\"NETWORK\"\n    else\n      ZMTYPE_CURRENT=\"FOSS\"\n    fi\n    ZM_CUR_MAJOR=$(perl -e '$v=$ENV{ZMVERSION_CURRENT}; $v =~ s/^(\\d+\\.\\d+\\.[^_]*_[^_]+_[^.]+).*/\\1/; ($maj,$min,$mic) = $v =~ m/^(\\d+)\\.(\\d+)\\.(\\d+)/; print \"$maj\\n\"')\n    ZM_CUR_MINOR=$(perl -e '$v=$ENV{ZMVERSION_CURRENT}; $v =~ s/^(\\d+\\.\\d+\\.[^_]*_[^_]+_[^.]+).*/\\1/; ($maj,$min,$mic) = $v =~ m/^(\\d+)\\.(\\d+)\\.(\\d+)/; print \"$min\\n\"')\n    ZM_CUR_MICRO=$(perl -e '$v=$ENV{ZMVERSION_CURRENT}; $v =~ s/^(\\d+\\.\\d+\\.[^_]*_[^_]+_[^.]+).*/\\1/; ($maj,$min,$mic) = $v =~ m/^(\\d+)\\.(\\d+)\\.(\\d+)/; print \"$mic\\n\"')\n    ZM_CUR_BUILD=$(perl -e '$v=$ENV{ZMVERSION_CURRENT}; $v =~ s/^(\\d+\\.\\d+\\.[^_]*_[^_]+_[^.]+).*/\\1/; ($maj,$min,$mic,$rtype,$build) = $v =~ m/^(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\w+)\\.(\\d+)/; ($maj,$min,$mic,$rtype,$build) = $v =~ m/(\\d+)\\.(\\d+)\\.(\\d+)_(\\w+[^_])_(\\d+)/ if ($rtype eq \"\"); print \"$build\\n\";')\n  fi\n\n  # if we are removing the install we don't need the rest of the info\n  if [ x\"$UNINSTALL\" = \"xyes\" ]; then\n    return\n  fi\n\n  # need way to determine type for other package types\n  ZMTYPE_INSTALLABLE=\"$(cat ${MYDIR}/.BUILD_TYPE)\"\n\n  ZM_INST_MAJOR=$(perl -e '$v=glob(\"packages/zimbra-core*\"); $v =~ s/^packages\\/zimbra-core[-_]//; $v =~ s/^(\\d+\\.\\d+\\.[^_]*_[^_]+_[^.]+).*/\\1/; ($maj,$min,$mic) = $v =~ m/^(\\d+)\\.(\\d+)\\.(\\d+)/; print \"$maj\\n\"')\n  ZM_INST_MINOR=$(perl -e '$v=glob(\"packages/zimbra-core*\"); $v =~ s/^packages\\/zimbra-core[-_]//; $v =~ s/^(\\d+\\.\\d+\\.[^_]*_[^_]+_[^.]+).*/\\1/; ($maj,$min,$mic) = $v =~ m/^(\\d+)\\.(\\d+)\\.(\\d+)/; print \"$min\\n\"')\n  ZM_INST_MICRO=$(perl -e '$v=glob(\"packages/zimbra-core*\"); $v =~ s/^packages\\/zimbra-core[-_]//; $v =~ s/^(\\d+\\.\\d+\\.[^_]*_[^_]+_[^.]+).*/\\1/; ($maj,$min,$mic) = $v =~ m/^(\\d+)\\.(\\d+)\\.(\\d+)/; print \"$mic\\n\"')\n  ZM_INST_RTYPE=$(perl -e '$v=glob(\"packages/zimbra-core*\"); $v =~ s/^packages\\/zimbra-core[-_]//; $v =~ s/^(\\d+\\.\\d+\\.[^_]*_[^_]+_[^.]+).*/\\1/; ($maj,$min,$mic,$rtype,$build) = $v =~ m/^(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\w+)\\.(\\d+)/; ($maj,$min,$mic,$rtype,$build) = $v =~ m/(\\d+)\\.(\\d+)\\.(\\d+)_(\\w+[^_])_(\\d+)/ if ($rtype eq \"\"); print \"$rtype\\n\";')\n  ZM_INST_BUILD=$(perl -e '$v=glob(\"packages/zimbra-core*\"); $v =~ s/^packages\\/zimbra-core[-_]//; $v =~ s/^(\\d+\\.\\d+\\.[^_]*_[^_]+_[^.]+).*/\\1/; ($maj,$min,$mic,$rtype,$build) = $v =~ m/^(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\w+)\\.(\\d+)/; ($maj,$min,$mic,$rtype,$build) = $v =~ m/(\\d+)\\.(\\d+)\\.(\\d+)_(\\w+[^_])_(\\d+)/ if ($rtype eq \"\"); print \"$build\\n\";')\n\n  if [ x\"$AUTOINSTALL\" = \"xyes\" ]; then\n    return\n  fi\n\n  #echo \"TYPE: CURRENT: $ZMTYPE_CURRENT INSTALLABLE: $ZMTYPE_INSTALLABLE\"\n  #echo \"VERSION: CURRENT: $ZM_CUR_MAJOR INSTALLABLE: $ZM_INST_MAJOR\"\n\n  checkVersionDowngrade\n\n  if [ x\"$ZMTYPE_CURRENT\" = \"xNETWORK\" ] && [ x\"$ZMTYPE_INSTALLABLE\" = \"xFOSS\" ]; then\n    echo \"Warning: You are about to upgrade from the Network Edition to the\"\n    echo \"Open Source Edition.  This will remove all Network features, including\"\n    echo \"Attachment Searching, Zimbra Mobile, Backup/Restore, and support for the \"\n    echo \"Zimbra Connector for Outlook.\"\n    while :; do\n     askYN \"Do you wish to continue?\" \"N\"\n     if [ $response = \"no\" ]; then\n      askYN \"Exit?\" \"N\"\n      if [ $response = \"yes\" ]; then\n        echo \"Exiting.\"\n        exit 1\n      fi\n     else\n      break\n     fi\n    done\n  fi\n\n  if [ x\"$ZMTYPE_CURRENT\" = \"xNETWORK\" ]; then\n    echo $ZM_INST_RTYPE | grep -v GA$ > /dev/null 2>&1\n    if [ $? = 0 ]; then\n      if [ ${ZM_CUR_MAJOR} -lt ${ZM_INST_MAJOR} ]; then\n        echo \"This is a Network Edition ${ZM_INST_RTYPE} build and is not intended for production.\"\n        if [ x\"$BETA_SUPPORT\" = \"x\" ]; then\n          echo \"Upgrades from $ZMVERSION_CURRENT are not supported.\"\n          exit 1\n        else\n          echo \"Support for developer versions of ZCS maybe limited to bugzilla and Zimbra forums.\"\n          #echo \"Installing non-GA versions in production is not recommended.\"\n          while :; do\n            askYN \"Do you wish to continue?\" \"N\"\n            if [ $response = \"no\" ]; then\n              askYN \"Exit?\" \"N\"\n              if [ $response = \"yes\" ]; then\n                echo \"Exiting.\"\n                exit 1\n              fi\n            else\n              break\n            fi\n          done\n        fi\n      fi\n    fi\n  fi\n}\n\nverifyUpgrade() {\n\n  if [ x\"$UNINSTALL\" = \"xyes\" ]; then\n    return\n  fi\n\n  if [ ${ZM_CUR_MAJOR} -lt 8 ] || [ ${ZM_CUR_MAJOR} -eq 8 -a ${ZM_CUR_MINOR} -lt 7 ]; then\n    if [ -x \"bin/checkService.pl\" ]; then\n      echo \"Checking for existing proxy service in your environment\"\n      # echo \"Running bin/checkService.pl -s proxy\"\n      if [ ${ZM_CUR_MAJOR} -lt 8 ]; then\n          `bin/checkService.pl -s imapproxy`\n      else\n          `bin/checkService.pl -s proxy`\n      fi\n      serviceProxyRC=$?;\n      if [ \"$serviceProxyRC\" != 0 ]; then\n          if [ \"$serviceProxyRC\" = 2 ]; then\n              echo \"Error: No proxy detected in your environment. Proxy is required for ZCS 8.7+.\"\n              echo \"See https://wiki.zimbra.com/wiki/Enabling_Zimbra_Proxy for details on installing proxy.\"\n          else\n            echo \"Error: Unable to contact the LDAP server.\"\n            exit 1\n          fi\n      fi\n\n      echo \"Checking for existing memcached service in your environment\"\n      # echo \"Running bin/checkService.pl -s memcached\"\n      `bin/checkService.pl -s memcached`\n      serviceMemcachedRC=$?;\n      if [ \"$serviceMemcachedRC\" != 0 ]; then\n          if [ \"$serviceMemcachedRC\" = 2 ]; then\n              echo \"Error: No memcached detected in your environment. Memcached is required for ZCS 8.7+.\"\n              echo \"See https://wiki.zimbra.com/wiki/Enabling_Zimbra_Memcached for details on installing memcached.\"\n          else\n            echo \"Error: Unable to contact the LDAP server.\"\n            exit 1\n          fi\n      fi\n    fi\n\n    if [ \"$serviceProxyRC\" != 0 ] || [ \"$serviceMemcachedRC\" != 0 ]; then\n      echo \"Proxy and Memcached services must exist. Exiting...\"\n      exit 1\n    fi\n  fi\n\n  if [ x\"$SKIP_UPGRADE_CHECK\" = \"xyes\" ]; then\n    return\n  fi\n\n  # sometimes we just don't want to check\n  if [ x\"$AUTOINSTALL\" = \"xyes\" ] || [ x\"$SOFTWAREONLY\" = \"xyes\" ]; then\n    return\n  fi\n\n  isInstalled \"zimbra-ldap\"\n  LDAP_INSTALLED=$PKGINSTALLED\n  if [ \"x$LDAP_INSTALLED\" != \"x\" ]; then\n\t  runAsZimbra \"ldap start\"\n  fi\n  isInstalled \"zimbra-store\"\n  STORE_INSTALLED=$PKGINSTALLED\n  if [ \"x$LDAP_INSTALLED\" != \"x\" ] || [ \"x$STORE_INSTALLED\" != \"x\" ]; then\n    # Upgrade tests specific to NE only\n    if [ x\"$ZMTYPE_CURRENT\" = \"xNETWORK\" ] && [ x\"$ZMTYPE_INSTALLABLE\" = \"xNETWORK\" ]; then\n      if [ x\"$SKIP_ACTIVATION_CHECK\" = \"xno\" ]; then\n        if [ -x \"bin/checkLicense.pl\" ]; then\n          echo \"Validating whether an existing license is expired or not and checking if it qualifies for an upgrade\"\n          echo $HOSTNAME | egrep -qe 'eng.zimbra.com$|lab.zimbra.com$|zimbradev.com$' > /dev/null 2>&1\n          if [ $? = 0 ]; then\n              bin/checkLicense.pl -i -uv $ZM_INST_VERSION -cv $ZM_CUR_VERSION\n          else\n              bin/checkLicense.pl -uv $ZM_INST_VERSION -cv $ZM_CUR_VERSION\n          fi\n          licenseRC=$?;\n          if [ $licenseRC != 0 ]; then\n            if [ $licenseRC = 6 ]; then\n              echo \"Error: Unable to bind to LDAP\"\n              exit 1\n            elif [ $licenseRC = 5 ]; then\n              echo \"Error: Unable to execute startTLS with LDAP\"\n              exit 1\n            elif [ $licenseRC = 4 ]; then\n              echo \"Error: Unable to connect to LDAP\"\n              exit 1\n            elif [ $licenseRC = 3 ]; then\n              echo \"Error: No upgrade version supplied\"\n              exit 1\n            elif [ $licenseRC = 2 ]; then\n              echo \"Error: license key not found\"\n              exit 1\n            elif [ $licenseRC = 7 ]; then\n              echo \"Error: The license key should be an alphanumeric string of 18-24 characters without any special characters\"\n\t      exit 1\n            elif [ $licenseRC = 1 ]; then\n              echo \"Error: License is expired or not authorized for upgrade or cannot be upgraded.\"\n              echo \"       Aborting upgrade\"\n              exit 1\n            else\n              echo \"Unknown Error.  It should be impossible to reach this statement.\"\n              exit 1\n            fi\n          else\n           echo \"License is valid and supports this upgrade.  Continuing.\"\n          fi\n        fi\n      fi\n    fi\n  fi\n\n  # Upgrade tests applicable to everyone\n  echo \"Validating ldap configuration\"\n  isInstalled \"zimbra-ldap\"\n  LDAP_OPT=\"\"\n  if [ x$PKGINSTALLED != \"x\" ]; then\n    LDAP_OPT=\"-l\"\n  fi\n  `bin/zmValidateLdap.pl --vmajor ${ZM_CUR_MAJOR} --vminor ${ZM_CUR_MINOR} --vmicro ${ZM_CUR_MICRO} \\\n     --umajor ${ZM_INST_MAJOR} --uminor ${ZM_INST_MINOR} --umicro ${ZM_INST_MICRO} ${LDAP_OPT} >/dev/null`\n  ldapRC=$?;\n  if [ $ldapRC != 0 ]; then\n    if [ $ldapRC = 1 ]; then\n      echo \"Error: Unable to create a successful TLS connection to the ldap masters.\"\n      echo \"       Fix cert configuration prior to upgrading.\"\n      exit 1\n    elif [ $ldapRC = 2 ]; then\n      echo \"Error: Unable to bind to the LDAP server as the root LDAP user.\"\n      echo \"       This is required to upgrade.\"\n      exit 1\n    elif [ $ldapRC = 3 ]; then\n      echo \"Error: Unable to bind to the LDAP server as the zimbra LDAP user.\"\n      echo \"       This is required to upgrade.\"\n      exit 1\n    elif [ $ldapRC = 4 ]; then\n      echo \"Error: Unable to search LDAP server as the zimbra LDAP user.\"\n      echo \"       This is required to upgrade.\"\n      exit 1\n    elif [ $ldapRC = 5 ]; then\n      echo \"Error: One or more LDAP master servers has not yet been upgraded.\"\n      echo \"       It is required for all LDAP master node(s) to be upgraded first.\"\n      exit 1\n    else\n      echo \"Unknown Error: It should be impossible to reach this statement.\"\n      exit 1\n   fi\n   else\n     echo \"LDAP validation succeeded.  Continuing.\"\n   fi\n}\n\nverifyNGModulesInstalled() {\n\tif [ x\"$SKIP_NG_CHECK\" = \"xyes\" ] || [ x\"$UNINSTALL\" = \"xyes\" ]; then\n\t\treturn\n\tfi\n\tNG_INSTALLED=\"no\"\n\tfor i in $ZEXTRAS_PACKAGES; do\n\t\tisInstalled $i\n\t\tif [ x\"$PKGINSTALLED\" != \"x\" ]; then\n\t\t\tNG_INSTALLED=\"yes\"\n\t\t\tbreak\n\t\tfi\n\tdone\n\tif [ $NG_INSTALLED = \"yes\" ]; then\n\t\techo -e \"\\e[1;31m NG Modules detected on this system. If you continue with this upgrade, NG module packages and the associated data will be deleted. \\033[0m\"\n\t\techo -e \"\\e[1;31m If you want to preserve NG data, consider migrating or a rolling upgrade strategy for upgrading your system. \\033[0m\"\n\t\techo -e \"\\e[1;31m For more information, please contact Zimbra Support. \\033[0m\"\n\t\techo -e \"\\e[1;31m If you still want to continue, start upgrade using --skip-ng-check \\033[0m\"\n\t\texit 1\n\tfi\n}\n\nverifyLicenseActivationServer() {\n\n  if [ x\"$SKIP_ACTIVATION_CHECK\" = \"xyes\" -o x\"$SKIP_UPGRADE_CHECK\" = \"xyes\" ]; then\n    return\n  fi\n\n  # sometimes we just don't want to check\n  if [ x\"$AUTOINSTALL\" = \"xyes\" ] || [ x\"$UNINSTALL\" = \"xyes\" ] || [ x\"$SOFTWAREONLY\" = \"xyes\" ]; then\n    return\n  fi\n\n  # make sure this is an upgrade\n  isInstalled zimbra-store\n  if [ x$PKGINSTALLED = \"x\" ]; then\n    return\n  fi\n\n  # make sure the current version we are trying to install is a NE version\n  if [ x\"$ZMTYPE_INSTALLABLE\" != \"xNETWORK\" ]; then\n    return\n  fi\n\n  # make sure we can contact the activation server for automated activation\n  echo $HOSTNAME | egrep -qe 'zimbra.com$|zimbradev.com$' > /dev/null 2>&1\n  if [ $? = 0 ]; then\n\t  url='https://zimbra-stage-license.eng.zimbra.com/zimbraLicensePortal/public/activation?action=test'\n  else\n\t  url='https://license.zimbra.com/zimbraLicensePortal/public/activation?action=test'\n  fi\n\n  cmd=$(which curl 2>/dev/null)\n  if [ -x \"$cmd\" ]; then\n\t  output=$($cmd --connect-timeout 5 -s -f $url)\n\t  if [ $? != 0 ]; then\n\t\t  output=$($cmd -k --connect-timeout 5 -s -f $url)\n\t\t  if [ $? != 0 ]; then\n\t\t\t  activationWarning\n\t\t  else\n\t\t\t  return\n\t\t  fi\n\t  else\n\t\t  return\n\t  fi\n  fi\n  cmd=$(which wget 2>/dev/null)\n  if [ -x \"$cmd\" ]; then\n\t  output=$($cmd --tries 1 -T 5 -q -O /tmp/zmlicense.tmp $url)\n\t  if [ $? != 0 ]; then\n\t\t  output=$($cmd --no-check-certificate --tries 1 -T 5 -q -O /tmp/zmlicense.tmp $url)\n\t\t  if [ $? != 0 ]; then\n\t\t\t  activationWarning\n\t\t  else\n\t\t\t  return\n\t\t  fi\n\t\t  activationWarning\n\t  else\n\t\t  return\n\t  fi\n  fi\n}\n\nactivationWarning() {\n  echo \"ERROR: Unable to reach the Zimbra License Activation Server.\"\n  echo \"\"\n  echo \"License Activation is required when upgrading to ZCS 7 or later.\"\n  echo \"\"\n  echo \"The ZCS Network upgrade will automatically attempt to activate the\"\n  echo \"current license as long as the activation server can be contacted.\"\n  echo \"\"\n  echo \"A manual license activation key can be obtained by either visiting\"\n  echo \"the Zimbra support portal or contacting Zimbra support or sales.\"\n  echo \"\"\n  exit 1;\n}\n\nverifyLicenseAvailable() {\n\n  if [ x\"$AUTOINSTALL\" = \"xyes\" ] || [ x\"$UNINSTALL\" = \"xyes\" ] || [ x\"$SOFTWAREONLY\" = \"xyes\" ]; then\n    return\n  fi\n\n  isInstalled zimbra-store\n  if [ x$PKGINSTALLED = \"x\" ]; then\n    return\n  fi\n\n  # need to finish for other native packagers\n  if [ \"$(cat ${MYDIR}/.BUILD_TYPE)\" != \"NETWORK\" ]; then\n     return\n  fi\n\n  echo \"Checking for available license...\"\n\n\n  # use the tool if it exists\n  if [ -f \"/opt/zimbra/bin/zmlicense\" ]; then\n\t  licenseCheck=`su - zimbra -c \"zmlicense -c\" 2> /dev/null`\n\t  if [ \"${ZM_CUR_MAJOR}\" -gt \"10\" ] || [ \"${ZM_CUR_MAJOR}\" -eq \"10\" -a \"${ZM_CUR_MINOR}\" -ge \"1\" ]; then\n\t\t  licensedUsers=$(su - zimbra -c \"zmprov gcf zimbraNetworkRealtimeActivation 2>/dev/null | grep -o '\\\"licenseFeatureDetails\\\":{[^}]*}' | grep -o '\\\"totalLimit\\\":\\\"[^\\\"]*' | awk -F '\\\"' '{print \\$4}'\")\n\t\t  licenseValidUntil=$(su - zimbra -c \"zmprov gcf zimbraNetworkRealtimeActivation 2>/dev/null | grep -o '\\\"licenseActivationDetails\\\":{[^}]*}' | grep -o '\\\"ValidUntil\\\":[^,}]*' | sed 's/\\\"ValidUntil\\\"://; s/\\\"//g'\")\n\t\t  licenseType=$(su - zimbra -c \"zmprov gcf zimbraNetworkRealtimeActivation 2>/dev/null | grep -o '\\\"licenseActivationDetails\\\":{[^}]*}' | grep -o '\\\"InstallType\\\":\\\"[^\\\"]*' | awk -F '\\\"' '{print \\$4}'\")\n\t  else\n\t\t  licensedUsers=`su - zimbra -c \"zmlicense -p | grep ^AccountsLimit | sed -e 's/AccountsLimit=//'\" 2> /dev/null`\n\t\t  licenseValidUntil=`su - zimbra -c \"zmlicense -p | grep ^ValidUntil= | sed -e 's/ValidUntil=//'\" 2> /dev/null`\n\t\t  licenseType=`su - zimbra -c \"zmlicense -p | grep ^InstallType= | sed -e 's/InstallType=//'\" 2> /dev/null`\n\t  fi\n  fi\n\n  # parse files if license tool wasn't there or didn't return a valid license\n  if [ x\"$licenseCheck\" = \"xlicense not installed\" ] || [ x\"$licenseCheck\" = \"x\" ] || [[ \"$licenseCheck\" =~ \"License is not activated\" ]]; then\n    if [ -f \"/opt/zimbra/conf/ZCSLicense.xml\" ]; then\n      licenseCheck=\"license is OK\"\n      licensedUsers=`cat /opt/zimbra/conf/ZCSLicense.xml | grep AccountsLimit | head -1  | awk '{print $3}' | awk -F= '{print $2}' | awk -F\\\" '{print $2}'`\n      licenseValidUntil=`cat /opt/zimbra/conf/ZCSLicense.xml | awk -F\\\" '{ if ($2 ~ /^ValidUntil$/) {print $4 } }'`\n      licenseType=`cat /opt/zimbra/conf/ZCSLicense.xml | awk -F\\\" '{ if ($2 ~ /^InstallType$/) {print $4 } }'`\n    elif [ -f \"/opt/zimbra/conf/ZCSLicense-Trial.xml\" ]; then\n      licenseCheck=\"license is OK\"\n      licensedUsers=`cat /opt/zimbra/conf/ZCSLicense-Trial.xml | grep AccountsLimit | head -1  | awk '{print $3}' | awk -F= '{print $2}' | awk -F\\\" '{print $2}'`\n      licenseValidUntil=`cat /opt/zimbra/conf/ZCSLicense-Trial.xml | awk -F\\\" '{ if ($2 ~ /^ValidUntil$/) {print $4 } }'`\n      licenseType=`cat /opt/zimbra/conf/ZCSLicense-Trial.xml | awk -F\\\" '{ if ($2 ~ /^InstallType$/) {print $4 } }'`\n    else\n      echo \"WARNING: The ZCS Network upgrade requires a valid license to be installed.\"\n      echo \"\"\n      echo \"New customers wanting to purchase or obtain a trial license\"\n      echo \"should contact Zimbra sales.  Contact information for Zimbra is\"\n      echo \"located at http://www.zimbra.com/about/contact_us.html\"\n      echo \"Existing customers can obtain an updated license file via the\"\n      echo \"Zimbra Support page located at http://www.zimbra.com/support.\"\n      echo \"\"\n    fi\n  fi\n\n  if [ \"${ZM_CUR_MAJOR}\" -gt \"10\" ] || [ \"${ZM_CUR_MAJOR}\" -eq \"10\" -a \"${ZM_CUR_MINOR}\" -ge \"1\" ]; then\n\t  now=`date -u \"+%Y-%m-%d\"`\n  else\n\t  now=`date -u \"+%Y%m%d%H%M%SZ\"`\n  fi\n  if [ \\( x\"$licenseValidUntil\" \\< x\"$now\" -o x\"$licenseValidUntil\" == x\"$now\" \\) -a x\"$ZMTYPE_INSTALLABLE\" == x\"NETWORK\" ]; then\n    if [ x\"$licenseType\" == x\"perpetual\" ]; then\n      echo \"\"\n      echo \"ERROR: The ZCS Network upgrade requires a previously installed license\"\n      echo \"to be valid and not expired.\"\n      echo \"\"\n      echo \"The upgrade cannot occur with an expired perpetual license.  In order\"\n      echo \"to perform an upgrade, you will need to have a valid support contract\"\n      echo \"in place.\"\n      echo \"\"\n      echo \"Your system has not been modified.\"\n      echo \"\"\n      exit 1;\n    else\n      echo \"\"\n      echo \"WARNING: The ZCS Network upgrade requires a previously installed license\"\n      echo \"to be valid and not expired.\"\n      echo \"\"\n      echo \"The upgrade can continue, but there will be some loss of functionality.\"\n      echo \"\"\n      while :; do\n        askYN \"Do you wish to continue? \" \"N\"\n        if [ $response == \"no\" ]; then\n          askYN \"Exit?\" \"N\"\n          if [ $response == \"yes\" ]; then\n            echo \"\"\n            echo \"Your system has not been modified.\"\n            echo\"\"\n            exit 1;\n          fi\n        else\n          break\n        fi\n      done\n    fi\n  fi\n\n\n  if [ x\"$licensedUsers\" = \"x\" ]; then\n    licensedUsers=0\n  fi\n\n  # return immediately if we have an unlimited license\n  if [ \"$licensedUsers\" = \"-1\" ]; then\n    return\n  fi\n\n  # Check for licensed user count and warn if necessary\n  oldUserCheck=0\n  if [ ${ZM_CUR_MAJOR} -eq 6 -a ${ZM_CUR_MICRO} -lt 8 ]; then\n    userProvCommand=\"zmprov -l gaa 2> /dev/null | wc -l\"\n    oldUserCheck=1\n  else\n    userProvCommand=\"zmprov -l cto userAccounts 2> /dev/null\"\n  fi\n\n  # Make sure zmprov is responsive and able to talk to LDAP before we do anything for real\n  zmprovTest=\"zmprov -l gac 2> /dev/null > /dev/null\"\n  su - zimbra -c \"$zmprovTest\"\n  zmprovTestRC=$?\n  if [ $zmprovTestRC -eq 0 ]; then\n    su - zimbra -c \"$zmprovTest\"\n    zmprovTestRC=$?\n  fi\n  if [ $zmprovTestRC -ne 0 ]; then\n    echo \"\"\n    echo \"Warning: Unable to determine the number of users on this system via zmprov command.\"\n    echo \"Please make sure LDAP services are running.\"\n    echo \"\"\n  fi\n\n  # Passed check to make sure zmprov and LDAP are working.  Now let's get a real count.\n  numCurrentUsers=-1;\n  if [ $zmprovTestRC -eq 0 ]; then\n    numCurrentUsers=`su - zimbra -c \"$userProvCommand\"`;\n    numUsersRC=$?\n    if [ $numUsersRC -ne 0 ]; then\n      numCurrentUsers=`su - zimbra -c \"$userProvCommand\"`;\n      numUsersRC=$?\n    fi\n  fi\n\n  # Unable to determine the number of current users\n  if [ \"$numCurrentUsers\"x = \"x\" ]; then\n    numCurrentUsers=-1;\n    echo \"\"\n    echo \"Warning: Unable to determine the number of users on this system via zmprov command.\"\n    echo \"Please make sure LDAP services are running.\"\n    echo \"\"\n  fi\n\n  if [ $oldUserCheck -eq 1 ]; then\n    numCurrentUsers=`expr $numCurrentUsers - 3`\n  fi\n  if [ $numCurrentUsers -gt 0 ]; then\n    echo \"Current Users=$numCurrentUsers Licensed Users=$licensedUsers\"\n  fi\n\n  if [ $numCurrentUsers -lt 0 ]; then\n    echo \"Warning: Could not determine the number of users on this system.\"\n    echo \"If you exceed the number of licensed users ($licensedUsers) then you will\"\n    echo \"not be able to create new users.\"\n    while :; do\n     askYN \"Do you wish to continue?\" \"N\"\n     if [ $response = \"no\" ]; then\n      askYN \"Exit?\" \"N\"\n      if [ $response = \"yes\" ]; then\n        echo \"Exiting. Please install a valid license and rerun.\"\n        exit 1\n      fi\n     else\n      break\n     fi\n    done\n  elif [ $numUsersRC -ne 0 ] || [ $numCurrentUsers -gt $licensedUsers ]; then\n    echo \"Warning: The number of users on this system ($numCurrentUsers) exceeds the licensed number\"\n    echo \"($licensedUsers).  You may continue with the upgrade, but you will not be able to create\"\n    echo \"new users.  Also, initialization of the Document feature will fail.  If you \"\n    echo \"later wish to use the Documents feature you'll need to resolve the licensing \"\n    echo \"issues and then run a separate script available from support to initialize the \"\n    echo \"Documents feature. \"\n    while :; do\n     askYN \"Do you wish to continue?\" \"N\"\n     if [ $response = \"no\" ]; then\n      askYN \"Exit?\" \"N\"\n      if [ $response = \"yes\" ]; then\n        echo \"Exiting. Please install a valid license and rerun.\"\n        exit 1\n      fi\n     else\n      break\n     fi\n    done\n  else\n    # valid license and user count\n    return\n  fi\n\n}\n\ncheckUserInfo() {\n  #Verify that the zimbra user either:\n  #  Doesn't exist OR\n  #  Exists with:\n  #     home: /opt/zimbra\n  #     shell: bash\n  id zimbra > /dev/null 2>&1\n  if [ $? -ne 0 ]; then\n    return\n  fi\n  if [ -x /usr/bin/getent ]\n  then\n    ZH=`getent passwd zimbra | awk -F: '{ print $6 }'`\n    ZS=`getent passwd zimbra | awk -F: '{ print $7 }' | sed -e s'|.*/||'`\n  else\n    ZH=`awk -F: '/^zimbra:/ {print $6}' /etc/passwd`\n    ZS=`awk -F: '/^zimbra:/ {print $7}' /etc/passwd | sed -e s'|.*/||'`\n  fi\n  if [ x$ZH != \"x/opt/zimbra\" ]; then\n    echo \"Error - zimbra user exists with incorrect home directory: $ZH\"\n    echo \"Exiting\"\n    exit 1\n  fi\n  if [ x$ZS != \"xbash\" ]; then\n    echo \"Error - zimbra user exists with incorrect shell: $ZS\"\n    echo \"Exiting\"\n    exit 1\n  fi\n}\n\nrunAsZimbra() {\n  # echo \"Running as zimbra: $1\"\n  echo \"COMMAND: $1\" >> $LOGFILE 2>&1\n  su - zimbra -c \"$1\" >> $LOGFILE 2>&1\n}\n\nshutDownSystem() {\n  runAsZimbra \"zmcontrol shutdown\"\n  isInstalled \"zimbra-license-daemon\"\n  if [ x$PKGINSTALLED != \"x\" ]; then\n\t  [ -x \"/opt/zimbra/bin/zmlicensectl\" ] && runAsZimbra \"/opt/zimbra/bin/zmlicensectl --service stop\"\n  fi\n  # stop all zimbra process that may have been orphaned\n  local OS=$(uname -s | tr A-Z a-z)\n  if [ x\"$OS\" = \"xlinux\" ]; then\n    if [ -x /bin/ps -a -x  /usr/bin/awk -a -x /usr/bin/xargs ]; then\n      /bin/ps -eFw | /usr/bin/awk '{ if ($1 == \"zimbra\" && $3 == \"1\") print $2 }' | /usr/bin/xargs kill -9 > /dev/null 2>&1\n    fi\n  fi\n}\n\ngetRunningSchemaVersion() {\n  RUNNINGSCHEMAVERSION=`su - zimbra -c \"echo \\\"select value from config where name='db.version';\\\" | mysql zimbra --skip-column-names\"`\n  if [ \"x$RUNNINGSCHEMAVERSION\" = \"x\" ]; then\n    RUNNINGSCHEMAVERSION=0\n  fi\n}\n\ngetPackageSchemaVersion() {\n  PACKAGESCHEMAVERSION=`cat data/versions-init.sql  | grep db.version | sed -e s/[^0-9]//g`\n}\n\ngetRunningIndexVersion() {\n  RUNNINGINDEXVERSION=`su - zimbra -c \"echo \\\"select value from config where name='index.version';\\\" | mysql zimbra --skip-column-names\"`\n  if [ \"x$RUNNINGINDEXVERSION\" = \"x\" ]; then\n    RUNNINGINDEXVERSION=0\n  fi\n}\n\ngetPackageIndexVersion() {\n  PACKAGEINDEXVERSION=`cat data/versions-init.sql  | grep index.version | sed -e s/[^0-9]//g`\n}\n\ncheckVersionMatches() {\n  VERSIONMATCH=\"yes\"\n\n  # This bombs when mysql isn't around, and was a really bad\n  # idea, anyway\n  return\n\n  getRunningSchemaVersion\n  getPackageSchemaVersion\n  getRunningIndexVersion\n  getPackageIndexVersion\n  if [ $RUNNINGSCHEMAVERSION != $PACKAGESCHEMAVERSION ]; then\n    VERSIONMATCH=\"no\"\n    return\n  fi\n  if [ $RUNNINGINDEXVERSION != $PACKAGEINDEXVERSION ]; then\n    VERSIONMATCH=\"no\"\n    return\n  fi\n}\n\nsetRemove() {\n\n  if [ $INSTALLED = \"yes\" -o $FORCE_UPGRADE = \"yes\" ]; then\n\n      checkVersionMatches\n      if [ $INSTALLED = \"yes\" ]; then\n\n      echo \"\"\n      echo \"The Zimbra Collaboration Server appears to already be installed.\"\n      if [ $VERSIONMATCH = \"yes\" ]; then\n        echo \"It can be upgraded with no effect on existing accounts,\"\n        echo \"or the current installation can be completely removed prior\"\n        echo \"to installation for a clean install.\"\n      else\n        echo \"\"\n        echo \"###WARNING###\"\n        if [ $RUNNINGSCHEMAVERSION -eq 0 -o $RUNNINGINDEXVERSION -eq 0 ]; then\n          echo \"\"\n          echo \"It appears that the mysql server is not running\"\n          echo \"This may be the cause of the problem\"\n          echo \"\"\n        fi\n        echo \"There is a mismatch in the versions of the installed schema\"\n        echo \"or index and the version included in this package\"\n        echo \"If you wish to upgrade, please correct this problem first.\"\n        askYN \"Exit now?\" \"Y\"\n        if [ $response = \"yes\" ]; then\n          exit 1;\n        fi\n      fi\n    fi\n\n    while :; do\n      UPGRADE=\"yes\"\n      if [ $FORCE_UPGRADE = \"yes\" -o $VERSIONMATCH = \"yes\" ]; then\n        askYN \"Do you wish to upgrade?\" \"Y\"\n      else\n        UPGRADE=\"no\"\n        response=\"no\"\n      fi\n      if [ $response = \"no\" ]; then\n        askYN \"Exit now?\" \"Y\"\n        if [ $response = \"yes\" ]; then\n          exit 1;\n        fi\n        echo \"\"\n        echo $INSTALLED_PACKAGES | grep zimbra-ldap > /dev/null 2>&1\n        if [ $? = 0 ]; then\n          echo \"*** WARNING - you are about to delete all existing users and mail\"\n        else\n          echo $INSTALLED_PACKAGES | grep zimbra-store > /dev/null 2>&1\n          if [ $? = 0 ]; then\n            echo \"*** WARNING - you are about to delete users and mail hosted on this server\"\n          else\n            REMOVE=\"yes\"\n            UPGRADE=\"no\"\n            break\n          fi\n        fi\n        askYN \"Delete users/mail?\" \"N\"\n        if [ $response = \"yes\" ]; then\n          REMOVE=\"yes\"\n          UPGRADE=\"no\"\n          break\n        fi\n      else\n        if [ $FORCE_UPGRADE = \"no\" ]; then\n          # Check for a history file - create it if it's not there\n          isInstalled \"zimbra-core\"\n          if [ ! -f \"/opt/zimbra/.install_history\" ]; then\n            cat > /opt/zimbra/.install_history << EOF\n0000000000: INSTALL SESSION START\n0000000000: INSTALLED $PKGVERSION\n0000000000: INSTALL SESSION COMPLETE\n0000000000: CONFIG SESSION START\n0000000000: CONFIGURED BEGIN\n0000000000: CONFIGURED END\n0000000000: CONFIG SESSION COMPLETE\nEOF\n          fi\n        fi\n        break\n      fi\n    done\n  else\n    # REMOVE = yes for non installed systems, to clean up /opt/zimbra\n    DETECTDIRS=\"db bin/zmcontrol redolog index store conf/localconfig.xml data\"\n    for i in $DETECTDIRS; do\n      if [ -e \"/opt/zimbra/$i\" ]; then\n        INSTALLED=\"yes\"\n      fi\n    done\n    if [ x$INSTALLED = \"xyes\" ]; then\n      echo \"\"\n      echo \"The Zimbra Collaboration Server does not appear to be installed,\"\n      echo \"yet there appears to be a ZCS directory structure in /opt/zimbra.\"\n      askYN \"Would you like to delete /opt/zimbra before installing?\" \"N\"\n      REMOVE=\"$response\"\n    else\n      REMOVE=\"yes\"\n    fi\n  fi\n\n}\n\nsetDefaultsFromExistingConfig() {\n\n  if [ ! -f \"$SAVEDIR/config.save\" ]; then\n    return\n  fi\n  echo \"\"\n  echo \"Setting defaults from saved config in $SAVEDIR/config.save\"\n  source $SAVEDIR/config.save\n\n  HOSTNAME=${zimbra_server_hostname}\n  LDAPHOST=${ldap_host}\n  LDAPPORT=${ldap_port}\n  SNMPTRAPHOST=${snmp_trap_host:-$SNMPTRAPHOST}\n  SMTPSOURCE=${smtp_source:-$SMTPSOURCE}\n  SMTPDEST=${smtp_destination:-$SMTPDEST}\n  SNMPNOTIFY=${snmp_notify:-0}\n  SMTPNOTIFY=${smtp_notify:-0}\n  LDAPROOTPW=${ldap_root_password}\n  LDAPZIMBRAPW=${zimbra_ldap_password}\n  LDAPPOSTPW=${ldap_postfix_password}\n  LDAPREPPW=${ldap_replication_password}\n  LDAPAMAVISPW=${ldap_amavis_password}\n  LDAPNGINXPW=${ldap_nginx_password}\n\n  echo \"   HOSTNAME=${zimbra_server_hostname}\"\n  echo \"   LDAPHOST=${ldap_host}\"\n  echo \"   LDAPPORT=${ldap_port}\"\n  echo \"   SNMPTRAPHOST=${snmp_trap_host}\"\n  echo \"   SMTPSOURCE=${smtp_source}\"\n  echo \"   SMTPDEST=${smtp_destination}\"\n  echo \"   SNMPNOTIFY=${snmp_notify:-0}\"\n  echo \"   SMTPNOTIFY=${smtp_notify:-0}\"\n  echo \"   LDAPROOTPW=*\"\n  echo \"   LDAPZIMBRAPW=*\"\n  echo \"   LDAPPOSTPW=*\"\n  echo \"   LDAPREPPW=*\"\n  echo \"   LDAPAMAVISPW=*\"\n  echo \"   LDAPNGINXPW=*\"\n\n}\n\nrestoreExistingConfig() {\n  if [ -d $RESTORECONFIG ]; then\n    RF=\"$RESTORECONFIG/localconfig.xml\"\n  fi\n  if [ -f $RF ]; then\n    echo -n \"Restoring existing configuration file from $RF...\"\n    cp -f $RF /opt/zimbra/conf/localconfig.xml\n    echo \"done\"\n  fi\n}\n\n# deprecated by the move of zimlets to /opt/zimbra/zimlets-deployed which isn't removed on upgrade\nrestoreZimlets() {\n  if [ -d $SAVEDIR/zimlet -a -d /opt/zimbra/mailboxd/webapps/service ]; then\n    cp -rf $SAVEDIR/zimlet /opt/zimbra/mailboxd/webapps/service/\n    chown -R zimbra:zimbra /opt/zimbra/mailboxd/webapps/service/zimlet\n    chmod 775 /opt/zimbra/mailboxd/webapps/service/zimlet\n  fi\n}\n\nrestoreCerts() {\n  if [ -f \"$SAVEDIR/keystore\" -a -d \"/opt/zimbra/jetty/etc\" ]; then\n    cp $SAVEDIR/keystore /opt/zimbra/jetty/etc/keystore\n    chown zimbra:zimbra /opt/zimbra/jetty/etc/keystore\n    chmod u+w /opt/zimbra/jetty/etc/keystore\n  elif [ -f \"$SAVEDIR/keystore\" -a -d \"/opt/zimbra/conf\" ]; then\n    cp $SAVEDIR/keystore /opt/zimbra/conf/keystore\n    chown zimbra:zimbra /opt/zimbra/conf/keystore\n    chmod u+w /opt/zimbra/conf/keystore\n  fi\n  if [ -f \"$SAVEDIR/smtpd.key\" ]; then\n    cp $SAVEDIR/smtpd.key /opt/zimbra/conf/smtpd.key\n    chown zimbra:zimbra /opt/zimbra/conf/smtpd.key\n  fi\n  if [ -f \"$SAVEDIR/smtpd.crt\" ]; then\n    cp $SAVEDIR/smtpd.crt /opt/zimbra/conf/smtpd.crt\n    chown zimbra:zimbra /opt/zimbra/conf/smtpd.crt\n  fi\n  if [ -f \"$SAVEDIR/slapd.crt\" ]; then\n    cp $SAVEDIR/slapd.crt /opt/zimbra/conf/slapd.crt\n    chown zimbra:zimbra /opt/zimbra/conf/slapd.crt\n  fi\n  if [ -f \"$SAVEDIR/nginx.key\" ]; then\n    cp $SAVEDIR/nginx.key /opt/zimbra/conf/nginx.key\n    chown zimbra:zimbra /opt/zimbra/conf/nginx.key\n  fi\n  if [ -f \"$SAVEDIR/nginx.crt\" ]; then\n    cp $SAVEDIR/nginx.crt /opt/zimbra/conf/nginx.crt\n    chown zimbra:zimbra /opt/zimbra/conf/nginx.crt\n  fi\n  mkdir -p /opt/zimbra/conf/ca\n  if [ -f \"$SAVEDIR/ca.key\" ]; then\n    cp $SAVEDIR/ca.key /opt/zimbra/conf/ca/ca.key\n    chown zimbra:zimbra /opt/zimbra/conf/ca/ca.key\n  fi\n  if [ -f \"$SAVEDIR/ca.pem\" ]; then\n    cp $SAVEDIR/ca.pem /opt/zimbra/conf/ca/ca.pem\n    chown zimbra:zimbra /opt/zimbra/conf/ca/ca.pem\n  fi\n  if [ -f \"/opt/zimbra/jetty/etc/keystore\" ]; then\n    chown zimbra:zimbra /opt/zimbra/jetty/etc/keystore\n    chmod u+w /opt/zimbra/jetty/etc/keystore\n  fi\n}\n\nsaveExistingConfig() {\n  if [ $UPGRADE != \"yes\" -o $FORCE_UPGRADE = \"yes\" ]; then\n    return\n  fi\n\n  echo \"\"\n  echo \"Saving existing configuration file to $SAVEDIR\"\n\n  # Since the location to java has changed, we need to fix localconfig.xml before we save the configuration\n  # and start the upgrade process\n\n  if [ -x \"/opt/zimbra/bin/zmlocalconfig\" ]; then\n    runAsZimbra \"zmlocalconfig -e zimbra_java_home=/opt/zimbra/common/lib/jvm/java\"\n    runAsZimbra \"zmlocalconfig -e mailboxd_truststore=/opt/zimbra/common/lib/jvm/java/lib/security/cacerts\"\n  fi\n  if [ ! -d \"$SAVEDIR\" ]; then\n    mkdir -p $SAVEDIR\n  fi\n  # make copies of existing save files\n  for f in localconfig.xml config.save keystore cacerts smtpd.key smtpd.crt slapd.key slapd.crt ca.key backup.save; do\n    if [ -f \"${SAVEDIR}/${f}\" ]; then\n      for (( i=0 ;; i++ )); do\n        if [ ! -f \"${SAVEDIR}/${ZMVERSION_CURRENT}/${i}/${f}\" ]; then\n          mkdir -p ${SAVEDIR}/${ZMVERSION_CURRENT}/${i} 2> /dev/null\n          mv -f \"${SAVEDIR}/${f}\" \"${SAVEDIR}/${ZMVERSION_CURRENT}/${i}/${f}\"\n          break\n        fi\n      done\n    fi\n  done\n  # yes, it needs massaging to be fed back in...\n  if [ -x \"/opt/zimbra/bin/zmlocalconfig\" ]; then\n    runAsZimbra \"zmlocalconfig -s | sed -e \\\"s/ = \\(.*\\)/=\\'\\1\\'/\\\" > $SAVEDIR/config.save\"\n  fi\n  if [ -f \"/opt/zimbra/conf/localconfig.xml\" ]; then\n    cp -f /opt/zimbra/conf/localconfig.xml $SAVEDIR/localconfig.xml\n  fi\n  if [ -f \"/opt/zimbra/common/lib/jvm/java/lib/security/cacerts\" ]; then\n    cp -f /opt/zimbra/common/lib/jvm/java/lib/security/cacerts $SAVEDIR\n  elif [ -f \"/opt/zimbra/java/lib/security/cacerts\" ]; then\n    cp -f /opt/zimbra/java/lib/security/cacerts $SAVEDIR\n  fi\n  if [ -f \"/opt/zimbra/jetty/etc/keystore\" ]; then\n    cp -f /opt/zimbra/jetty/etc/keystore $SAVEDIR\n  fi\n  if [ -f \"/opt/zimbra/conf/smtpd.key\" ]; then\n    cp -f /opt/zimbra/conf/smtpd.key $SAVEDIR\n  fi\n  if [ -f \"/opt/zimbra/conf/smtpd.crt\" ]; then\n    cp -f /opt/zimbra/conf/smtpd.crt $SAVEDIR\n  fi\n  if [ -f \"/opt/zimbra/conf/slapd.key\" ]; then\n    cp -f /opt/zimbra/conf/slapd.key $SAVEDIR\n  fi\n  if [ -f \"/opt/zimbra/conf/slapd.crt\" ]; then\n    cp -f /opt/zimbra/conf/slapd.crt $SAVEDIR\n  fi\n  if [ -f \"/opt/zimbra/conf/nginx.key\" ]; then\n    cp -f /opt/zimbra/conf/nginx.key $SAVEDIR\n  fi\n  if [ -f \"/opt/zimbra/conf/nginx.crt\" ]; then\n    cp -f /opt/zimbra/conf/nginx.crt $SAVEDIR\n  fi\n  if [ -f \"/opt/zimbra/conf/ca/ca.key\" ]; then\n    cp -f /opt/zimbra/conf/ca/ca.key $SAVEDIR\n  fi\n  if [ -f \"/opt/zimbra/conf/ca/ca.pem\" ]; then\n    cp -f /opt/zimbra/conf/ca/ca.pem $SAVEDIR\n  fi\n  if [ -d \"/opt/zimbra/mailboxd/webapps/service/zimlet\" ]; then\n    cp -rf /opt/zimbra/mailboxd/webapps/service/zimlet $SAVEDIR\n  fi\n  if [ -x /opt/zimbra/bin/zmschedulebackup ]; then\n    runAsZimbra \"zmschedulebackup -s > $SAVEDIR/backup.save\"\n  fi\n  if [ -d /opt/zimbra/wiki ]; then\n    cp -rf /opt/zimbra/wiki $SAVEDIR\n  fi\n\n  if [ -f \"/opt/zimbra/.enable_replica\" ]; then\n    rm -f /opt/zimbra/.enable_replica\n  fi\n\n  if [ -f /opt/zimbra/data/ldap/config/cn\\=config.ldif ]; then\n    if [ -f /opt/zimbra/data/ldap/config/cn\\=config/olcDatabase\\=\\{2\\}mdb/olcOverlay\\=*syncprov.ldif ]; then\n      touch /opt/zimbra/.enable_replica\n    fi\n  fi\n}\n\nfindUbuntuExternalPackageDependencies() {\n  # Handle external packages like logwatch, mailutils depends on zimbra-mta.\n  if [ $INSTALLED = \"yes\" -a $ISUBUNTU = \"true\" ]; then\n    RABBITMQINSTALLED=\"no\"\n    isInstalled \"zimbra-onlyoffice\"\n    if [ x$PKGINSTALLED != \"x\" ]; then\n      RABBITMQINSTALLED=\"yes\"\n    fi\n\n    $PACKAGERMSIMULATE $INSTALLED_PACKAGES > /dev/null 2>&1\n    if [ $? -ne 0 ]; then\n      EXTPACKAGESTMP=`$PACKAGERMSIMULATE $INSTALLED_PACKAGES 2>&1 | grep \" depends on \" | cut -d' ' -f2 | grep -v zimbra`\n      for p in $EXTPACKAGESTMP; do\n        EXTPACKAGES=\"$p $EXTPACKAGES\"\n      done\n\n      if [ -z \"$EXTPACKAGES\" ]; then\n        echo \"External package dependencies not found\"\n      else\n        echo \"External package dependencies found: $EXTPACKAGES\"\n        $PACKAGERMSIMULATE $INSTALLED_PACKAGES $EXTPACKAGES >> $LOGFILE 2>&1\n        if [ $? -eq 0 ]; then\n          while :; do\n            askYN \"$EXTPACKAGES package[s] will be removed. Continue?\" \"N\"\n            if [ $response = \"no\" ]; then\n              askYN \"Exit?\" \"N\"\n              if [ $response = \"yes\" ]; then\n                removeErrorMessage\n              fi\n            else\n              break\n            fi\n          done\n        fi\n      fi\n    fi\n  fi\n}\n\nremoveErrorMessage() {\n  echo \"Can not remove packages. Check $LOGFILE for details.\"\n  echo \"Exiting - the system is unchanged\"\n  exit 1\n}\n\nremoveNalpeironPackages() {\n\tnalpeironPackages=\"zimbra-nalpeiron-offline-daemon nalpdaemon nalppgsql\"\n\tfor i in $nalpeironPackages; do\n\t\tisInstalled $i\n\t\tif [ x$PKGINSTALLED != \"x\" ]; then\n\t\t\techo -n \"   Removing $i...\"\n\t\t\t$PACKAGERM $i >/dev/null 2>&1\n\t\t\techo \"done\"\n\t\tfi\n\tdone\n\tif [ -f /etc/sudoers.d/02_zimbra-nalpdaemon ]; then\n\t\trm /etc/sudoers.d/02_zimbra-nalpdaemon\n\tfi\n}\n\nremoveExistingPackages() {\n  removeNalpeironPackages\n  echo \"\"\n  echo \"Removing existing packages\"\n  echo \"\"\n  $REPORM zimbra-* >>$LOGFILE 2>&1\n  if [ $? -ne 0 ]; then\n      echo \"Failed to remove existing zimbra packages\"\n      exit 1;\n  else\n      echo \"done\"\n  fi\n}\n\nremoveZextrasPackagesIfInstalled() {\n\tfor i in $ZEXTRAS_PACKAGES; do\n\t\techo \"\"\n\t\techo \"Remove $i if it is installed ...\"\n\t\tisInstalled $i\n\t\tif [ x$PKGINSTALLED != \"x\" ]; then\n\t\t\techo -n \"   $i FOUND...\"\n\t\t\techo \"\"\n\t\t\techo -n \"   Removing $i...\"\n\t\t\t$PACKAGERM $i >/dev/null 2>&1\n\t\t\techo \"done\"\n\t\tfi\n\tdone\n}\n\nremoveUnsupportedPackagesIfInstalled() {\n\tfor i in $DEPRECATED_PACKAGES_IN_10; do\n\t\techo \"\"\n\t\techo \"Remove $i if it is installed ...\"\n\t\tisInstalled $i\n\t\tif [ x$PKGINSTALLED != \"x\" ]; then\n\t\t\techo -n \"   $i FOUND...\"\n\t\t\techo \"\"\n\t\t\techo -n \"   Removing $i...\"\n\t\t\t$PACKAGERM $i >/dev/null 2>&1\n\t\t\techo \"done\"\n\t\tfi\n\tdone\n}\n\n\nremoveExistingInstall() {\n  if [ $INSTALLED = \"yes\" ]; then\n    echo \"\"\n    echo \"Shutting down zimbra mail\"\n    shutDownSystem\n    if [ -f \"/opt/zimbra/bin/zmiptables\" ]; then\n      /opt/zimbra/bin/zmiptables -u\n    fi\n\n    isInstalled \"zimbra-ldap\"\n    if [ x$PKGINSTALLED != \"x\" ]; then\n      if ( test -x \"/opt/zimbra/common/sbin/slapcat\" || test -x \"/opt/zimbra/openldap/sbin/slapcat\" ) && test x\"$UNINSTALL\" != \"xyes\" && test x\"$REMOVE\" != \"xyes\"; then\n        if [ -d \"/opt/zimbra/data/ldap/config\" ]; then\n          echo \"\"\n          echo -n \"Backing up the ldap database...\"\n          tmpfile=`mktemp -t slapcat.XXXXXX 2> /dev/null` || { echo \"Failed to create tmpfile\"; exit 1; }\n          mkdir -p /opt/zimbra/data/ldap\n          chown -R zimbra:zimbra /opt/zimbra/data/ldap\n          runAsZimbra \"/opt/zimbra/libexec/zmslapcat /opt/zimbra/data/ldap\"\n          if [ $? != 0 ]; then\n            echo \"failed.\"\n          else\n            echo \"done.\"\n          fi\n          chmod 640 /opt/zimbra/data/ldap/ldap.bak\n          if [ -x /opt/zimbra/libexec/zmslapadd ]; then\n            if [ -f /opt/zimbra/data/ldap/config/cn\\=config/olcDatabase\\=\\{3\\}mdb.ldif -o -f /opt/zimbra/data/ldap/config/cn\\=config/olcDatabase\\=\\{3\\}hdb.ldif ]; then\n              echo \"\"\n              echo -n \"Backing up the ldap accesslog database...\"\n              runAsZimbra \"/opt/zimbra/libexec/zmslapcat -a /opt/zimbra/data/ldap\"\n              if [ $? != 0 ]; then\n                echo \"failed.\"\n              else\n                echo \"done.\"\n              fi\n              chmod 640 /opt/zimbra/data/ldap/ldap-accesslog.bak\n            fi\n          fi\n        fi\n      fi\n      if [ x\"$OLD_LDR_PATH\" != \"x\" ]; then\n        LD_LIBRARY_PATH=$OLD_LDR_PATH\n      fi\n    fi\n    isInstalled \"zimbra-zco\"\n    if [ x$PKGINSTALLED != \"x\" ]; then\n      echo -n \"Removing stale package zimbra-zco while upgrade...\"\n      $PACKAGERM zimbra-zco >/dev/null 2>&1\n      echo \"done\"\n    fi\n    if [ \"$UPGRADE\" = \"yes\" -a \"$POST87UPGRADE\" = \"true\" -a \"$FORCE_UPGRADE\" != \"yes\" -a \"$ZM_CUR_BUILD\" != \"$ZM_INST_BUILD\" ]; then\n      echo \"Upgrading the remote packages\"\n      removeZextrasPackagesIfInstalled\n      removeUnsupportedPackagesIfInstalled\n    else\n      removeExistingPackages\n    fi\n    if egrep -q '^%zimbra[[:space:]]' /etc/sudoers 2>/dev/null; then\n      local sudotmp=`mktemp -t zsudoers.XXXXX 2> /dev/null` || { echo \"Failed to create tmpfile\"; exit 1; }\n      SUDOMODE=`perl -e 'my $mode=(stat(\"/etc/sudoers\"))[2];printf(\"%04o\\n\",$mode & 07777);'`\n      egrep -v \"^\\%zimbra[[:space:]]\" /etc/sudoers > $sudotmp\n      mv -f $sudotmp /etc/sudoers\n      chmod $SUDOMODE /etc/sudoers\n    fi\n    echo \"\"\n    if [ -d \"/opt/zimbra/jetty/webapps\" ]; then\n      echo \"Removing deployed webapp directories\"\n      deleteWebApp zimbra jetty\n      deleteWebApp zimbraAdmin jetty\n      deleteWebApp service jetty\n      /bin/rm -rf /opt/zimbra/jetty/work\n    fi\n  fi\n\n  if [ $REMOVE = \"yes\" ]; then\n    isInstalled zimbra-base\n    if [ x$PKGINSTALLED != \"x\" ]; then\n        echo -n \"   zimbra-base...\"\n        $REPORM zimbra-base >>$LOGFILE 2>&1\n        echo \"done\"\n    fi\n\n    if [ ! -L \"/opt/zimbra\" ]; then\n      echo \"\"\n      echo \"Removing /opt/zimbra\"\n      umount /opt/zimbra/amavisd/tmp > /dev/null 2>&1\n      MOUNTPOINTS=`mount | awk '{print $3}' | grep /opt/zimbra/`\n      for mp in $MOUNTPOINTS; do\n        if [ x$mp != \"x/opt/zimbra\" ]; then\n          /bin/rm -rf ${mp}/*\n          umount -f ${mp}\n        fi\n      done\n\n      for i in `ls /opt/zimbra`; do\n        if [ x$i != \"xlost+found\" ]; then\n          /bin/rm -rf /opt/zimbra/$i\n        fi\n      done\n\n      if [ -e \"/opt/zimbra/.enable_replica\" ]; then\n        /bin/rm -f /opt/zimbra/.enable_replica\n      fi\n\n      if [ -x /usr/bin/crontab ]; then\n        echo -n \"Removing zimbra crontab entry...\"\n        /usr/bin/crontab -u zimbra -r 2> /dev/null\n        echo \"done.\"\n      fi\n\n      if [ -L /usr/sbin/sendmail ]; then\n        if [ -x /bin/readlink ]; then\n          SMPATH=$(/bin/readlink /usr/sbin/sendmail)\n          if [ x$SMPATH = x\"/opt/zimbra/postfix/sbin/sendmail\" -o x$SMPATH = x\"/opt/zimbra/common/sbin/sendmail\" ]; then\n            /bin/rm -f /usr/sbin/sendmail\n          fi\n        fi\n      fi\n\n      if [ -L /etc/aliases ]; then\n        if [ -x /bin/readlink ]; then\n          SMPATH=$(/bin/readlink /etc/aliases)\n          if [ x$SMPATH = x\"/opt/zimbra/postfix/conf/aliases\" -o x$SMPATH = x\"/opt/zimbra/common/conf/aliases\" ]; then\n            rm -f /etc/aliases\n          fi\n        fi\n      fi\n\n      if [ -f /etc/syslog-ng/syslog-ng.conf ]; then\n        egrep -q 'zimbra' /etc/syslog-ng/syslog-ng.conf\n        if [ $? = 0 ]; then\n          echo -n \"Cleaning up /etc/syslog-ng/syslog-ng.conf...\"\n          sed -i -e '/zimbra/d' /etc/syslog-ng/syslog-ng.conf\n          sed -i -e 's/filter f_messages   { not facility(news, mail) and not filter(f_iptables) and/filter f_messages   { not facility(news, mail) and not filter(f_iptables); };/' /etc/syslog-ng/syslog-ng.conf\n          sed -i -e 's/^                               local4, local5, local6, local7) and not/                               local4, local5, local6, local7); };/' /etc/syslog-ng/syslog-ng.conf\n          if [ -x /sbin/rcsyslog ]; then\n            /sbin/rcsyslog restart > /dev/null 2>&1\n            echo \"done.\"\n          else\n            echo \"Unable to restart syslog-ng service. Please do it manually.\"\n          fi\n        fi\n      elif [ -f /etc/rsyslog.conf ]; then\n        if [ -d /etc/rsyslog.d ]; then\n          if [ -f /etc/rsyslog.d/60-zimbra.conf ]; then\n            echo -n \"Cleaning up /etc/rsyslog.d...\"\n            rm -f /etc/rsyslog.d/60-zimbra.conf\n            if [ -x /usr/bin/systemctl ]; then\n              /usr/sbin/systemctl restart rsyslog.service >/dev/null 2>&1\n              echo \"done.\"\n            elif [ -x /usr/bin/service ]; then\n              /usr/sbin/service rsyslog restart >/dev/null 2>&1\n              echo \"done.\"\n            elif [ -x /etc/init.d/rsyslog ]; then\n              /etc/init.d/rsyslog restart > /dev/null 2>&1\n              echo \"done.\"\n            else\n              echo \"Unable to restart rsyslog service. Please do it manually.\"\n            fi\n          else\n            egrep -q 'zimbra' /etc/rsyslog.conf\n            if [ $? = 0 ]; then\n              echo -n \"Cleaning up /etc/rsyslog.conf...\"\n              sed -i -e '/zimbra/d' /etc/rsyslog.conf\n              if [ $PLATFORM = \"RHEL6_64\" -o $PLATFORM = \"RHEL7_64\" -o $PLATFORM = \"RHEL8_64\" -o $PLATFORM = \"RHEL9_64\" ]; then\n                sed -i -e 's/^*.info;local0.none;local1.none;mail.none;auth.none/*.info/' /etc/rsyslog.conf\n                sed -i -e 's/^*.info;local0.none;local1.none;auth.none/*.info/' /etc/rsyslog.conf\n              fi\n              if [ -x /usr/bin/systemctl ]; then\n                /usr/sbin/systemctl restart rsyslog.service >/dev/null 2>&1\n                echo \"done.\"\n              elif [ -x /usr/bin/service ]; then\n                /usr/sbin/service rsyslog restart >/dev/null 2>&1\n                echo \"done.\"\n              elif [ -x /etc/init.d/rsyslog ]; then\n                /etc/init.d/rsyslog restart > /dev/null 2>&1\n                echo \"done.\"\n              else\n                echo \"Unable to restart rsyslog service. Please do it manually.\"\n              fi\n            fi\n          fi\n        fi\n      fi\n\n      echo -n \"Cleaning up zimbra init scripts...\"\n      if [ -x /sbin/chkconfig ]; then\n        /sbin/chkconfig zimbra off 2> /dev/null\n        /sbin/chkconfig --del zimbra 2> /dev/null\n      else\n        /bin/rm -f /etc/rc*.d/S99zimbra 2> /dev/null\n        /bin/rm -f /etc/rc*.d/K01zimbra 2> /dev/null\n      fi\n      if [ -f /etc/init.d/zimbra ]; then\n        /bin/rm -f /etc/init.d/zimbra\n      fi\n      echo \"done.\"\n\n      if [ -f /etc/logrotate.d/zimbra ]; then\n        echo -n \"Cleaning up /etc/logrotate.d/zimbra...\"\n        /bin/rm -f /etc/logrotate.d/zimbra 2> /dev/null\n        echo \"done.\"\n      fi\n\n      if [ -f /etc/security/limits.conf ]; then\n        echo -n \"Cleaning up /etc/security/limits.conf...\"\n        egrep -q '^zimbra|^liquid' /etc/security/limits.conf\n        if [ $? = 0 ]; then\n          sed -i -e '/^zimbra/d' -e '/^liquid/d' /etc/security/limits.conf\n        fi\n        echo \"done.\"\n      fi\n\n      if [ -f /etc/security/limits.d/80-zimbra.conf ]; then\n        echo -n \"Cleaning up /etc/security/limits.d/80-zimbra.conf...\"\n        rm -f /etc/security/limits.d/80-zimbra.conf\n        echo \"done.\"\n      fi\n\n      if [ -f /etc/security/limits.d/10-zimbra.conf ]; then\n        echo -n \"Cleaning up /etc/security/limits.d/10-zimbra.conf...\"\n        rm -f /etc/security/limits.d/10-zimbra.conf\n        echo \"done.\"\n      fi\n\n      for mp in $MOUNTPOINTS; do\n        if [ x$mp != \"x/opt/zimbra\" ]; then\n          mkdir -p ${mp}\n          mount ${mp}\n        fi\n      done\n\n      echo \"\"\n      echo \"Finished removing Zimbra Collaboration Server.\"\n      echo \"\"\n    fi\n  fi\n}\n\nsetServiceIP() {\n  askNonBlank \"Please enter the service IP for this host\" \"$SERVICEIP\"\n  SERVICEIP=$response\n}\n\nsetHostName() {\n\n  OLD=$HOSTNAME\n  while :; do\n    askNonBlank \"Please enter the logical hostname for this host\" \"$HOSTNAME\"\n\n    fq=`isFQDN $response`\n\n    if [ $fq = 1 ]; then\n      HOSTNAME=$response\n      break\n    else\n      echo \"\"\n      echo \"Please enter a fully qualified hostname\"\n    fi\n  done\n  if [ \"x$OLD\" != \"x$HOSTNAME\" ]; then\n    if [ \"x$SMTPHOST\" = \"x$OLD\" ]; then\n      SMTPHOST=$HOSTNAME\n    fi\n    if [ \"x$SNMPTRAPHOST\" = \"x$OLD\" ]; then\n      SNMPTRAPHOST=$HOSTNAME\n    fi\n    if [ \"x$CREATEDOMAIN\" = \"x$OLD\" ]; then\n      CREATEDOMAIN=$HOSTNAME\n    fi\n  fi\n}\n\ncheckConflicts() {\n  echo \"\"\n  echo \"Checking for sendmail/postfix\"\n  echo \"\"\n\n  if [ -f /var/lock/subsys/postfix ]; then\n    askYN \"Postfix appears to be running.  Shut it down?\" \"Y\"\n    if [ $response = \"yes\" ]; then\n      /etc/init.d/postfix stop\n      if [ -x /sbin/chkconfig ]; then\n        /sbin/chkconfig postfix off\n      fi\n    fi\n  fi\n\n  if [ -f /var/lock/subsys/sendmail ]; then\n    askYN \"Sendmail appears to be running.  Shut it down?\" \"Y\"\n    if [ $response = \"yes\" ]; then\n      /etc/init.d/sendmail stop\n      if [ -x /sbin/chkconfig ]; then\n        /sbin/chkconfig sendmail off\n      fi\n    fi\n  fi\n\n  echo \"\"\n  echo \"Checking for exim4\"\n  echo \"\"\n\n  if [ -f /var/run/exim4/exim.pid ]; then\n    askYN \"Exim4 appears to be running.  Shut it down?\" \"Y\"\n    if [ $response = \"yes\" ]; then\n      /etc/init.d/exim4 stop\n      /usr/sbin/update-rc.d -f exim4 remove\n    fi\n  fi\n\n  echo \"\"\n  echo \"Checking for mysqld\"\n  echo \"\"\n\n  if [ -f /var/lock/subsys/mysqld ]; then\n    while :; do\n      askYN \"Mysql appears to be running.  Shut it down?\" \"Y\"\n      if [ $response = \"yes\" ]; then\n        /etc/init.d/mysqld stop\n        if [ -x /sbin/chkconfig ]; then\n          /sbin/chkconfig mysqld off\n        fi\n        break\n      else\n        echo \"Installation will probably fail with mysql running\"\n        askYN \"Install anyway?\" \"N\"\n        if [ $response = \"yes\" ]; then\n          break\n        else\n          askYN \"Exit?\" \"N\"\n          if [ $response = \"yes\" ]; then\n            echo \"Exiting - the system is unchanged\"\n            exit 1\n          fi\n        fi\n      fi\n    done\n  fi\n}\n\ncleanUp() {\n  # Dump all the config data to a file\n  runAsZimbra \"zmlocalconfig -s > .localconfig.save.$$\"\n  runAsZimbra \"zmprov gs $HOSTNAME > .zmprov.$HOSTNAME.save.$$\"\n  runAsZimbra \"zmprov gacf $HOSTNAME > .zmprov.gacf.save.$$\"\n}\n\nverifyLdapServer() {\n\n  if [ $LDAP_HERE = \"yes\" ]; then\n    LDAPOK=\"yes\"\n    return\n  fi\n\n  echo \"\"\n  echo -n  \"Contacting ldap server $LDAPHOST on $LDAPPORT...\"\n\n  $MYLDAPSEARCH -x -h $LDAPHOST -p $LDAPPORT -w $LDAPZIMBRAPW -D \"uid=zimbra,cn=admins,cn=zimbra\" > /dev/null 2>&1\n  LDAPRESULT=$?\n\n  if [ $LDAPRESULT != 0 ]; then\n    echo \"FAILED\"\n    LDAPOK=\"no\"\n  else\n    echo \"Success\"\n    LDAPOK=\"yes\"\n  fi\n}\n\nconfigurePackageServer() {\n  echo -e \"\"\n  response=\"no\"\n  TMP_PACKAGE_SERVER=\"repo.zimbra.com\"\n  if [ x\"$USE_ZIMBRA_PACKAGE_SERVER\" = \"x\" ]; then\n    askYN \"Use Zimbra's package repository\" \"Y\"\n    if [ $response = \"yes\" ]; then\n      USE_ZIMBRA_PACKAGE_SERVER=\"yes\"\n      PACKAGE_SERVER=\"repo.zimbra.com\"\n      response=\"no\"\n      echo $HOSTNAME | egrep -qe 'eng.zimbra.com$|lab.zimbra.com$|zimbradev.com$' > /dev/null 2>&1\n      if [ $? = 0 ]; then\n        askYN \"Use internal development repo\" \"N\"\n        if [ $response = \"yes\" ]; then\n          PACKAGE_SERVER=\"repo-dev.eng.zimbra.com\"\n        else\n          response=\"no\"\n          askYN \"Use internal production mirror\" \"N\"\n          if [ $response = \"yes\" ]; then\n            PACKAGE_SERVER=\"repo.eng.zimbra.com\"\n          fi\n        fi\n      fi\n    fi\n  fi\n\n  if [ x\"$USE_ZIMBRA_PACKAGE_SERVER\" = \"xyes\" ]; then # Handle automated installations correctly\n    echo \"\";\n    if [ x\"$PACKAGE_SERVER\" = \"x\" ]; then # Allow config files w/ no PACKAGE_SERVER variable set\n      PACKAGE_SERVER=$TMP_PACKAGE_SERVER\n    fi\n    echo $PLATFORM | egrep -q \"UBUNTU|DEBIAN\"\n    if [ $? = 0 ]; then\n      if [ $PLATFORM = \"UBUNTU24_64\" ]; then\n        repo=\"noble\"\n      elif [ $PLATFORM = \"UBUNTU22_64\" ]; then\n        repo=\"jammy\"\t      \n      elif [ $PLATFORM = \"UBUNTU20_64\" ]; then\n        repo=\"focal\"\n      elif [ $PLATFORM = \"UBUNTU18_64\" ]; then\n        repo=\"bionic\"\n      elif [ $PLATFORM = \"UBUNTU16_64\" ]; then\n        repo=\"xenial\"\n      elif [ $PLATFORM = \"UBUNTU14_64\" ]; then\n        repo=\"trusty\"\n      elif [ $PLATFORM = \"UBUNTU12_64\" ]; then\n        repo=\"precise\"\n      else\n        print \"Aborting, unknown platform: $PLATFORM\"\n        exit 1\n      fi\n      gpg --list-keys --keyring /etc/apt/trusted.gpg.d/zimbra.gpg 2>/dev/null | grep -w 254F9170B966D193D6BAD300D5CEF8BF9BE6ED79 >/dev/null\n      if [ $? -ne 0 ]; then\n        echo \"Importing Zimbra GPG key\"\n        gpg --no-default-keyring --keyring /tmp/zimbra.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 9BE6ED79 >>$LOGFILE 2>&1\n        if [ $? -ne 0 ]; then\n          echo \"ERROR: Unable to retrive Zimbra GPG key for package validation\"\n          echo \"Please fix system to allow normal package installation before proceeding\"\n          exit 1\n        else\n\t  gpg --no-default-keyring --keyring /tmp/zimbra.gpg --export > /etc/apt/trusted.gpg.d/zimbra.gpg\n          if [ $? -ne 0 ]; then\n            echo \"ERROR: Unable to export Zimbra GPG key for package validation\"\n\t    exit 1\n\t  else\n\t    rm -f /tmp/zimbra.gpg\n\t  fi\n        fi\n      fi\n      echo\n      echo \"Configuring package repository\"\n      apt-get install -y apt-transport-https >>$LOGFILE 2>&1\n      if [ $? -ne 0 ]; then\n        echo \"ERROR: Unable to install packages via apt-get\"\n        echo \"Please fix system to allow normal package installation before proceeding\"\n        exit 1\n      fi\nif [ \"$PLATFORM\" = \"UBUNTU24_64\" ]; then\n  cat > /etc/apt/sources.list.d/zimbra.sources << EOF\nTypes: deb deb-src\nURIs: https://$PACKAGE_SERVER/apt/87\nSuites: $repo\nComponents: zimbra\nArchitectures: amd64\nSigned-By: /etc/apt/trusted.gpg.d/zimbra.gpg\n\nTypes: deb\nURIs: https://$PACKAGE_SERVER/apt/1000\nSuites: $repo\nComponents: zimbra\nArchitectures: amd64\nSigned-By: /etc/apt/trusted.gpg.d/zimbra.gpg\n\nTypes: deb\nURIs: https://$PACKAGE_SERVER/apt/1010\nSuites: $repo\nComponents: zimbra\nArchitectures: amd64\nSigned-By: /etc/apt/trusted.gpg.d/zimbra.gpg\nEOF\n\n  if [ \"x$ZMTYPE_INSTALLABLE\" = \"xNETWORK\" ]; then\n    cat >> /etc/apt/sources.list.d/zimbra.sources << EOF\n\nTypes: deb\nURIs: https://$PACKAGE_SERVER/apt/1000-ne\nSuites: $repo\nComponents: zimbra\nArchitectures: amd64\nSigned-By: /etc/apt/trusted.gpg.d/zimbra.gpg\n\nTypes: deb\nURIs: https://$PACKAGE_SERVER/apt/1010-ne\nSuites: $repo\nComponents: zimbra\nArchitectures: amd64\nSigned-By: /etc/apt/trusted.gpg.d/zimbra.gpg\nEOF\n\n    cat > /etc/apt/sources.list.d/zimbra-onlyoffice.sources << EOF\nTypes: deb\nURIs: https://$PACKAGE_SERVER/apt/onlyoffice-1010\nSuites: $repo\nComponents: zimbra\nArchitectures: amd64\nSigned-By: /etc/apt/trusted.gpg.d/zimbra.gpg\nEOF\n  fi\n\nelse\n  cat > /etc/apt/sources.list.d/zimbra.list << EOF\ndeb     [arch=amd64] https://$PACKAGE_SERVER/apt/87 $repo zimbra\ndeb-src [arch=amd64] https://$PACKAGE_SERVER/apt/87 $repo zimbra\ndeb     [arch=amd64] https://$PACKAGE_SERVER/apt/1000 $repo zimbra\ndeb     [arch=amd64] https://$PACKAGE_SERVER/apt/1010 $repo zimbra\nEOF\n\n  if [ \"x$ZMTYPE_INSTALLABLE\" = \"xNETWORK\" ]; then\n    cat >> /etc/apt/sources.list.d/zimbra.list << EOF\ndeb     [arch=amd64] https://$PACKAGE_SERVER/apt/1000-ne $repo zimbra\ndeb     [arch=amd64] https://$PACKAGE_SERVER/apt/1010-ne $repo zimbra\nEOF\n\n    cat > /etc/apt/sources.list.d/zimbra-onlyoffice.list << EOF\ndeb     [arch=amd64] https://$PACKAGE_SERVER/apt/onlyoffice-1010 $repo zimbra\nEOF\n  fi\nfi\n      apt-get update >>$LOGFILE 2>&1\n      if [ $? -ne 0 ]; then\n        echo \"ERROR: Unable to install packages via apt-get\"\n        echo \"Please fix system to allow normal package installation before proceeding\"\n        exit 1\n      fi\n    else\n      if [ $PLATFORM = \"RHEL6_64\" ]; then\n        repo=\"rhel6\"\n      elif [ $PLATFORM = \"RHEL7_64\" ]; then\n        repo=\"rhel7\"\n     elif [ $PLATFORM = \"RHEL8_64\" ]; then\n        repo=\"rhel8\"\n     elif [ $PLATFORM = \"RHEL9_64\" ]; then\n\trepo=\"rhel9\"\n      else\n        print \"Aborting, unknown platform: $PLATFORM\"\n        exit 1\n      fi\n      if [ $PLATFORM = \"RHEL9_64\" ]; then\n\t      rpm -q gpg-pubkey-7c66bd84-6583eafa > /dev/null\n      else\n\t      rpm -q gpg-pubkey-0f30c305-5564be70 > /dev/null\n      fi\n      if [ $? -ne 0 ]; then\n        echo \"Importing Zimbra GPG key\"\n\tif [ $PLATFORM = \"RHEL9_64\" ]; then\n\t\trpm --import https://files.zimbra.com/downloads/security/public-sha-256.key >>$LOGFILE 2>&1\n\telse\n\t\trpm --import https://files.zimbra.com/downloads/security/public.key >>$LOGFILE 2>&1\n\tfi\n        if [ $? -ne 0 ]; then\n          echo \"ERROR: Unable to retrive Zimbra GPG key for package validation\"\n          echo \"Please fix system to allow normal package installation before proceeding\"\n          exit 1\n        fi\n      fi\n      echo\n      echo \"Configuring package repository\"\ncat > /etc/yum.repos.d/zimbra.repo <<EOF\n[zimbra]\nname=Zimbra RPM Repository\nbaseurl=https://$PACKAGE_SERVER/rpm/87/$repo\ngpgcheck=1\nenabled=1\n[zimbra-1000-oss]\nname=Zimbra New RPM Repository\nbaseurl=https://$PACKAGE_SERVER/rpm/1000/$repo\ngpgcheck=1\nenabled=1\n[zimbra-1010-oss]\nname=Zimbra 1010 OSS RPM Repository\nbaseurl=https://$PACKAGE_SERVER/rpm/1010/$repo\ngpgcheck=1\nenabled=1\nEOF\n      yum --disablerepo=* --enablerepo=zimbra clean metadata >>$LOGFILE 2>&1\n      yum check-update --disablerepo=* --enablerepo=zimbra --noplugins >>$LOGFILE 2>&1\n      yum --disablerepo=* --enablerepo=zimbra-1000-oss clean metadata >>$LOGFILE 2>&1\n      yum check-update --disablerepo=* --enablerepo=zimbra-1000-oss --noplugins >>$LOGFILE 2>&1\n      yum --disablerepo=* --enablerepo=zimbra-1010-oss clean metadata >>$LOGFILE 2>&1\n      yum check-update --disablerepo=* --enablerepo=zimbra-1010-oss --noplugins >>$LOGFILE 2>&1\nif [ x\"$ZMTYPE_INSTALLABLE\" = \"xNETWORK\" ]; then\ncat >> /etc/yum.repos.d/zimbra.repo <<EOF\n[zimbra-1000-network]\nname=Zimbra New RPM Repository\nbaseurl=https://$PACKAGE_SERVER/rpm/1000-ne/$repo\ngpgcheck=1\nenabled=1\nEOF\ncat >> /etc/yum.repos.d/zimbra.repo <<EOF\n[zimbra-1010-network]\nname=Zimbra 1010 NW RPM Repository\nbaseurl=https://$PACKAGE_SERVER/rpm/1010-ne/$repo\ngpgcheck=1\nenabled=1\nEOF\ncat > /etc/yum.repos.d/zimbra-onlyoffice.repo <<EOF\n[zimbra-onlyoffice]\nname=Zimbra Onlyoffice RPM Repository\nbaseurl=https://$PACKAGE_SERVER/rpm/onlyoffice-1010/$repo\ngpgcheck=1\nenabled=1\nEOF\n      yum --disablerepo=* --enablerepo=zimbra-1000-network clean metadata >>$LOGFILE 2>&1\n      yum check-update --disablerepo=* --enablerepo=zimbra-1000-network --noplugins >>$LOGFILE 2>&1\n      yum --disablerepo=* --enablerepo=zimbra-1010-network clean metadata >>$LOGFILE 2>&1\n      yum check-update --disablerepo=* --enablerepo=zimbra-1010-network --noplugins >>$LOGFILE 2>&1\n      yum --disablerepo=* --enablerepo=zimbra-onlyoffice clean metadata >>$LOGFILE 2>&1\n      yum check-update --disablerepo=* --enablerepo=zimbra-onlyoffice --noplugins >>$LOGFILE 2>&1\n\nfi\n      if [ $? -ne 0 -a $? -ne 100 ]; then\n        echo \"ERROR: yum check-update failed\"\n        echo \"Please validate ability to install packages\"\n        exit 1\n      fi\n    fi\n  fi\n}\n\n\ngetInstallPackages() {\n\n  echo \"\"\n  if [ $UPGRADE = \"yes\" ]; then\n    echo \"Scanning for any new or additional packages available for installation\"\n    echo \"Existing packages will be upgraded\"\n    echo \"    Upgrading zimbra-core\"\n  else\n    echo \"Select the packages to install\"\n  fi\n\n  APACHE_SELECTED=\"no\"\n  LOGGER_SELECTED=\"no\"\n  STORE_SELECTED=\"no\"\n  MTA_SELECTED=\"no\"\n  PROXY_SELECTED=\"no\"\n  LDAP_SELECTED=\"no\"\n  ONLYOFFICE_SELECTED=\"no\"\n  LICENSE_DAEMON_SELECTED=\"no\"\n\n  for i in $AVAILABLE_PACKAGES; do\n    if [ $i = \"zimbra-core\" ]; then\n      continue\n    fi\n    # Reset the response before processing the next package.\n    response=\"no\"\n\n    # If we're upgrading, and it's installed, don't ask stoopid questions\n    if [ $UPGRADE = \"yes\" ]; then\n      echo $INSTALLED_PACKAGES | grep $i > /dev/null 2>&1\n      if [ $? = 0 ]; then\n        echo \"    Upgrading $i\"\n        if [ $i = \"zimbra-mta\" ]; then\n          CONFLICTS=\"no\"\n          for j in $CONFLICT_PACKAGES; do\n            conflictInstalled $j\n            if [ \"x$CONFLICTINSTALLED\" != \"x\" ]; then\n              echo \"     Conflicting package: $CONFLICTINSTALLED\"\n              CONFLICTS=\"yes\"\n            fi\n          done\n          if [ $CONFLICTS = \"yes\" ]; then\n            echo \"\"\n            echo \"###ERROR###\"\n            echo \"\"\n            echo \"One or more package conflicts exists.\"\n            echo \"Please remove them before running this installer.\"\n            echo \"\"\n            echo \"Installation cancelled.\"\n            echo \"\"\n            exit 1\n          fi\n        fi\n        INSTALL_PACKAGES=\"$INSTALL_PACKAGES $i\"\n        if [ $i = \"zimbra-apache\" ]; then\n          APACHE_SELECTED=\"yes\"\n        elif [ $i = \"zimbra-logger\" ]; then\n          LOGGER_SELECTED=\"yes\"\n        elif [ $i = \"zimbra-license-daemon\" ]; then\n          LICENSE_DAEMON_SELECTED=\"yes\"\n        elif [ $i = \"zimbra-store\" ]; then\n          STORE_SELECTED=\"yes\"\n          checkLicenseDaemonServiceRunning $LICENSE_DAEMON_SELECTED\n        elif [ $i = \"zimbra-mta\" ]; then\n          MTA_SELECTED=\"yes\"\n        elif [ $i = \"zimbra-proxy\" ]; then\n          PROXY_SELECTED=\"yes\"\n        elif [ $i = \"zimbra-ldap\" ]; then\n          LDAP_SELECTED=\"yes\"\n        elif [ $i = \"zimbra-onlyoffice\" ]; then\n          ONLYOFFICE_SELECTED=\"yes\"\n        fi\n        continue\n      fi\n    fi\n\n    # askInstallPkgYN args : PROMPT REQUIRE_STORE=yes|no YES_STORE_DEFAULT=Y|N NO_STORE_DEFAULT=Y|N\n\n    ZIMBRAINTERNAL=no\n    echo $HOSTNAME | egrep -qe 'eng.zimbra.com$|lab.zimbra.com$|zimbradev.com$' > /dev/null 2>&1\n    if [ $? = 0 ]; then\n       ZIMBRAINTERNAL=yes\n    fi\n    if [ $i = \"zimbra-license-tools\" ]; then\n      response=\"yes\"\n    elif [ $i = \"zimbra-modern-ui\" ]; then\n      ifStoreSelectedY\n    elif [ $i = \"zimbra-modern-zimlets\" ]; then\n      ifStoreSelectedY\n    elif [ $i = \"zimbra-zimlet-document-editor\" ]; then\n      ifStoreSelectedY\n    elif [ $i = \"zimbra-zimlet-classic-document-editor\" ]; then\n      ifStoreSelectedY\n    elif [ $i = \"zimbra-zimlet-classic-set-default-client\" ]; then\n      ifStoreSelectedY\n    elif [ $i = \"zimbra-patch\" ]; then\n        if [ x\"$ZIMBRAINTERNAL\" = \"xyes\" ] && [ $STORE_SELECTED = \"yes\" ]; then\n            askYN \"Install $i\" \"Y\"\n        else\n            ifStoreSelectedY\n        fi\n    elif [ $i = \"zimbra-mta-patch\" ]; then\n        if [ x\"$ZIMBRAINTERNAL\" = \"xyes\" ] && [ $MTA_SELECTED = \"yes\" ]; then\n            askYN \"Install $i\" \"Y\"\n        else\n            response=\"$MTA_SELECTED\"\n        fi\n    elif [ $i = \"zimbra-proxy-patch\" ]; then\n        if [ x\"$ZIMBRAINTERNAL\" = \"xyes\" ] && [ $PROXY_SELECTED = \"yes\" ]; then\n            askYN \"Install $i\" \"Y\"\n        else\n            response=\"$PROXY_SELECTED\"\n        fi\n    elif [ $i = \"zimbra-ldap-patch\" ]; then\n\tif [ x\"$ZIMBRAINTERNAL\" = \"xyes\" ] && [ $LDAP_SELECTED = \"yes\" ]; then\n            askYN \"Install $i\" \"Y\"\n\telse\n            response=\"$LDAP_SELECTED\"\n\tfi\n    elif [ $i = \"zimbra-onlyoffice-patch\" ]; then\n        if [ x\"$ZIMBRAINTERNAL\" = \"xyes\" ] && [ $ONLYOFFICE_SELECTED = \"yes\" ]; then\n            askYN \"Install $i\" \"Y\"\n        else\n            response=\"$ONLYOFFICE_SELECTED\"\n        fi\n    elif [ $i = \"zimbra-lds-patch\" ]; then\n        if [ x\"$ZIMBRAINTERNAL\" = \"xyes\" ] && [ $LICENSE_DAEMON_SELECTED = \"yes\" ]; then\n            askYN \"Install $i\" \"Y\"\n        else\n            response=\"$LICENSE_DAEMON_SELECTED\"\n        fi\n    elif [ $i = \"zimbra-license-extension\" ]; then\n      ifStoreSelectedY\n    elif [ $i = \"zimbra-network-store\" ]; then\n      ifStoreSelectedY\n    elif [ $UPGRADE = \"yes\" ]; then\n      if [ $i = \"zimbra-archiving\" ]; then\n        askInstallPkgYN \"Install $i\" \"yes\" \"N\" \"N\"\n      elif [ $i = \"zimbra-imapd\" ]; then\n        askInstallPkgYN \"Install $i (BETA - for evaluation only)\" \"no\" \"N\" \"N\"\n      else\n        askYN \"Install $i\" \"N\"\n      fi\n    else\n      if [ $i = \"zimbra-archiving\" ]; then\n        askInstallPkgYN \"Install $i\" \"yes\" \"N\" \"N\"\n      elif [ $i = \"zimbra-convertd\" ]; then\n        askInstallPkgYN \"Install $i\" \"no\" \"Y\" \"N\"\n      elif [ $i = \"zimbra-imapd\" ]; then\n        askInstallPkgYN \"Install $i (BETA - for evaluation only)\" \"no\" \"N\" \"N\"\n      elif [ $i = \"zimbra-dnscache\" ]; then\n        if [ $MTA_SELECTED = \"yes\" ]; then\n          askYN \"Install $i\" \"Y\"\n        else\n          askYN \"Install $i\" \"N\"\n        fi\n      else\n        askYN \"Install $i\" \"Y\"\n      fi\n    fi\n\n    if [ $response = \"yes\" ]; then\n      if [ $i = \"zimbra-logger\" ]; then\n        LOGGER_SELECTED=\"yes\"\n      elif [ $i = \"zimbra-license-daemon\" ]; then\n        LICENSE_DAEMON_SELECTED=\"yes\"\n      elif [ $i = \"zimbra-store\" ]; then\n        STORE_SELECTED=\"yes\"\n        checkLicenseDaemonServiceRunning $LICENSE_DAEMON_SELECTED\n      elif [ $i = \"zimbra-apache\" ]; then\n        APACHE_SELECTED=\"yes\"\n      elif [ $i = \"zimbra-mta\" ]; then\n        MTA_SELECTED=\"yes\"\n      elif [ $i = \"zimbra-proxy\" ]; then\n        PROXY_SELECTED=\"yes\"\n      elif [ $i = \"zimbra-ldap\" ]; then\n        LDAP_SELECTED=\"yes\"\n      elif [ $i = \"zimbra-onlyoffice\" ]; then\n        ONLYOFFICE_SELECTED=\"yes\"\n      fi\n\n      if [ $i = \"zimbra-mta\" ]; then\n        CONFLICTS=\"no\"\n        for j in $CONFLICT_PACKAGES; do\n          conflictInstalled $j\n          if [ \"x$CONFLICTINSTALLED\" != \"x\" ]; then\n            echo \"     Conflicting package: $CONFLICTINSTALLED\"\n            CONFLICTS=\"yes\"\n          fi\n        done\n        if [ $CONFLICTS = \"yes\" ]; then\n          echo \"\"\n          echo \"###ERROR###\"\n          echo \"\"\n          echo \"One or more package conflicts exists.\"\n          echo \"Please remove them before running this installer.\"\n          echo \"\"\n          echo \"Installation cancelled.\"\n          echo \"\"\n          exit 1\n        fi\n      fi\n      if [ $i = \"zimbra-spell\" -a $APACHE_SELECTED = \"no\" ]; then\n        APACHE_SELECTED=\"yes\"\n        INSTALL_PACKAGES=\"$INSTALL_PACKAGES zimbra-apache\"\n      fi\n\n      if [ $i = \"zimbra-convertd\" -a $APACHE_SELECTED = \"no\" ]; then\n        APACHE_SELECTED=\"yes\"\n        INSTALL_PACKAGES=\"$INSTALL_PACKAGES zimbra-apache\"\n      fi\n\n      INSTALL_PACKAGES=\"$INSTALL_PACKAGES $i\"\n    fi\n\n  done\n  isp7zipRequired\n  checkRequiredSpace\n\n  isInstalled zimbra-store\n  isToBeInstalled zimbra-store\n\n  if [ \"x$PKGINSTALLED\" != \"x\" -o \"x$PKGTOBEINSTALLED\" != \"x\" ]; then\n    checkStoreRequirements\n  fi\n\n  isOnlyofficeStandalone $ONLYOFFICE_SELECTED\n\n  echo \"\"\n  echo \"Installing:\"\n  for i in $INSTALL_PACKAGES; do\n    echo \"    $i\"\n  done\n}\n\nisp7zipRequired() {\n\tP7ZIPREQUIRED=no\n\tif [[ $MTA_SELECTED == \"yes\" && $PLATFORM = \"RHEL9_64\" ]]; then\n\t\tisInstalled p7zip-plugins\n\t\tif [ x$PKGINSTALLED = \"x\" ]; then\n\t\t\taskYN \"Install p7zip-plugins from epel-release repository (without p7zip-plugins, some decoders for Amavis may not be available).\" \"Y\"\n\t\t\tif [ $response = \"yes\" ]; then\n\t\t\t\tP7ZIPREQUIRED=yes\n\t\t\tfi\n\t\tfi\n\tfi\n}\n\ninstallEPELRepo() {\n\tif [ $P7ZIPREQUIRED = \"yes\" ]; then\n\t\tOS_NAME=`grep -E '^(NAME)=' /etc/os-release | cut -d = -f 2 | tr -d '\"'`\n\t\tcase \"$OS_NAME\" in\n\t\t\t\"Red Hat\"*)\n\t\t\t\tisInstalled epel-release-latest-9\n\t\t\t\tif [ x$PKGINSTALLED = \"x\" ]; then\n\t\t\t\t\techo -n \"Installing epel-release-latest-9...\"\n\t\t\t\t\tif ! yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm -y >>$LOGFILE 2>&1 ; then\n\t\t\t\t\t\techo \"failed to install epel-release.\"\n\t\t\t\t\t\texit 1\n\t\t\t\t\telse\n\t\t\t\t\t\techo \"done.\"\n\t\t\t\t\tfi\n\t\t\t\tfi\n\t\t\t\techo -n \"Installing p7zip-plugins...\"\n\t\t\t\tif ! yum install p7zip-plugins --enablerepo=epel -y >>$LOGFILE 2>&1 ; then\n\t\t\t\t\techo \"failed to install p7zip-plugins.\"\n\t\t\t\t\texit 1\n\t\t\t\telse\n\t\t\t\t\techo \"done.\"\n\t\t\t\tfi\n\t\t\t\t;;\n\t\t\t\"Oracle\"*)\n\t\t\t\tisInstalled oracle-epel-release-el9\n\t\t\t\tif [ x$PKGINSTALLED = \"x\" ]; then\n\t\t\t\t\techo -n \"Installing oracle-epel-release-el9...\"\n\t\t\t\t\tif ! yum install oracle-epel-release-el9 -y >>$LOGFILE 2>&1 ; then\n\t\t\t\t\t\techo \"failed to install epel-release.\"\n\t\t\t\t\t\texit 1\n\t\t\t\t\telse\n\t\t\t\t\t\techo \"done.\"\n\t\t\t\t\tfi\n\t\t\t\tfi\n\t\t\t\techo -n \"Installing p7zip-plugins...\"\n\t\t\t\tif ! yum install p7zip-plugins --enablerepo=ol9_developer_EPEL -y >>$LOGFILE 2>&1 ; then\n\t\t\t\t\techo \"failed to install p7zip-plugins.\"\n\t\t\t\t\texit 1\n\t\t\t\telse\n\t\t\t\t\techo \"done.\"\n\t\t\t\tfi\n\t\t\t\t;;\n\t\t\t\"Rocky\"*|\"CentOS\"*)\n\t\t\t\tisInstalled epel-release\n\t\t\t\tif [ x$PKGINSTALLED = \"x\" ]; then\n\t\t\t\t\techo -n \"Installing epel-release...\"\n\t\t\t\t\tif ! yum install epel-release -y > /dev/null >>$LOGFILE 2>&1 ; then\n\t\t\t\t\t\techo \"failed to install epel-release.\"\n\t\t\t\t\t\texit 1\n\t\t\t\t\telse\n\t\t\t\t\t\techo \"done.\"\n\t\t\t\t\tfi\n\t\t\t\tfi\n\t\t\t\techo -n \"Installing p7zip-plugins...\"\n\t\t\t\tif ! yum install p7zip-plugins --enablerepo=epel -y >>$LOGFILE 2>&1; then\n\t\t\t\t\techo \"failed to install p7zip-plugins.\"\n\t\t\t\t\texit 1\n\t\t\t\telse\n\t\t\t\t\techo \"done.\"\n\t\t\t\tfi\n\t\t\t\t;;\n\t\tesac\n\tfi\n}\n\ncheckLicenseDaemonServiceRunning() {\n\tif [ x\"$ZMTYPE_INSTALLABLE\" = \"xNETWORK\" ]; then\n\t\tLICENSE_DAEMON_PKG=$1\n\t\tLICENSE_DAEMON_HOST=\"\"\n\t\tLICENSE_DAEMON_PORT=\"8081\"\n\t\tif [ $LICENSE_DAEMON_PKG == \"no\" ]; then\n\t\t\tif [ $UPGRADE = \"yes\" ]; then\n\t\t\t\tLDAP_URL_LIST=$(su - zimbra -c \"zmlocalconfig -m nokey -s ldap_url\")\n\t\t\t\tLDAP_STARTTLS_SUPPORTED=$(su - zimbra -c \"zmlocalconfig -m nokey -s ldap_starttls_supported\")\n\t\t\t\tLDAP_BIND_DN=$(su - zimbra -c \"zmlocalconfig -m nokey -s zimbra_ldap_userdn\")\n\t\t\t\tLDAP_BIND_PASSWORD=$(su - zimbra -c \"zmlocalconfig -m nokey -s zimbra_ldap_password\")\n\t\t\t\tLICENSE_DAEMON_FOUND=0\n\t\t\t\tfor ldap_url in $LDAP_URL_LIST; do\n\t\t\t\t\tif [[ \"$ldap_url\" =~ ^ldap:// ]] && [[ \"$LDAP_STARTTLS_SUPPORTED\" == \"true\" || \"$LDAP_STARTTLS_SUPPORTED\" == \"1\" ]]; then\n\t\t\t\t\t\techo \"Trying ldapsearch on $ldap_url with -ZZ\" >> $LOGFILE\n\t\t\t\t\t\tLDAP_RESULT=$(su - zimbra -c \"ldapsearch -x -H \\\"$ldap_url\\\" -ZZ -D \\\"$LDAP_BIND_DN\\\" -w \\\"$LDAP_BIND_PASSWORD\\\" -b \\\"cn=config,cn=zimbra\\\" \\\"(objectClass=zimbraGlobalConfig)\\\" zimbraLicenseDaemonServerHost\" 2>>\"$LOGFILE\")\n\t\t\t\t\t\tLDAP_EXIT_CODE=$?\n\t\t\t\t\telse\n\t\t\t\t\t\techo \"Trying ldapsearch on $ldap_url without -ZZ\" >> $LOGFILE\n\t\t\t\t\t\tLDAP_RESULT=$(su - zimbra -c \"ldapsearch -x -H \\\"$ldap_url\\\" -D \\\"$LDAP_BIND_DN\\\" -w \\\"$LDAP_BIND_PASSWORD\\\" -b \\\"cn=config,cn=zimbra\\\" \\\"(objectClass=zimbraGlobalConfig)\\\" zimbraLicenseDaemonServerHost\" 2>>\"$LOGFILE\")\n\t\t\t\t\t\tLDAP_EXIT_CODE=$?\n\t\t\t\t\tfi\n\n\t\t\t\t\tif [ $LDAP_EXIT_CODE -ne 0 ]; then\n\t\t\t\t\t\techo \"ldapsearch failed on $ldap_url with exit code $LDAP_EXIT_CODE\" >> $LOGFILE\n\t\t\t\t\t\tcontinue\n\t\t\t\t\tfi\n\n\t\t\t\t\tLICENSE_DAEMON_HOST=$(echo \"$LDAP_RESULT\" | awk '/^zimbraLicenseDaemonServerHost: /{print $2}')\n\t\t\t\t\tif [ -n \"$LICENSE_DAEMON_HOST\" ]; then\n\t\t\t\t\t\techo \"Found zimbraLicenseDaemonServerHost: $LICENSE_DAEMON_HOST via $ldap_url\" >> $LOGFILE\n\t\t\t\t\t\tLICENSE_DAEMON_FOUND=1\n\t\t\t\t\t\tbreak\n\t\t\t\t\tfi\n\t\t\t\tdone\n\n\t\t\t\tif [ $LICENSE_DAEMON_FOUND -eq 0 ]; then\n\t\t\t\t\tprintWarning \"zimbra-license-daemon should be installed prior to zimbra-store\"\n\t\t\t\t\texit 1\n\t\t\t\tfi\n\t\t\tfi\n\t\t\tif [ -z \"$LICENSE_DAEMON_HOST\" ]; then\n\t\t\t\taskYN \"Have you installed zimbra-license-daemon package on different node\" \"N\"\n\t\t\t\tif [ $response = \"yes\" ]; then\n\t\t\t\t\taskNonBlank \"Please enter the zimbra-license-daemon host\" \"$LICENSE_DAEMON_HOST\"\n\t\t\t\t\tLICENSE_DAEMON_HOST=$response\n\t\t\t\telse\n\t\t\t\t\tprintWarning \"zimbra-license-daemon should be installed prior to zimbra-store\"\n\t\t\t\t\texit 1\n\t\t\t\tfi\n\t\t\tfi\n\t\t\tLICENSE_DAEMON_API=\"http://${LICENSE_DAEMON_HOST}:${LICENSE_DAEMON_PORT}/actuator/health\"\n\t\t\tLICENSE_DAEMON_STATUS=$(curl -s --connect-timeout 5 \"$LICENSE_DAEMON_API\")\n\t\t\tif [ $? -ne 0 ]; then\n\t\t\t\tprintWarning \"Failed to connect to $LICENSE_DAEMON_API\"\n\t\t\t\tprintWarning \"license-daemon should be running and healthy.\"\n\t\t\t\texit 1\n\t\t\telse\n\t\t\t\tif [[ \"$LICENSE_DAEMON_STATUS\" != *'\"status\":\"UP\"'* ]]; then\n\t\t\t\t\tprintWarning \"license-daemon is not running. license-daemon should be running and healthy.\"\n\t\t\t\t\texit 1\n\t\t\t\tfi\n\t\t\tfi\n\t\tfi\n\tfi\n}\n\nprintWarning() {\n    echo -e \"\\033[0;31m$@\\033[0m\"\n}\n\nisOnlyofficeStandalone() {\n  onlyofficepkg=$1\n  # check if store is being installed too.\n  # if it is not being intsalled, add zimbra-mariadb to the list of packages to be installed\n  isInstalled zimbra-store\n  isToBeInstalled zimbra-store\n  isStandAlone=\"yes\"\n\n  if [ \"x$PKGINSTALLED\" != \"x\" -o \"x$PKGTOBEINSTALLED\" != \"x\" ]; then\n    isStandAlone=\"no\"\n  fi\n  ## install rabbit mq\n  if [ $onlyofficepkg == \"yes\" ]; then\n    INSTALL_PACKAGES=\"$INSTALL_PACKAGES zimbra-rabbitmq-server\"\n  fi\n\n  if [ $isStandAlone == \"yes\" -a $onlyofficepkg == \"yes\" ]; then\n    INSTALL_PACKAGES=\"$INSTALL_PACKAGES zimbra-mariadb\"\n  fi\n\n}\n\nremoveZimbraPatch(){\n\tisInstalled zimbra-patch\n\tif [ x$PKGINSTALLED != \"x\" ]; then\n\t\techo -n \"Removing zimbra-patch...\"\n\t\t$PACKAGERM zimbra-patch >/dev/null 2>&1\n\t\techo \"done\"\n\tfi\n}\n\nremoveModernUI(){\n\tisInstalled zimbra-modern-ui\n\tif [ x$PKGINSTALLED != \"x\" ]; then\n\t\techo -n \"Removing zimbra-modern-ui...\"\n\t\t$PACKAGERM zimbra-modern-ui >/dev/null 2>&1\n\t\techo \"done\"\n\tfi\n}\n\ndeleteWebApp() {\n  WEBAPPNAME=$1\n  CONTAINERDIR=$2\n\n  /bin/rm -rf /opt/zimbra/$CONTAINERDIR/webapps/$WEBAPPNAME\n  /bin/rm -rf /opt/zimbra/$CONTAINERDIR/webapps/$WEBAPPNAME.war\n  if [ $WEBAPPNAME == \"zimbra\" ]; then\n\t  #zimbra-modern-ui package needs to re-install\n\t  #because deleting /opt/zimbra/jetty/webapps/zimbra/ will remove modern directory from webapps\n\t  #so first uninstall zimbra-modern-ui to install it\n\t  # To remove zimbra-modern-ui,first zimbra-patch needs to remove\n\t  removeZimbraPatch\n\t  removeModernUI\n  fi\n}\n\nsetInstallPackages() {\n  for i in $OPTIONAL_PACKAGES; do\n    isInstalled $i\n    if [ x$PKGINSTALLED != \"x\" ]; then\n      INSTALL_PACKAGES=\"$INSTALL_PACKAGES $i\"\n    fi\n  done\n  for i in $PACKAGES $CORE_PACKAGES; do\n    isInstalled $i\n    if [ x$PKGINSTALLED != \"x\" ]; then\n      INSTALL_PACKAGES=\"$INSTALL_PACKAGES $i\"\n    fi\n  done\n}\n\nsetHereFlags() {\n\n  setInstallPackages\n\n  LDAP_HERE=\"no\"\n  POSTFIX_HERE=\"no\"\n  STORE_HERE=\"no\"\n  SNMP_HERE=\"no\"\n  LOGGER_HERE=\"no\"\n\n  for i in $INSTALL_PACKAGES; do\n    if [ $i = \"zimbra-store\" ]; then\n      STORE_HERE=\"yes\"\n    fi\n    if [ $i = \"zimbra-mta\" ]; then\n      POSTFIX_HERE=\"yes\"\n      # Don't change it if we read in a value from an existing config.\n      if [ \"x$RUNAV\" = \"x\" ]; then\n        RUNAV=\"yes\"\n      fi\n      if [ \"x$RUNSA\" = \"x\" ]; then\n        RUNSA=\"yes\"\n      fi\n    fi\n    if [ $i = \"zimbra-ldap\" ]; then\n      LDAP_HERE=\"yes\"\n    fi\n    if [ $i = \"zimbra-snmp\" ]; then\n      SNMP_HERE=\"yes\"\n    fi\n    if [ $i = \"zimbra-logger\" ]; then\n      LOGGER_HERE=\"yes\"\n    fi\n  done\n}\n\nstartServers() {\n  echo -n \"Starting servers...\"\n  runAsZimbra \"zmcontrol startup\"\n  su - zimbra -c \"zmcontrol status\"\n  echo \"done\"\n}\n\nverifyExecute() {\n  while :; do\n    askYN \"The system will be modified.  Continue?\" \"N\"\n\n    if [ $response = \"no\" ]; then\n      askYN \"Exit?\" \"N\"\n      if [ $response = \"yes\" ]; then\n        echo \"Exiting - the system is unchanged\"\n        exit 1\n      fi\n    else\n      break\n    fi\n  done\n}\n\nsetupCrontab() {\n  crontab -u zimbra -l > /tmp/crontab.zimbra.orig\n  grep ZIMBRASTART /tmp/crontab.zimbra.orig > /dev/null 2>&1\n  if [ $? != 0 ]; then\n    cat /dev/null > /tmp/crontab.zimbra.orig\n  fi\n  grep ZIMBRAEND /tmp/crontab.zimbra.orig > /dev/null 2>&1\n  if [ $? != 0 ]; then\n    cat /dev/null > /tmp/crontab.zimbra.orig\n  fi\n  cat /tmp/crontab.zimbra.orig | sed -e '/# ZIMBRASTART/,/# ZIMBRAEND/d' > \\\n    /tmp/crontab.zimbra.proc\n  cp -f /opt/zimbra/conf/crontabs/crontab /tmp/crontab.zimbra\n\n  isInstalled zimbra-store\n  if [ x$PKGINSTALLED != \"x\" ]; then\n    cat /opt/zimbra/conf/crontabs/crontab.store >> /tmp/crontab.zimbra\n  fi\n\n  isInstalled zimbra-logger\n  if [ x$PKGINSTALLED != \"x\" ]; then\n    cat /opt/zimbra/conf/crontabs/crontab.logger >> /tmp/crontab.zimbra\n  fi\n\n  echo \"# ZIMBRAEND -- DO NOT EDIT ANYTHING BETWEEN THIS LINE AND ZIMBRASTART\" >> /tmp/crontab.zimbra\n  cat /tmp/crontab.zimbra.proc >> /tmp/crontab.zimbra\n\n  crontab -u zimbra /tmp/crontab.zimbra\n}\n\nisToBeInstalled() {\n  pkg=$1\n  PKGTOBEINSTALLED=\"\"\n  for i in $INSTALL_PACKAGES; do\n    if [ \"x$pkg\" = \"x$i\" ]; then\n      PKGTOBEINSTALLED=$i\n      continue\n    fi\n  done\n}\n\nisInstalled() {\n  pkg=$1\n  PKGINSTALLED=\"\"\n  if [ \"x$PACKAGEEXT\" = \"xrpm\" ]; then\n    $PACKAGEQUERY $pkg >/dev/null 2>&1\n    if [ $? = 0 ]; then\n      PKGVERSION=`$PACKAGEQUERY $pkg 2> /dev/null | sort -u`\n      PKGINSTALLED=`$PACKAGEQUERY $pkg | sed -e 's/\\.[a-zA-Z].*$//' 2> /dev/null`\n    fi\n  elif [ \"x$PACKAGEEXT\" = \"xccs\" ]; then\n    $PACKAGEQUERY $pkg >/dev/null 2>&1\n    if [ $? = 0 ]; then\n      PKGVERSION=`$PACKAGEQUERY $pkg 2> /dev/null | sort -u`\n      PKGINSTALLED=`$PACKAGEQUERY $pkg | sed -e 's/\\.[a-zA-Z].*$//' 2> /dev/null`\n    fi\n  else\n    Q=`$PACKAGEQUERY $pkg 2>/dev/null | egrep '^Status: ' `\n    if [ \"x$Q\" != \"x\" ]; then\n      echo $Q | grep 'not-installed' > /dev/null 2>&1\n      if [ $? != 0 ]; then\n        echo $Q | grep 'deinstall ok' > /dev/null 2>&1\n        if [ $? != 0 ]; then\n          PKGVERSION=`$PACKAGEQUERY $pkg | egrep '^Version: ' | sed -e 's/Version: //' 2> /dev/null`\n          PKGINSTALLED=\"${pkg}-${PKGVERSION}\"\n        fi\n      fi\n    fi\n  fi\n}\n\nconflictInstalled() {\n  pkg=$1\n  CONFLICTINSTALLED=\"\"\n  QP=`dpkg-query -W -f='\\${Package}: \\${Provides}\\n' '*' | grep \": .*$pkg\" | sed -e 's/:.*//'`\n  while [ \"x$QP\" != \"x\" ]; do\n    QF=`echo $QP | sed -e 's/\\s.*//'`\n    QP=`echo $QP | sed -e 's/\\S*\\s*//'`\n    isInstalled $QF\n    if [ x$PKGINSTALLED != \"x\" ]; then\n      CONFLICTINSTALLED=$QF\n      if [ x$CONFLICTINSTALLED = \"xzimbra-mta\" ]; then\n        CONFLICTINSTALLED=\"\"\n      fi\n    fi\n  done\n}\n\nsuggestedVersion() {\n  pkg=$1\n  PKGINSTALLED=\"\"\n  if [ \"x$PACKAGEEXT\" = \"xrpm\" ]; then\n    $PACKAGEQUERY $pkg >/dev/null 2>&1\n    if [ $? = 0 ]; then\n      PKGINSTALLED=`$PACKAGEQUERY $pkg | sed -e 's/\\.[a-zA-Z].*$//' 2> /dev/null`\n    else\n      sugpkg=${pkg%-*}\n      PKGVERSION=`$PACKAGEQUERY $sugpkg 2> /dev/null | sort -u | grep -v 'not installed$'`\n      PKGVERSION=${PKGVERSION:-notfound}\n    fi\n  elif [ $PACKAGEEXT = \"ccs\" ]; then\n    $PACKAGEQUERY $pkg >/dev/null 2>&1\n    if [ $? = 0 ]; then\n      PKGINSTALLED=`$PACKAGEQUERY $pkg | sed -e 's/\\.[a-zA-Z].*$//' 2> /dev/null`\n    else\n      sugpkg=${pkg%=*}\n      PKGVERSION=`$PACKAGEQUERY $sugpkg 2> /dev/null | sort -u`\n    fi\n  else\n    sugpkg=${pkg%-*}\n    sugversion=${pkg#*-}\n    Q=`$PACKAGEQUERY $sugpkg 2>/dev/null | egrep '^Status: ' `\n    if [ \"x$Q\" != \"x\" ]; then\n      echo $Q | grep 'not-installed' > /dev/null 2>&1\n      if [ $? != 0 ]; then\n        PKGVERSION=`$PACKAGEVERSION $sugpkg 2> /dev/null`\n        if [ x\"$sugversion\" != x\"$sugpkg\" ]; then\n\t  if [[ \"$PKGVERSION\" == \"$sugversion\"* ]]; then\n            PKGINSTALLED=\"${sugpkg}-${PKGVERSION}\"\n          fi\n        else\n          PKGINSTALLED=\"${sugpkg}-${PKGVERSION}\"\n        fi\n      fi\n    fi\n  fi\n}\n\ngetPlatformVars() {\n  CONFLICT_PACKAGES=\"\"\n  echo $PLATFORM | egrep -q \"UBUNTU|DEBIAN\"\n  if [ $? = 0 ]; then\n    ISUBUNTU=true\n    checkUbuntuRelease\n    REPOINST='apt-get install -y'\n    PACKAGEDOWNLOAD='apt-get --download-only install -y --force-yes'\n    REPORM='apt-get -y --purge purge'\n    PACKAGEINST='dpkg -i --auto-deconfigure'\n    PACKAGERM='dpkg --purge'\n    PACKAGERMSIMULATE='dpkg --purge --dry-run'\n    PACKAGEQUERY='dpkg -s'\n    PACKAGEEXT='deb'\n    PACKAGEVERSION=\"dpkg-query -W -f \\${Version}\"\n    CONFLICT_PACKAGES=\"mail-transport-agent\"\n    if [ $PLATFORM = \"UBUNTU12_64\" -o $PLATFORM = \"UBUNTU14_64\" -o $PLATFORM = \"UBUNTU16_64\" -o $PLATFORM = \"UBUNTU18_64\" -o $PLATFORM = \"UBUNTU20_64\" -o $PLATFORM = \"UBUNTU22_64\" -o $PLATFORM = \"UBUNTU24_64\" ]; then\n      STORE_PACKAGES=\"libreoffice\"\n    fi\n    DumpFileDetailsFromPackage() {\n       local pkg_n=\"$1\"; shift\n       LANG=\"en_US.UTF-8\" LANGUAGE=\"en_US\" dpkg-query -W -f='${package}_${Version}_${Architecture}.deb\\n' \"$pkg_n\"\n    }\n    LocalPackageDepList() {\n       local pkg_f=\"$1\"; shift;\n       LANG=\"en_US.UTF-8\" LANGUAGE=\"en_US\" \\\n         dpkg -I \"$pkg_f\" \\\n            | sed -n -e '/Depends:/ { s/.*:\\s*//; s/,\\s*/\\n/g; p; }' \\\n            | sed -n -e '/^zimbra-/ { s/\\s*(.*//; p; }'\n    }\n    RepoPackageDepList() {\n       local pkg=\"$1\"; shift;\n       LANG=\"en_US.UTF-8\" LANGUAGE=\"en_US\" \\\n         apt-cache depends \"^$pkg$\" \\\n            | sed -e 's/[<]\\([a-z]\\)/\\1/g' \\\n                  -e 's/\\([a-z]\\)[>]/\\1/g' \\\n            | sed -n -e '/Depends:\\s*zimbra-/ { s/.*:\\s*//; p; }'\n    }\n    LocatePackageInRepo() {\n       local pkg=\"$1\"; shift;\n       LANG=\"en_US.UTF-8\" LANGUAGE=\"en_US\" \\\n         apt-cache search --names-only \"^$pkg\" 2>/dev/null\n    }\n  else\n      ISUBUNTU=false\n      REPOINST='yum -y install'\n      REPORM='yum erase -y'\n      PACKAGEINST='rpm -Uvh --replacefiles --replacepkgs'\n      # TODO: This should kept in os-requirement.\n      yum -y install --downloadonly dummyxxxxxxx 2>&1 | grep \"no such option: --downloadonly\" >/dev/null 2>&1\n      if [ $? -eq 0 ]; then\n        echo \"Installing yum-plugin-downloadonly.\"\n        yum -y install yum-plugin-downloadonly\n        if [ $? -ne 0 ]; then\n          echo \"yum --downloadonly should be available. To continue installation.\"\n          exit 1;\n        fi\n      fi\n      PACKAGEDOWNLOAD='yum -y install --downloadonly'\n      PACKAGERM='yum -y --disablerepo=* erase -v'\n      PACKAGERMSIMULATE='yum -n --disablerepo=* erase -v'\n      PACKAGEEXT='rpm'\n      PACKAGEQUERY='rpm -q'\n      PACKAGEVERIFY='rpm -K'\n      if [ $PLATFORM = \"RHEL6_64\" ]; then\n         STORE_PACKAGES=\"libreoffice libreoffice-headless\"\n      fi\n      if [ $PLATFORM = \"RHEL7_64\" -o $PLATFORM = \"RHEL8_64\" -o $PLATFORM = \"RHEL9_64\" ]; then\n         STORE_PACKAGES=\"libreoffice libreoffice-core\"\n      fi\n      DumpFileDetailsFromPackage() {\n         local pkg_n=\"$1\"; shift\n         echo \"$(LANG=\"en_US.UTF-8\" LANGUAGE=\"en_US\" rpm -q \"$pkg_n\").rpm\"\n      }\n      LocalPackageDepList() {\n         local pkg_f=\"$1\"; shift;\n         LANG=\"en_US.UTF-8\" LANGUAGE=\"en_US\" \\\n            rpm -q --requires -p \"$pkg_f\" \\\n               | sed -n -e '/^zimbra-/ { s/\\s*[<=>].*//; p; }'\n      }\n      RepoPackageDepList() {\n         local pkg=\"$1\"; shift;\n         LANG=\"en_US.UTF-8\" LANGUAGE=\"en_US\" \\\n            yum deplist \"$pkg\" \\\n               | sed -n -e '/dependency:\\s*zimbra-/ { s/^[^:]*:\\s*//; s/\\s*[<=>].*//; p }'\n      }\n      LocatePackageInRepo() {\n         local pkg=\"$1\"; shift;\n         LANG=\"en_US.UTF-8\" LANGUAGE=\"en_US\" \\\n            yum --showduplicates list available -q -e 0 \"$pkg\" 2>/dev/null\n      }\n  fi\n}\n"
  },
  {
    "path": "rpmconf/Install/install.sh",
    "content": "#!/bin/bash\n#\n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n#\n\nID=`id -u`\n\nif [ \"x$ID\" != \"x0\" ]; then\n  echo \"Run as root!\"\n  exit 1\nfi\n\nif [ ! -x \"/usr/bin/perl\" ]; then\n  echo \"ERROR: System perl at /usr/bin/perl must be present before installation.\"\n  exit 1\nfi\n\n# Function to check for rsyslog or syslog-ng package\nis_rsyslog_or_syslog_ng_present() {\n  if command -v rsyslogd >/dev/null 2>&1 || command -v syslog-ng >/dev/null 2>&1; then\n    return 0\n  else\n    echo \"ERROR: Zimbra installation requires rsyslog or syslog-ng package to be installed.\"\n    exit 1\n  fi\n}\n\n# Perform logging prerequisite check\nis_rsyslog_or_syslog_ng_present\n\nMYDIR=\"$(cd \"$(dirname \"$0\")\" && pwd)\"\n\n. ./util/utilfunc.sh\n\nfor i in ./util/modules/*sh; do\n\t. $i\ndone\n\nUNINSTALL=\"no\"\nSOFTWAREONLY=\"no\"\nSKIP_ACTIVATION_CHECK=\"no\"\nSKIP_UPGRADE_CHECK=\"no\"\nSKIP_NG_CHECK=\"no\"\nALLOW_PLATFORM_OVERRIDE=\"no\"\nFORCE_UPGRADE=\"no\"\n\nusage() {\n  echo \"$0 [-r <dir> -l <licensekey> -u -s -c type -x -h] [defaultsfile]\"\n  echo \"\"\n  echo \"-h|--help               Usage\"\n  echo \"-l|--licensekey         License key to install.\"\n  echo \"-r|--restore <dir>      Restore contents of <dir> to localconfig\"\n  echo \"-s|--softwareonly       Software only installation.\"\n  echo \"-u|--uninstall          Uninstall ZCS\"\n  echo \"-x|--skipspacecheck     Skip filesystem capacity checks.\"\n  echo \"--beta-support          Allows installer to upgrade Network Edition Betas.\"\n  echo \"--platform-override     Allows installer to continue on an unknown OS.\"\n  echo \"--skip-activation-check Allows installer to continue if license activation checks fail.\"\n  echo \"--skip-upgrade-check    Allows installer to skip upgrade validation checks.\"\n  echo \"--skip-ng-check         Allows installer to upgrade by removing NG modules and related data.\"\n  echo \"--force-upgrade         Force upgrade to be set to YES. Used if there is package installation failure for remote packages.\"\n  echo \"[defaultsfile]          File containing default install values.\"\n  echo \"\"\n  exit\n}\n\nvalidateLicensekey() {\n    local new=\"$1\"\n    if [[ ! \"$new\" =~ ^[A-Za-z0-9]+$ ]] || (( ${#new} < 18 )) || (( ${#new} > 24 )) || [[ -z \"$new\" ]]; then\n\techo \"Invalid license key entered. The license key should be a non-blank alphanumeric string of 18-24 characters without any special characters!\"\n        usage\n    fi\n}\n\ncheckSkipActivation() {\n\tif [ x\"$SKIP_ACTIVATION_CHECK\" = \"xyes\" ]; then\n\t\tif [ ! -d \"/opt/zimbra/conf\" ]; then\n\t\t\tmkdir -p /opt/zimbra/conf\n\t\tfi\n\t\techo \"$SKIP_ACTIVATION_CHECK\" > /opt/zimbra/conf/skip_activation_check\n\t\tchown zimbra:zimbra /opt/zimbra/conf/skip_activation_check\n\t\tchmod 644 /opt/zimbra/conf/skip_activation_check\n\tfi\n}\n\n\nwhile [ $# -ne 0 ]; do\n  case $1 in\n    -r|--restore|--config)\n      shift\n      RESTORECONFIG=$1\n      ;;\n    -l|--licensekey)\n      shift\n      LICENSEKEY=$1\n      validateLicensekey $LICENSEKEY\n      ;;\n    -u|--uninstall)\n      UNINSTALL=\"yes\"\n      ;;\n    -s|--softwareonly)\n      SOFTWAREONLY=\"yes\"\n      ;;\n    -x|--skipspacecheck)\n      SKIPSPACECHECK=\"yes\"\n      ;;\n    -platform-override|--platform-override)\n      ALLOW_PLATFORM_OVERRIDE=\"yes\"\n      ;;\n    -beta-support|--beta-support)\n      BETA_SUPPORT=\"yes\"\n      ;;\n    -skip-activation-check|--skip-activation-check)\n      SKIP_ACTIVATION_CHECK=\"yes\"\n      ;;\n    -skip-upgrade-check|--skip-upgrade-check)\n      SKIP_UPGRADE_CHECK=\"yes\"\n      ;;\n    -skip-ng-check|--skip-ng-check)\n      SKIP_NG_CHECK=\"yes\"\n      ;;\n    -force-upgrade|--force-upgrade)\n      FORCE_UPGRADE=\"yes\"\n      UPGRADE=\"yes\"\n      ;;\n    -h|-help|--help)\n      usage\n      ;;\n    *)\n      DEFAULTFILE=$1\n      if [ ! -f \"$DEFAULTFILE\" ]; then\n        echo \"ERROR: Unknown option $DEFAULTFILE\"\n        usage\n      fi\n      ;;\n  esac\n  shift\ndone\n\n. ./util/globals.sh\n\ngetPlatformVars\n\nmkdir -p $SAVEDIR\nchown zimbra:zimbra $SAVEDIR 2> /dev/null\nchmod 750 $SAVEDIR\n\necho \"\"\necho \"Operations logged to $LOGFILE\"\n\nlicensefiles=(\n    \"/opt/zimbra/conf/ZCSLicense-activated.xml\"\n    \"/opt/zimbra/conf/ZCSLicensekey\"\n    \"/opt/zimbra/conf/skip_activation_check\"\n)\n\nfor file in \"${licensefiles[@]}\"; do\n    if [[ -e \"$file\" ]]; then\n        rm -f \"$file\"\n    fi\ndone\n\nif [ \"x$DEFAULTFILE\" != \"x\" ]; then\n\tAUTOINSTALL=\"yes\"\nelse\n\tAUTOINSTALL=\"no\"\nfi\n\nif [ \"x$LICENSEKEY\" != \"x\" ] ; then\n  if [ ! -d \"/opt/zimbra/conf\" ]; then\n    mkdir -p /opt/zimbra/conf\n  fi\n  echo \"$LICENSEKEY\" > /opt/zimbra/conf/ZCSLicensekey\n  chown zimbra:zimbra /opt/zimbra/conf/ZCSLicensekey\n  chmod 644 /opt/zimbra/conf/ZCSLicensekey\nfi\n\ncheckSkipActivation\ncheckExistingInstall\n\nif [ x$UNINSTALL = \"xyes\" ]; then\n\taskYN \"Completely remove existing installation?\" \"N\"\n\tif [ $response = \"yes\" ]; then\n\t\tREMOVE=\"yes\"\n\t\tfindUbuntuExternalPackageDependencies\n\t\tsaveExistingConfig\n\t\tremoveExistingInstall\n\tfi\n\texit 1\nfi\n\ndisplayLicense\n\ncheckUser root\n\nif [ $AUTOINSTALL = \"yes\" ]; then\n\tloadConfig $DEFAULTFILE\nfi\n\ncheckRequired\n\ninstallable_platform=$(cat ${MYDIR}/.BUILD_PLATFORM)\n\nif [ x\"$PLATFORM\" = x\"$installable_platform\" -a x\"${ALLOW_PLATFORM_OVERRIDE}\" = \"xyes\" ]; then\n  ALLOW_PLATFORM_OVERRIDE=\"no\"\nfi\n\nif [ x\"${ALLOW_PLATFORM_OVERRIDE}\" = \"xno\" ]; then\n  configurePackageServer\nfi\n\ncheckPackages\n\nif [ $AUTOINSTALL = \"no\" ]; then\n  setRemove\n\n  getInstallPackages\n\n  if [ x\"$PLATFORM\" != x\"$installable_platform\" ]; then\n    echo \"\"\n    echo \"You appear to be installing packages on a platform different\"\n    echo \"than the platform for which they were built.\"\n    echo \"\"\n    echo \"This platform is $PLATFORM\"\n    echo \"Packages found: $installable_platform\"\n    echo \"This may or may not work.\"\n    echo \"\"\n\n    if [ x\"${ALLOW_PLATFORM_OVERRIDE}\" = \"xyes\" ]; then\n\n    \techo \"Using packages for a platform in which they were not designed for\"\n    \techo \"may result in an installation that is NOT usable. Your support\"\n    \techo \"options may be limited if you choose to continue.\"\n        echo \"You will also be responsible for configuring the system to point\"\n        echo \"at an appropriate package repository for third party.\"\n    \techo \"\"\n    \taskYN \"Install anyway?\" \"N\"\n    \tif [ $response = \"no\" ]; then\n    \t\techo \"Exiting...\"\n    \t\texit 1\n    \tfi\n    else\n    \techo \"Installation can not continue without manual override.\"\n    \techo \"You can override this safety check with $0 --platform-override\"\n    \techo \"\"\n    \techo \"WARNING: Bypassing this check may result in an install or\"\n    \techo \"upgrade that is NOT usable.\"\n    \techo \"\"\n    \texit 1\n    fi\n  fi\n\n  verifyExecute\n\nelse\n  checkVersionMatches\n  if [ $VERSIONMATCH = \"no\" ]; then\n    if [ $UPGRADE = \"yes\" ]; then\n      echo \"\"\n      echo \"###ERROR###\"\n      echo \"\"\n      echo \"There is a mismatch in the versions of the installed schema\"\n      echo \"or index and the version included in this package\"\n      echo \"\"\n      echo \"Automatic upgrade cancelled\"\n      echo \"\"\n      exit 1\n    fi\n  fi\nfi\n\n\nD=`date +%s`\necho \"${D}: INSTALL SESSION START\" >> /opt/zimbra/.install_history\ninstallPackages\n\nD=`date +%s`\necho \"${D}: INSTALL SESSION COMPLETE\" >> /opt/zimbra/.install_history\n\nif [ x$RESTORECONFIG != \"x\" ]; then\n\tSAVEDIR=$RESTORECONFIG\nfi\n\nif [ x$SAVEDIR != \"x\" -a x$REMOVE = \"xno\" ]; then\n    setDefaultsFromExistingConfig\nfi\n\nif [ $UPGRADE = \"yes\" ]; then\n\trestoreExistingConfig\n\trestoreCerts\n  # deprecated by move of zimlets to /opt/zimbra/zimlets-deployed which isn't removed on upgrade\n  #restoreZimlets\nfi\n\nif [ \"x$LICENSEKEY\" != \"x\" ] ; then\n  if [ ! -d \"/opt/zimbra/conf\" ]; then\n    mkdir -p /opt/zimbra/conf\n  fi\n  echo \"$LICENSEKEY\" > /opt/zimbra/conf/ZCSLicensekey\n  chown zimbra:zimbra /opt/zimbra/conf/ZCSLicensekey\n  chmod 644 /opt/zimbra/conf/ZCSLicensekey\nfi\n\ncheckSkipActivation\nif [ $SOFTWAREONLY = \"yes\" ]; then\n\n\techo \"\"\n\techo \"Software Installation complete!\"\n\techo \"\"\n\techo \"Operations logged to $LOGFILE\"\n\techo \"\"\n\n\texit 0\nfi\n\nif [ -e \"$LOGFILE\" ]; then\n\tLOG_DIR=\"/opt/zimbra/log\"\n\tif [ ! -d \"$LOG_DIR\" ]; then\n\t\tmkdir -p \"$LOG_DIR\"\n\t\tchown zimbra:zimbra \"$LOG_DIR\"\n\tfi\n\techo \"Copying $LOGFILE to $LOG_DIR\"\n\tcp -f $LOGFILE $LOG_DIR/\n\tchown zimbra:zimbra \"$LOG_DIR/$(basename \"$LOGFILE\")\"\nfi\n#\n# Installation complete, now configure\n#\nif [ \"x$DEFAULTFILE\" != \"x\" ]; then\n\t/opt/zimbra/libexec/zmsetup.pl -c $DEFAULTFILE\nelse\n\t/opt/zimbra/libexec/zmsetup.pl\nfi\nRC=$?\nif [ $RC -ne 0 ]; then\n\texit $RC\nfi\n"
  },
  {
    "path": "rpmconf/Install/postinstall.pm",
    "content": "#!/usr/bin/perl\n# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2005, 2006, 2007, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n# \n\npackage postinstall;\n\nsub configure {\n\n\tif (main::isEnabled(\"zimbra-ldap\")) {\n\t\tmain::runAsZimbra (\"${main::ZMPROV} mcf zimbraComponentAvailable ''\");\n\t\tmain::runAsZimbra (\"zmlocalconfig -u trial_expiration_date\");\n\t}\n\n  # we temporary set this to true during the install/upgrade\n  main::setLocalConfig(\"ssl_allow_untrusted_certs\", \"false\")\n    if $main::newinstall;\n\n  if (main::isEnabled(\"zimbra-mta\") && $main::newinstall) {\n    my @mtalist = main::getAllServers(\"mta\");\n    if (scalar(@mtalist) gt 1) { \n      main::setLocalConfig(\"zmtrainsa_cleanup_host\", \"false\")\n    } else {\n      main::setLocalConfig(\"zmtrainsa_cleanup_host\", \"true\")\n    }\n  }\n}\n\n\nsub notifyZimbra {\n  if (!defined ($main::options{c}) && 1) {\n    if (main::askYN(\"\\nYou have the option of notifying Zimbra of your installation.\\nThis helps us to track the uptake of the Zimbra Collaboration Server.\\nThe only information that will be transmitted is:\\n\\tThe VERSION of zcs installed (${main::curVersion}_${main::platform})\\n\\tThe ADMIN EMAIL ADDRESS created ($main::config{CREATEADMIN})\\n\\nNotify Zimbra of your installation?\", \"Yes\") eq \"yes\") {\n      if (open NOTIFY, \"/opt/zimbra/libexec/zmnotifyinstall ${main::curVersion}_${main::platform} $main::config{CREATEADMIN} |\") {\n        while (<NOTIFY>) {\n          main::progress (\"$_\");\n        }\n        close NOTIFY;\n        #main::progress (\"Notification complete!\\n\");\n      } else {\n        #main::progress (\"ERROR: Notification failed!\\n\\n\");\n      }\n    } else {\n    main::progress (\"Notification skipped\\n\");\n    }\n  }\n}\n\n1\n"
  },
  {
    "path": "rpmconf/Install/preinstall.pm",
    "content": "#!/usr/bin/perl\n# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2006, 2007, 2009, 2010, 2013, 2014, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n# \n\npackage preinstall;\n\nsub mainMenuExtensions {\n\tmy ($mm, $i) = (@_);\n\treturn $i;\n}\n\n1\n"
  },
  {
    "path": "rpmconf/Install/test.pl",
    "content": ""
  },
  {
    "path": "rpmconf/Install/zmsetup.pl",
    "content": "#!/usr/bin/perl\n#\n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n#\n\nuse strict;\n\nuse lib \"/opt/zimbra/libexec\";\nuse lib \"/opt/zimbra/common/lib/perl5\";\nuse Zimbra::Util::Common;\nuse Zimbra::Util::Timezone;\nuse Net::LDAP;\nuse IPC::Open3;\nuse Cwd;\nuse Time::localtime qw(ctime);\nuse File::Path qw(make_path);\n\n\n$|=1; # don't buffer stdout\n\nour $platform = qx(/opt/zimbra/libexec/get_plat_tag.sh);\nchomp $platform;\nmy $logFileName = \"zmsetup.\".getDateStamp().\".log\";\nmy $logfile = \"/tmp/\".$logFileName;\nopen LOGFILE, \">$logfile\" or die \"Can't open $logfile: $!\\n\";\nunlink(\"/tmp/zmsetup.log\") if (-e \"/tmp/zmsetup.log\");\nsymlink($logfile, \"/tmp/zmsetup.log\");\n\nmy $ol = select (LOGFILE);\nselect ($ol);\n$| = 1;\n\nprogress(\"Operations logged to $logfile\\n\");\n\nour $ZMPROV = \"/opt/zimbra/bin/zmprov -r -m -l\";\nour $SU = \"su - zimbra -c \";\n\nmy $filename=\"/opt/zimbra/conf/localconfig.xml\";\nmy $uid = (stat $filename)[4];\nmy $user = (getpwuid $uid)[0];\nmy $license_file = \"/opt/zimbra/conf/ZCSLicensekey\";\nmy $skip_activation_file = \"/opt/zimbra/conf/skip_activation_check\";\nmy $skip_activation_check = `cat $skip_activation_file 2>/dev/null`;\nchomp($skip_activation_check);\n\nif ($user ne \"zimbra\") {\n    progress (\"\\n\\nERROR\\n\\n\");\n    progress (\"/opt/zimbra/conf/localconfig.xml is not owned by zimbra\\n\");\n    progress (\"This will cause installation failure.\\n\");\n    exit (1);\n}\n\nuse preinstall;\nuse postinstall;\nuse zmupgrade;\nuse Getopt::Std;\nuse Net::DNS::Resolver;\nuse NetAddr::IP;\n\nour %options = ();\nour %config = ();\nour %loaded = ();\nour %saved = ();\n\nmy @packageList = (\n  \"zimbra-core\",\n  \"zimbra-ldap\",\n  \"zimbra-logger\",\n  \"zimbra-mta\",\n  \"zimbra-dnscache\",\n  \"zimbra-snmp\",\n  \"zimbra-store\",\n  \"zimbra-apache\",\n  \"zimbra-spell\",\n  \"zimbra-convertd\",\n  \"zimbra-memcached\",\n  \"zimbra-proxy\",\n  \"zimbra-archiving\",\n  \"zimbra-imapd\",\n  \"zimbra-onlyoffice\",\n  \"zimbra-license-daemon\",\n);\n\nmy %packageServiceMap = (\n  amavis    => \"zimbra-mta\",\n  antivirus => \"zimbra-mta\",\n  antispam  => \"zimbra-mta\",\n  opendkim  => \"zimbra-mta\",\n  cbpolicyd => \"zimbra-mta\",\n  dnscache  => \"zimbra-dnscache\",\n  imapd     => \"zimbra-imapd\",\n  mta       => \"zimbra-mta\",\n  logger    => \"zimbra-logger\",\n  mailbox   => \"zimbra-store\",\n  snmp      => \"zimbra-snmp\",\n  ldap      => \"zimbra-ldap\",\n  spell     => \"zimbra-spell\",\n  stats     => \"zimbra-core\",\n  'vmware-ha' => \"zimbra-core\",\n  memcached => \"zimbra-memcached\",\n  proxy     => \"zimbra-proxy\",\n  archiving => \"zimbra-archiving\",\n  convertd  => \"zimbra-convertd\",\n  service   => \"zimbra-store\",\n  zimbra    => \"zimbra-store\",\n  zimbraAdmin   => \"zimbra-store\",\n  zimlet    => \"zimbra-store\",\n  onlyoffice    => \"zimbra-onlyoffice\",\n  'license-daemon' => \"zimbra-license-daemon\",\n);\n\nmy @webappList = (\n  \"service\",\n  \"zimbra\",\n  \"zimbraAdmin\",\n  \"zimlet\",\n);\n\nmy %installedPackages = ();\nour %installedWebapps = ();\nmy %prevInstalledPackages = ();\nmy %enabledPackages = ();\nmy %enabledServices = ();\n\nmy %installStatus = ();\nour %configStatus = ();\nour %migratedStatus= ();\n\nmy $prevVersion = \"\";\nour $curVersion = \"\";\nmy ($prevVersionMinor,$prevVersionMajor,$prevVersionMicro,$prevVersionBuild);\nmy ($curVersionMinor,$curVersionMajor,$curVersionMicro,$curVersionMicroMicro,$curVersionType,$curVersionBuild);\nour $newinstall = 1;\nchomp (my $ldapSchemaVersion = do {\n    local $/ = undef;\n    open my $fh, \"<\", \"/opt/zimbra/conf/zimbra-attrs-schema\"\n        or die \"could not open /opt/zimbra/conf/zimbra-attrs-schema: $!\";\n    <$fh>;\n});\n\nmy $ldapConfigured = 0;\nmy $haveSetLdapSchemaVersion = 0;\nmy $ldapRunning = 0;\nmy $sqlConfigured = 0;\nmy $sqlRunning = 0;\nmy $loggerSqlConfigured = 0;\nmy $loggerSqlRunning = 0;\nmy @installedServiceList = ();\nmy @enabledServiceList = ();\n\nmy $ldapRootPassChanged = 0;\nmy $ldapAdminPassChanged = 0;\nmy $ldapRepChanged = 0;\nmy $ldapPostChanged = 0;\nmy $ldapAmavisChanged = 0;\nmy $ldapNginxChanged = 0;\nmy $ldapBesSearcherChanged = 0;\nmy $ldapReplica = 0;\nmy $starttls = 0;\nmy $needNewCert = \"\";\nmy $ssl_cert_type = \"self\";\n\nmy @ssl_digests = (\"ripemd160\",\"sha\",\"sha1\",\"sha224\",\"sha256\",\"sha384\",\"sha512\");\nmy @interfaces = ();\n\n($>) and usage();\n\ngetopts(\"c:hd\", \\%options) or usage();\n\nmy $debug = $options{d};\n\nusage() if ($options{h});\n\ngetInstallStatus();\n\nif ($0 =~ /testMenu/) {\n  #delete $installedPackages{\"zimbra-ldap\"};\n  #delete $installedPackages{\"zimbra-mta\"};\n  getInstalledPackages();\n  setDefaults();\n  setLdapDefaults();\n  setEnabledDependencies();\n  mainMenu();\n  exit;\n}\n\nif (isInstalled(\"zimbra-ldap\")) {\n  if ($newinstall || ! -f \"/opt/zimbra/data/ldap/config/cn\\=config.ldif\") {\n    installLdapConfig();\n  }\n}\n\nif(isInstalled(\"zimbra-ldap\")) {\n  installLdapSchema();\n}\n\nif (! $newinstall ) {\n  # zimbra-openjdk-cacerts replaces OZC/lib/jvm/java/jre/lib/security/cacerts\n  # (re)import our CA cert to reestablish our CA trust\n  if ( -f \"/opt/zimbra/conf/ca/ca.pem\" ) {\n    progress(\"Adding /opt/zimbra/conf/ca/ca.pem to cacerts\\n\");\n    main::runAsZimbra(\"/opt/zimbra/bin/zmcertmgr addcacert /opt/zimbra/conf/ca/ca.pem\");\n  }\n\n  # if we're an upgrade, run the upgrader...\n  if ($prevVersion eq \"\") {\n    $prevVersion = $curVersion;\n  }\n  if (($prevVersion ne $curVersion )) {\n    progress (\"Upgrading from $prevVersion to $curVersion\\n\");\n    open (H, \">>/opt/zimbra/.install_history\");\n    print H time(),\": CONFIG SESSION START\\n\";\n    # This is the postinstall config\n    configLog (\"BEGIN\");\n    if (zmupgrade::upgrade($prevVersion, $curVersion)){\n      progress (\"UPGRADE FAILED - exiting.\\n\");\n      exit 1;\n    } else {\n      progress (\"Upgrade complete.\\n\\n\");\n    }\n  }\n}\n\ngetInstalledPackages();\n\n# This is somewhat of a catch-22.\n# We can't check ldap to see if it is enabled or not\n# prior to upgrade, because ldap may not be functional.\n# Long term, we need to split out zmupgrade.pm into\n# per-package upgrade scripts, rather than the monolithic\n# monstrosity it is now.\nunless (isEnabled(\"zimbra-core\")) {\n  progress(\"zimbra-core must be enabled.\");\n  exit 1;\n}\n\ngetInstalledWebapps();\n\nif ($options{d}) {\n  foreach my $pkg (keys %installedPackages) {\n    detail(\"Package $pkg is installed\");\n  }\n  foreach my $pkg (keys %enabledPackages) {\n    detail(\"Package $pkg is $enabledPackages{$pkg}\");\n  }\n}\n\nsetDefaults();\nsetDefaultsFromLocalConfig() if (! $newinstall);\n\nsetEnabledDependencies();\n\ncheckPortConflicts();\n\ngetSystemStatus();\n\nstartLdap() if ($ldapConfigured);\n\nif (!$newinstall) {\n  my $rc = runAsZimbra (\"/opt/zimbra/libexec/zmldapupdateldif\");\n}\n\nif ($ldapConfigured ||\n  (($config{LDAPHOST} ne $config{HOSTNAME}) && ldapIsAvailable())) {\n  setLdapDefaults();\n  getAvailableComponents();\n}\n\nif ($options{c}) {\n  loadConfig ($options{c});\n  applyConfig();\n} else {\n  if ($configStatus{BEGIN} eq \"CONFIGURED\" &&\n    $configStatus{END}  ne \"CONFIGURED\") {\n    resumeConfiguration();\n  }\n  if (!$newinstall) {\n    my $m = createMainMenu();\n    if (checkMenuConfig($m)) {\n      applyConfig();\n    }\n  }\n  mainMenu();\n}\n\nsetLdapServerConfig($config{HOSTNAME}, 'zimbraServerVersion', $curVersion);\nsetLdapServerConfig($config{HOSTNAME}, 'zimbraServerVersionMajor', $curVersionMajor);\nsetLdapServerConfig($config{HOSTNAME}, 'zimbraServerVersionMinor', $curVersionMinor);\nsetLdapServerConfig($config{HOSTNAME}, 'zimbraServerVersionMicro', $curVersionMicroMicro);\nsetLdapServerConfig($config{HOSTNAME}, 'zimbraServerVersionType', $curVersionType);\nsetLdapServerConfig($config{HOSTNAME}, 'zimbraServerVersionBuild', $curVersionBuild);\n\nclose LOGFILE;\nchmod 0600, $logfile;\nif (-d \"/opt/zimbra/log\") {\n  main::progress(\"Moving $logfile to /opt/zimbra/log\\n\");\n  system(\"cp -f $logfile /opt/zimbra/log/\");\n  system(\"chown zimbra:zimbra /opt/zimbra/log/$logFileName\");\n}\n\n################################################################\n# End Main\n################################################################\n\n################################################################\n# Subroutines\n################################################################\n\nsub usage {\n  ($>) and print STDERR \"Warning: $0 must be run as root!\\n\\n\";\n  print STDERR \"Usage: $0 [-h] [-c <config file>]\\n\";\n  print STDERR \"\\t-h: display this help message\\n\";\n  print STDERR \"\\t-c: configure with values in <config file>\\n\\n\";\n  #print STDERR \"\\t-l: install license in <license file>\\n\\n\";\n  exit 1;\n}\n\nsub progress {\n  my $msg = shift;\n  print \"$msg\";\n  my ($sub,$line) = (caller(1))[3,2];\n  $msg = \"$sub:$line $msg\" if $options{d};\n  detail ($msg);\n}\n\nsub detail {\n  my $msg = shift;\n  my ($sub,$line) = (caller(1))[3,2];\n  my $date = ctime();\n  $msg =~ s/\\n$//;\n  $msg = \"$sub:$line $msg\" if $options{d};\n  open(LOG, \">>$logfile\");\n  print LOG \"$date $msg\\n\";\n  close(LOG);\n  #qx(echo \"$date $msg\" >> $logfile);\n}\n\nsub defineInstallWebapps {\n  if (!defined $config{INSTALL_WEBAPPS}) {\n    $config{INSTALL_WEBAPPS} = \"zimlet\";\n    if ($config{SERVICEWEBAPP} eq \"yes\") {\n      $config{INSTALL_WEBAPPS} = \"service $config{INSTALL_WEBAPPS}\";\n    }\n    if ($config{UIWEBAPPS} eq \"yes\") {\n      $config{INSTALL_WEBAPPS} = \"$config{INSTALL_WEBAPPS} zimbra zimbraAdmin\";\n    }\n  }\n}\n\nsub saveConfig {\n  my $fname = \"/opt/zimbra/config.$$\";\n  if (!(defined ($options{c})) && $newinstall ) {\n    $fname = askNonBlank (\"Save config in file:\", $fname);\n  }\n\n  if (open CONF, \">$fname\") {\n    progress (\"Saving config in $fname...\");\n    foreach (sort keys %config) {\n      # Don't write passwords or previous INSTALL_PACKAGES\n      if (/PASS|INSTALL_PACKAGES/) {next;}\n      print CONF qq($_=\"$config{$_}\"\\n);\n    }\n    print CONF qq(INSTALL_PACKAGES=\");\n    foreach (@packageList) {\n      my $el = $_;\n      if (grep (/$el/, keys %installedPackages)) {\n        print CONF \"$_ \";\n      }\n    }\n    print CONF qq(\"\\n);\n    close CONF;\n    chmod 0600, $fname;\n    progress (\"done.\\n\");\n  } else {\n    progress( \"Can't open $fname: $!\\n\");\n  }\n}\n\nsub loadConfig {\n  my $filename = shift;\n  open (CONF, $filename) or die \"Can't open $filename: $!\";\n  my @lines = <CONF>;\n  close CONF;\n  foreach (@lines) {\n    chomp;\n    my ($k, $v) = split ('=', $_, 2);\n    $v=~s/\"//g;\n    $config{$k} = $v;\n  }\n\n  $config{ALLOWSELFSIGNED} = \"true\";\n}\n\nsub checkPortConflicts {\n  progress ( \"Checking for port conflicts\\n\" );\n  my %needed = (\n    25 => 'zimbra-mta',\n    53 => 'zimbra-dnscache',\n    80 => 'zimbra-store',\n    110 => 'zimbra-store',\n    143 => 'zimbra-store',\n    389 => 'zimbra-ldap',\n    443 => 'zimbra-store',\n    636 => 'zimbra-ldap',\n    993 => 'zimbra-store',\n    995 => 'zimbra-store',\n    7025 => 'zimbra-store',\n    7071 => 'zimbra-store',\n    7072 => 'zimbra-store',\n    7047 => 'zimbra-convertd',\n    7306 => 'zimbra-store',\n    7307 => 'zimbra-store',\n    7780 => 'zimbra-spell',\n    8143 => 'zimbra-imapd',\n    8993 => 'zimbra-imapd',\n    8465 => 'zimbra-mta',\n    10024 => 'zimbra-mta',\n    10025 => 'zimbra-mta',\n    10026 => 'zimbra-mta',\n    10027 => 'zimbra-mta',\n    10028 => 'zimbra-mta',\n    10029 => 'zimbra-mta',\n    10030 => 'zimbra-mta',\n    7084 => 'zimbra-onlyoffice',\n    7085 => 'zimbra-onlyoffice',\n  );\n\n  open PORTS, \"netstat -an | egrep '^tcp' | grep LISTEN | awk '{print \\$4}' | sed -e 's/.*://' |\";\n  my @ports = <PORTS>;\n  close PORTS;\n  chomp @ports;\n\n  my $any = 0;\n  foreach (@ports) {\n    if (defined ($needed{$_}) && isEnabled($needed{$_})) {\n      # don't report ldap conflicts on upgrade # 14438\n      unless ($needed{$_} eq \"zimbra-ldap\" && $newinstall == 0) {\n        $any = 1;\n        progress ( \"Port conflict detected: $_ ($needed{$_})\\n\" );\n      }\n    }\n  }\n\n  if (!$options{c}) {\n    if ($any) { ask(\"Port conflicts detected! - Press Enter/Return key to continue\", \"\"); }\n  }\n\n}\n\nsub isComponentAvailable {\n  my $component = shift;\n  detail(\"checking isComponentAvailable $component\");\n  # if its already defined return;\n  if (exists $main::loaded{components}{$component}) {\n    return 1;\n  }\n  if ($ldapConfigured ||\n    (($config{LDAPHOST} ne $config{HOSTNAME}) && ldapIsAvailable())) {\n    getAvailableComponents();\n  }\n  if (exists $main::loaded{components}{$component}) {\n    detail(\"Component $component is available.\");\n    return 1;\n  } else {\n    detail(\"Component $component is not available.\");\n    return 0;\n  }\n\n}\n\nsub getAvailableComponents {\n  detail(\"Getting available components\");\n  open(ZM, \"$ZMPROV gcf zimbraComponentAvailable 2> /dev/null|\") or\n    return undef;\n  while (<ZM>) {\n    chomp;\n    if (/^zimbraComponentAvailable: (\\S+)/) {\n      $main::loaded{components}{$1} = \"zimbraComponentAvailable\";\n    }\n  }\n  close(ZM) or return undef;\n}\n\nsub getDateStamp() {\n  my ($sec,$min,$hour,$mday,$mon,$year) = localtime(time());\n  $year = 1900+$year;\n  $sec = sprintf(\"%02d\", $sec);\n  $min = sprintf(\"%02d\", $min);\n  $hour = sprintf(\"%02d\", $hour);\n  $mday = sprintf(\"%02d\", $mday);\n  $mon = sprintf(\"%02d\", $mon+1);\n  my $stamp = \"$year$mon$mday-$hour$min$sec\";\n  return $stamp;\n}\n\nsub getInstalledPackages {\n  detail(\"Getting installed packages\");\n  foreach my $p (@packageList) {\n    if (isInstalled($p)) {\n      $installedPackages{$p} = $p;\n    }\n  }\n\n  # get list of previously installed packages on upgrade\n  if ($newinstall == 0) {\n    $config{zimbra_server_hostname} = getLocalConfig (\"zimbra_server_hostname\")\n      if ($config{zimbra_server_hostname} eq \"\");\n    detail (\"DEBUG: zimbra_server_hostname=$config{zimbra_server_hostname}\")\n      if $options{d};\n\n    $config{ldap_url} = getLocalConfig (\"ldap_url\")\n      if ($config{ldap_url} eq \"\");\n    detail (\"DEBUG: ldap_url=$config{ldap_url}\")\n      if $options{d};\n\n    if (index($config{ldap_url}, \"/\".$config{zimbra_server_hostname}) != -1) {\n      detail (\"zimbra_server_hostname contained in ldap_url checking ldap status\");\n      if (startLdap()) {return 1;}\n    } else {\n      detail (\"zimbra_server_hostname not in ldap_url not starting slapd\");\n    }\n    detail(\"Getting installed services from ldap\");\n    open(ZMPROV, \"$ZMPROV gs $config{zimbra_server_hostname}|\");\n    while (<ZMPROV>) {\n      chomp;\n      if (/zimbraServiceInstalled:\\s(.*)/) {\n        my $service = $1;\n\tif ($service eq \"imapproxy\") {\n\t\t$service = \"proxy\";\n\t}\n        if (exists $packageServiceMap{$service}) {\n          detail (\"Marking $service as previously installed.\")\n            if ($debug);\n          $prevInstalledPackages{$packageServiceMap{$service}} = \"Installed\";\n        } else {\n          progress(\"WARNING: Unknown package installed for $service.\\n\");\n        }\n      } else {\n        detail (\"DEBUG: skipping not zimbraServiceInstalled =>  $_\") if $debug;\n      }\n    }\n  }\n\n}\n\nsub getInstalledWebapps {\n  detail(\"Determining installed web applications\");\n  my $webappsDir = \"/opt/zimbra/jetty/webapps\";\n  foreach my $app (@webappList) {\n    if (($newinstall && -d \"$webappsDir/$app\") ||\n        (!$newinstall && isServiceEnabled($app))) {\n      $installedWebapps{$app}=\"Enabled\";\n      detail(\"Web application $app is enabled.\");\n    } else {\n      if ($newinstall || (!$newinstall && $installedWebapps{$app} ne \"Enabled\")) {\n        $installedWebapps{$app}=\"Disabled\";\n      }\n    }\n  }\n  if (!$newinstall && !defined($config{INSTALL_WEBAPPS})) {\n    foreach my $app (%installedWebapps) {\n      if ($installedWebapps{$app} eq \"Enabled\") {\n        $config{INSTALL_WEBAPPS}=\"$app $config{INSTALL_WEBAPPS}\";\n      }\n    }\n  }\n}\n\nsub isServiceEnabled {\n  my $service = shift;\n\n  if (defined ($enabledServices{$service})) {\n    if ($enabledServices{$service} eq \"Enabled\") {\n      detail (\"$service is enabled\");\n      return 1;\n    } else {\n      detail(\"$service is not enabled\");\n      return undef;\n    }\n  } else {\n    detail(\"$service not in enabled cache\");\n  }\n\n  return undef;\n}\n\nsub isEnabled {\n  my $package = shift;\n  detail(\"checking isEnabled $package\");\n  # if its already defined return;\n  if (defined $enabledPackages{$package}) {\n    if ($enabledPackages{$package} eq \"Enabled\") {\n      detail(\"$package is enabled\");\n      return 1;\n    } else {\n      detail(\"$package is not enabled\");\n      return undef;\n    }\n  } else {\n    detail(\"$package not in enabled cache\");\n    my $packages = join(\" \", keys %enabledPackages);\n    detail(\"enabled packages $packages\");\n  }\n\n\n  # lookup service in ldap\n  if ($newinstall == 0) {\n    $config{zimbra_server_hostname} = getLocalConfig (\"zimbra_server_hostname\")\n      if ($config{zimbra_server_hostname} eq \"\");\n    detail (\"DEBUG: zimbra_server_hostname=$config{zimbra_server_hostname}\")\n      if $options{d};\n\n    $config{ldap_url} = getLocalConfig (\"ldap_url\")\n      if ($config{ldap_url} eq \"\");\n    detail (\"DEBUG: ldap_url=$config{ldap_url}\")\n      if $options{d};\n\n    if (index($config{ldap_url}, \"/\".$config{zimbra_server_hostname}) != -1) {\n      detail (\"zimbra_server_hostname contained in ldap_url checking ldap status\");\n      if (startLdap()) {return 1;}\n    } else {\n      detail (\"zimbra_server_hostname not in ldap_url not starting slapd\");\n    }\n    detail(\"Getting enabled services from ldap\");\n    $enabledPackages{\"zimbra-core\"} = \"Enabled\"\n      if (isInstalled(\"zimbra-core\"));\n\n    open(ZMPROV, \"$ZMPROV gs $config{zimbra_server_hostname}|\");\n    while (<ZMPROV>) {\n      chomp;\n      if (/zimbraServiceEnabled:\\s(.*)/) {\n        my $service = $1;\n\tif ($service eq \"imapproxy\") {\n\t\t$service = \"proxy\";\n\t}\n        if (exists $packageServiceMap{$service}) {\n          detail (\"Marking $service as an enabled service.\")\n            if ($debug);\n          $enabledPackages{$packageServiceMap{$service}} = \"Enabled\";\n          $enabledServices{$service} = \"Enabled\";\n        } else {\n          progress(\"WARNING: Unknown package installed for $service.\\n\");\n        }\n      } else {\n        detail (\"DEBUG: skipping not zimbraServiceEnabled => $_\") if $debug;\n      }\n    }\n    foreach my $p (@packageList) {\n      if (isInstalled($p) and not defined $prevInstalledPackages{$p}) {\n        detail(\"Marking $p as installed. Services for $p will be enabled.\");\n        $enabledPackages{$p} = \"Enabled\";\n      } elsif (isInstalled($p) and not defined $enabledPackages{$p}) {\n        detail(\"Marking $p as disabled.\");\n        $enabledPackages{$p} = \"Disabled\";\n      }\n    }\n    close(ZMPROV);\n  } else {\n    detail(\"Newinstall enabling all installed packages\");\n    foreach my $p (@packageList) {\n      if (isInstalled($p)) {\n        unless ($enabledPackages{$p} eq \"Disabled\") {\n          detail(\"Enabling $p\");\n          $enabledPackages{$p} = \"Enabled\"\n        }\n      }\n    }\n  }\n\n  $enabledPackages{$package} = \"Disabled\"\n    if ($enabledPackages{$package} ne \"Enabled\");\n\n  return ($enabledPackages{$package} eq \"Enabled\" ? 1 : 0);\n}\n\nsub isInstalled {\n  my $pkg = shift;\n\n  my $pkgQuery;\n\n  my $good = 0;\n  if ($platform =~ /^DEBIAN/ || $platform =~ /^UBUNTU/) {\n    $pkgQuery = \"dpkg -s $pkg\";\n  } else {\n    $pkgQuery = \"rpm -q $pkg\";\n  }\n\n  my $rc = 0xffff & system (\"$pkgQuery > /dev/null 2>&1\");\n  $rc >>= 8;\n  if (($platform =~ /^DEBIAN/ || $platform =~ /^UBUNTU/) && $rc == 0 ) {\n    $good = 1;\n    $pkgQuery = \"dpkg -s $pkg | egrep '^Status: ' | grep 'not-installed'\";\n    $rc = 0xffff & system (\"$pkgQuery > /dev/null 2>&1\");\n    $rc >>= 8;\n    return ($rc == $good);\n  } else {\n    return ($rc == $good);\n  }\n}\n\nsub genRandomPass {\n  open RP, \"/opt/zimbra/bin/zmjava com.zimbra.common.util.RandomPassword -l 8 10|\" or\n    die \"Can't generate random password: $!\\n\";\n  my $rp = <RP>;\n  close RP;\n  chomp $rp;\n  return $rp;\n}\n\nsub getSystemStatus {\n\n  if (isEnabled(\"zimbra-ldap\")) {\n    if (-f \"/opt/zimbra/data/ldap/mdb/db/data.mdb\") {\n      $ldapConfigured = 1;\n      $ldapRunning = 0xffff & system(\"/opt/zimbra/bin/ldap status > /dev/null 2>&1\");\n      if ($ldapRunning) {\n        $ldapRunning = 0;\n      } else {\n        $ldapRunning = 1;\n      }\n      # Mac on x86 choked on this line?\n      #$ldapRunning = ($ldapRunning)?0:1;\n    } else {\n      $config{DOCREATEDOMAIN} = \"yes\";\n    }\n  }\n\n  if (isEnabled(\"zimbra-store\")) {\n    if (-d \"/opt/zimbra/db/data/zimbra\") {\n      $sqlConfigured = 1;\n      $sqlRunning = 0xffff & system(\"/opt/zimbra/bin/mysqladmin status > /dev/null 2>&1\");\n      $sqlRunning = ($sqlRunning)?0:1;\n    }\n    if ($newinstall) {\n      $config{DOCREATEADMIN} = \"yes\";\n      $config{DOTRAINSA} = \"yes\";\n    }\n  }\n\n  if (isEnabled(\"zimbra-logger\")) {\n    if (-d \"/opt/zimbra/logger/db/data/zimbra_logger\") {\n      $loggerSqlConfigured = 1;\n      $loggerSqlRunning = 0xffff &\n        system(\"/opt/zimbra/bin/logmysqladmin status > /dev/null 2>&1\");\n      $loggerSqlRunning = ($loggerSqlRunning)?0:1;\n    }\n  }\n\n  if (isEnabled(\"zimbra-mta\")) {\n    $config{SMTPHOST} = $config{HOSTNAME} if ($config{SMTPHOST} eq \"\");\n  }\n}\n\nsub getAllServers {\n  my ($service) = @_;\n  my @servers;\n  detail(\"Running $ZMPROV gas $service\");\n  open(ZMPROV, \"$ZMPROV gas $service 2>/dev/null|\");\n  chomp(@servers = <ZMPROV>);\n  close(ZMPROV);\n\n  return @servers;\n}\n\nsub getLdapAccountValue($$) {\n  my ($attrib,$sub) = @_;\n  my ($val,$err);\n  my $sec=\"acct\";\n  if (exists $main::loaded{$sec}{$sub}{$attrib}) {\n    $val = $main::loaded{$sec}{$sub}{$attrib};\n    detail(\"Returning cached config attribute for Account $sub: $attrib=$val\");\n    return $val;\n  }\n  my ($rfh,$wfh,$efh,$cmd,$rc);\n  $rfh = new FileHandle;\n  $wfh = new FileHandle;\n  $efh = new FileHandle;\n  $cmd = \"$ZMPROV ga $sub\";\n  my $pid = open3($wfh,$rfh,$efh,$cmd);\n  unless(defined($pid)) {\n    return undef;\n  }\n  close $wfh;\n  my @d = <$rfh>;\n  while (scalar(@d) > 0)  {\n    chomp(my $line = shift(@d));\n    my ($k, $v) = $line =~ m/^(\\w+):\\s(.*)/;\n    while ($d[0] !~ m/^\\w+:\\s.*/ && scalar(@d) > 0) {\n      chomp($v .= shift(@d));\n    }\n    if (!$main::loaded{$sec}{$sub}{zmsetuploaded} || ($main::loaded{$sec}{$sub}{zmsetuploaded} && $k eq $attrib)) {\n      if (exists $main::loaded{$sec}{$sub}{$k}) {\n        $main::loaded{$sec}{$sub}{$k}=\"$main::loaded{$sec}{$sub}{$k}\\n$v\";\n      } else {\n        $main::loaded{$sec}{$sub}{$k}=\"$v\";\n      }\n    }\n  }\n  chomp($err = join \"\", <$efh>);\n  detail(\"$err\") if (length($err) > 0);\n  waitpid($pid,0);\n  if ($? == -1) {\n    # failed to execute\n    return undef;\n  } elsif ($? & 127) {\n    # died with signal\n    return undef;\n  } else {\n    $rc = $? >> 8;\n    return undef if ($rc != 0);\n  }\n  $val=$main::loaded{$sec}{$sub}{$attrib};\n  $main::loaded{$sec}{$sub}{zmsetuploaded}=1;\n  detail(\"Returning retrieved account config attribute for $sub: $attrib=$val\");\n  return $val;\n}\nsub getLdapCOSValue {\n  my ($attrib,$sub) = @_;\n\n  $sub = \"default\" if ($sub eq \"\");\n  my $sec=\"gc\";\n  my ($val,$err);\n  if (exists $main::loaded{$sec}{$sub}{$attrib}) {\n    $val=$main::loaded{$sec}{$sub}{$attrib};\n    detail(\"Returning cached cos config attribute for $sub: $attrib=$val\");\n    return $val;\n  }\n\n  my ($rfh,$wfh,$efh,$cmd,$rc);\n  $rfh = new FileHandle;\n  $wfh = new FileHandle;\n  $efh = new FileHandle;\n  $cmd = \"$ZMPROV gc $sub\";\n  my $pid = open3($wfh,$rfh,$efh, $cmd);\n  unless(defined($pid)) {\n    return undef;\n  }\n  close $wfh;\n  my @d = <$rfh>;\n  while (scalar(@d) > 0)  {\n    chomp(my $line = shift(@d));\n    my ($k, $v) = $line =~ m/^(\\w+):\\s(.*)/;\n    while ($d[0] !~ m/^\\w+:\\s.*/ && scalar(@d) > 0) {\n      chomp($v .= shift(@d));\n    }\n    if (!$main::loaded{$sec}{$sub}{zmsetuploaded} || ($main::loaded{$sec}{$sub}{zmsetuploaded} && $k eq $attrib)) {\n      if (exists $main::loaded{$sec}{$sub}{$k}) {\n        $main::loaded{$sec}{$sub}{$k}=\"$main::loaded{$sec}{$sub}{$k}\\n$v\";\n      } else {\n        $main::loaded{$sec}{$sub}{$k}=\"$v\";\n      }\n    }\n  }\n  chomp($err = join \"\", <$efh>);\n  detail(\"$err\") if (length($err) > 0);\n  waitpid($pid,0);\n  if ($? == -1) {\n    # failed to execute\n    close $rfh; close $efh;\n    return undef;\n  } elsif ($? & 127) {\n    # died with signal\n    close $rfh; close $efh;\n    return undef;\n  } else {\n    $rc = $? >> 8;\n    close $rfh; close $efh;\n    return undef if ($rc != 0);\n  }\n  close $rfh; close $efh;\n  $val=$main::loaded{$sec}{$sub}{$attrib};\n  $main::loaded{$sec}{$sub}{zmsetuploaded}=1;\n  detail(\"Returning retrieved cos config attribute for $sub: $attrib=$val\");\n  return $val;\n}\n\nsub getLdapConfigValue {\n  my $attrib = shift;\n  my ($val,$err);\n  my $sec=\"gcf\";\n  my $sub=$sec;\n  if (exists $main::loaded{$sec}{$sub}{$attrib}) {\n    $val=$main::loaded{$sec}{$sub}{$attrib};\n    detail(\"Returning cached global config attribute: $attrib=$val\");\n    return $val;\n  }\n  my ($rfh,$wfh,$efh,$cmd,$rc);\n  $rfh = new FileHandle;\n  $wfh = new FileHandle;\n  $efh = new FileHandle;\n  $cmd = \"$ZMPROV gacf\";\n  my $pid = open3($wfh,$rfh,$efh, $cmd);\n  unless(defined($pid)) {\n    return undef;\n  }\n  close $wfh;\n  my @d = <$rfh>;\n  while (scalar(@d) > 0)  {\n    chomp(my $line = shift(@d));\n    my ($k, $v) = $line =~ m/^(\\w+):\\s(.*)/;\n    while ($d[0] !~ m/^\\w+:\\s.*/ && scalar(@d) > 0) {\n      chomp($v .= shift(@d));\n    }\n    if (!$main::loaded{$sec}{$sub}{zmsetuploaded} || ($main::loaded{$sec}{$sub}{zmsetuploaded} && $k eq $attrib)) {\n      if (exists $main::loaded{$sec}{$sub}{$k}) {\n        $main::loaded{$sec}{$sub}{$k}=\"$main::loaded{$sec}{$sub}{$k}\\n$v\";\n      } else {\n        $main::loaded{$sec}{$sub}{$k}=\"$v\";\n      }\n    }\n  }\n  chomp($err = join \"\", <$efh>);\n  detail(\"$err\") if (length($err) > 0);\n  waitpid($pid,0);\n  if ($? == -1) {\n    # failed to execute\n    close $rfh; close $efh;\n    return undef;\n  } elsif ($? & 127) {\n    # died with signal\n    close $rfh; close $efh;\n    return undef;\n  } else {\n    $rc = $? >> 8;\n    close $rfh; close $efh;\n    return undef if ($rc != 0);\n  }\n  close $rfh; close $efh;\n  $val=$main::loaded{$sec}{$sub}{$attrib};\n  $main::loaded{$sec}{$sub}{zmsetuploaded}=1;\n  detail(\"Returning retrieved global config attribute $attrib=$val\");\n  return $val;\n}\n\nsub getLdapDomainValue {\n  my ($attrib,$sub) = @_;\n\n  $sub = $config{zimbraDefaultDomainName}\n    if ($sub eq \"\");\n\n  return undef if ($sub eq \"\");\n  my $sec=\"domain\";\n\n  my ($val,$err);\n  if (exists $main::loaded{$sec}{$sub}{$attrib}) {\n    $val = $main::loaded{$sec}{$sub}{$attrib};\n    detail(\"Returning cached domain config attribute for $sub: $attrib=$val\");\n    return $val;\n  }\n\n  my ($rfh,$wfh,$efh,$cmd,$rc);\n  $rfh = new FileHandle;\n  $wfh = new FileHandle;\n  $efh = new FileHandle;\n  $cmd = \"$ZMPROV gd $sub\";\n  my $pid = open3($wfh,$rfh,$efh, $cmd);\n  unless(defined($pid)) {\n    return undef;\n  }\n  close $wfh;\n  my @d = <$rfh>;\n  while (scalar(@d) > 0)  {\n    chomp(my $line = shift(@d));\n    my ($k, $v) = $line =~ m/^(\\w+):\\s(.*)/;\n    while ($d[0] !~ m/^\\w+:\\s.*/ && scalar(@d) > 0) {\n      chomp($v .= shift(@d));\n    }\n    if (!$main::loaded{$sec}{$sub}{zmsetuploaded} || ($main::loaded{$sec}{$sub}{zmsetuploaded} && $k eq $attrib)) {\n      if (exists $main::loaded{$sec}{$sub}{$k}) {\n        $main::loaded{$sec}{$sub}{$k}=\"$main::loaded{$sec}{$sub}{$k}\\n$v\";\n      } else {\n        $main::loaded{$sec}{$sub}{$k}=\"$v\";\n      }\n    }\n  }\n  chomp($err = join \"\", <$efh>);\n  detail(\"$err\") if (length($err) > 0);\n  waitpid($pid,0);\n  if ($? == -1) {\n    # failed to execute\n    close $rfh; close $efh;\n    return undef;\n  } elsif ($? & 127) {\n    # died with signal\n    close $rfh; close $efh;\n    return undef;\n  } else {\n    $rc = $? >> 8;\n    close $rfh; close $efh;\n    return undef if ($rc != 0);\n  }\n  close $rfh; close $efh;\n  $main::loaded{$sec}{$sub}{zmsetuploaded}=1;\n  $val=$main::loaded{$sec}{$sub}{$attrib};\n  detail(\"Returning retrieved domain config attribute for $sub: $attrib=$val\");\n  return $val;\n}\n\nsub getLdapServerValue {\n  my ($attrib,$sub) = @_;\n  $sub = $main::config{HOSTNAME} if ($sub eq \"\");\n  my $sec=\"gs\";\n  my ($val,$err);\n  if (exists $main::loaded{$sec}{$sub}{$attrib}) {\n    $val = $main::loaded{$sec}{$sub}{$attrib};\n    detail(\"Returning cached server config attribute for $sub: $attrib=$val\");\n    return $val;\n  }\n  my ($rfh,$wfh,$efh,$cmd,$rc);\n  $rfh = new FileHandle;\n  $wfh = new FileHandle;\n  $efh = new FileHandle;\n  $cmd = \"$ZMPROV gs $sub\";\n  my $pid = open3($wfh,$rfh,$efh, $cmd);\n  unless(defined($pid)) {\n    return undef;\n  }\n  close $wfh;\n  my @d = <$rfh>;\n  while (scalar(@d) > 0)  {\n    chomp(my $line = shift(@d));\n    my ($k, $v) = $line =~ m/^(\\w+):\\s(.*)/;\n    while ($d[0] !~ m/^\\w+:\\s.*/ && scalar(@d) > 0) {\n      chomp($v .= shift(@d));\n    }\n    if (!$main::loaded{$sec}{$sub}{zmsetuploaded} || ($main::loaded{$sec}{$sub}{zmsetuploaded} && $k eq $attrib)) {\n      if (exists $main::loaded{$sec}{$sub}{$k}) {\n        $main::loaded{$sec}{$sub}{$k}=\"$main::loaded{$sec}{$sub}{$k}\\n$v\";\n      } else {\n        $main::loaded{$sec}{$sub}{$k}=\"$v\";\n      }\n    }\n  }\n  chomp($err = join \"\", <$efh>);\n  detail(\"$err\") if (length($err) > 0);\n  waitpid($pid,0);\n  if ($? == -1) {\n    # failed to execute\n    close $rfh; close $efh;\n    return undef;\n  } elsif ($? & 127) {\n    # died with signal\n    close $rfh; close $efh;\n    return undef;\n  } else {\n    $rc = $? >> 8;\n    close $rfh; close $efh;\n    return undef if ($rc != 0);\n  }\n  close $rfh; close $efh;\n  $main::loaded{$sec}{$sub}{zmsetuploaded}=1;\n  $val = $main::loaded{$sec}{$sub}{$attrib};\n  detail(\"Returning retrieved server config attribute for $sub: $attrib=$val\");\n  return $val;\n}\n\n\nsub getRealLdapServerValue {\n  my ($attrib,$sub) = @_;\n  $sub = $main::config{HOSTNAME} if ($sub eq \"\");\n  my $sec=\"gsreal\";\n  my ($val,$err);\n  if (exists $main::loaded{$sec}{$sub}{$attrib}) {\n    $val = $main::loaded{$sec}{$sub}{$attrib};\n    detail(\"Returning cached server config attribute for $sub: $attrib=$val\");\n    return $val;\n  }\n  my ($rfh,$wfh,$efh,$cmd,$rc);\n  $rfh = new FileHandle;\n  $wfh = new FileHandle;\n  $efh = new FileHandle;\n  $cmd = \"$ZMPROV gs -e $sub\";\n  my $pid = open3($wfh,$rfh,$efh, $cmd);\n  unless(defined($pid)) {\n    return undef;\n  }\n  close $wfh;\n  my @d = <$rfh>;\n  while (scalar(@d) > 0)  {\n    chomp(my $line = shift(@d));\n    my ($k, $v) = $line =~ m/^(\\w+):\\s(.*)/;\n    while ($d[0] !~ m/^\\w+:\\s.*/ && scalar(@d) > 0) {\n      chomp($v .= shift(@d));\n    }\n    if (!$main::loaded{$sec}{$sub}{zmsetuploaded} || ($main::loaded{$sec}{$sub}{zmsetuploaded} && $k eq $attrib)) {\n      if (exists $main::loaded{$sec}{$sub}{$k}) {\n        $main::loaded{$sec}{$sub}{$k}=\"$main::loaded{$sec}{$sub}{$k}\\n$v\";\n      } else {\n        $main::loaded{$sec}{$sub}{$k}=\"$v\";\n      }\n    }\n  }\n  chomp($err = join \"\", <$efh>);\n  detail(\"$err\") if (length($err) > 0);\n  waitpid($pid,0);\n  if ($? == -1) {\n    # failed to execute\n    close $rfh; close $efh;\n    return undef;\n  } elsif ($? & 127) {\n    # died with signal\n    close $rfh; close $efh;\n    return undef;\n  } else {\n    $rc = $? >> 8;\n    close $rfh; close $efh;\n    return undef if ($rc != 0);\n  }\n  close $rfh; close $efh;\n  $main::loaded{$sec}{$sub}{zmsetuploaded}=1;\n  $val = $main::loaded{$sec}{$sub}{$attrib};\n  detail(\"Returning retrieved server config attribute for $sub: $attrib=$val\");\n  return $val;\n}\n\nsub setLdapDefaults {\n\n  return if exists $config{LDAPDEFAULTSLOADED};\n  progress ( \"Setting defaults from ldap...\" );\n\n  #\n  # Load server specific attributes only if server exists\n  #\n  my $serverid = getLdapServerValue(\"zimbraId\");\n  if ($serverid ne \"\")  {\n\n    $config{zimbraIPMode}          = getLdapServerValue(\"zimbraIPMode\");\n    $config{zimbraDNSMasterIP}     = getLdapServerValue(\"zimbraDNSMasterIP\");\n    $config{zimbraDNSUseTCP}       = getLdapServerValue(\"zimbraDNSUseTCP\");\n    $config{zimbraDNSUseUDP}       = getLdapServerValue(\"zimbraDNSUseUDP\");\n    $config{zimbraDNSTCPUpstream}  = getLdapServerValue(\"zimbraDNSTCPUpstream\");\n\n    $config{IMAPPORT}              = getLdapServerValue(\"zimbraImapBindPort\");\n    $config{IMAPSSLPORT}           = getLdapServerValue(\"zimbraImapSSLBindPort\");\n    $config{REMOTEIMAPBINDPORT}    = getLdapServerValue(\"zimbraRemoteImapBindPort\");\n    $config{REMOTEIMAPSSLBINDPORT} = getLdapServerValue(\"zimbraRemoteImapSSLBindPort\");\n    $config{POPPORT}               = getLdapServerValue(\"zimbraPop3BindPort\");\n    $config{POPSSLPORT}            = getLdapServerValue(\"zimbraPop3SSLBindPort\");\n\n    $config{IMAPPROXYPORT}         = getLdapServerValue(\"zimbraImapProxyBindPort\");\n    $config{IMAPSSLPROXYPORT}      = getLdapServerValue(\"zimbraImapSSLProxyBindPort\");\n    $config{POPPROXYPORT}          = getLdapServerValue(\"zimbraPop3ProxyBindPort\");\n    $config{POPSSLPROXYPORT}       = getLdapServerValue(\"zimbraPop3SSLProxyBindPort\");\n    $config{MAILPROXY}             = getLdapServerValue(\"zimbraReverseProxyMailEnabled\");\n\n    $config{MODE}                  = getLdapServerValue(\"zimbraMailMode\");\n    $config{PROXYMODE}             = getLdapServerValue(\"zimbraReverseProxyMailMode\");\n    $config{HTTPPORT}              = getLdapServerValue(\"zimbraMailPort\");\n    $config{HTTPSPORT}             = getLdapServerValue(\"zimbraMailSSLPort\");\n\n    $config{HTTPPROXYPORT}         = getLdapServerValue(\"zimbraMailProxyPort\");\n    $config{HTTPSPROXYPORT}        = getLdapServerValue(\"zimbraMailSSLProxyPort\");\n    $config{HTTPPROXY}             = getLdapServerValue(\"zimbraReverseProxyHttpEnabled\");\n    $config{SMTPHOST}              = getLdapServerValue(\"zimbraSmtpHostname\");\n\n\n    $config{zimbraReverseProxyLookupTarget} = getLdapServerValue(\"zimbraReverseProxyLookupTarget\")\n      if ($config{zimbraReverseProxyLookupTarget} eq \"\");\n\n    if (isEnabled(\"zimbra-mta\")) {\n      my $tmpval = getLdapServerValue(\"zimbraMtaMyNetworks\");\n      $config{zimbraMtaMyNetworks} = $tmpval\n        unless ($tmpval eq \"\");\n    }\n  }\n\n  #\n  # Load Global config values\n  #\n  # default domainname\n  $config{zimbraDefaultDomainName} = getLdapConfigValue(\"zimbraDefaultDomainName\");\n  if ($config{zimbraDefaultDomainName} eq \"\") {\n    $config{zimbraDefaultDomainName} = $config{CREATEDOMAIN};\n  } else {\n    $config{CREATEDOMAIN} = $config{zimbraDefaultDomainName};\n    $config{CREATEADMIN} = \"admin\\@$config{CREATEDOMAIN}\";\n  }\n\n  if ($config{SMTPHOST} eq \"\") {\n      my $smtphost = getLdapConfigValue(\"zimbraSmtpHostname\");\n      $smtphost =~ s/\\n/ /g;\n      $config{SMTPHOST} = $smtphost if ($smtphost ne \"localhost\");\n  }\n\n  $config{TRAINSASPAM}      = getLdapConfigValue(\"zimbraSpamIsSpamAccount\");\n  if ($config{TRAINSASPAM} eq \"\") {\n    $config{TRAINSASPAM} = \"spam.\".lc(genRandomPass()).'@'.$config{CREATEDOMAIN};\n  }\n  $config{TRAINSAHAM}       = getLdapConfigValue(\"zimbraSpamIsNotSpamAccount\");\n  if ($config{TRAINSAHAM} eq \"\") {\n    $config{TRAINSAHAM} = \"ham.\".lc(genRandomPass()).'@'.$config{CREATEDOMAIN};\n  }\n  $config{VIRUSQUARANTINE}       = getLdapConfigValue(\"zimbraAmavisQuarantineAccount\");\n  if ($config{VIRUSQUARANTINE} eq \"\") {\n    $config{VIRUSQUARANTINE} = \"virus-quarantine.\".lc(genRandomPass()).'@'.$config{CREATEDOMAIN};\n  }\n\n  if (isNetwork() && isEnabled(\"zimbra-store\")) {\n    $config{zimbraBackupReportEmailRecipients} = getLdapConfigValue(\"zimbraBackupReportEmailRecipients\");\n    $config{zimbraBackupReportEmailRecipients} = $config{CREATEADMIN}\n      if ($config{zimbraBackupReportEmailRecipients} eq \"\");\n\n    $config{zimbraBackupReportEmailSender} = getLdapConfigValue(\"zimbraBackupReportEmailSender\");\n    $config{zimbraBackupReportEmailSender} = $config{CREATEADMIN}\n      if ($config{zimbraBackupReportEmailSender} eq \"\");\n  }\n\n  $config{zimbraVersionCheckInterval} =\n    getLdapConfigValue(\"zimbraVersionCheckInterval\");\n  if ($config{zimbraVersionCheckInterval} eq \"\") {\n    $config{VERSIONUPDATECHECKS}=\"\";\n  } else {\n    $config{VERSIONUPDATECHECKS} =\n      (($config{zimbraVersionCheckInterval} eq \"0\") ? \"FALSE\" : \"TRUE\");\n  }\n\n  $config{zimbraVersionCheckSendNotifications} =\n    getLdapConfigValue(\"zimbraVersionCheckSendNotifications\");\n  $config{zimbraVersionCheckSendNotifications} = \"TRUE\"\n    if ($config{zimbraVersionCheckSendNotifications} eq \"\");\n\n  if ($config{zimbraVersionCheckSendNotifications} eq \"TRUE\") {\n    $config{zimbraVersionCheckServer} =\n      getLdapConfigValue(\"zimbraVersionCheckServer\");\n\n    $config{zimbraVersionCheckNotificationEmail} =\n      getLdapConfigValue(\"zimbraVersionCheckNotificationEmail\");\n\n    # force confirmation of choice during upgrade if this was never setup before\n    if (!$newinstall && $config{zimbraVersionCheckNotificationEmail} eq \"\" && !$options{c}) {\n      $config{VERSIONUPDATECHECKS}=\"\";\n    }\n\n    $config{zimbraVersionCheckNotificationEmail} = $config{CREATEADMIN}\n      if ($config{zimbraVersionCheckNotificationEmail} eq \"\");\n\n    $config{zimbraVersionCheckNotificationEmailFrom} =\n      getLdapConfigValue(\"zimbraVersionCheckNotificationEmailFrom\");\n    $config{zimbraVersionCheckNotificationEmailFrom} = $config{CREATEADMIN}\n      if ($config{zimbraVersionCheckNotificationEmailFrom} eq \"\");\n  }\n\n  $config{EphemeralBackendURL} = getLdapConfigValue(\"zimbraEphemeralBackendURL\");\n  $config{USEEPHEMERALSTORE} = \"yes\" if ($config{EphemeralBackendURL} ne \"\");\n\n  # get the onlyoffice zimbraDocumentServerHost global config\n  if (isEnabled(\"zimbra-onlyoffice\")) {\n    my $tmpval = getLdapConfigValue(\"zimbraDocumentServerHost\");\n    $config{ONLYOFFICEHOSTNAME} = $tmpval;\n  }\n  #\n  # Load default COS\n  #\n  $config{USEKBSHORTCUTS} = getLdapCOSValue(\"zimbraPrefUseKeyboardShortcuts\");\n  $config{zimbraPrefTimeZoneId}=getLdapCOSValue(\"zimbraPrefTimeZoneId\");\n\n  $config{zimbraFeatureTasksEnabled}=getLdapCOSValue(\"zimbraFeatureTasksEnabled\");\n  $config{zimbraFeatureTasksEnabled}=\"Enabled\"\n    if (lc($config{zimbraFeatureTasksEnabled}) eq \"true\");\n  $config{zimbraFeatureTasksEnabled}=\"Disabled\"\n    if (lc($config{zimbraFeatureTasksEnabled}) eq \"false\");\n\n  $config{zimbraFeatureBriefcasesEnabled}=getLdapCOSValue(\"zimbraFeatureBriefcasesEnabled\");\n  $config{zimbraFeatureBriefcasesEnabled}=\"Enabled\"\n    if (lc($config{zimbraFeatureBriefcasesEnabled}) eq \"true\");\n  $config{zimbraFeatureBriefcasesEnabled}=\"Disabled\"\n    if (lc($config{zimbraFeatureBriefcasesEnabled}) eq \"false\");\n\n  #\n  # Load default domain values\n  #\n  my $galacct = getLdapDomainValue(\"zimbraGalAccountId\");\n  $config{ENABLEGALSYNCACCOUNTS}=(($galacct eq \"\") ? \"no\" : \"yes\");\n\n  #\n  # Set some sane defaults if values were missing in LDAP\n  #\n  $config{HTTPPORT} = 80 if ($config{HTTPPORT} eq 0);\n  $config{HTTPSPORT} = 443 if ($config{HTTPSPORT} eq 0);\n  $config{MODE} = \"https\" if ($config{MODE} eq \"\");\n  $config{PROXYMODE} = \"https\" if ($config{PROXYMODE} eq \"\");\n  $config{REMOTEIMAPBINDPORT} = 8143 if ($config{REMOTEIMAPBINDPORT} eq 0);\n  $config{REMOTEIMAPSSLBINDPORT} = 8993 if ($config{REMOTEIMAPSSLBINDPORT} eq 0);\n\n  if (isInstalled(\"zimbra-proxy\") && isEnabled(\"zimbra-proxy\")) {\n     if ($config{MAILPROXY} eq \"TRUE\") {\n        if ($config{IMAPPORT} == $config{IMAPPROXYPORT} && $config{IMAPPORT} == 143) {\n            $config{IMAPPORT} = 7143;\n        }\n        if ($config{IMAPSSLPORT} == $config{IMAPSSLPROXYPORT} && $config{IMAPSSLPORT} == 993) {\n            $config{IMAPSSLPORT} = 7993;\n        }\n        if ($config{POPPORT} == $config{POPPROXYPORT} && $config{POPPORT} == 110) {\n            $config{POPPORT} = 7110;\n        }\n        if ($config{POPSSLPORT} == $config{POPSSLPROXYPORT} && $config{POPSSLPORT} == 995) {\n            $config{POPSSLPORT} = 7995;\n        }\n        if ($config{IMAPPORT} == $config{IMAPPROXYPORT} && $config{IMAPPORT} == 7143) {\n            $config{IMAPPROXYPORT} = 143;\n        }\n        if ($config{IMAPSSLPORT} == $config{IMAPSSLPROXYPORT} && $config{IMAPSSLPORT} == 7993) {\n            $config{IMAPSSLPROXYPORT} = 993;\n        }\n        if ($config{POPPORT} == $config{POPPROXYPORT} && $config{POPPORT} == 7110) {\n            $config{POPPROXYPORT} = 110;\n        }\n        if ($config{POPSSLPORT} == $config{POPSSLPROXYPORT} && $config{POPSSLPORT} == 7995) {\n            $config{POPSSLPROXYPORT} = 995;\n        }\n     }\n     if ($config{HTTPPROXY} eq \"TRUE\") {\n        if ($config{HTTPPORT} == $config{HTTPPROXYPORT} && $config{HTTPPORT} == 80) {\n            $config{HTTPPORT} = 8080;\n        }\n        if ($config{HTTPSPORT} == $config{HTTPSPROXYPORT} && $config{HTTPSPORT} == 443) {\n            $config{HTTPSPORT} = 8443;\n        }\n        if ($config{HTTPPORT} == $config{HTTPPROXYPORT} && $config{HTTPPORT} == 8080) {\n            $config{HTTPPROXYPORT} = 80;\n        }\n        if ($config{HTTPSPORT} == $config{HTTPSPROXYPORT} && $config{HTTPSPORT} == 8443) {\n            $config{HTTPSPROXYPORT} = 443;\n        }\n     }\n  } else {\n        if ($config{IMAPPORT} == $config{IMAPPROXYPORT} && $config{IMAPPORT} == 143) {\n            $config{IMAPPROXYPORT} = 7143;\n        }\n        if ($config{IMAPSSLPORT} == $config{IMAPSSLPROXYPORT} && $config{IMAPSSLPORT} == 993) {\n            $config{IMAPSSLPROXYPORT} = 7993;\n        }\n        if ($config{POPPORT} == $config{POPPROXYPORT} && $config{POPPORT} == 110) {\n            $config{POPPROXYPORT} = 7110;\n        }\n        if ($config{POPSSLPORT} == $config{POPSSLPROXYPORT} && $config{POPSSLPORT} == 995) {\n            $config{POPSSLPROXYPORT} = 7995;\n        }\n        if ($config{IMAPPORT} == $config{IMAPPROXYPORT} && $config{IMAPPORT} == 7143) {\n            $config{IMAPPORT} = 143;\n        }\n        if ($config{IMAPSSLPORT} == $config{IMAPSSLPROXYPORT} && $config{IMAPSSLPORT} == 7993) {\n            $config{IMAPSSLPORT} = 993;\n        }\n        if ($config{POPPORT} == $config{POPPROXYPORT} && $config{POPPORT} == 7110) {\n            $config{POPPORT} = 110;\n        }\n        if ($config{POPSSLPORT} == $config{POPSSLPROXYPORT} && $config{POPSSLPORT} == 7995) {\n            $config{POPSSLPORT} = 995;\n        }\n        if ($config{HTTPPORT} == $config{HTTPPROXYPORT} && $config{HTTPPORT} == 80) {\n            $config{HTTPPROXYPORT} = 8080;\n        }\n        if ($config{HTTPSPORT} == $config{HTTPSPROXYPORT} && $config{HTTPSPORT} == 443) {\n            $config{HTTPSPROXYPORT} = 8443;\n        }\n        if ($config{HTTPPORT} == $config{HTTPPROXYPORT} && $config{HTTPPORT} == 8080) {\n            $config{HTTPPORT} = 80;\n        }\n        if ($config{HTTPSPORT} == $config{HTTPSPROXYPORT} && $config{HTTPSPORT} == 8443) {\n            $config{HTTPSPORT} = 443;\n        }\n  }\n\n  #\n  # debug output\n  #\n  if ($options{d}) {\n    foreach my $key (sort keys %config) {\n      print \"\\tDEBUG: $key=$config{$key}\\n\";\n    }\n  }\n  $config{LDAPDEFAULTSLOADED}=1;\n  progress ( \"done.\\n\" );\n}\n\nsub installLdapConfig {\n  my $config_src=\"/opt/zimbra/common/etc/openldap/zimbra/config\";\n  my $config_dest=\"/opt/zimbra/data/ldap/config\";\n  if (-d \"/opt/zimbra/data/ldap/config\") {\n    main::progress(\"Installing LDAP configuration database...\");\n    qx(mkdir -p $config_dest/cn\\=config/olcDatabase\\=\\{2\\}mdb);\n    system(\"cp -f $config_src/cn\\=config.ldif $config_dest/cn\\=config.ldif\");\n    system(\"cp -f $config_src/cn\\=config/cn\\=module\\{0\\}.ldif $config_dest/cn\\=config/cn\\=module\\{0\\}.ldif\");\n    system(\"cp -f $config_src/cn\\=config/cn\\=schema.ldif $config_dest/cn\\=config/cn\\=schema.ldif\");\n    system(\"cp -f $config_src/cn\\=config/olcDatabase\\=\\{-1\\}frontend.ldif $config_dest/cn\\=config/olcDatabase\\=\\{-1\\}frontend.ldif\");\n    system(\"cp -f $config_src/cn\\=config/olcDatabase\\=\\{0\\}config.ldif $config_dest/cn\\=config/olcDatabase\\=\\{0\\}config.ldif\");\n    system(\"cp -f $config_src/cn\\=config/olcDatabase\\=\\{1\\}monitor.ldif $config_dest/cn\\=config/olcDatabase\\=\\{1\\}monitor.ldif\");\n    system(\"cp -f $config_src/cn\\=config/olcDatabase\\=\\{2\\}mdb.ldif $config_dest/cn\\=config/olcDatabase\\=\\{2\\}mdb.ldif\");\n    system(\"cp -f $config_src/cn\\=config/olcDatabase\\=\\{2\\}mdb/olcOverlay\\=\\{0\\}dynlist.ldif $config_dest/cn\\=config/olcDatabase\\=\\{2\\}mdb/olcOverlay\\=\\{0\\}dynlist.ldif\");\n    system(\"cp -f $config_src/cn\\=config/olcDatabase\\=\\{2\\}mdb/olcOverlay\\=\\{1\\}unique.ldif $config_dest/cn\\=config/olcDatabase\\=\\{2\\}mdb/olcOverlay\\=\\{1\\}unique.ldif\");\n    system(\"cp -f $config_src/cn\\=config/olcDatabase\\=\\{2\\}mdb/olcOverlay\\=\\{2\\}noopsrch.ldif $config_dest/cn\\=config/olcDatabase\\=\\{2\\}mdb/olcOverlay\\=\\{2\\}noopsrch.ldif\");\n    qx(chmod 600 $config_dest/cn\\=config.ldif);\n    qx(chmod 600 $config_dest/cn\\=config/*.ldif);\n    qx(chown -R zimbra:zimbra $config_dest);\n    main::progress(\"done.\\n\");\n  }\n}\n\nsub installLdapSchema {\n  main::runAsZimbra(\"/opt/zimbra/libexec/zmldapschema 2>/dev/null\");\n}\n\nsub setDefaults {\n  progress ( \"Setting defaults...\" ) unless $options{d};\n\n  # Get the interfaces.\n  # Do this in perl, since it's the same on all platforms.\n  my $ipv4found=0;\n  my $ipv6found=0;\n\n  open INTS, \"/sbin/ifconfig | grep ' addr' |\";\n  foreach (<INTS>) {\n    chomp;\n    if ($_ =~ /inet6/) {\n      next if ($_ =~ /Link/);\n      s/.*inet6 //;\n      s/.*addr: //;\n      s/\\/.*//;\n      if ($_ ne \"::1\") {\n        $ipv6found=1;\n      }\n    } else {\n      s/.*inet //;\n      s/\\s.*//;\n      s/[a-zA-Z:]//g;\n      s/^\\n//g;\n      next if ($_ eq \"\");\n      if ($_ ne \"127.0.0.1\") {\n        $ipv4found=1;\n      }\n    }\n    push @interfaces, $_;\n  }\n  close INTS;\n  if (-x \"/sbin/ip\") {\n    open INTS, \"/sbin/ip addr| grep ' scope ' |\";\n    foreach (<INTS>) {\n      chomp;\n      if ($_ =~ /inet6/) {\n        next if ($_ =~ /link/);\n        s/.*inet6 //;\n        s/.*addr: //;\n        s/\\/.*//;\n        if ($_ ne \"::1\") {\n          $ipv6found=1;\n        }\n      } else {\n        s/.*inet //;\n        s/\\/.*//;\n        s/[a-zA-Z:]//g;\n        s/^\\n//g;\n        next if ($_ eq \"\");\n        if ($_ ne \"127.0.0.1\") {\n          $ipv4found=1;\n        }\n      }\n      push @interfaces, $_;\n    }\n    close INTS;\n  }\n\n  my %seen=();\n  @interfaces = grep {!$seen{$_}++} @interfaces;\n\n  $config{EXPANDMENU} = \"no\";\n  $config{REMOVE} = \"no\";\n  $config{UPGRADE} = \"yes\";\n  $config{LDAPPORT} = 389;\n  $config{USESPELL} = \"no\";\n  $config{SPELLURL} = \"\";\n\n  $config{IMAPPORT} = 143;\n  $config{IMAPSSLPORT} = 993;\n  $config{POPPORT} = 110;\n  $config{POPSSLPORT} = 995;\n  $config{HTTPPORT} = 80;\n  $config{HTTPSPORT} = 443;\n  $config{ssl_default_digest} = \"sha256\";\n\n  if (!$ipv4found && $ipv6found) {\n    $config{zimbraIPMode}     = \"ipv6\";\n  } else {\n    $config{zimbraIPMode}     = \"ipv4\";\n  }\n\n  $config{JAVAHOME} = \"/opt/zimbra/common/lib/jvm/java\";\n  setLocalConfig (\"zimbra_java_home\", \"$config{JAVAHOME}\");\n  $config{HOSTNAME} = lc(qx(hostname --fqdn));\n  chomp $config{HOSTNAME};\n\n  $config{ldap_dit_base_dn_config} = \"cn=zimbra\"\n    if ($config{ldap_dit_base_dn_config} eq \"\");\n  $config{mailboxd_directory} = \"/opt/zimbra/mailboxd\";\n  if ( -f \"/opt/zimbra/common/jetty_home/start.jar\" ) {\n    $config{mailboxd_keystore} = \"$config{mailboxd_directory}/etc/keystore\";\n    $config{mailboxd_server} = \"jetty\";\n  } elsif ( -f \"/opt/zimbra/tomcat/bin/startup.sh\" ) {\n    $config{mailboxd_keystore} = \"$config{mailboxd_directory}/conf/keystore\";\n    $config{mailboxd_server} = \"tomcat\";\n  } else {\n    $config{mailboxd_keystore} = \"/opt/zimbra/conf/keystore\";\n  }\n  $config{mailboxd_truststore} = \"/opt/zimbra/common/lib/jvm/java/lib/security/cacerts\";\n  $config{mailboxd_keystore_password} = genRandomPass();\n  $config{mailboxd_truststore_password} = \"changeit\";\n\n  if ( -f \"/opt/zimbra/bin/zmimapdctl\" ) {\n    $config{imapd_keystore} = \"/opt/zimbra/conf/imapd.keystore\";\n    $config{imapd_keystore_password} = $config{mailboxd_keystore_password};\n  }\n\n  $config{SMTPHOST} = \"\";\n  $config{SNMPTRAPHOST} = $config{HOSTNAME};\n  $config{DOCREATEDOMAIN} = \"no\";\n  $config{CREATEDOMAIN} = $config{HOSTNAME};\n  $config{DOCREATEADMIN} = \"no\";\n\n  if (isEnabled(\"zimbra-dnscache\")) {\n    my @dnsMasters;\n    my @resolv;\n    if ( -r \"/etc/resolv.conf\" && -f \"/etc/resolv.conf\" ) {\n      open(RESOLV, '</etc/resolv.conf');\n      @resolv=<RESOLV>;\n      close RESOLV;\n      foreach my $line (@resolv) {\n        chomp($line);\n        if ($line =~ /^nameserver /) {\n          if ($line !~ /127.0.0.1/ && $line !~ /::1/) {\n            my ($junk, $tmpip);\n            ($junk, $tmpip) = split(/ /, $line, 2);\n            push(@dnsMasters, $tmpip);\n          }\n        }\n      }\n    }\n    if (scalar(@dnsMasters) > 0) {\n      $config{zimbraDNSMasterIP} = join(' ', @dnsMasters);\n    } else {\n      $config{zimbraDNSMasterIP} = \"\";\n    }\n    $config{zimbraDNSUseTCP} = \"yes\";\n    $config{zimbraDNSUseUDP} = \"yes\";\n    $config{zimbraDNSTCPUpstream} = \"no\";\n  }\n\n  if (isEnabled(\"zimbra-store\")) {\n    progress  \"setting defaults for zimbra-store.\\n\" if $options{d};\n    $config{DOCREATEADMIN} = \"yes\" if $newinstall;\n    $config{DOTRAINSA} = \"yes\";\n    $config{SERVICEWEBAPP} = \"yes\";\n    $config{UIWEBAPPS} = \"yes\";\n    $config{zimbraReverseProxyLookupTarget} = \"TRUE\" if $newinstall;\n    $config{zimbraMailProxy} = \"TRUE\" if $newinstall;\n    $config{zimbraWebProxy} = \"TRUE\" if $newinstall;\n\n    # default values for upgrades\n    if ($config{TRAINSASPAM} eq \"\") {\n      $config{TRAINSASPAM} = \"spam.\".lc(genRandomPass());\n      $config{TRAINSASPAM} .= '@'.$config{CREATEDOMAIN};\n    }\n    if ($config{TRAINSAHAM} eq \"\") {\n      $config{TRAINSAHAM} = \"ham.\".lc(genRandomPass());\n      $config{TRAINSAHAM} .= '@'.$config{CREATEDOMAIN};\n    }\n    if ($config{VIRUSQUARANTINE} eq \"\") {\n      $config{VIRUSQUARANTINE} = \"virus-quarantine.\".lc(genRandomPass());\n      $config{VIRUSQUARANTINE} .= '@'.$config{CREATEDOMAIN};\n    }\n\n\n\n    if (!$newinstall) {\n      $config{zimbraFeatureBriefcasesEnabled} = \"Enabled\"\n        if ($config{zimbraFeatureBriefcasesEnabled} eq \"\");\n      $config{zimbraFeatureTasksEnabled} = \"Disabled\"\n        if ($config{zimbraFeatureTasksEnabled} eq \"\");\n    } else {\n      $config{zimbraFeatureBriefcasesEnabled} = \"Enabled\"\n        if ($config{zimbraFeatureBriefcasesEnabled} eq \"\");\n      $config{zimbraFeatureTasksEnabled} = \"Enabled\"\n        if ($config{zimbraFeatureTasksEnabled} eq \"\");\n    }\n\n  }\n\n  if (isEnabled(\"zimbra-imapd\")) {\n    progress  \"setting defaults for zimbra-imapd.\\n\" if $options{d};\n    $config{DOADDUPSTREAMIMAP} = \"no\";\n  }\n\n  $config{zimbra_require_interprocess_security} = 1;\n  $config{ZIMBRA_REQ_SECURITY}=\"yes\";\n\n  if (isEnabled(\"zimbra-ldap\")) {\n    progress \"setting defaults for zimbra-ldap.\\n\" if $options{d};\n    $config{DOCREATEDOMAIN} = \"yes\" if $newinstall;\n    $config{LDAPROOTPASS} = genRandomPass();\n    $config{LDAPADMINPASS} = $config{LDAPROOTPASS};\n    $config{LDAPREPPASS} =  $config{LDAPADMINPASS};\n    $config{LDAPPOSTPASS} = $config{LDAPADMINPASS};\n    $config{LDAPAMAVISPASS} =  $config{LDAPADMINPASS};\n    $config{ldap_nginx_password} = $config{LDAPADMINPASS};\n    $config{ldap_bes_searcher_password} = $config{LDAPADMINPASS};\n    $config{LDAPREPLICATIONTYPE} = \"master\"; # Values can be master, mmr, replica\n    $config{USEEPHEMERALSTORE} = \"no\";\n    $config{LDAPSERVERID} = 2; # Aleady enabled master should be 1, so default to next ID.\n    $ldapRepChanged = 1;\n    $ldapPostChanged = 1;\n    $ldapAmavisChanged = 1;\n    $ldapNginxChanged = 1;\n    if ($newinstall) {\n      $ldapBesSearcherChanged = 1;\n    }\n  }\n\n  if(isInstalled(\"zimbra-proxy\") && !isEnabled(\"zimbra-ldap\")) {\n    $config{ldap_nginx_password} = genRandomPass();\n    $ldapNginxChanged = 1;\n  }\n\n  $config{CREATEADMIN} = \"admin\\@$config{CREATEDOMAIN}\";\n\n  if (isEnabled(\"zimbra-store\")) {\n    $config{VERSIONUPDATECHECKS} = \"TRUE\";\n    $config{zimbraVersionCheckSendNotifications} = \"TRUE\"\n      if ($config{zimbraVersionCheckSendNotifications} eq \"\");\n    $config{zimbraVersionCheckNotificationEmail} = $config{CREATEADMIN}\n      if ($config{zimbraVersionCheckNotificationEmail} eq \"\");\n    $config{zimbraVersionCheckNotificationEmailFrom} = $config{CREATEADMIN}\n      if ($config{zimbraVersionCheckNotificationEmailFrom} eq \"\");\n  }\n\n  my $tzname=qx(/bin/date '+%Z');\n  chomp($tzname);\n\n  detail(\"Local timezone detected as $tzname\\n\");\n  my $tzdata = Zimbra::Util::Timezone->parse;\n  my $tz = $tzdata->gettzbyname($tzname);\n  $config{zimbraPrefTimeZoneId} = $tz->tzid if (defined $tz);\n  $config{zimbraPrefTimeZoneId} = 'America/Los_Angeles'\n    if ($config{zimbraPrefTimeZoneId} eq \"\");\n  detail(\"Default Olson timezone name $config{zimbraPrefTimeZoneId}\\n\");\n\n  #progress(\"tzname=$tzname tzid=$config{zimbraPrefTimeZoneId}\");\n\n  $config{zimbra_ldap_userdn} = \"uid=zimbra,cn=admins,$config{ldap_dit_base_dn_config}\";\n\n  $config{SMTPSOURCE} = $config{CREATEADMIN};\n  $config{SMTPDEST} = $config{CREATEADMIN};\n  $config{AVUSER} = $config{CREATEADMIN};\n  $config{AVDOMAIN} = $config{CREATEDOMAIN};\n  $config{SNMPNOTIFY} = \"yes\";\n  $config{SMTPNOTIFY} = \"yes\";\n  $config{STARTSERVERS} = \"yes\";\n\n  if (isEnabled(\"zimbra-store\") && isNetwork()) {\n    $config{zimbraBackupReportEmailRecipients} = $config{CREATEADMIN};\n    $config{zimbraBackupReportEmailSender} = $config{CREATEADMIN};\n  }\n\n  if (isEnabled(\"zimbra-mta\")) {\n    progress  \"setting defaults for zimbra-mta.\\n\" if $options{d};\n    my @tmpval = (qx(/opt/zimbra/libexec/zmserverips -n));\n    chomp(@tmpval);\n    if (@tmpval) {\n      $config{zimbraMtaMyNetworks} = \"@tmpval\";\n    } else {\n      $config{zimbraMtaMyNetworks} = \"127.0.0.0/8 [::1]/128 @interfaces\";\n    }\n    $config{postfix_mail_owner} = \"postfix\";\n    $config{postfix_setgid_group} = \"postdrop\";\n  }\n\n  $config{MODE} = \"https\";\n  $config{PROXYMODE} = \"https\";\n\n  $config{SYSTEMMEMORY} = getSystemMemory();\n  $config{MYSQLMEMORYPERCENT} = mysqlMemoryPercent($config{SYSTEMMEMORY});\n  $config{MAILBOXDMEMORY} = mailboxdMemoryMB($config{SYSTEMMEMORY});\n\n  $config{CREATEADMINPASS} = \"\" unless ($config{CREATEADMINPASS});\n\n  if (!$options{c} && $newinstall) {\n    progress \"no config file and newinstall checking dns resolution\\n\" if $options{d};\n\n    if (lookupHostName ($config{HOSTNAME}, 'A')) {\n      if (lookupHostName ($config{HOSTNAME}, 'AAAA')) {\n        progress(\"\\n\\nDNS ERROR resolving $config{HOSTNAME}\\n\");\n        progress(\"It is suggested that the hostname be resolvable via DNS\\n\");\n        if (askYN(\"Change hostname\",\"Yes\") eq \"yes\") {\n          setHostName();\n        }\n      }\n    }\n\n    my $good = 0;\n\n    if ($config{DOCREATEDOMAIN} eq \"yes\") {\n      my $ans = getDnsRecords($config{CREATEDOMAIN}, 'MX');\n      if (!defined($ans)) {\n        progress(\"\\n\\nDNS ERROR resolving MX for $config{CREATEDOMAIN}\\n\");\n        progress(\"It is suggested that the domain name have an MX record configured in DNS\\n\");\n        if (askYN(\"Change domain name?\",\"Yes\") eq \"yes\") {\n          setCreateDomain();\n        }\n      } elsif (isEnabled(\"zimbra-mta\")) {\n\n        my @answer = $ans->answer;\n        foreach my $a (@answer) {\n          if ($a->type eq \"MX\") {\n            my $h = getDnsRecords ($a->exchange,'A');\n            my $ipv6 = 0;\n            if (!defined $h) {\n              $h = getDnsRecords ($a->exchange, 'AAAA');\n              $ipv6 = 1;\n            }\n            if (defined $h) {\n              my @ha = $h->answer;\n              foreach $h (@ha) {\n                if ($ipv6) {\n                  if ($h->type eq 'AAAA') {\n                    progress \"\\tMX: \".$a->exchange.\" (\".$h->address.\")\\n\";\n                  }\n                } else {\n                  if ($h->type eq 'A') {\n                    progress \"\\tMX: \".$a->exchange.\" (\".$h->address.\")\\n\";\n                  }\n                }\n              }\n            } else {\n              progress \"\\n\\nDNS ERROR - No A or AAAA record for $config{CREATEDOMAIN}.\\n\";\n            }\n          }\n        }\n        progress \"\\n\";\n        foreach my $i (@interfaces) {\n          progress \"\\tInterface: $i\\n\";\n        }\n        foreach my $a (@answer) {\n          foreach my $i (@interfaces) {\n            if ($a->type eq \"MX\") {\n              my $h = getDnsRecords ($a->exchange,'A');\n              if (!defined $h) {\n                $h = getDnsRecords ($a->exchange, 'AAAA');\n              }\n              if (defined $h) {\n                my @ha = $h->answer;\n                foreach $h (@ha) {\n                  my $interIp = NetAddr::IP->new(\"$i\");\n                  my $interface= lc($interIp->addr);\n                  if ($h->type eq 'A' || $h->type eq 'AAAA') {\n                    print \"\\t\\t\".$h->address.\"\\n\";\n                    if ($h->address eq $interface) {\n                      $good = 1;\n                      last;\n                    }\n                  }\n                }\n                if ($good) { last; }\n              }\n            }\n          }\n          if ($good) {last;}\n        }\n        if (!$good) {\n          progress (\"\\n\\nDNS ERROR - none of the MX records for $config{CREATEDOMAIN}\\n\");\n          progress (\"resolve to this host\\n\");\n          if (askYN(\"Change domain name?\",\"Yes\") eq \"yes\") {\n            setCreateDomain();\n          }\n        }\n\n      }\n    }\n\n  }\n  if (isInstalled(\"zimbra-proxy\")) {\n    progress  \"setting defaults for zimbra-proxy.\\n\" if $options{d};\n    $config{STRICTSERVERNAMEENABLED} = \"TRUE\";\n    $config{IMAPPROXYPORT} = 143;\n    $config{IMAPSSLPROXYPORT} = 993;\n    $config{POPPROXYPORT} = 110;\n    $config{POPSSLPROXYPORT} = 995;\n    $config{IMAPPORT} = 7143;\n    $config{IMAPSSLPORT} = 7993;\n    $config{POPPORT} = 7110;\n    $config{POPSSLPORT} = 7995;\n    $config{MAILPROXY} = \"TRUE\";\n    $config{HTTPPROXY} = \"TRUE\";\n    $config{HTTPPROXYPORT} = 8080;\n    $config{HTTPSPROXYPORT} = 8443;\n    $config{HTTPPORT} = 80;\n    $config{HTTPSPORT} = 443;\n  } else {\n    $config{IMAPPROXYPORT} = 7143;\n    $config{IMAPSSLPROXYPORT} = 7993;\n    $config{POPPROXYPORT} = 7110;\n    $config{POPSSLPROXYPORT} = 7995;\n    $config{HTTPPROXYPORT} = 8080;\n    $config{HTTPSPROXYPORT} = 8443;\n  }\n\n  if ($options{d}) {\n    foreach my $key (sort keys %config) {\n      print \"\\tDEBUG: $key=$config{$key}\\n\";\n    }\n  }\n\n  progress ( \"done.\\n\" );\n}\n\nsub getInstallStatus {\n  progress \"getting install status...\" if $options{d};\n\n  if (open H, \"/opt/zimbra/.install_history\") {\n\n    my @history = <H>;\n    close H;\n    foreach my $h (@history) {\n      if ($h =~ /CONFIG SESSION COMPLETE/) {\n        next;\n      }\n      if ($h =~ /CONFIG SESSION START/) {\n        %configStatus = ();\n        next;\n      }\n      if ($h =~ /INSTALL SESSION COMPLETE/) {\n        next;\n      }\n      if ($h =~ /INSTALL SESSION START/) {\n        %installStatus = ();\n        %configStatus = ();\n        next;\n      }\n      my ($d, $op, $stage) = split ' ', $h;\n      if ($op eq \"INSTALLED\" || $op eq \"UPGRADED\") {\n        my $v = $stage;\n        $stage =~ s/[-_]\\d.*//;\n        $installStatus{$stage}{op} = $op;\n        $installStatus{$stage}{date} = $d;\n        if ($stage eq \"zimbra-core\") {\n          $v =~ s/_HEAD.*//;\n          $v =~ s/^zimbra-core[-_]//;\n          if ($v =~ /\\.deb$/) {\n            my $orig_v=$v;\n            $v =~ s/^(\\d+\\.\\d+\\.\\d+\\.\\w+\\.\\w+)\\..*/\\1/;\n            $v = reverse($v);\n            $v =~ s/\\./_/;\n            $v =~ s/\\./_/;\n            $v = reverse($v);\n            if ($v =~ /\\_deb$/) {\n              $v = $orig_v;\n              $v =~ s/^(\\d+\\.\\d+\\.[^_]*_[^_]+_[^.]+).*/\\1/;\n            }\n          } else {\n            $v =~ s/^(\\d+\\.\\d+\\.[^_]*_[^_]+_[^.]+).*/\\1/;\n          }\n          $curVersion = $v;\n        }\n      } elsif ($op eq \"CONFIGURED\") {\n        $configStatus{$stage} = $op;\n\tif ($stage =~ /Migrated/ || $stage =~ /Upgraded/) {\n\t\t$migratedStatus{$stage} = $op;\n\t}\n        if ($stage eq \"END\") {\n          $prevVersion = $curVersion;\n        }\n      }\n    }\n\n    if( !exists $installStatus{\"zimbra-core\"} )\n    {\n       progress (\"\\nERROR:\\n\");\n       progress (\"zimbra-core does not seem to be installed.\\n\");\n       progress (\"Please install required components first. Exiting.\\n\\n\");\n       exit (1);\n    }\n\n    if ( ($installStatus{\"zimbra-core\"}{op} eq \"INSTALLED\") &&\n      ($configStatus{\"END\"} ne \"CONFIGURED\") ){\n      $newinstall = 1;\n    } else {\n      $newinstall = 0;\n      #$config{DOCREATEDOMAIN} = \"no\";\n      #$config{DOCREATEADMIN} = \"no\";\n      #setDefaultsFromLocalConfig();\n    }\n  } else {\n    $newinstall = 1;\n  }\n\n  ($prevVersionMajor,$prevVersionMinor,$prevVersionMicro,$prevVersionBuild) =\n    $prevVersion =~ /(\\d+)\\.(\\d+)\\.(\\d+_[^_]*)_(\\d+)/;\n  ($curVersionMajor,$curVersionMinor,$curVersionMicro,$curVersionBuild) =\n    $curVersion =~ /(\\d+)\\.(\\d+)\\.(\\d+_[^_]*)_(\\d+)/;\n  ($curVersionMicroMicro, $curVersionType) = $curVersionMicro =~ /(\\d+)_(.*)/;\n\n  if ($options{d}) {\n    progress \"done.\\n\";\n    progress \"Previous version  maj:$prevVersionMajor minor:$prevVersionMinor micro:$prevVersionMicro build:$prevVersionBuild\\n\";\n    progress \"Current version  maj:$curVersionMajor minor:$curVersionMinor micro:$curVersionMicro build:$curVersionBuild\\n\";\n  }\n}\n\nsub setDefaultsFromLocalConfig {\n  progress (\"Setting defaults from existing config...\");\n  $config{HOSTNAME} = getLocalConfig (\"zimbra_server_hostname\");\n  $config{HOSTNAME} = lc ($config{HOSTNAME});\n  my $ldapUrl = getLocalConfig (\"ldap_master_url\");\n  my $ld = (split ' ', $ldapUrl)[0];\n  my $p = $ld;\n  $p =~ s/ldaps?:\\/\\///;\n  $p =~ s/.*:?//;\n  if ($p ne \"\") {\n    $config{LDAPPORT} = $p;\n  } else {\n    $p = getLocalConfig (\"ldap_port\");\n    if ($p ne \"\") {\n      $config{LDAPPORT} = $p;\n    }\n  }\n  my $h = $ld;\n  chomp($h);\n  $h =~ s/\"//g;\n  $h =~ s/ldaps?:\\/\\///g;\n  $h =~ s/:\\d+//g;\n  if ($h ne \"\") {\n    $config{LDAPHOST} = $h;\n  } else {\n    $h = getLocalConfig (\"ldap_host\");\n    if ($h ne \"\") {\n      $config{LDAPHOST} = $h;\n    }\n  }\n  $config{ldap_url} = getLocalConfig(\"ldap_url\");\n  $config{LDAPROOTPASS} = getLocalConfig (\"ldap_root_password\");\n  $config{LDAPADMINPASS} = getLocalConfig (\"zimbra_ldap_password\");\n  $config{SQLROOTPASS} = getLocalConfig (\"mysql_root_password\");\n  $config{ZIMBRASQLPASS} = getLocalConfig (\"zimbra_mysql_password\");\n  $config{MAILBOXDMEMORY} = getLocalConfig (\"mailboxd_java_heap_size\");\n  $config{mailboxd_directory} = getLocalConfig(\"mailboxd_directory\");\n  $config{mailboxd_keystore} = getLocalConfig(\"mailboxd_keystore\");\n  $config{mailboxd_keystore_password} = getLocalConfig (\"mailboxd_keystore_password\")\n    if (getLocalConfig(\"mailboxd_keystore_password\") ne \"\");\n  $config{mailboxd_truststore_password} = getLocalConfig (\"mailboxd_truststore_password\")\n    if (getLocalConfig(\"mailboxd_truststore_password\") ne \"\");\n  $config{zimbra_ldap_userdn} = getLocalConfig(\"zimbra_ldap_userdn\")\n    if (getLocalConfig(\"zimbra_ldap_userdn\") ne \"\");\n\n  $config{zimbra_require_interprocess_security} = getLocalConfig(\"zimbra_require_interprocess_security\");\n  if ($config{zimbra_require_interprocess_security}) {\n     $config{ZIMBRA_REQ_SECURITY} = \"yes\";\n  } else {\n     $config{ZIMBRA_REQ_SECURITY} = \"no\";\n  }\n\n  $config{ldap_dit_base_dn_config} = getLocalConfig(\"ldap_dit_base_dn_config\");\n  $config{ldap_dit_base_dn_config} = \"cn=zimbra\"\n    if ($config{ldap_dit_base_dn_config} eq \"\");\n\n  if (isEnabled(\"zimbra-snmp\")) {\n    $config{SNMPNOTIFY} = getLocalConfig(\"snmp_notify\");\n    $config{SNMPNOTIFY} = \"yes\" if ($config{SNMPNOTIFY} eq \"\");\n\n    $config{SMTPNOTIFY} = getLocalConfig(\"smtp_notify\");\n    $config{SMTPNOTIFY} = \"yes\" if ($config{SMTPNOTIFY} eq \"\");\n\n    $config{SNMPTRAPHOST} = getLocalConfig(\"snmp_trap_host\");\n    $config{SNMPTRAPHOST} = $config{HOSTNAME}\n      if ($config{SNMPTRAPHOST} eq \"\");\n  }\n\n  $config{SMTPSOURCE} = getLocalConfig(\"smtp_source\");\n  $config{SMTPSOURCE} = $config{CREATEADMIN}\n    if ($config{SMTPSOURCE} eq \"\");\n\n  $config{SMTPDEST} = getLocalConfig(\"smtp_destination\");\n  $config{SMTPDEST} = $config{CREATEADMIN}\n    if ($config{SMTPDEST} eq \"\");\n\n  $config{AVUSER} = getLocalConfig(\"av_notify_user\");\n  $config{AVUSER} = $config{CREATEADMIN}\n    if ($config{AVUSER} eq \"\");\n\n  $config{AVDOMAIN} = getLocalConfig(\"av_notify_domain\");\n  $config{AVDOMAIN} = $config{CREATEDOMAIN}\n    if ($config{AVDOMAIN} eq \"\");\n\n  if (isEnabled(\"zimbra-mta\")) {\n    $config{postfix_mail_owner} = getLocalConfig (\"postfix_mail_owner\");\n    if ($config{postfix_mail_owner} eq \"\") {\n      $config{postfix_mail_owner} = \"postfix\";\n    }\n    $config{postfix_setgid_group} = getLocalConfig (\"postfix_setgid_group\");\n    if ($config{postfix_setgid_group} eq \"\") {\n      $config{postfix_setgid_group} = \"postdrop\";\n    }\n\n  }\n\n  if (isEnabled(\"zimbra-ldap\")) {\n    $config{LDAPREPPASS} = getLocalConfig (\"ldap_replication_password\");\n    if ($config{LDAPREPPASS} eq \"\") {\n      $config{LDAPREPPASS} = $config{LDAPADMINPASS};\n      $ldapRepChanged = 1;\n    }\n  }\n  if (isEnabled(\"zimbra-ldap\")) {\n    if (isLdapMaster()) {\n      $config{ldap_bes_searcher_password} = getLocalConfig (\"ldap_bes_searcher_password\");\n      if ($config{ldap_bes_searcher_password} eq \"\") {\n        $config{ldap_bes_searcher_password} = $config{LDAPADMINPASS};\n        $ldapBesSearcherChanged = 1;\n      }\n    }\n  }\n  if (isEnabled(\"zimbra-ldap\") || isEnabled(\"zimbra-mta\")) {\n    $config{LDAPPOSTPASS} = getLocalConfig (\"ldap_postfix_password\");\n    if ($config{LDAPPOSTPASS} eq \"\") {\n      $config{LDAPPOSTPASS} = $config{LDAPADMINPASS};\n      $ldapPostChanged = 1;\n    }\n    $config{LDAPAMAVISPASS} = getLocalConfig (\"ldap_amavis_password\");\n    if ($config{LDAPAMAVISPASS} eq \"\") {\n      $config{LDAPAMAVISPASS} = $config{LDAPADMINPASS};\n      $ldapAmavisChanged = 1;\n    }\n  }\n  if (isEnabled(\"zimbra-ldap\") || isEnabled(\"zimbra-proxy\")) {\n    $config{ldap_nginx_password} = getLocalConfig (\"ldap_nginx_password\");\n    if ($config{ldap_nginx_password} eq \"\") {\n      $config{ldap_nginx_password} = $config{LDAPADMINPASS};\n      $ldapNginxChanged = 1;\n    }\n  }\n  if ($options{d}) {\n    foreach my $key (sort keys %config) {\n      print \"\\tlc DEBUG: $key=$config{$key}\\n\";\n    }\n  }\n  progress(\"done.\\n\");\n}\n\nsub ask {\n  my $prompt = shift;\n  my $default = shift;\n  if ($default eq \"\") {\n    print \"$prompt \";\n  } else {\n    print \"$prompt [$default] \";\n  }\n  my $rc = <>;\n  chomp $rc;\n  if ($rc eq \"\") {return $default;}\n  return $rc;\n}\n\nsub askPassword {\n  my $prompt = shift;\n  my $default = shift;\n  while (1) {\n    my $v = ask($prompt, $default);\n    # although they are valid pass characters avoid $ and |\n    # here because they cause quoting problems.\n    if ($v =~ /\\$|\\\\/g) {\n      print \"Invalid metacharater used.\\n\";\n      next;\n    }\n    if ($v ne \"\") {return $v;}\n    print \"A non-blank answer is required\\n\";\n  }\n}\n\nsub askYN {\n  my $prompt = shift;\n  my $default = shift;\n  while (1) {\n    my $v = ask($prompt, $default);\n    $v = lc($v);\n    $v = substr ($v,0,1);\n    if ($v eq \"y\") {return \"yes\";}\n    if ($v eq \"n\") {return \"no\";}\n    print \"A Yes/No answer is required\\n\";\n  }\n}\n\nsub askTF {\n  my $prompt = shift;\n  my $default = shift;\n  while (1) {\n    my $v = ask($prompt, $default);\n    $v = lc($v);\n    $v = substr ($v,0,1);\n    if ($v eq \"t\") {return \"TRUE\";}\n    if ($v eq \"f\") {return \"FALSE\";}\n    print \"A True/False answer is required\\n\";\n  }\n}\n\nsub askNum {\n  my $prompt = shift;\n  my $default = shift;\n  while (1) {\n    my $v = ask($prompt, $default);\n    my $i = int($v);\n    if ($v eq $i) { return $v; }\n    print \"A numeric response is required!\\n\";\n  }\n}\n\nsub askPositiveInt {\n  my $prompt = shift;\n  my $default = shift;\n  while (1) {\n    my $v = ask($prompt, $default);\n    my $i = int($v);\n    if ($v eq $i && $v > 0) { return $v; }\n    print \"A positive integer response is required!\\n\";\n  }\n}\n\nsub askNonBlank {\n  my $prompt = shift;\n  my $default = shift;\n  while (1) {\n    my $v = ask($prompt, $default);\n    if ($v ne \"\") {return $v;}\n    print \"A non-blank answer is required\\n\";\n  }\n}\n\nsub askFileName {\n  my $prompt = shift;\n  my $default = shift;\n  while (1) {\n    my $v = ask($prompt, $default);\n    if ($v ne \"\" && -f $v) {return $v;}\n    print \"A non-blank answer is required\\n\" if ($v eq \"\");\n    print \"$v must exist and be readable\\n\" if (!-f $v && $v ne \"\");\n  }\n}\n\nsub setEphemeralBackendURL {\n  my $rc = 1;\n  while ($rc != 0) {\n    my $newURL = ask(\"Value for zimbraEphemeralBackendURL:\", $config{EphemeralBackendURL});\n    $rc = runAsZimbra(\"zmjava com.zimbra.cs.ephemeral.EphemeralStore -u $newURL\");\n    if ($rc == 0) {\n        $config{EphemeralBackendURL} = $newURL;\n        last;\n    }\n    progress(\"\\nUnable to access the Ephemeral Store provider using $newURL\\n\");\n    progress(\"The Ephemeral Store provider must be active\\n\");\n    if (askYN(\"Revert to storing ephemeral attributes in Ldap?\",\"No\") eq \"yes\") {\n      $config{USEEPHEMERALSTORE} = \"no\";\n      delete($config{EphemeralBackendURL}) if (exists($config{EphemeralBackendURL}));\n      last;\n    }\n  }\n}\n\nsub setCreateDomain {\n  my $oldDomain = $config{CREATEDOMAIN};\n  my $good = 0;\n  while (1) {\n    $config{CREATEDOMAIN} =\n      ask(\"Create domain:\",\n        $config{CREATEDOMAIN});\n    my $ans = getDnsRecords($config{CREATEDOMAIN}, 'MX');\n    if (!defined ($ans)) {\n      progress(\"\\n\\nDNS ERROR resolving MX for $config{CREATEDOMAIN}\\n\");\n      progress(\"It is suggested that the domain name have an MX record configured in DNS\\n\");\n      if (askYN(\"Re-Enter domain name?\",\"Yes\") eq \"no\") {\n        last;\n      }\n      $config{CREATEDOMAIN} = $oldDomain;\n      next;\n    } elsif (isEnabled(\"zimbra-mta\")) {\n      my @answer = $ans->answer;\n      foreach my $a (@answer) {\n        if ($a->type eq \"MX\") {\n          my $h = getDnsRecords ($a->exchange,'A');\n          my $ipv6 = 0;\n          if (!defined $h) {\n            $h = getDnsRecords ($a->exchange, 'AAAA');\n            $ipv6 = 1;\n          }\n          if (defined $h) {\n            my @ha = $h->answer;\n            foreach $h (@ha) {\n              if ($ipv6) {\n                if ($h->type eq 'AAAA') {\n                  progress \"\\tMX: \".$a->exchange.\" (\".$h->address.\")\\n\";\n                }\n              } else {\n                if ($h->type eq 'A') {\n                  progress \"\\tMX: \".$a->exchange.\" (\".$h->address.\")\\n\";\n                }\n              }\n            }\n          } else {\n            progress \"\\n\\nDNS ERROR - No A or AAAA record for $config{CREATEDOMAIN}.\\n\";\n          }\n        }\n      }\n      progress \"\\n\";\n      foreach my $i (@interfaces) {\n        progress \"\\tInterface: $i\\n\";\n      }\n      foreach my $a (@answer) {\n        foreach my $i (@interfaces) {\n          if ($a->type eq \"MX\") {\n            my $h = getDnsRecords ($a->exchange,'A');\n            if (!defined $h) {\n              $h = getDnsRecords ($a->exchange, 'AAAA');\n            }\n            if (defined $h) {\n              my @ha = $h->answer;\n              foreach $h (@ha) {\n                my $interIp = NetAddr::IP->new(\"$i\");\n                my $interface= lc($interIp->addr);\n                if ($h->type eq 'A' || $h->type eq 'AAAA') {\n                  if ($h->address eq $interface) {\n                    $good = 1;\n                    last;\n                  }\n                }\n              }\n            }\n            if ($good) { last; }\n          }\n        }\n        if ($good) { last; }\n      }\n      if ($good) { last; }\n      else {\n        progress (\"\\n\\nDNS ERROR - none of the MX records for $config{CREATEDOMAIN}\\n\");\n        progress (\"resolve to this host\\n\");\n        progress (\"It is suggested that the MX record resolve to this host\\n\");\n        if (askYN(\"Re-Enter domain name?\",\"Yes\") eq \"no\") {\n          last;\n        }\n        $config{CREATEDOMAIN} = $oldDomain;\n        next;\n      }\n    }\n    last;\n  }\n  my ($u,$d) = split ('@', $config{CREATEADMIN});\n  my $old = $config{CREATEADMIN};\n  $config{CREATEADMIN} = $u.'@'.$config{CREATEDOMAIN};\n\n  $config{AVUSER} = $config{CREATEADMIN}\n    if ($old eq $config{AVUSER});\n\n  $config{AVDOMAIN} = $config{CREATEDOMAIN}\n    if ($config{AVDOMAIN} eq $oldDomain);\n\n  if ($old eq $config{SMTPDEST}) {\n    $config{SMTPDEST} = $config{CREATEADMIN};\n  }\n  if ($old eq $config{SMTPSOURCE}) {\n    $config{SMTPSOURCE} = $config{CREATEADMIN};\n  }\n  my ($spamUser, $spamDomain) = split ('@', $config{TRAINSASPAM});\n  $config{TRAINSASPAM} = $spamUser.'@'.$config{CREATEDOMAIN}\n    if ($spamDomain eq $oldDomain);\n\n  my ($hamUser, $hamDomain) = split ('@', $config{TRAINSAHAM});\n  $config{TRAINSAHAM} = $hamUser.'@'.$config{CREATEDOMAIN}\n    if ($hamDomain eq $oldDomain);\n\n  my ($virusUser, $virusDomain) = split ('@', $config{VIRUSQUARANTINE});\n  $config{VIRUSQUARANTINE} = $virusUser.'@'.$config{CREATEDOMAIN}\n    if ($virusDomain eq $oldDomain);\n\n  my ($vcFromUser, $vcFromDomain) = split ('@', $config{zimbraVersionCheckNotificationEmailFrom});\n  $config{zimbraVersionCheckNotificationEmailFrom} = $vcFromUser.'@'.$config{CREATEDOMAIN}\n    if ($vcFromDomain eq $oldDomain);\n\n  my ($vcUser, $vcDomain) = split ('@', $config{zimbraVersionCheckNotificationEmail});\n  $config{zimbraVersionCheckNotificationEmail} = $vcUser.'@'.$config{CREATEDOMAIN}\n    if ($vcDomain eq $oldDomain);\n\n}\n\nsub setLdapBaseDN {\n  while (1) {\n    print \"Warning: Do not change this from the default value unless\\n\";\n    print \"you are absolutely sure you know what you are doing!\\n\\n\";\n    my $new =\n      askNonBlank(\"Ldap base DN:\",\n        $config{ldap_dit_base_dn_config});\n    if ($config{ldap_dit_base_dn_config} ne $new) {\n      $config{ldap_dit_base_dn_config} = $new;\n    }\n    return;\n  }\n}\n\nsub setNotebookAccount {\n  while (1) {\n    my $new =\n      ask(\"Global Documents account:\",\n        $config{NOTEBOOKACCOUNT});\n    my ($u,$d) = split ('@', $new);\n    my ($adminUser,$adminDomain) = split('@', $config{CREATEADMIN});\n    if ($d ne $config{CREATEDOMAIN} && $d ne $adminDomain) {\n      if ($config{CREATEDOMAIN} eq $adminDomain) {\n        progress ( \"You must create the user under the domain $config{CREATEDOMAIN}\\n\" );\n      } else {\n        progress ( \"You must create the user under the domain $config{CREATEDOMAIN} or $adminDomain\\n\" );\n      }\n    } else {\n      $config{NOTEBOOKACCOUNT} = $new;\n      last;\n    }\n  }\n}\n\nsub setTrainSASpam {\n  while (1) {\n\n    my $new = ask(\"Spam training user:\", $config{TRAINSASPAM});\n\n    my ($u,$d) = split ('@', $new);\n    my ($adminUser,$adminDomain) = split('@', $config{CREATEADMIN});\n    if ($d ne $config{CREATEDOMAIN} && $d ne $adminDomain) {\n      if ($config{CREATEDOMAIN} eq $adminDomain) {\n        progress ( \"You must create the user under the domain $config{CREATEDOMAIN}\\n\" );\n      } else {\n        progress ( \"You must create the user under the domain $config{CREATEDOMAIN} or $adminDomain\\n\" );\n      }\n    } else {\n      $config{TRAINSASPAM} = $new;\n      last;\n    }\n  }\n}\n\nsub setTrainSAHam {\n  while (1) {\n    my $new =\n      ask(\"Ham training user:\",\n        $config{TRAINSAHAM});\n    my ($u,$d) = split ('@', $new);\n    my ($adminUser,$adminDomain) = split('@', $config{CREATEADMIN});\n    if ($d ne $config{CREATEDOMAIN} && $d ne $adminDomain) {\n      if ($config{CREATEDOMAIN} eq $adminDomain) {\n        progress ( \"You must create the user under the domain $config{CREATEDOMAIN}\\n\" );\n      } else {\n        progress ( \"You must create the user under the domain $config{CREATEDOMAIN} or $adminDomain\\n\" );\n      }\n    } else {\n      $config{TRAINSAHAM} = $new;\n      last;\n    }\n  }\n}\n\nsub setAmavisVirusQuarantine{\n  while (1) {\n    my $new =\n      ask(\"Anti-virus quarantine user:\",\n        $config{VIRUSQUARANTINE});\n    my ($u,$d) = split ('@', $new);\n    my ($adminUser,$adminDomain) = split('@', $config{CREATEADMIN});\n    if ($d ne $config{CREATEDOMAIN} && $d ne $adminDomain) {\n      if ($config{CREATEDOMAIN} eq $adminDomain) {\n        progress ( \"You must create the user under the domain $config{CREATEDOMAIN}\\n\" );\n      } else {\n        progress ( \"You must create the user under the domain $config{CREATEDOMAIN} or $adminDomain\\n\" );\n      }\n    } else {\n      $config{VIRUSQUARANTINE} = $new;\n      last;\n    }\n  }\n}\n\nsub setVersionCheckNotificationEmail {\n  while (1) {\n    my $new = ask(\"Version update destination address:\",\n        $config{zimbraVersionCheckNotificationEmail});\n    unless(validEmailAddress($new)) {\n      progress ( \"Must enter a valid email address.\\n\");\n      next;\n    }\n    $config{zimbraVersionCheckNotificationEmail} = $new;\n    last;\n  }\n}\n\nsub setVersionCheckNotificationEmailFrom {\n  while (1) {\n    my $new = ask(\"Version update source address:\",\n        $config{zimbraVersionCheckNotificationEmailFrom});\n    unless(validEmailAddress($new)) {\n      progress ( \"Must enter a valid email address.\\n\");\n      next;\n    }\n    $config{zimbraVersionCheckNotificationEmailFrom} = $new;\n    last;\n  }\n}\n\nsub setMasterDNSIP {\n  while (1) {\n    my $new =\n      ask(\"IP Address(es) of Master DNS Server(s), space separated:\", $config{zimbraDNSMasterIP});\n    my @IPs = split (' ', $new);\n    unless(!validIPAddress(@IPs)) {\n      progress(\"Supplied IP address(es) must be valid\\n\");\n      next;\n    }\n    $config{zimbraDNSMasterIP} = $new;\n    last;\n  }\n}\n\nsub setCreateAdmin {\n\n  while (1) {\n    my $new =\n      ask(\"Create admin user:\", $config{CREATEADMIN});\n    my ($u,$d) = split ('@', $new);\n\n    unless(validEmailAddress($new)) {\n      progress ( \"Admin user must be a valid email account [$u\\@$config{CREATEDOMAIN}]\\n\");\n      next;\n    }\n\n    # spam/ham/quanrantine accounts follow admin domain if ldap isn't install\n    # this prevents us from trying to provision in a non-existent domain\n    if (!isEnabled(\"zimbra-ldap\")) {\n      my ($spamUser, $spamDomain) = split ('@', $config{TRAINSASPAM});\n      my ($hamUser, $hamDomain) = split ('@', $config{TRAINSAHAM});\n      my ($virusUser, $virusDomain) = split ('@', $config{VIRUSQUARANTINE});\n      $config{CREATEDOMAIN} = $d\n        if ($config{CREATEDOMAIN} ne $d);\n\n      $config{TRAINSASPAM} = $spamUser.'@'.$d\n        if ($spamDomain ne $d);\n\n      $config{TRAINSAHAM} = $hamUser.'@'.$d\n        if ($hamDomain ne $d);\n\n      $config{VIRUSQUARANTINE} = $virusUser.'@'.$d\n        if ($virusDomain ne $d);\n\n      $config{AVDOMAIN} = $d\n        if ($config{AVDOMAIN} ne $d);\n    }\n\n    $config{zimbraBackupReportEmailRecipients} = $new\n      if ($config{zimbraBackupReportEmailRecipients} eq $config{CREATEADMIN});\n    $config{zimbraBackupReportEmailSender} = $new\n      if ($config{zimbraBackupReportEmailSender} eq $config{CREATEADMIN});\n\n    if ($config{CREATEADMIN} eq $config{AVUSER}) {\n      $config{AVUSER} = $new;\n    }\n    if ($config{CREATEADMIN} eq $config{SMTPDEST}) {\n      $config{SMTPDEST} = $new;\n    }\n    if ($config{CREATEADMIN} eq $config{SMTPSOURCE}) {\n      $config{SMTPSOURCE} = $new;\n    }\n    $config{CREATEADMIN} = $new;\n    last;\n  }\n\n  setAdminPass();\n\n}\n\nsub removeUnusedWebapps {\n  my $webAppsDir = \"/opt/zimbra/jetty/webapps\";\n  if ($config{SERVICEWEBAPP} eq \"no\") {\n    system(\"rm -rf $webAppsDir/service\")\n      if (-d \"$webAppsDir/service\");\n  }\n  if ($config{UIWEBAPPS} eq \"no\") {\n    system(\"rm -rf $webAppsDir/zimbra\")\n      if (-d \"$webAppsDir/zimbra\");\n    system(\"rm -rf $webAppsDir/zimbraAdmin\")\n      if (-d \"$webAppsDir/zimbraAdmin\");\n  }\n  defineInstallWebapps();\n  getInstalledWebapps();\n}\n\nsub validEmailAddress {\n   return($_[0] =~ m/^[^@]+@([-\\w]+\\.)+[A-Za-z]{2,4}/ ? 1 : 0);\n}\n\nsub validIPAddress {\n  my $rc = 0;\n  foreach my $ip (@_) {\n    chomp($ip);\n    my $testip = NetAddr::IP->new($ip);\n    if (ref($testip) ne 'NetAddr::IP') {\n      $rc = 1;\n    }\n  }\n  return $rc;\n}\n\nsub setLdapRootPass {\n  while (1) {\n    my $new =\n      askPassword(\"Password for ldap root user (min 6 characters):\",\n        $config{LDAPROOTPASS});\n    if (length($new) >= 6) {\n      if ($config{LDAPROOTPASS} ne $new) {\n        $config{LDAPROOTPASS} = $new;\n        $ldapRootPassChanged = 1;\n      }\n      return;\n    } else {\n      print \"Minimum length of 6 characters!\\n\";\n    }\n  }\n}\n\nsub setLdapAdminPass {\n  while (1) {\n    my $new =\n      askPassword(\"Password for ldap admin user (min 6 characters):\",\n        $config{LDAPADMINPASS});\n    if (length($new) >= 6) {\n      if ($config{LDAPADMINPASS} ne $new) {\n        $config{LDAPADMINPASS} = $new;\n        $ldapAdminPassChanged = 1;\n      }\n      ldapIsAvailable() if ($config{HOSTNAME} ne $config{LDAPHOST});\n      return;\n    } else {\n      print \"Minimum length of 6 characters!\\n\";\n    }\n  }\n}\n\nsub setLdapRepPass {\n  while (1) {\n    my $new =\n      askPassword(\"Password for ldap replication user (min 6 characters):\",\n        $config{LDAPREPPASS});\n    if (length($new) >= 6) {\n      if ($config{LDAPREPPASS} ne $new) {\n        $config{LDAPREPPASS} = $new;\n        $ldapRepChanged = 1;\n      }\n      ldapIsAvailable() if ($config{HOSTNAME} ne $config{LDAPHOST});\n      return;\n    } else {\n      print \"Minimum length of 6 characters!\\n\";\n    }\n  }\n}\n\nsub setLdapBesSearchPass {\n  while (1) {\n    my $new =\n      askPassword(\"Password for ldap BES user (min 6 characters):\",\n        $config{ldap_bes_searcher_password});\n    if (length($new) >= 6) {\n      if ($config{ldap_bes_searcher_password} ne $new) {\n        $config{ldap_bes_searcher_password} = $new;\n        $ldapBesSearcherChanged = 1;\n      }\n      ldapIsAvailable() if ($config{HOSTNAME} ne $config{LDAPHOST});\n      return;\n    } else {\n      print \"Minimum length of 6 characters!\\n\";\n    }\n  }\n}\n\nsub setLdapPostPass {\n  while (1) {\n    my $new =\n      askPassword(\"Password for ldap Postfix user (min 6 characters):\",\n        $config{LDAPPOSTPASS});\n    if (length($new) >= 6) {\n      if ($config{LDAPPOSTPASS} ne $new) {\n        $config{LDAPPOSTPASS} = $new;\n        $ldapPostChanged = 1;\n      }\n      ldapIsAvailable() if ($config{HOSTNAME} ne $config{LDAPHOST});\n      return;\n    } else {\n      print \"Minimum length of 6 characters!\\n\";\n    }\n  }\n}\n\nsub setLdapAmavisPass {\n  while (1) {\n    my $new =\n      askPassword(\"Password for ldap Amavis user (min 6 characters):\",\n        $config{LDAPAMAVISPASS});\n    if (length($new) >= 6) {\n      if ($config{LDAPAMAVISPASS} ne $new) {\n        $config{LDAPAMAVISPASS} = $new;\n        $ldapAmavisChanged = 1;\n      }\n      ldapIsAvailable() if ($config{HOSTNAME} ne $config{LDAPHOST});\n      return;\n    } else {\n      print \"Minimum length of 6 characters!\\n\";\n    }\n  }\n}\n\nsub setLdapNginxPass {\n  while (1) {\n    my $new =\n      askPassword(\"Password for ldap Nginx user (min 6 characters):\",\n        $config{ldap_nginx_password});\n    if (length($new) >= 6) {\n      if ($config{ldap_nginx_password} ne $new) {\n        $config{ldap_nginx_password} = $new;\n        $ldapNginxChanged = 1;\n      }\n      ldapIsAvailable() if ($config{HOSTNAME} ne $config{LDAPHOST});\n      return;\n    } else {\n      print \"Minimum length of 6 characters!\\n\";\n    }\n  }\n}\n\nsub setAdminPass {\n  if ($config{CREATEADMIN} ne \"\") {\n    while (1) {\n      if ($config{CREATEADMINPASS} eq \"\") { $config{CREATEADMINPASS} = genRandomPass(); }\n      my $new =\n        askPassword(\"Password for $config{CREATEADMIN} (min 6 characters):\",\n          $config{CREATEADMINPASS});\n      if (length($new) >= 6) {\n        $config{CREATEADMINPASS} = $new;\n        return;\n      } else {\n        print \"Minimum length of 6 characters!\\n\";\n      }\n    }\n  }\n}\n\nsub setLicenseKey {\n\twhile (1) {\n\t\tmy $new = askNonBlank(\"Please enter the license key (enter 'r' for previous menu):\",$config{LICENSEKEY});\n\t\tif ($new eq \"r\") {\n\t\t\tchooseLicenseActivationOption();\n\t\t\treturn;\n\t\t}\n\t\tif ((length($new) >= 18 && length($new) <= 24) && $new =~ /^[A-Za-z0-9]+$/) {\n\t\t\t$config{LICENSEKEY} = $new;\n\t\t\treturn;\n\t\t} else {\n\t\t\tprint \"Invalid license key entered. The license key should be an alphanumeric string of 18-24 characters without any special characters!\\n\";\n\t\t}\n\t}\n}\n\nsub chooseLicenseActivationOption {\n\t\t\twhile (1) {\n\t\t\t\tprint \"1) Activate license with installation\\n\";\n\t\t\t\tprint \"2) Activate license after installation\\n\\n\";\n\t\t\t\tmy $choice = askNonBlank(\"Select, or 'r' for previous menu\",\"r\");\n\t\t\t\tif ($choice eq \"1\") {\n\t\t\t\t\tsetLicenseKey();\n\t\t\t\t\tif ($config{LICENSEKEY} ne \"\") {\n\t\t\t\t\t\tsystem(\"echo \\\"$config{LICENSEKEY}\\\" > $license_file\");\n\t\t\t\t\t\tsystem(\"chown zimbra:zimbra $license_file\");\n\t\t\t\t\t\tsystem(\"chmod 644 $license_file\");\n\t\t\t\t\t\t$config{LICENSEACTIVATIONOPTION} = $choice;\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif ($choice eq \"2\") {\n\t\t\t\t\tsystem(\"rm -rf $license_file\") if -e $license_file;\n\t\t\t\t\t$config{LICENSEACTIVATIONOPTION} = $choice;\n\t\t\t\t\tprint \"After the successful installation, use zmlicense -a <licensekey> to activate license key or contact support team for an offline activation file \\n\";\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif ($choice eq \"r\") {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tprint \"Please enter a valid option!\\n\\n\";\n\t\t\t}\n}\n\n\nsub setSmtpSource {\n  $config{SMTPSOURCE} =\n    askNonBlank(\"SMTP Source address:\",\n      $config{SMTPSOURCE});\n}\n\nsub setSmtpDest {\n  $config{SMTPDEST} =\n    askNonBlank(\"SMTP Destination address:\",\n      $config{SMTPDEST});\n}\n\nsub setSnmpTrapHost {\n  $config{SNMPTRAPHOST} =\n    askNonBlank(\"SNMP Trap host:\",\n      $config{SNMPTRAPHOST});\n}\n\nsub setOnlyOfficeHost {\n  $config{ONLYOFFICEHOSTNAME} =\n    askNonBlank(\"Onlyoffice server:\",\n      $config{ONLYOFFICEHOSTNAME});\n}\n\nsub setAvUser {\n  $config{AVUSER} =\n    askNonBlank(\"Notification address for AV alerts:\",\n      $config{AVUSER});\n  (undef, $config{AVDOMAIN}) = (split ('@',$config{AVUSER}))[1];\n}\n\nsub toggleYN {\n  my $key = shift;\n  $config{$key} = ($config{$key} eq \"yes\")?\"no\":\"yes\";\n}\nsub toggleTF {\n  my $key = shift;\n  $config{$key} = ($config{$key} eq \"TRUE\")?\"FALSE\":\"TRUE\";\n  if ($key eq \"MAILPROXY\") {\n    &toggleMailProxy();\n  }\n  if ($key eq \"HTTPPROXY\") {\n    &toggleWebProxy();\n  }\n}\n\nsub toggleSERVICEWEBAPP {\n    my $key = shift;\n    $config{SERVICEWEBAPP} = ($config{SERVICEWEBAPP} eq \"yes\")?\"no\":\"yes\";\n}\n\nsub toggleConfigEnabled {\n  my $key = shift;\n  $config{$key} = ($config{$key} eq \"Enabled\")?\"Disabled\":\"Enabled\";\n}\n\nsub toggleMailProxy() {\n  if ($config{MAILPROXY} eq \"TRUE\") {\n    $config{IMAPPORT} = 7143;\n    $config{IMAPSSLPORT} = 7993;\n    $config{POPPORT} = 7110;\n    $config{POPSSLPORT} = 7995;\n    $config{IMAPPROXYPORT} = 143;\n    $config{IMAPSSLPROXYPORT} = 993;\n    $config{POPPROXYPORT} = 110;\n    $config{POPSSLPROXYPORT} = 995;\n  } else {\n    $config{IMAPPORT} = 143;\n    $config{IMAPSSLPORT} = 993;\n    $config{POPPORT} = 110;\n    $config{POPSSLPORT} = 995;\n    $config{IMAPPROXYPORT} = 7143;\n    $config{IMAPSSLPROXYPORT} = 7993;\n    $config{POPPROXYPORT} = 7110;\n    $config{POPSSLPROXYPORT} = 7995;\n  }\n}\n\nsub toggleWebProxy() {\n  if ($config{HTTPPROXY} eq \"TRUE\") {\n    $config{HTTPPORT} = 8080;\n    $config{HTTPSPORT} = 8443;\n    $config{HTTPPROXYPORT} = 80;\n    $config{HTTPSPROXYPORT} = 443;\n  } else {\n    $config{HTTPPORT} = 80;\n    $config{HTTPSPORT} = 443;\n    $config{HTTPPROXYPORT} = 8080;\n    $config{HTTPSPROXYPORT} = 8443;\n  }\n}\n\nsub setUseProxy {\n\n   if (isEnabled(\"zimbra-proxy\")) {\n      if ($config{MAILPROXY} eq \"TRUE\") {\n         if ($config{IMAPPROXYPORT} == $config{IMAPPORT}) {\n             $config{IMAPPORT} = 7000+$config{IMAPPROXYPORT};\n         }\n         if ($config{IMAPPORT}+7000 == $config{IMAPPROXYPORT}) {\n             $config{IMAPPORT} = $config{IMAPPROXYPORT};\n             $config{IMAPPROXYPORT} = $config{IMAPPROXYPORT}-7000;\n         }\n         if ($config{IMAPSSLPROXYPORT} == $config{IMAPSSLPORT}) {\n             $config{IMAPSSLPORT} = 7000+$config{IMAPSSLPROXYPORT};\n         }\n         if ($config{IMAPSSLPORT}+7000 == $config{IMAPSSLPROXYPORT}) {\n             $config{IMAPSSLPORT} = $config{IMAPSSLPROXYPORT};\n             $config{IMAPSSLPROXYPORT} = $config{IMAPSSLPROXYPORT}-7000;\n         }\n         if ($config{POPPROXYPORT} == $config{POPPORT}) {\n             $config{POPPORT} = 7000+$config{POPPROXYPORT};\n         }\n         if ($config{POPPORT}+7000 == $config{POPPROXYPORT}) {\n             $config{POPPORT} = $config{POPPROXYPORT};\n             $config{POPPROXYPORT} = $config{POPPROXYPORT}-7000;\n         }\n         if ($config{POPSSLPROXYPORT} == $config{POPSSLPORT}) {\n             $config{POPSSLPORT} = 7000+$config{POPSSLPROXYPORT};\n         }\n         if ($config{POPSSLPORT}+7000 == $config{POPSSLPROXYPORT}) {\n             $config{POPSSLPORT} = $config{POPSSLPROXYPORT};\n             $config{POPSSLPROXYPORT} = $config{POPSSLPROXYPORT}-7000;\n         }\n      } else {\n         if ($config{IMAPPROXYPORT}+7000 == $config{IMAPPORT}) {\n             $config{IMAPPORT} = $config{IMAPPROXYPORT};\n             $config{IMAPPROXYPORT} = $config{IMAPPROXYPORT}+7000;\n         }\n         if ($config{IMAPSSLPROXYPORT}+7000 == $config{IMAPSSLPORT}) {\n             $config{IMAPSSLPORT} = $config{IMAPSSLPROXYPORT};\n             $config{IMAPSSLPROXYPORT} = $config{IMAPSSLPROXYPORT} + 7000;\n         }\n         if ($config{POPPROXYPORT}+7000 == $config{POPPORT}) {\n             $config{POPPORT} = $config{POPPROXYPORT};\n             $config{POPPROXYPORT} = $config{POPPROXYPORT} + 7000;\n         }\n         if ($config{POPSSLPROXYPORT}+7000 == $config{POPSSLPORT}) {\n             $config{POPSSLPORT} = $config{POPSSLPROXYPORT};\n             $config{POPSSLPROXYPORT} = $config{POPSSLPROXYPORT}+7000;\n         }\n      }\n      if ($config{HTTPPROXY} eq \"TRUE\") {\n         if ($config{HTTPROXYPPORT} == $config{HTTPPORT}) {\n             $config{HTTPPORT} = 8000+$config{HTTPPROXYPORT};\n         }\n         if ($config{HTTPPORT}+8000 == $config{HTTPPROXYPORT}) {\n             $config{HTTPPORT} = $config{HTTPPROXYPORT};\n             $config{HTTPPROXYPORT} = $config{HTTPPORT} - 8000;\n         }\n         if ($config{HTTPSPROXYPORT} == $config{HTTPSPORT}) {\n             $config{HTTPSPORT} = 8000+$config{HTTPSPROXYPORT};\n         }\n         if ($config{HTTPSPORT}+8000 == $config{HTTPSPROXYPORT}) {\n             $config{HTTPSPORT} = $config{HTTPSPROXYPORT};\n             $config{HTTPSPROXYPORT} = $config{HTTPSPORT} - 8000;\n         }\n      } else {\n         if ($config{HTTPPROXYPORT}+8000 == $config{HTTPPORT}) {\n             $config{HTTPPORT} = $config{HTTPPROXYPORT};\n             $config{HTTPPROXYPORT} = $config{HTTPPORT}+8000;\n         }\n         if ($config{HTTPSPROXYPORT}+8000 == $config{HTTPSPORT}) {\n             $config{HTTPSPORT} = $config{HTTPSPROXYPORT};\n             $config{HTTPSPROXYPORT} = $config{HTTPSPORT}+8000;\n         }\n      }\n   } else {\n      if (!isInstalled(\"zimbra-store\")) {\n         if ($config{IMAPPROXYPORT}+7000 == $config{IMAPPORT}) {\n             $config{IMAPPORT} = $config{IMAPPROXYPORT};\n             $config{IMAPPROXYPORT} = $config{IMAPPROXYPORT}+7000;\n         }\n         if ($config{IMAPSSLPROXYPORT}+7000 == $config{IMAPSSLPORT}) {\n             $config{IMAPSSLPORT} = $config{IMAPSSLPROXYPORT};\n             $config{IMAPSSLPROXYPORT} = $config{IMAPSSLPROXYPORT} + 7000;\n         }\n         if ($config{POPPROXYPORT}+7000 == $config{POPPORT}) {\n             $config{POPPORT} = $config{POPPROXYPORT};\n              $config{POPPROXYPORT} = $config{POPPROXYPORT} + 7000;\n         }\n         if ($config{POPSSLPROXYPORT}+7000 == $config{POPSSLPORT}) {\n             $config{POPSSLPORT} = $config{POPSSLPROXYPORT};\n             $config{POPSSLPROXYPORT} = $config{POPSSLPROXYPORT}+7000;\n         }\n         if ($config{HTTPPROXYPORT}+8000 == $config{HTTPPORT}) {\n             $config{HTTPPORT} = $config{HTTPPROXYPORT};\n             $config{HTTPPROXYPORT} = $config{HTTPPORT}+8000;\n         }\n         if ($config{HTTPSPROXYPORT}+8000 == $config{HTTPSPORT}) {\n             $config{HTTPSPORT} = $config{HTTPSPROXYPORT};\n             $config{HTTPSPROXYPORT} = $config{HTTPSPORT}+8000;\n         }\n      } else {\n         if ($config{\"zimbraMailProxy\"} eq \"TRUE\") {\n            if ($config{IMAPPROXYPORT} == $config{IMAPPORT}) {\n                $config{IMAPPORT} = 7000+$config{IMAPPROXYPORT};\n            }\n            if ($config{IMAPPORT}+7000 == $config{IMAPPROXYPORT}) {\n                $config{IMAPPORT} = $config{IMAPPROXYPORT};\n                $config{IMAPPROXYPORT} = $config{IMAPPROXYPORT}-7000;\n            }\n            if ($config{IMAPSSLPROXYPORT} == $config{IMAPSSLPORT}) {\n                $config{IMAPSSLPORT} = 7000+$config{IMAPSSLPROXYPORT};\n            }\n            if ($config{IMAPSSLPORT}+7000 == $config{IMAPSSLPROXYPORT}) {\n                $config{IMAPSSLPORT} = $config{IMAPSSLPROXYPORT};\n                $config{IMAPSSLPROXYPORT} = $config{IMAPSSLPROXYPORT}-7000;\n            }\n            if ($config{POPPROXYPORT} == $config{POPPORT}) {\n                $config{POPPORT} = 7000+$config{POPPROXYPORT};\n            }\n            if ($config{POPPORT}+7000 == $config{POPPROXYPORT}) {\n                $config{POPPORT} = $config{POPPROXYPORT};\n                $config{POPPROXYPORT} = $config{POPPROXYPORT}-7000;\n            }\n            if ($config{POPSSLPROXYPORT} == $config{POPSSLPORT}) {\n                $config{POPSSLPORT} = 7000+$config{POPSSLPROXYPORT};\n            }\n            if ($config{POPSSLPORT}+7000 == $config{POPSSLPROXYPORT}) {\n                $config{POPSSLPORT} = $config{POPSSLPROXYPORT};\n                $config{POPSSLPROXYPORT} = $config{POPSSLPROXYPORT}-7000;\n            }\n         }\n         if ($config{\"zimbraWebProxy\"} eq \"TRUE\") {\n            if ($config{HTTPROXYPPORT} == $config{HTTPPORT}) {\n                $config{HTTPPORT} = 8000+$config{HTTPPROXYPORT};\n            }\n            if ($config{HTTPPORT}+8000 == $config{HTTPPROXYPORT}) {\n                $config{HTTPPORT} = $config{HTTPPROXYPORT};\n                $config{HTTPPROXYPORT} = $config{HTTPPORT} - 8000;\n            }\n            if ($config{HTTPSPROXYPORT} == $config{HTTPSPORT}) {\n                $config{HTTPSPORT} = 8000+$config{HTTPSPROXYPORT};\n            }\n            if ($config{HTTPSPORT}+8000 == $config{HTTPSPROXYPORT}) {\n                $config{HTTPSPORT} = $config{HTTPSPROXYPORT};\n                $config{HTTPSPROXYPORT} = $config{HTTPSPORT} - 8000;\n            }\n         }\n      }\n   }\n}\n\nsub setStoreMode {\n  while (1) {\n    my $m =\n      askNonBlank(\"Please enter the web server mode (http,https,both,mixed,redirect)\",\n        $config{MODE});\n    if (isInstalled(\"zimbra-proxy\")) {\n      if ($config{zimbra_require_interprocess_security}) {\n        if ($m eq \"https\" || $m eq \"both\" ) {\n          $config{MODE} = $m;\n          return;\n        } else {\n          print qq(Only \"https\" and \"both\" are valid modes when requiring interprocess security with web proxy.\\n);\n        }\n      } else {\n        if ($m eq \"http\" || $m eq \"both\" ) {\n          $config{MODE} = $m;\n          return;\n        } else {\n          print qq(Only \"http\" and \"both\" are valid modes when not requiring interprocess security with web proxy.\\n);\n        }\n      }\n    } else {\n      my @proxytargets;\n      open(ZMPROV, \"$ZMPROV gas proxy 2>/dev/null|\");\n      chomp(@proxytargets = <ZMPROV>);\n      close(ZMPROV);\n      if (scalar @proxytargets) {\n        if ($config{zimbra_require_interprocess_security}) {\n          if ($m eq \"https\" || $m eq \"both\" ) {\n            $config{MODE} = $m;\n            return;\n          } else {\n            print qq(Only \"https\" and \"both\" are valid modes when requiring interprocess security with web proxy.\\n);\n          }\n        } else {\n          if ($m eq \"http\" || $m eq \"both\" ) {\n            $config{MODE} = $m;\n            return;\n          } else {\n            print qq(Only \"http\" and \"both\" are valid modes when not requiring interprocess security with web proxy.\\n);\n          }\n        }\n      } else {\n        if ($m eq \"http\" || $m eq \"https\" || $m eq \"mixed\" || $m eq \"both\" || $m eq \"redirect\" ) {\n          $config{MODE} = $m;\n          return;\n        }\n      }\n    }\n    print \"Please enter a valid mode!\\n\";\n  }\n}\n\nsub setProxyMode {\n  while (1) {\n    my $m =\n      askNonBlank(\"Please enter the proxy server mode (http,https,both,mixed,redirect)\",\n        $config{PROXYMODE});\n    if ($config{zimbra_require_interprocess_security}) {\n      if ($m eq \"https\" || $m eq \"redirect\") {\n        $config{PROXYMODE} = $m;\n        return;\n      } else {\n        print qq(Only \"https\" and \"redirect\" are valid modes when requiring interprocess security with web proxy.\\n);\n      }\n    } else {\n      if ($m eq \"http\" || $m eq \"https\" || $m eq \"mixed\" || $m eq \"both\" || $m eq \"redirect\" ) {\n        $config{PROXYMODE} = $m;\n        return;\n      }\n    }\n    print \"Please enter a valid mode!\\n\";\n  }\n}\n\nsub changeLdapHost {\n  $config{LDAPHOST} = shift;\n  $config{LDAPHOST} = lc($config{LDAPHOST});\n  if (isInstalled(\"zimbra-ldap\") && $config{LDAPHOST} eq \"\") {\n      $ldapReplica=0;\n      $config{LDAPREPLICATIONTYPE}=\"master\";\n  } elsif (isInstalled(\"zimbra-ldap\") && $config{LDAPHOST} ne $config{HOSTNAME}) {\n      $ldapReplica=1;\n      $config{LDAPREPLICATIONTYPE}=\"replica\";\n  } elsif (isInstalled(\"zimbra-ldap\") && $config{LDAPHOST} eq $config{HOSTNAME}) {\n      $ldapReplica=0;\n      $config{LDAPREPLICATIONTYPE}=\"master\";\n  }\n}\n\nsub changeLdapPort {\n  $config{LDAPPORT} = shift;\n}\n\nsub changeLdapServerID {\n  $config{LDAPSERVERID} = shift;\n}\n\nsub getDnsRecords {\n  my $name = shift;\n  my $qtype = shift;\n\n  my $res = Net::DNS::Resolver->new;\n  my @servers = $res->nameservers();\n  my $ans = $res->search ($name, $qtype);\n\n  return $ans;\n}\n\nsub lookupHostName {\n  my $name = shift;\n  my $qtype = shift;\n\n  my $res = Net::DNS::Resolver->new;\n  my @servers = $res->nameservers();\n  my $ans = $res->search ($name, $qtype);\n  if (!defined ($ans)) {\n    progress (\"No results returned for $qtype lookup of $name\\n\");\n    progress (\"Checked nameservers:\\n\");\n    foreach (@servers) {\n      progress (\"\\t$_\\n\");\n    }\n    return 1;\n  } else {\n    #progress (\"Received answer:\\n\");\n    #progress ($ans->string().\"\\n\");\n    return 0;\n  }\n}\n\nsub setHostName {\n  my $old = $config{HOSTNAME};\n  while (1) {\n    $config{HOSTNAME} =\n      askNonBlank(\"Please enter the logical hostname for this host\",\n        $config{HOSTNAME});\n    if (lookupHostName ($config{HOSTNAME}, 'A')) {\n      progress(\"\\n\\nDNS ERROR resolving $config{HOSTNAME}\\n\");\n      progress(\"It is suggested that the hostname be resolvable via DNS\\n\");\n      if (askYN(\"Re-Enter hostname\",\"Yes\") eq \"no\") {\n        last;\n      }\n      $config{HOSTNAME} = $old;\n    } else {last;}\n  }\n  $config{HOSTNAME} = lc($config{HOSTNAME});\n  if ($config{SMTPHOST} eq $old) {\n    $config{SMTPHOST} = $config{HOSTNAME};\n  }\n  if ($config{SNMPTRAPHOST} eq $old) {\n    $config{SNMPTRAPHOST} = $config{HOSTNAME};\n  }\n  if ($config{LDAPHOST} eq $old) {\n    changeLdapHost($config{HOSTNAME});\n  }\n  if ($config{CREATEDOMAIN} eq $old) {\n    $config{CREATEDOMAIN} = $config{HOSTNAME};\n\n    my ($u,$d) = split ('@', $config{CREATEADMIN});\n    $config{CREATEADMIN} = $u.'@'.$config{CREATEDOMAIN};\n\n    my ($u,$d) = split ('@', $config{AVUSER});\n    $config{AVUSER} = $u.'@'.$config{CREATEDOMAIN};\n\n    $config{AVDOMAIN} = $config{CREATEDOMAIN};\n\n    my ($u,$d) = split ('@', $config{TRAINSASPAM});\n    $config{TRAINSASPAM} = $u.'@'.$config{CREATEDOMAIN};\n\n    my ($u,$d) = split ('@', $config{TRAINSAHAM});\n    $config{TRAINSAHAM} = $u.'@'.$config{CREATEDOMAIN};\n\n    my ($u,$d) = split ('@', $config{VIRUSQUARANTINE});\n    $config{VIRUSQUARANTINE} = $u.'@'.$config{CREATEDOMAIN};\n\n    my ($u,$d) = split ('@', $config{zimbraBackupReportEmailRecipients});\n    $config{zimbraBackupReportEmailRecipients} = $u.'@'.$config{CREATEDOMAIN};\n\n    my ($u,$d) = split ('@', $config{zimbraBackupReportEmailRecipients});\n    $config{zimbraBackupReportEmailRecipients} = $u.'@'.$config{CREATEDOMAIN};\n  }\n  my ($suser,$sdomain) = split ('@', $config{SMTPSOURCE}, 2);\n  if ($sdomain eq $old) {\n    $config{SMTPSOURCE} = $suser.'@'.$config{CREATEDOMAIN};\n  }\n  ($suser,$sdomain) = split ('@', $config{SMTPDEST}, 2);\n  if ($sdomain eq $old) {\n    $config{SMTPDEST} = $suser.'@'.$config{CREATEDOMAIN};\n  }\n  if ($config{SPELLURL} eq \"http://${old}:7780/aspell.php\") {\n    $config{SPELLURL} = \"http://$config{HOSTNAME}:7780/aspell.php\";\n  }\n}\n\nsub setSmtpHost {\n  $config{SMTPHOST} =\n    askNonBlank(\"Please enter the SMTP server hostname:\",\n      $config{SMTPHOST});\n}\n\nsub setLdapHost {\n  changeLdapHost( askNonBlank(\"Please enter the ldap server hostname:\",\n      $config{LDAPHOST}));\n}\n\nsub setLdapPort {\n  changeLdapPort( askNum(\"Please enter the ldap server port:\",\n      $config{LDAPPORT}));\n}\n\nsub setLdapServerID {\n  changeLdapServerID(askPositiveInt(\"Please enter the ldap Server ID:\", $config{LDAPSERVERID}));\n}\n\nsub setLdapReplicationType {\n  while (1) {\n    my $m =\n      askNonBlank(\"Please enter the LDAP replication type (replica, mmr)\",\n        $config{LDAPREPLICATIONTYPE});\n    if ($m eq \"replica\" || $m eq \"mmr\") {\n      $config{LDAPREPLICATIONTYPE} = $m;\n      return;\n    }\n    print \"Please enter a valid replication type!\\n\";\n  }\n}\n\nsub setHttpPort {\n  $config{HTTPPORT} = askNum(\"Please enter the HTTP server port:\",\n      $config{HTTPPORT});\n\n  if($config{HTTPPROXY} eq \"TRUE\" || $config{zimbraMailProxy} eq \"TRUE\") {\n    if($config{HTTPPORT} == $config{HTTPPROXYPORT}) {\n      $config{HTTPPROXYPORT}=\"UNSET\";\n    }\n  } elsif (isInstalled(\"zimbra-store\") && !isInstalled(\"zimbra-proxy\")) {\n    if($config{HTTPPORT} == $config{HTTPPROXYPORT}) {\n      if ($config{HTTPPORT} > 8000) {\n        $config{HTTPPROXYPORT} = $config{HTTPPORT} - 8000;\n      } else {\n        $config{HTTPPROXYPORT} = $config{HTTPPORT} + 8000;\n      }\n    }\n  }\n}\n\nsub setHttpsPort {\n  $config{HTTPSPORT} = askNum(\"Please enter the HTTPS server port:\",\n      $config{HTTPSPORT});\n\n  if($config{HTTPPROXY} eq \"TRUE\" || $config{zimbraMailProxy} eq \"TRUE\") {\n    if($config{HTTPSPORT} == $config{HTTPSPROXYPORT}) {\n      $config{HTTPSPROXYPORT}=\"UNSET\";\n    }\n  } elsif (isInstalled(\"zimbra-store\") && !isInstalled(\"zimbra-proxy\")) {\n    if($config{HTTPSPORT} == $config{HTTPSPROXYPORT}) {\n      if ($config{HTTPSPORT} > 8000) {\n        $config{HTTPSPROXYPORT} = $config{HTTPSPORT} - 8000;\n      } else {\n        $config{HTTPSPROXYPORT} = $config{HTTPSPORT} + 8000;\n      }\n    }\n  }\n}\n\nsub setImapPort {\n  $config{IMAPPORT} = askNum(\"Please enter the IMAP server port:\",\n      $config{IMAPPORT});\n\n  if($config{MAILPROXY} eq \"TRUE\" || $config{zimbraMailProxy} eq \"TRUE\") {\n    if($config{IMAPPORT} == $config{IMAPPROXYPORT}) {\n      $config{IMAPPROXYPORT}=\"UNSET\";\n    }\n  } elsif (isInstalled(\"zimbra-store\") && !isInstalled(\"zimbra-proxy\")) {\n    if($config{IMAPPORT} == $config{IMAPPROXYPORT}) {\n      if ($config{IMAPPORT} > 7000) {\n        $config{IMAPPROXYPORT} = $config{IMAPPORT} - 7000;\n      } else {\n        $config{IMAPPROXYPORT} = $config{IMAPPORT} + 7000;\n      }\n    }\n  }\n}\n\nsub setImapSSLPort {\n  $config{IMAPSSLPORT} = askNum(\"Please enter the IMAP SSL server port:\",\n      $config{IMAPSSLPORT});\n\n  if($config{MAILPROXY} eq \"TRUE\" || $config{zimbraMailProxy} eq \"TRUE\") {\n    if($config{IMAPSSLPORT} == $config{IMAPSSLPROXYPORT}) {\n      $config{IMAPSSLPROXYPORT}=\"UNSET\";\n    }\n  } elsif (isInstalled(\"zimbra-store\") && !isInstalled(\"zimbra-proxy\")) {\n    if($config{IMAPSSLPORT} == $config{IMAPSSLPROXYPORT}) {\n      if ($config{IMAPSSLPORT} > 7000) {\n        $config{IMAPSSLPROXYPORT} = $config{IMAPSSLPORT} - 7000;\n      } else {\n        $config{IMAPSSLPROXYPORT} = $config{IMAPSSLPORT} + 7000;\n      }\n    }\n  }\n}\n\nsub setPopPort {\n  $config{POPPORT} = askNum(\"Please enter the POP server port:\",\n      $config{POPPORT});\n\n  if($config{MAILPROXY} eq \"TRUE\" || $config{zimbraMailProxy} eq \"TRUE\") {\n    if($config{POPPORT} == $config{POPPROXYPORT}) {\n      $config{POPPROXYPORT}=\"UNSET\";\n    }\n  } elsif (isInstalled(\"zimbra-store\") && !isInstalled(\"zimbra-proxy\")) {\n    if($config{POPPORT} == $config{POPPROXYPORT}) {\n      if ($config{POPPORT} > 7000) {\n        $config{POPPROXYPORT} = $config{POPPORT} - 7000;\n      } else {\n        $config{POPPROXYPORT} = $config{POPPORT} + 7000;\n      }\n    }\n  }\n}\n\nsub setPopSSLPort {\n  $config{POPSSLPORT} = askNum(\"Please enter the POP SSL server port:\",\n      $config{POPSSLPORT});\n\n  if($config{MAILPROXY} eq \"TRUE\" || $config{zimbraMailProxy} eq \"TRUE\") {\n    if($config{POPSSLPORT} == $config{POPSSLPROXYPORT}) {\n      $config{POPSSLPROXYPORT}=\"UNSET\";\n    }\n  } elsif (isInstalled(\"zimbra-store\") && !isInstalled(\"zimbra-proxy\")) {\n    if($config{POPSSLPORT} == $config{POPSSLPROXYPORT}) {\n      if ($config{POPSSLPORT} > 7000) {\n        $config{POPSSLPROXYPORT} = $config{POPSSLPORT} - 7000;\n      } else {\n        $config{POPSSLPROXYPORT} = $config{POPSSLPORT} + 7000;\n      }\n    }\n  }\n}\n\nsub setImapProxyPort {\n  $config{IMAPPROXYPORT} = askNum(\"Please enter the IMAP Proxy server port:\",\n      $config{IMAPPROXYPORT});\n\n  if($config{MAILPROXY} eq \"TRUE\" || $config{zimbraMailProxy} eq \"TRUE\") {\n    if($config{IMAPPROXYPORT} == $config{IMAPPORT}) {\n      $config{IMAPPORT}=\"UNSET\";\n    }\n  }\n}\nsub setImapSSLProxyPort {\n  $config{IMAPSSLPROXYPORT} = askNum(\"Please enter the IMAP SSL Proxy server port:\",\n      $config{IMAPSSLPROXYPORT});\n\n  if($config{MAILPROXY} eq \"TRUE\" || $config{zimbraMailProxy} eq \"TRUE\") {\n    if($config{IMAPSSLPROXYPORT} == $config{IMAPSSLPORT}) {\n      $config{IMAPSSLPORT}=\"UNSET\";\n    }\n  }\n}\nsub setPopProxyPort {\n  $config{POPPROXYPORT} = askNum(\"Please enter the POP Proxy server port:\",\n      $config{POPPROXYPORT});\n\n  if($config{MAILPROXY} eq \"TRUE\" || $config{zimbraMailProxy} eq \"TRUE\") {\n    if($config{POPPROXYPORT} == $config{POPPORT}) {\n      $config{POPPORT}=\"UNSET\";\n    }\n  }\n}\nsub setPopSSLProxyPort {\n  $config{POPSSLPROXYPORT} = askNum(\"Please enter the POP SSL Proxyserver port:\",\n      $config{POPSSLPROXYPORT});\n\n  if($config{MAILPROXY} eq \"TRUE\" || $config{zimbraMailProxy} eq \"TRUE\") {\n    if($config{POPSSLPROXYPORT} == $config{POPSSLPORT}) {\n      $config{POPSSLPORT}=\"UNSET\";\n    }\n  }\n}\n\nsub setHttpProxyPort {\n  $config{HTTPPROXYPORT} = askNum(\"Please enter the HTTP Proxyserver port:\",\n      $config{HTTPPROXYPORT});\n\n  if($config{HTTPPROXY} eq \"TRUE\" || $config{zimbraMailProxy} eq \"TRUE\") {\n    if($config{HTTPPROXYPORT} == $config{HTTPPORT}) {\n      $config{HTTPPORT}=\"UNSET\";\n    }\n  }\n}\n\nsub setHttpsProxyPort {\n  $config{HTTPSPROXYPORT} = askNum(\"Please enter the HTTPS Proxyserver port:\",\n      $config{HTTPSPROXYPORT});\n\n  if($config{HTTPPROXY} eq \"TRUE\" || $config{zimbraMailProxy} eq \"TRUE\") {\n    if($config{HTTPSPROXYPORT} == $config{HTTPSPORT}) {\n      $config{HTTPSPORT}=\"UNSET\";\n    }\n  }\n}\n\nsub setSpellUrl {\n  $config{SPELLURL} = askNonBlank(\"Please enter the spell server URL:\",\n    $config{SPELLURL});\n}\n\nsub setLicenseFile {\n  $config{LICENSEFILE} = askFileName(\"Enter the name of the file that contains the license:\",\n    $config{LICENSEFILE});\n  system(\"cp $config{LICENSEFILE} /opt/zimbra/conf/ZCSLicense.xml\")\n    if ($config{LICENSEFILE} ne \"/opt/zimbra/conf/ZCSLicense.xml\");\n  if ( -f \"/opt/zimbra/conf/ZCSLicense.xml\") {\n    qx(chown zimbra:zimbra /opt/zimbra/conf/ZCSLicense.xml);\n    qx(chmod 444 /opt/zimbra/conf/ZCSLicense.xml);\n  }\n}\n\nsub setTimeZone {\n  my $timezones=\"/opt/zimbra/conf/timezones.ics\";\n  if (-f $timezones) {\n    detail(\"Loading default list of timezones.\\n\");\n    my $tz = new Zimbra::Util::Timezone;\n    $tz->parse;\n\n    my $new;\n\n    # build a hash of the timezone objects with a unique number as the value\n    my %TZID = undef;\n    my $ctr=1;\n    $TZID{$_} = $ctr++ foreach sort $tz->dump;\n    my %RTZID = reverse %TZID;\n\n    # get a reference to the default value or attempt to lookup the system locale.\n    detail(\"Previous TimeZoneID $config{zimbraPrefTimeZoneId}\\n\");\n    my $ltzref=$tz->gettzbyid(\"$config{zimbraPrefTimeZoneId}\");\n    unless (defined $ltzref) {\n      detail (\"Determining system locale.\\n\");\n      my $localtzname=qx(/bin/date '+%Z');\n      chomp($localtzname);\n      detail(\"DEBUG: Local tz name $localtzname\\n\");\n      $ltzref=$tz->gettzbyname($localtzname);\n    }\n\n    # look up the current value and present a list\n    my $default = $TZID{$ltzref->tzid} || \"21\";\n    while ($new eq \"\") {\n      foreach (sort {$TZID{$a} <=> $TZID{$b}} keys %TZID) {\n        print \"$TZID{$_} $_\\n\";\n      }\n      my $ans=askNum(\"Enter the number for the local timezone:\", $default);\n      $new = $RTZID{$ans};\n    }\n    $config{zimbraPrefTimeZoneId} = $new;\n  }\n}\n\nsub setIPMode {\n  while (1) {\n    my $new =\n      askPassword(\"IP Mode for Zimbra (ipv4, both, ipv6):\",\n        $config{zimbraIPMode});\n    if ($new eq \"ipv4\" ||  $new eq \"both\" || $new eq \"ipv6\") {\n      if ($config{zimbraIPMode} ne $new) {\n        $config{zimbraIPMode} = $new;\n      }\n      return;\n    } else {\n      print \"IP Mode must be one of ipv4, both, or ipv6!\\n\";\n    }\n  }\n}\n\nsub setSSLDefaultDigest {\n  while (1) {\n    my $new =\n      askPassword(\"Default OpenSSL digest:\",\n        $config{ssl_default_digest});\n    my $ssl_digests= join(' ', @ssl_digests);\n    if ($ssl_digests =~ /\\b$new\\b/) {\n      if ($config{ssl_default_digest} ne $new) {\n        $config{ssl_default_digest} = $new;\n      }\n      return;\n    } else {\n      print \"Valid digest modes are: $ssl_digests!\\n\";\n    }\n  }\n}\n\nsub setEnabledDependencies {\n  if (isEnabled(\"zimbra-ldap\")) {\n    if ($config{LDAPHOST} eq \"\") {\n      changeLdapHost($config{HOSTNAME});\n    }\n  } else {\n    if ($config{LDAPHOST} eq $config{HOSTNAME}) {\n      changeLdapHost(\"\");\n      $config{LDAPADMINPASS} = \"\";\n      $config{LDAPROOTPASS} = \"\";\n    }\n  }\n\n  if (isEnabled(\"zimbra-store\")) {\n    if (isEnabled(\"zimbra-mta\")) {\n      $config{SMTPHOST} = $config{HOSTNAME};\n    }\n    if ($config{\"zimbraMailProxy\"} eq \"TRUE\" || $config{\"zimbraWebProxy\"} eq \"TRUE\") {\n     setUseProxy();\n    }\n  }\n\n  if (isEnabled(\"zimbra-mta\")) {\n    if ($newinstall) {\n      $config{RUNAV} = \"yes\";\n      $config{RUNSA} = \"yes\";\n      $config{RUNDKIM} = \"yes\";\n      $config{RUNARCHIVING} = \"no\";\n      $config{RUNCBPOLICYD} = \"no\";\n    } else {\n      $config{RUNSA} = (isServiceEnabled(\"antispam\") ? \"yes\" : \"no\");\n      $config{RUNAV} = (isServiceEnabled(\"antivirus\") ? \"yes\" : \"no\");\n      if ($config{RUNDKIM} ne \"yes\") {\n        $config{RUNDKIM} = (isServiceEnabled(\"opendkim\") ? \"yes\" : \"no\");\n      }\n      $config{RUNARCHIVING} = (isServiceEnabled(\"archiving\") ? \"yes\" : \"no\");\n      $config{RUNCBPOLICYD} = (isServiceEnabled(\"cbpolicyd\") ? \"yes\" : \"no\");\n    }\n  }\n\n  if (isEnabled(\"zimbra-core\")) {\n    if ($newinstall) {\n      $config{RUNVMHA} = \"no\";\n    } else {\n      if(isNetwork()) {\n        $config{RUNVMHA} = (isServiceEnabled(\"vmware-ha\") ? \"yes\" : \"no\");\n      } else {\n        $config{RUNVMHA} = \"no\";\n      }\n    }\n  }\n\n  if (isEnabled(\"zimbra-spell\")) {\n    $config{USESPELL} = \"yes\";\n    $config{SPELLURL} = \"http://$config{HOSTNAME}:7780/aspell.php\";\n  }\n  if (isInstalled(\"zimbra-proxy\")) {\n     setUseProxy();\n  }\n}\n\nsub toggleEnabled {\n  my $p = shift;\n  $enabledPackages{$p} = (isEnabled($p))?\"Disabled\":\"Enabled\";\n  setEnabledDependencies();\n}\n\nsub verifyQuit {\n  if (askYN(\"Quit without applying changes?\", \"No\") eq \"yes\") {return 1;}\n  return 0;\n}\n\nsub genPackageMenu {\n  my $package = shift;\n  my %lm = ();\n  $lm{menuitems}{1} = {\n    \"prompt\" => \"Status:\",\n    \"var\" => \\$enabledPackages{$package},\n    \"callback\" => \\&toggleEnabled,\n    \"arg\" => $package};\n  $lm{promptitem} = {\n    \"selector\" => \"r\",\n    \"prompt\" => \"Select, or 'r' for previous menu \",\n    \"action\" => \"return\"};\n  $lm{default} = \"r\";\n  return \\%lm;\n}\n\nsub genSubMenu {\n  my %lm = ();\n  $lm{promptitem} = {\n    \"selector\" => \"r\",\n    \"prompt\" => \"Select, or 'r' for previous menu \",\n    \"action\" => \"return\"};\n  $lm{default} = \"r\";\n  return \\%lm;\n}\n\nsub isNetwork {\n  return((-f \"/opt/zimbra/bin/zmbackup\") ? 1 : 0);\n}\n\nsub isLdapMaster {\n  return(($config{LDAPHOST} eq $config{HOSTNAME}) ? 1 : 0);\n}\n\nsub isZCS {\n  return((grep(/\\b\\w+-store\\b/,@packageList)) ? 1 : 0);\n}\n\nsub isZCA {\n  return (glob(\"/opt/vmware-zca-installer/conf/optConfig/*.cfg\") ? 1 : 0);\n}\n\nsub isFoss {\n  return((-f \"/opt/zimbra/bin/zmbackup\") ? 0 : 1);\n}\n\nsub isLicenseDaemonConfigured {\n\treturn isInstalled(\"zimbra-license-daemon\") && isEnabled(\"zimbra-license-daemon\") && -d \"/opt/zimbra/license\";\n}\n\nsub isLicenseActivated {\n\trunAsZimbra(\"/opt/zimbra/bin/zmlicensectl --service restart\") if isLicenseDaemonConfigured() && !$newinstall;\n\tmy $status = runAsZimbra(\"/opt/zimbra/bin/zmlicense -c >/dev/null\") ? 0 : 1;\n\trunAsZimbra(\"/opt/zimbra/bin/zmlicensectl --service stop\") if isLicenseDaemonConfigured() && !$newinstall;\n\treturn $status;\n}\n\nsub createPackageMenu {\n  my $package = shift;\n  if ($package eq \"zimbra-ldap\") {\n    return createLdapMenu($package);\n  } elsif ($package eq \"zimbra-mta\") {\n    return createMtaMenu($package);\n  } elsif ($package eq \"zimbra-snmp\") {\n    return createSnmpMenu($package);\n  } elsif ($package eq \"zimbra-store\") {\n    return createStoreMenu($package);\n  } elsif ($package eq \"zimbra-proxy\") {\n    return createProxyMenu($package);\n  } elsif ($package eq \"zimbra-dnscache\") {\n    return createDNSCacheMenu($package);\n  } elsif ($package eq \"zimbra-imapd\") {\n    return createImapMenu($package);\n  } elsif ($package eq \"zimbra-onlyoffice\") {\n    return createOnlyofficeMenu($package);\n  }\n}\n\nsub createCommonMenu {\n  my $package = shift;\n  my $lm = genSubMenu();\n\n  $$lm{title} = \"Common configuration\";\n\n  $$lm{createsub} = \\&createCommonMenu;\n  $$lm{createarg} = $package;\n\n  my $i = 1;\n  $$lm{menuitems}{$i} = {\n    \"prompt\" => \"Hostname:\",\n    \"var\" => \\$config{HOSTNAME},\n    \"callback\" => \\&setHostName\n    };\n  $i++;\n  $$lm{menuitems}{$i} = {\n    \"prompt\" => \"Ldap master host:\",\n    \"var\" => \\$config{LDAPHOST},\n    \"callback\" => \\&setLdapHost\n    };\n  $i++;\n  $$lm{menuitems}{$i} = {\n    \"prompt\" => \"Ldap port:\",\n    \"var\" => \\$config{LDAPPORT},\n    \"callback\" => \\&setLdapPort\n    };\n  $i++;\n  if ($config{LDAPADMINPASS} eq \"\") {\n    $config{LDAPADMINPASSSET} = \"UNSET\";\n  } else {\n    $config{LDAPADMINPASSSET} = \"set\" unless ($config{LDAPADMINPASSSET} eq \"Not Verified\");\n  }\n  $$lm{menuitems}{$i} = {\n    \"prompt\" => \"Ldap Admin password:\",\n    \"var\" => \\$config{LDAPADMINPASSSET},\n    \"callback\" => \\&setLdapAdminPass\n    };\n  $i++;\n  # ldap users\n  if (!defined($installedPackages{\"zimbra-ldap\"})) {\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"LDAP Base DN:\",\n      \"var\" => \\$config{ldap_dit_base_dn_config},\n      \"callback\" => \\&setLdapBaseDN,\n      };\n    $i++;\n  }\n  $config{USEEPHEMERALSTORE} = \"no\" unless (exists $config{USEEPHEMERALSTORE});\n  $$lm{menuitems}{$i} = {\n    \"prompt\" => \"Store ephemeral attributes outside Ldap:\",\n    \"var\" => \\$config{USEEPHEMERALSTORE},\n    \"callback\" => \\&toggleYN,\n    \"arg\" => \"USEEPHEMERALSTORE\",\n    };\n  $i++;\n  if ($config{USEEPHEMERALSTORE} eq \"yes\") {\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Value for zimbraEphemeralBackendURL:\",\n      \"var\" => \\$config{EphemeralBackendURL},\n      \"callback\" => \\&setEphemeralBackendURL,\n      };\n    $i++;\n  }\n  # interprocess security\n  $$lm{menuitems}{$i} = {\n    \"prompt\" => \"Secure interprocess communications:\",\n    \"var\" => \\$config{ZIMBRA_REQ_SECURITY},\n    \"callback\" => \\&toggleYN,\n    \"arg\" => \"ZIMBRA_REQ_SECURITY\",\n  };\n  $i++;\n  if ($config{ZIMBRA_REQ_SECURITY} eq \"yes\") {\n     $config{zimbra_require_interprocess_security} = 1;\n  } else {\n     $config{zimbra_require_interprocess_security} = 0;\n     $starttls=0;\n  }\n  $$lm{menuitems}{$i} = {\n    \"prompt\" => \"TimeZone:\",\n    \"var\" => \\$config{zimbraPrefTimeZoneId},\n    \"callback\" => \\&setTimeZone\n  };\n  $i++;\n  $$lm{menuitems}{$i} = {\n    \"prompt\" => \"IP Mode:\",\n    \"var\" => \\$config{zimbraIPMode},\n    \"callback\" => \\&setIPMode\n  };\n  $i++;\n  $$lm{menuitems}{$i} = {\n    \"prompt\" => \"Default SSL digest:\",\n    \"var\" => \\$config{ssl_default_digest},\n    \"callback\" => \\&setSSLDefaultDigest\n  };\n  $i++;\n  return $lm;\n}\n\nsub createOnlyofficeMenu {\n  my $package = shift;\n  my $lm = genPackageMenu($package);\n\n  $$lm{title} = \"Onlyoffice configuration\";\n\n  $$lm{createsub} = \\&createOnlyofficeMenu;\n  $$lm{createarg} = $package;\n\n  my $i = 2;\n\n  if (isEnabled($package)) {\n    # get the hostname for onlyoffice to be put into config\n    # if standalone server :\n    #    1. global config already present, do not override\n    #    2. global config not present, this server name goes as global config\n    # if not standalone:\n    #    set the server host name at server level config\n    if (isEnabled(\"zimbra-store\")) {\n      $config{ONLYOFFICESTANDALONE} = \"no\";\n    } else {\n      $config{ONLYOFFICESTANDALONE} = \"yes\";\n    }\n\n    if ($config{ONLYOFFICEHOSTNAME} eq \"\") {\n        $config{ONLYOFFICEHOSTNAME} = $config{HOSTNAME};\n    }\n\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Onlyoffice server:\",\n      \"var\" => \\$config{ONLYOFFICEHOSTNAME},\n      \"callback\" => \\&setOnlyOfficeHost\n      };\n    $i++;\n\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Standalone Onlyoffice:\",\n      \"var\" => \\$config{ONLYOFFICESTANDALONE}\n      };\n    $i++;\n  }\n\n  return $lm;\n}\n\nsub createLdapMenu {\n  my $package = shift;\n  my $lm = genPackageMenu($package);\n\n  $$lm{title} = \"Ldap configuration\";\n\n  $$lm{createsub} = \\&createLdapMenu;\n  $$lm{createarg} = $package;\n\n  my $i = 2;\n  if (isEnabled($package)) {\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Create Domain:\",\n      \"var\" => \\$config{DOCREATEDOMAIN},\n      \"callback\" => \\&toggleYN,\n      \"arg\" => \"DOCREATEDOMAIN\",\n      };\n    $i++;\n    if ($config{DOCREATEDOMAIN} eq \"yes\") {\n      $$lm{menuitems}{$i} = {\n        \"prompt\" => \"Domain to create:\",\n        \"var\" => \\$config{CREATEDOMAIN},\n        \"callback\" => \\&setCreateDomain,\n        };\n      $i++;\n    }\n    #$$lm{menuitems}{$i} = {\n      #\"prompt\" => \"Sync domain GALs to contact folders:\",\n      #\"var\" => \\$config{ENABLEGALSYNCACCOUNTS},\n      #\"callback\" => \\&toggleYN,\n      #\"arg\" => \"ENABLEGALSYNCACCOUNTS\",\n      #};\n    #$i++;\n    if($config{LDAPREPLICATIONTYPE} ne \"master\") {\n      $$lm{menuitems}{$i} = {\n        \"prompt\" => \"Ldap replication type:\",\n        \"var\" => \\$config{LDAPREPLICATIONTYPE},\n        \"callback\" => \\&setLdapReplicationType\n      };\n      $i++;\n    }\n    if ($config{LDAPREPLICATIONTYPE} eq \"mmr\") {\n      $$lm{menuitems}{$i} = {\n        \"prompt\" => \"Ldap Server ID:\",\n        \"var\" => \\$config{LDAPSERVERID},\n        \"callback\" => \\&setLdapServerID\n      };\n      $i++;\n    }\n    if ($config{LDAPROOTPASS} ne \"\") {\n      $config{LDAPROOTPASSSET} = \"set\";\n    } else {\n      $config{LDAPROOTPASSSET} = \"UNSET\" unless ($config{LDAPROOTPASSSET} eq \"Not Verified\");\n    }\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Ldap root password:\",\n      \"var\" => \\$config{LDAPROOTPASSSET},\n      \"callback\" => \\&setLdapRootPass\n      };\n    $i++;\n    if ($config{LDAPREPPASS} eq \"\") {\n      $config{LDAPREPPASSSET} = \"UNSET\";\n    } else {\n      $config{LDAPREPPASSSET} = \"set\" unless ($config{LDAPREPPASSSET} eq \"Not Verified\");\n    }\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Ldap replication password:\",\n      \"var\" => \\$config{LDAPREPPASSSET},\n      \"callback\" => \\&setLdapRepPass\n      };\n    $i++;\n    if ($config{HOSTNAME} eq $config{LDAPHOST} || $config{LDAPREPLICATIONTYPE} ne \"replica\" || isEnabled(\"zimbra-mta\")) {\n      if ($config{LDAPPOSTPASS} eq \"\") {\n        $config{LDAPPOSTPASSSET} = \"UNSET\";\n      } else {\n        $config{LDAPPOSTPASSSET} = \"set\" unless ($config{LDAPPOSTPASSSET} eq \"Not Verified\");\n      }\n      $$lm{menuitems}{$i} = {\n        \"prompt\" => \"Ldap postfix password:\",\n        \"var\" => \\$config{LDAPPOSTPASSSET},\n        \"callback\" => \\&setLdapPostPass\n        };\n      $i++;\n      if ($config{LDAPAMAVISPASS} eq \"\") {\n        $config{LDAPAMAVISPASSSET} = \"UNSET\";\n      } else {\n        $config{LDAPAMAVISPASSSET} = \"set\" unless ($config{LDAPAMAVISPASSSET} eq \"Not Verified\");\n      }\n      $$lm{menuitems}{$i} = {\n        \"prompt\" => \"Ldap amavis password:\",\n        \"var\" => \\$config{LDAPAMAVISPASSSET},\n        \"callback\" => \\&setLdapAmavisPass\n        };\n      $i++;\n    }\n    if ($config{HOSTNAME} eq $config{LDAPHOST} || $config{LDAPREPLICATIONTYPE} ne \"replica\" || isEnabled(\"zimbra-proxy\")) {\n      if ($config{ldap_nginx_password} eq \"\") {\n        $config{LDAPNGINXPASSSET} = \"UNSET\";\n      } else {\n        $config{LDAPNGINXPASSSET} = \"set\" unless ($config{LDAPNGINXPASSSET} eq \"Not Verified\");\n      }\n      $$lm{menuitems}{$i} = {\n        \"prompt\" => \"Ldap nginx password:\",\n        \"var\" => \\$config{LDAPNGINXPASSSET},\n        \"callback\" => \\&setLdapNginxPass\n        };\n      $i++;\n    }\n    if ($config{HOSTNAME} eq $config{LDAPHOST} || $config{LDAPREPLICATIONTYPE} ne \"replica\" ) {\n      if ($config{ldap_bes_searcher_password} eq \"\") {\n        $config{LDAPBESSEARCHSET} = \"UNSET\";\n      } else {\n        $config{LDAPBESSEARCHSET} = \"set\" unless ($config{LDAPBESSEARCHSET} eq \"Not Verified\");\n      }\n      $$lm{menuitems}{$i} = {\n        \"prompt\" => \"Ldap Bes Searcher password:\",\n        \"var\" => \\$config{LDAPBESSEARCHSET},\n        \"callback\" => \\&setLdapBesSearchPass\n        };\n      $i++;\n    }\n  }\n  return $lm;\n}\nsub createCOSMenu {\n  my $package = shift;\n  my $lm = genSubMenu();\n\n  $$lm{title} = \"Default Class of Service configuration\";\n\n  $$lm{createsub} = \\&createCOSMenu;\n  $$lm{createarg} = $package;\n\n  my $i = 1;\n  $$lm{menuitems}{$i} = {\n    \"prompt\" => \"Enable Tasks Feature:\",\n    \"var\" => \\$config{zimbraFeatureTasksEnabled},\n    \"callback\" => \\&toggleConfigEnabled,\n    \"arg\" => \"zimbraFeatureTasksEnabled\",\n    };\n  $i++;\n  return $lm;\n}\n\nsub createLdapUsersMenu {\n  my $package = shift;\n  my $lm = genSubMenu();\n\n  $$lm{title} = \"Ldap Users configuration\";\n\n  $$lm{createsub} = \\&createLdapUsersMenu;\n  $$lm{createarg} = $package;\n\n  my $i = 1;\n  return $lm;\n}\n\nsub createArchivingMenu {\n  my $package = shift;\n  my $lm = genPackageMenu($package);\n  $$lm{title} = \"Archiving configuration\";\n  $$lm{createsub} = \\&createArchivingMenu;\n  $$lm{createarg} = $package;\n  my $i = 2;\n  return $lm;\n}\n\nsub createSnmpMenu {\n  my $package = shift;\n  my $lm = genPackageMenu($package);\n\n  $$lm{title} = \"Snmp configuration\";\n\n  $$lm{createsub} = \\&createSnmpMenu;\n  $$lm{createarg} = $package;\n\n  my $i = 2;\n  if (isEnabled($package)) {\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Enable SNMP notifications:\",\n      \"var\" => \\$config{SNMPNOTIFY},\n      \"callback\" => \\&toggleYN,\n      \"arg\" => \"SNMPNOTIFY\",\n      };\n    $i++;\n    if ($config{SNMPNOTIFY} eq \"yes\") {\n      $$lm{menuitems}{$i} = {\n        \"prompt\" => \"SNMP Trap hostname:\",\n        \"var\" => \\$config{SNMPTRAPHOST},\n        \"callback\" => \\&setSnmpTrapHost,\n        };\n      $i++;\n    }\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Enable SMTP notifications:\",\n      \"var\" => \\$config{SMTPNOTIFY},\n      \"callback\" => \\&toggleYN,\n      \"arg\" => \"SMTPNOTIFY\",\n      };\n    $i++;\n    if ($config{SMTPNOTIFY} eq \"yes\") {\n      $$lm{menuitems}{$i} = {\n        \"prompt\" => \"SMTP Source email address:\",\n        \"var\" => \\$config{SMTPSOURCE},\n        \"callback\" => \\&setSmtpSource,\n        };\n      $i++;\n      $$lm{menuitems}{$i} = {\n        \"prompt\" => \"SMTP Destination email address:\",\n        \"var\" => \\$config{SMTPDEST},\n        \"callback\" => \\&setSmtpDest,\n        };\n      $i++;\n    }\n  }\n  return $lm;\n}\n\nsub createMtaMenu {\n  my $package = shift;\n  my $lm = genPackageMenu($package);\n\n  $$lm{title} = \"Mta configuration\";\n\n  $$lm{createsub} = \\&createMtaMenu;\n  $$lm{createarg} = $package;\n\n  my $i = 2;\n  if (isEnabled($package)) {\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Enable Spamassassin:\",\n      \"var\" => \\$config{RUNSA},\n      \"callback\" => \\&toggleYN,\n      \"arg\" => \"RUNSA\",\n      };\n    $i++;\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Enable Clam AV:\",\n      \"var\" => \\$config{RUNAV},\n      \"callback\" => \\&toggleYN,\n      \"arg\" => \"RUNAV\",\n      };\n    $i++;\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Enable OpenDKIM:\",\n      \"var\" => \\$config{RUNDKIM},\n      \"callback\" => \\&toggleYN,\n      \"arg\" => \"RUNDKIM\",\n      };\n    $i++;\n    if ($config{RUNAV} eq \"yes\") {\n      $$lm{menuitems}{$i} = {\n        \"prompt\" => \"Notification address for AV alerts:\",\n        \"var\" => \\$config{AVUSER},\n        \"callback\" => \\&setAvUser,\n        };\n      $i++;\n    }\n    if (isEnabled(\"zimbra-archiving\") || isComponentAvailable(\"archiving\")) {\n      $$lm{menuitems}{$i} = {\n        \"prompt\" => \"Enable Archiving and Discovery:\",\n        \"var\" => \\$config{RUNARCHIVING},\n        \"callback\" => \\&toggleYN,\n        \"arg\" => \"RUNARCHIVING\",\n        };\n      $i++;\n    }\n    if ($config{LDAPPOSTPASS} eq \"\") {\n      $config{LDAPPOSTPASSSET} = \"UNSET\";\n    } else {\n      $config{LDAPPOSTPASSSET} = \"set\" unless ($config{LDAPPOSTPASSSET} eq \"Not Verified\");\n    }\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Bind password for postfix ldap user:\",\n      \"var\" => \\$config{LDAPPOSTPASSSET},\n      \"callback\" => \\&setLdapPostPass\n      };\n    $i++;\n    if ($config{LDAPAMAVISPASS} eq \"\") {\n      $config{LDAPAMAVISPASSSET} = \"UNSET\";\n    } else {\n      $config{LDAPAMAVISPASSSET} = \"set\" unless ($config{LDAPAMAVISPASSSET} eq \"Not Verified\");\n    }\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Bind password for amavis ldap user:\",\n      \"var\" => \\$config{LDAPAMAVISPASSSET},\n      \"callback\" => \\&setLdapAmavisPass\n      };\n    $i++;\n  }\n  return $lm;\n}\n\nsub createProxyMenu {\n  my $package = shift;\n  my $lm = genPackageMenu($package);\n\n  $$lm{title} = \"Proxy configuration\";\n\n  $$lm{createsub} = \\&createProxyMenu;\n  $$lm{createarg} = $package;\n\n  my $i = 2;\n  if (isInstalled($package)) {\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Enable POP/IMAP Proxy:\",\n      \"var\" => \\$config{MAILPROXY},\n      \"callback\" => \\&toggleTF,\n      \"arg\" => \"MAILPROXY\",\n    };\n    $i++;\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Enable strict server name enforcement?\",\n      \"var\" => \\$config{STRICTSERVERNAMEENABLED},\n      \"callback\" => \\&toggleYN,\n      \"arg\" => \"STRICTSERVERNAMEENABLED\",\n    };\n    $i++;\n    if($config{MAILPROXY} eq \"TRUE\") {\n       if(!isEnabled(\"zimbra-store\")) {\n          $$lm{menuitems}{$i} = {\n            \"prompt\" => \"IMAP server port:\",\n            \"var\" => \\$config{IMAPPORT},\n            \"callback\" => \\&setImapPort,\n            };\n          $i++;\n          $$lm{menuitems}{$i} = {\n            \"prompt\" => \"IMAP server SSL port:\",\n            \"var\" => \\$config{IMAPSSLPORT},\n            \"callback\" => \\&setImapSSLPort,\n            };\n          $i++;\n       }\n       $$lm{menuitems}{$i} = {\n         \"prompt\" => \"IMAP proxy port:\",\n         \"var\" => \\$config{IMAPPROXYPORT},\n         \"callback\" => \\&setImapProxyPort,\n       };\n       $i++;\n       $$lm{menuitems}{$i} = {\n         \"prompt\" => \"IMAP SSL proxy port:\",\n         \"var\" => \\$config{IMAPSSLPROXYPORT},\n         \"callback\" => \\&setImapSSLProxyPort,\n       };\n       $i++;\n       if(!isEnabled(\"zimbra-store\")) {\n          $$lm{menuitems}{$i} = {\n            \"prompt\" => \"POP server port:\",\n            \"var\" => \\$config{POPPORT},\n            \"callback\" => \\&setPopPort,\n            };\n          $i++;\n          $$lm{menuitems}{$i} = {\n            \"prompt\" => \"POP server SSL port:\",\n            \"var\" => \\$config{POPSSLPORT},\n            \"callback\" => \\&setPopSSLPort,\n            };\n          $i++;\n       }\n       $$lm{menuitems}{$i} = {\n         \"prompt\" => \"POP proxy port:\",\n         \"var\" => \\$config{POPPROXYPORT},\n         \"callback\" => \\&setPopProxyPort,\n       };\n       $i++;\n       $$lm{menuitems}{$i} = {\n         \"prompt\" => \"POP SSL proxy port:\",\n         \"var\" => \\$config{POPSSLPROXYPORT},\n         \"callback\" => \\&setPopSSLProxyPort,\n       };\n       $i++;\n    }\n    if ($config{HTTPPROXY} eq \"TRUE\" || $config{MAILPROXY} eq \"TRUE\") {\n      if ($config{ldap_nginx_password} eq \"\") {\n        $config{LDAPNGINXPASSSET} = \"UNSET\";\n      } else {\n        $config{LDAPNGINXPASSSET} = \"set\" unless ($config{LDAPNGINXPASSSET} eq \"Not Verified\");\n      }\n      $$lm{menuitems}{$i} = {\n        \"prompt\" => \"Bind password for nginx ldap user:\",\n        \"var\" => \\$config{LDAPNGINXPASSSET},\n        \"callback\" => \\&setLdapNginxPass\n      };\n      $i++;\n    }\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Enable HTTP[S] Proxy:\",\n      \"var\" => \\$config{HTTPPROXY},\n      \"callback\" => \\&toggleTF,\n      \"arg\" => \"HTTPPROXY\",\n    };\n    $i++;\n    if ($config{HTTPPROXY} eq \"TRUE\") {\n       if(!isEnabled(\"zimbra-store\")) {\n          $$lm{menuitems}{$i} = {\n            \"prompt\" => \"Web server HTTP port:\",\n            \"var\" => \\$config{HTTPPORT},\n            \"callback\" => \\&setHttpPort,\n            };\n          $i++;\n          $$lm{menuitems}{$i} = {\n            \"prompt\" => \"Web server HTTPS port:\",\n            \"var\" => \\$config{HTTPSPORT},\n            \"callback\" => \\&setHttpsPort,\n            };\n          $i++;\n       }\n       $$lm{menuitems}{$i} = {\n         \"prompt\" => \"HTTP proxy port:\",\n         \"var\" => \\$config{HTTPPROXYPORT},\n         \"callback\" => \\&setHttpProxyPort,\n       };\n       $i++;\n       $$lm{menuitems}{$i} = {\n         \"prompt\" => \"HTTPS proxy port:\",\n         \"var\" => \\$config{HTTPSPROXYPORT},\n         \"callback\" => \\&setHttpsProxyPort,\n       };\n       $i++;\n       $$lm{menuitems}{$i} = {\n         \"prompt\" => \"Proxy server mode:\",\n         \"var\" => \\$config{PROXYMODE},\n         \"callback\" => \\&setProxyMode,\n       };\n       $i++;\n    }\n  }\n  return $lm;\n}\n\nsub createDNSCacheMenu {\n  my $package = shift;\n  my $lm = genPackageMenu($package);\n\n  $$lm{title} = \"DNS Cache configuration\";\n\n  $$lm{createsub} = \\&createDNSCacheMenu;\n  $$lm{createarg} = $package;\n\n  my $i = 2;\n  if (isEnabled($package)) {\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Master DNS IP address(es):\",\n      \"var\" => \\$config{zimbraDNSMasterIP},\n      \"callback\" => \\&setMasterDNSIP,\n      };\n    $i++;\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Enable DNS lookups over TCP:\",\n      \"var\" => \\$config{zimbraDNSUseTCP},\n      \"callback\" => \\&toggleYN,\n      \"arg\" => \"zimbraDNSUseTCP\",\n      };\n    $i++;\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Enable DNS lookups over UDP:\",\n      \"var\" => \\$config{zimbraDNSUseUDP},\n      \"callback\" => \\&toggleYN,\n      \"arg\" => \"zimbraDNSUseUDP\",\n      };\n    $i++;\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Only allow TCP to communicate with Master DNS:\",\n      \"var\" => \\$config{zimbraDNSTCPUpstream},\n      \"callback\" => \\&toggleYN,\n      \"arg\" => \"zimbraDNSTCPUpstream\",\n      };\n    $i++;\n  }\n  return $lm;\n}\n\nsub createImapMenu {\n  my $package = shift;\n  my $lm = genPackageMenu($package);\n\n  $$lm{title} = \"IMAPD configuration\";\n\n  $$lm{createsub} = \\&createImapMenu;\n  $$lm{createarg} = $package;\n\n  my $i = 2;\n  if (isEnabled($package)) {\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Add to upstream IMAP Servers?:\",\n      \"var\" => \\$config{DOADDUPSTREAMIMAP},\n      \"callback\" => \\&toggleYN,\n      \"arg\" => \"DOADDUPSTREAMIMAP\",\n      };\n    $i++;\n  }\n  return $lm;\n\n}\n\nsub createStoreMenu {\n  my $package = shift;\n  my $lm = genPackageMenu($package);\n\n  $$lm{title} = \"Store configuration\";\n\n  $$lm{createsub} = \\&createStoreMenu;\n  $$lm{createarg} = $package;\n\n  my $i = 2;\n  if (isEnabled($package)) {\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Create Admin User:\",\n      \"var\" => \\$config{DOCREATEADMIN},\n      \"callback\" => \\&toggleYN,\n      \"arg\" => \"DOCREATEADMIN\",\n      };\n    $i++;\n    if ($config{DOCREATEADMIN} eq \"yes\") {\n      $$lm{menuitems}{$i} = {\n        \"prompt\" => \"Admin user to create:\",\n        \"var\" => \\$config{CREATEADMIN},\n        \"callback\" => \\&setCreateAdmin\n        };\n      $i++;\n      if ($config{CREATEADMINPASS} ne \"\") {\n        $config{ADMINPASSSET} = \"set\";\n      } else {\n        $config{ADMINPASSSET} = \"UNSET\";\n      }\n      $$lm{menuitems}{$i} = {\n        \"prompt\" => \"Admin Password\",\n        \"var\" => \\$config{ADMINPASSSET},\n        \"callback\" => \\&setAdminPass\n        };\n      $i++;\n    }\n    my $ldap_virusquarantine = getLdapConfigValue(\"zimbraAmavisQuarantineAccount\")\n      if (ldapIsAvailable());\n\n    if ($ldap_virusquarantine eq \"\") {\n      $$lm{menuitems}{$i} = {\n        \"prompt\" => \"Anti-virus quarantine user:\",\n        \"var\" => \\$config{VIRUSQUARANTINE},\n        \"callback\" => \\&setAmavisVirusQuarantine\n        };\n      $i++;\n    } else {\n      $config{VIRUSQUARANTINE} = $ldap_virusquarantine;\n    }\n\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Enable automated spam training:\",\n      \"var\" => \\$config{DOTRAINSA},\n      \"callback\" => \\&toggleYN,\n      \"arg\" => \"DOTRAINSA\",\n      };\n    $i++;\n    if ($config{DOTRAINSA} eq \"yes\") {\n\n      my $ldap_trainsaspam = getLdapConfigValue(\"zimbraSpamIsSpamAccount\")\n        if (ldapIsAvailable());\n\n      if ($ldap_trainsaspam eq \"\") {\n        $$lm{menuitems}{$i} = {\n          \"prompt\" => \"Spam training user:\",\n          \"var\" => \\$config{TRAINSASPAM},\n          \"callback\" => \\&setTrainSASpam\n          };\n        $i++;\n      } else {\n        $config{TRAINSASPAM} = $ldap_trainsaspam;\n      }\n\n\n      my $ldap_trainsaham = getLdapConfigValue(\"zimbraSpamIsNotSpamAccount\")\n        if (ldapIsAvailable());\n\n      if ($ldap_trainsaham eq \"\") {\n        $$lm{menuitems}{$i} = {\n          \"prompt\" => \"Non-spam(Ham) training user:\",\n          \"var\" => \\$config{TRAINSAHAM},\n          \"callback\" => \\&setTrainSAHam\n          };\n        $i++;\n      } else {\n        $config{TRAINSAHAM} = $ldap_trainsaham;\n      }\n    }\n\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"SMTP host:\",\n      \"var\" => \\$config{SMTPHOST},\n      \"callback\" => \\&setSmtpHost,\n      };\n    $i++;\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Web server HTTP port:\",\n      \"var\" => \\$config{HTTPPORT},\n      \"callback\" => \\&setHttpPort,\n      };\n    $i++;\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Web server HTTPS port:\",\n      \"var\" => \\$config{HTTPSPORT},\n      \"callback\" => \\&setHttpsPort,\n      };\n    $i++;\n    if(!isEnabled(\"zimbra-proxy\") && $config{\"zimbraWebProxy\"} eq \"TRUE\") {\n       $$lm{menuitems}{$i} = {\n         \"prompt\" => \"HTTP proxy port:\",\n         \"var\" => \\$config{HTTPPROXYPORT},\n         \"callback\" => \\&setHttpProxyPort,\n       };\n       $i++;\n       $$lm{menuitems}{$i} = {\n         \"prompt\" => \"HTTPS proxy port:\",\n         \"var\" => \\$config{HTTPSPROXYPORT},\n         \"callback\" => \\&setHttpsProxyPort,\n       };\n       $i++;\n    }\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Web server mode:\",\n      \"var\" => \\$config{MODE},\n      \"callback\" => \\&setStoreMode,\n      };\n    $i++;\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"IMAP server port:\",\n      \"var\" => \\$config{IMAPPORT},\n      \"callback\" => \\&setImapPort,\n      };\n    $i++;\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"IMAP server SSL port:\",\n      \"var\" => \\$config{IMAPSSLPORT},\n      \"callback\" => \\&setImapSSLPort,\n      };\n    $i++;\n    if(!isEnabled(\"zimbra-proxy\") && $config{\"zimbraMailProxy\"} eq \"TRUE\") {\n       $$lm{menuitems}{$i} = {\n         \"prompt\" => \"IMAP proxy port:\",\n         \"var\" => \\$config{IMAPPROXYPORT},\n         \"callback\" => \\&setImapProxyPort,\n       };\n       $i++;\n       $$lm{menuitems}{$i} = {\n         \"prompt\" => \"IMAP SSL proxy port:\",\n         \"var\" => \\$config{IMAPSSLPROXYPORT},\n         \"callback\" => \\&setImapSSLProxyPort,\n       };\n       $i++;\n    }\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"POP server port:\",\n      \"var\" => \\$config{POPPORT},\n      \"callback\" => \\&setPopPort,\n      };\n    $i++;\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"POP server SSL port:\",\n      \"var\" => \\$config{POPSSLPORT},\n      \"callback\" => \\&setPopSSLPort,\n      };\n    $i++;\n    if(!isEnabled(\"zimbra-proxy\") && $config{\"zimbraMailProxy\"} eq \"TRUE\") {\n       $$lm{menuitems}{$i} = {\n         \"prompt\" => \"POP proxy port:\",\n         \"var\" => \\$config{POPPROXYPORT},\n         \"callback\" => \\&setPopProxyPort,\n       };\n       $i++;\n       $$lm{menuitems}{$i} = {\n         \"prompt\" => \"POP SSL proxy port:\",\n         \"var\" => \\$config{POPSSLPROXYPORT},\n         \"callback\" => \\&setPopSSLProxyPort,\n       };\n       $i++;\n    }\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Use spell check server:\",\n      \"var\" => \\$config{USESPELL},\n      \"callback\" => \\&toggleYN,\n      \"arg\" => \"USESPELL\",\n      };\n    $i++;\n    if ($config{USESPELL} eq \"yes\") {\n      $$lm{menuitems}{$i} = {\n        \"prompt\" => \"Spell server URL:\",\n        \"var\" => \\$config{SPELLURL},\n        \"callback\" => \\&setSpellUrl,\n        };\n      $i++;\n    }\n    if (!isInstalled(\"zimbra-proxy\") && $newinstall) {\n      $$lm{menuitems}{$i} = {\n        \"prompt\" => \"Configure for use with mail proxy:\",\n        \"var\" => \\$config{zimbraMailProxy},\n        \"callback\" => \\&toggleTF,\n        \"arg\" => \"zimbraMailProxy\",\n      };\n      $i++;\n      $$lm{menuitems}{$i} = {\n        \"prompt\" => \"Configure for use with web proxy:\",\n        \"var\" => \\$config{zimbraWebProxy},\n        \"callback\" => \\&toggleTF,\n        \"arg\" => \"zimbraWebProxy\",\n      };\n      $i++;\n    }\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Enable version update checks:\",\n      \"var\" => \\$config{VERSIONUPDATECHECKS},\n      \"callback\" => \\&toggleTF,\n      \"arg\" => \"VERSIONUPDATECHECKS\",\n      };\n    $i++;\n    if ($config{VERSIONUPDATECHECKS} eq \"TRUE\") {\n      $$lm{menuitems}{$i} = {\n        \"prompt\" => \"Enable version update notifications:\",\n        \"var\" => \\$config{zimbraVersionCheckSendNotifications},\n        \"callback\" => \\&toggleTF,\n        \"arg\" => \"zimbraVersionCheckSendNotifications\",\n        };\n      $i++;\n      if ($config{zimbraVersionCheckSendNotifications} eq \"TRUE\") {\n\n        my $version_dst_addr =\n          getLdapConfigValue(\"zimbraVersionCheckNotificationEmail\")\n          if (ldapIsAvailable());\n\n        if ($version_dst_addr eq \"\") {\n          $$lm{menuitems}{$i} = {\n            \"prompt\" => \"Version update notification email:\",\n            \"var\" => \\$config{zimbraVersionCheckNotificationEmail},\n            \"callback\" => \\&setVersionCheckNotificationEmail\n            };\n          $i++;\n        } else {\n          $config{zimbraVersionCheckNotificationEmail} = $version_dst_addr;\n        }\n\n        my $version_src_addr =\n        getLdapConfigValue(\"zimbraVersionCheckNotificationEmailFrom\")\n          if (ldapIsAvailable());\n\n        if ($version_src_addr eq \"\") {\n          $$lm{menuitems}{$i} = {\n          \"prompt\" => \"Version update source email:\",\n            \"var\" => \\$config{zimbraVersionCheckNotificationEmailFrom},\n            \"callback\" => \\&setVersionCheckNotificationEmailFrom\n            };\n          $i++;\n        } else {\n          $config{zimbraVersionCheckNotificationEmailFrom} = $version_src_addr;\n        }\n      }\n    }\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Install mailstore (service webapp):\",\n      \"var\" => \\$config{SERVICEWEBAPP},\n      \"callback\" => \\&toggleSERVICEWEBAPP,\n      \"arg\" => \"SERVICEWEBAPP\"\n    };\n    $i++;\n    $$lm{menuitems}{$i} = {\n      \"prompt\" => \"Install UI (zimbra,zimbraAdmin webapps):\",\n      \"var\" => \\$config{UIWEBAPPS},\n      \"callback\" => \\&toggleYN,\n      \"arg\" => \"UIWEBAPPS\"\n    };\n    $i++;\n    if (-e $license_file) {\n\t    chomp($config{LICENSEKEY} = qx(cat $license_file));\n\t    $config{LICENSEACTIVATIONOPTION} = \"1\";\n    }\n    if ($config{LICENSEACTIVATIONOPTION} eq \"1\") {\n\t    $config{LICENSEACTIVATIONOPTIONMSG} = \"Activate license with installation\";\n    } elsif ($config{LICENSEACTIVATIONOPTION} eq \"2\") {\n\t    $config{LICENSEACTIVATIONOPTIONMSG} = \"Activate license after installation\";\n    } else {\n\t    $config{LICENSEACTIVATIONOPTIONMSG} = \"UNSET\";\n    }\n    # only prompt for license if it is a network install, the license is not activated, and the skip_activation_check is not set to \"yes\".\n    if (isNetwork() && !isLicenseActivated() && $skip_activation_check ne \"yes\") {\n\t    $$lm{menuitems}{$i} = {\n\t\t    \"prompt\" => \"License Activation:\",\n\t\t    \"var\" => \\$config{LICENSEACTIVATIONOPTIONMSG},\n\t\t    \"callback\" => \\&chooseLicenseActivationOption,\n\t    };\n\t    $i++;\n    }\n  }\n  return $lm;\n}\n\nsub displaySubMenuItems {\n  my $items = shift;\n  my $parentmenuvar = shift;\n  my $indent = shift;\n\n  if (defined($$items{createsub})) {\n    $items = &{$$items{createsub}}($$items{createarg});\n  }\n#  print \"$indent$$items{title}\\n\";\n  foreach my $i (sort menuSort keys %{$$items{menuitems}}) {\n    if (defined($$items{menuitems}{$i}{var}) &&\n      $$items{menuitems}{$i}{var} == $parentmenuvar) {next;}\n    my $len = 44-(length($indent));\n    my $v;\n    my $ind = $indent;\n    if (defined $$items{menuitems}{$i}{var}) {\n      $v = ${$$items{menuitems}{$i}{var}};\n      if ($v eq \"\" || $v eq \"none\" || $v eq \"UNSET\") { $v = \"UNSET\"; $ind=~s/ /*/g; }\n      if ($v eq \"Not Verified\") { $v = \"Not Verified\"; $ind=~s/ /*/g; }\n    }\n    printf (\"%s +%-${len}s %-30s\\n\", $ind,\n      $$items{menuitems}{$i}{prompt}, $v);\n    if (defined ($$items{menuitems}{$i}{submenu}) ) {\n      displaySubMenuItems($$items{menuitems}{$i}{submenu},\"$indent  \");\n    }\n  }\n}\n\nsub menuSort {\n  if ( ($a eq int($a)) && ($b eq int($b)) ) {\n    return $a <=> $b;\n  }\n  return $a cmp $b;\n}\n\nsub displayMenu {\n  my $items = shift;\n  while (1) {\n    if (defined($$items{createsub})) {\n      $items = &{$$items{createsub}}($$items{createarg});\n    }\n\n    print \"\\n$$items{title}\\n\\n\";\n    foreach my $i (sort menuSort keys %{$$items{menuitems}}) {\n      my $v;\n      my $ind = \"  \";\n      if (defined $$items{menuitems}{$i}{var}) {\n        $v = ${$$items{menuitems}{$i}{var}};\n        if ($v eq \"\" || $v eq \"none\" || $v eq \"UNSET\") { $v = \"UNSET\"; $ind=\"**\"; }\n        if ($v eq \"Not Verified\") { $ind=\"**\"; }\n      }\n      my $subMenuCheck = 1;\n      if (defined ($$items{menuitems}{$i}{submenu}) ||\n        defined ($$items{menuitems}{$i}{callback}) ) {\n        if (defined ($$items{menuitems}{$i}{submenu})) {\n          $subMenuCheck = checkMenuConfig($$items{menuitems}{$i}{submenu});\n        }\n        printf (\"${ind}%2s) %-40s %-30s\\n\", $i,\n          $$items{menuitems}{$i}{prompt}, $v);\n      } else {\n        # Disabled items\n        printf (\"${ind}    %-40s %-30s\\n\",\n          $$items{menuitems}{$i}{prompt}, $v);\n      }\n      if ($config{EXPANDMENU} eq \"yes\" || !$subMenuCheck) {\n        if (defined ($$items{menuitems}{$i}{submenu}) ) {\n          displaySubMenuItems($$items{menuitems}{$i}{submenu},\n            $$items{menuitems}{$i}{var},\"       \");\n          print \"\\n\";\n        }\n      }\n    }\n    if (defined($$items{lastitem})) {\n      printf (\"  %2s) %-40s\\n\", $$items{lastitem}{selector},\n        $$items{lastitem}{prompt});\n    }\n    my $menuprompt = \"\\n\";\n    if (defined($$items{promptitem})) {\n      $menuprompt .= $$items{promptitem}{prompt};\n    } else {\n      $menuprompt .= \"Select \";\n    }\n    if (defined($$items{help})) {\n      $menuprompt .= \" (? - help) \";\n    }\n    print \"$menuprompt\";\n    if (defined $$items{default}) {\n      print \"[$$items{default}] \";\n    }\n    my $r = <>;\n    chomp $r;\n    if ($r eq \"\") { $r = $$items{default}; }\n    if ($r eq \"\") { next; }\n    if ($r eq $$items{lastitem}{selector}) {\n      if ($$items{lastitem}{action} eq \"quit\") {\n        if (verifyQuit()) {\n          exit 0;\n        }\n      } elsif ($$items{lastitem}{action} eq \"return\") {\n        return;\n      }\n    } elsif (defined $$items{help} && $r eq \"?\") {\n      print \"\\n\\n\";\n      print $$items{help}{helptext};\n      print \"\\n\";\n      ask(\"Press any key to continue\", \"\");\n      print \"\\n\\n\";\n    } elsif (defined $$items{promptitem} && $r eq $$items{promptitem}{selector}) {\n      if (defined $$items{promptitem}{callback}) {\n        &{$$items{promptitem}{callback}}($$items{promptitem}{arg});\n      } elsif (defined $$items{promptitem}{action}) {\n        if ($$items{promptitem}{action} eq \"quit\") {\n          if (verifyQuit()) {\n            exit 0;\n          }\n        } elsif ($$items{promptitem}{action} eq \"return\") {\n          return;\n        }\n      }\n    } elsif (defined $$items{menuitems}{$r}) {\n      print \"\\n\";\n      if (defined $$items{menuitems}{$r}{callback}) {\n        &{$$items{menuitems}{$r}{callback}}($$items{menuitems}{$r}{arg});\n      } elsif (defined ($$items{menuitems}{$r}{submenu})) {\n        displayMenu($$items{menuitems}{$r}{submenu});\n      }\n    } else {\n      ask(\"Invalid selection! - press any key to continue\", \"\");\n      print \"\\n\\n\";\n    }\n  }\n}\n\nsub createMainMenu {\n  my %mm = ();\n  $mm{createsub} = \\&createMainMenu;\n  $mm{title} = \"Main menu\";\n  $mm{help} = {\n    \"selector\" => \"?\",\n    \"prompt\" => \"Help\",\n    \"action\" => \"help\",\n    \"helptext\" =>\n      \"Main Menu help\\n\\n\".\n      \"Items marked with ** MUST BE CONFIGURED prior to applying configuration\\n\\n\".\n      \"\",\n    };\n  $mm{lastitem} = {\n    \"selector\" => \"q\",\n    \"prompt\" => \"Quit\",\n    \"action\" => \"quit\",\n    };\n  my $i = 1;\n  my $submenu = createCommonMenu(\"zimbra-core\");\n  $mm{menuitems}{$i} = {\n    \"prompt\" => \"Common Configuration:\",\n    \"submenu\" => $submenu,\n  };\n  $i++;\n  foreach my $package (@packageList) {\n    if ($package eq \"zimbra-core\") {next;}\n    if ($package eq \"zimbra-apache\") {next;}\n    if ($package eq \"zimbra-archiving\") {next;}\n    if ($package eq \"zimbra-memcached\") {next;}\n    if (defined($installedPackages{$package})) {\n      if ($package =~ /logger|spell|convertd|license-daemon/) {\n        $mm{menuitems}{$i} = {\n          \"prompt\" => \"$package:\",\n          \"var\" => \\$enabledPackages{$package},\n          \"callback\" => \\&toggleEnabled,\n          \"arg\" => $package\n        };\n        $i++;\n        next;\n      }\n      my $submenu = createPackageMenu($package);\n      $mm{menuitems}{$i} = {\n        \"prompt\" => \"$package:\",\n        \"var\" => \\$enabledPackages{$package},\n        \"submenu\" => $submenu,\n      };\n      $i++;\n    } else {\n      #push @mm, \"$package not installed\";\n    }\n  }\n  if (defined($installedPackages{\"zimbra-core\"}) && isNetwork()) {\n    # simple test to see if we are running in a VM.\n    if ( -x \"/usr/lib/vmware-tools/sbin64/vmware-checkvm\") {\n      my $rc = runAsRoot(\"/usr/lib/vmware-tools/sbin64/vmware-checkvm\");\n      if ($rc == 0) {\n        $mm{menuitems}{$i} = {\n          \"prompt\" => \"Enable VMware HA:\",\n          \"var\" => \\$config{RUNVMHA},\n          \"callback\" => \\&toggleYN,\n          \"arg\" => \"RUNVMHA\",\n          };\n        $i++;\n      }\n    }\n  }\n  if (defined($installedPackages{\"zimbra-store\"})) {\n    my $submenu = createCOSMenu(\"cos\");\n    $mm{menuitems}{$i} = {\n      \"prompt\" => \"Default Class of Service Configuration:\",\n      \"submenu\" => $submenu,\n    };\n    $i++;\n  }\n  $i = &preinstall::mainMenuExtensions(\\%mm, $i);\n#  $mm{menuitems}{r} = {\n#    \"prompt\" => \"Start servers after configuration\",\n#    \"callback\" => \\&toggleYN,\n#    \"var\" => \\$config{STARTSERVERS},\n#    \"arg\" => \"STARTSERVERS\"\n#    };\n  if ($config{EXPANDMENU} eq \"yes\") {\n    $mm{menuitems}{c} = {\n      \"prompt\" => \"Collapse menu\",\n      \"callback\" => \\&toggleYN,\n      \"arg\" => \"EXPANDMENU\"\n      };\n  } else {\n    $mm{menuitems}{x} = {\n      \"prompt\" => \"Expand menu\",\n      \"callback\" => \\&toggleYN,\n      \"arg\" => \"EXPANDMENU\"\n      };\n  }\n  # Allow save of even incomplete config\n  $mm{menuitems}{s} = {\n    \"prompt\" => \"Save config to file\",\n    \"callback\" => \\&saveConfig,\n    };\n  if (checkMenuConfig(\\%mm)) {\n    $mm{promptitem} = {\n      \"selector\" => \"a\",\n      \"prompt\" => \"*** CONFIGURATION COMPLETE - press 'a' to apply\\nSelect from menu, or press 'a' to apply config\",\n      \"callback\" => \\&applyConfig,\n      };\n  } else {\n    $mm{promptitem} = {\n      \"selector\" => \"qqazyre\",\n      \"prompt\" => \"Address unconfigured (**) items \",\n      \"callback\" => \\&applyConfig,\n      };\n    if (!ldapIsAvailable() && $ldapConfigured) {\n      $mm{promptitem}{prompt} .= \"or correct ldap configuration \";\n    }\n    if ($config{LDAPHOST} ne $config{HOSTNAME} && !ldapIsAvailable() && isInstalled(\"zimbra-ldap\")) {\n      $mm{promptitem}{prompt} .= \"and enable ldap replication on ldap master \"\n        if (checkLdapReplicationEnabled($config{zimbra_ldap_userdn},$config{LDAPADMINPASS}));\n    }\n  }\n\n  return \\%mm;\n}\n\nsub checkMenuConfig {\n  my $items = shift;\n\n  my $needldapverified = 0;\n\n  foreach my $i (sort menuSort keys %{$$items{menuitems}}) {\n    my $v;\n    my $ind = \"  \";\n    if (defined $$items{menuitems}{$i}{var}) {\n      $v = ${$$items{menuitems}{$i}{var}};\n      if ($v eq \"\" || $v eq \"none\" || $v eq \"UNSET\" || $v eq \"Not Verified\") { return 0; }\n      foreach my $var (qw(LDAPHOST LDAPPORT)) {\n        if ($$items{menuitems}{$i}{var} == \\$config{$var}) {\n          $needldapverified = 1;\n        }\n      }\n    }\n    if (defined ($$items{menuitems}{$i}{submenu}) ) {\n      if (!checkMenuConfig($$items{menuitems}{$i}{submenu})) {\n        return 0;\n      }\n    }\n  }\n  if ($needldapverified) {\n    return 1 if ($config{LDAPHOST} eq $config{HOSTNAME} && !$ldapConfigured);\n    return 0 if (!ldapIsAvailable());\n  }\n  if (defined($installedPackages{\"zimbra-store\"}) && $config{SERVICEWEBAPP} eq \"no\" && $config{UIWEBAPPS} eq \"no\" ) {\n    $config{SERVICEWEBAPP}=\"UNSET\";\n    $config{UIWEBAPPS}=\"UNSET\";\n    return 0;\n  }\n  return 1;\n}\n\nsub ldapIsAvailable {\n  my $failedcheck=0;\n  if (($config{LDAPHOST} eq $config{HOSTNAME}) && !$ldapConfigured) {\n    detail(\"This is the ldap master and ldap hasn't been configured yet.\");\n    return 0;\n  }\n\n  # check zimbra ldap admin user binding to the master\n  if ($config{LDAPADMINPASS} eq \"\" || $config{LDAPPORT} eq \"\" || $config{LDAPHOST} eq \"\") {\n    detail ( \"ldap configuration not complete\\n\" );\n    return 0;\n  }\n\n  if (checkLdapBind($config{zimbra_ldap_userdn},$config{LDAPADMINPASS})) {\n    detail (\"Couldn't bind to $config{LDAPHOST} as $config{zimbra_ldap_userdn}\\n\");\n    $config{LDAPADMINPASSSET} = \"Not Verified\";\n    $failedcheck++;\n  } else {\n    detail (\"Verified $config{zimbra_ldap_userdn} on $config{LDAPHOST}.\\n\");\n    $config{LDAPADMINPASSSET} = \"set\";\n    setLocalConfig (\"zimbra_ldap_password\", $config{LDAPADMINPASS});\n    setLdapDefaults() if ($config{LDAPHOST} ne $config{HOSTNAME});\n  }\n\n  # check zmbes searcher binding to the master\n  if ($config{LDAPHOST} eq $config{HOSTNAME}) {\n    if ($config{ldap_bes_searcher_password} eq \"\") {\n      detail (\"BES searcher configuration not complete\\n\");\n      $failedcheck++;\n    }\n    my $binduser = \"uid=zmbes-searcher,cn=appaccts,$config{ldap_dit_base_dn_config}\";\n    if (checkLdapBind($binduser,$config{ldap_bes_searcher_password})) {\n      detail (\"Couldn't bind to $config{LDAPHOST} as $binduser\\n\");\n      $config{LDAPBESSEARCHSET} = \"Not Verified\";\n      $failedcheck++;\n    } else {\n      detail (\"Verified $binduser on $config{LDAPHOST}.\\n\");\n      $config{LDAPBESSEARCHSET} = \"set\";\n    }\n  }\n  # check nginx user binding to the master\n  if (isInstalled(\"zimbra-proxy\")) {\n    if ($config{ldap_nginx_password} eq \"\") {\n      detail (\"nginx configuration not complete\\n\");\n      $failedcheck++;\n    }\n    my $binduser = \"uid=zmnginx,cn=appaccts,$config{ldap_dit_base_dn_config}\";\n    if (checkLdapBind($binduser,$config{ldap_nginx_password})) {\n      detail (\"Couldn't bind to $config{LDAPHOST} as $binduser\\n\");\n      $config{LDAPNGINXPASSSET} = \"Not Verified\";\n      $failedcheck++;\n    } else {\n      detail (\"Verified $binduser on $config{LDAPHOST}.\\n\");\n      $config{LDAPNGINXPASSSET} = \"set\";\n    }\n  }\n\n  # check postfix and amavis user binding to the master\n  if (isInstalled(\"zimbra-mta\")) {\n    if ($config{LDAPPOSTPASS} eq \"\" || $config{LDAPAMAVISPASS} eq \"\") {\n      detail (\"mta configuration not complete\\n\");\n      $failedcheck++;\n    }\n    my $binduser = \"uid=zmpostfix,cn=appaccts,$config{ldap_dit_base_dn_config}\";\n    if (checkLdapBind($binduser,$config{LDAPPOSTPASS})) {\n      detail (\"Couldn't bind to $config{LDAPHOST} as $binduser\\n\");\n      $config{LDAPPOSTPASSSET} = \"Not Verified\";\n      detail (\"Setting LDAPPOSTPASSSET to $config{LDAPPOSTPASSSET}\") if $debug;\n      $failedcheck++;\n    } else {\n      detail (\"Verified $binduser on $config{LDAPHOST}.\\n\");\n      $config{LDAPPOSTPASSSET} = \"set\";\n    }\n    my $binduser = \"uid=zmamavis,cn=appaccts,$config{ldap_dit_base_dn_config}\";\n    if (checkLdapBind($binduser,$config{LDAPAMAVISPASS})) {\n      detail (\"Couldn't bind to $config{LDAPHOST} as $binduser\\n\");\n      $config{LDAPAMAVISPASSSET} = \"Not Verified\";\n      detail (\"Setting LDAPAMAVISPASSSET to $config{LDAPAMAVISPASSSET}\") if $debug;\n      $failedcheck++;\n    } else {\n      detail (\"Verified $binduser on $config{LDAPHOST}.\\n\");\n      $config{LDAPAMAVISPASSSET}=\"set\";\n    }\n  }\n\n  # check replication user binding to master\n  if (isInstalled(\"zimbra-ldap\") && $config{LDAPHOST} ne $config{HOSTNAME}) {\n    if ($config{LDAPREPPASS} eq \"\") {\n      detail (\"ldap configuration not complete. Ldap Replication password is not set.\\n\");\n      $failedcheck++;\n    }\n    my $binduser = \"uid=zmreplica,cn=admins,$config{ldap_dit_base_dn_config}\";\n    if (checkLdapBind($binduser,$config{LDAPREPPASS})) {\n      detail (\"Couldn't bind to $config{LDAPHOST} as $binduser\\n\");\n      $config{LDAPREPPASSSET}=\"Not Verified\";\n      detail (\"Setting LDAPREPPASSSET to $config{LDAPREPPASSSET}\") if $debug;\n      $failedcheck++;\n    } else {\n      detail (\"Verified $binduser on $config{LDAPHOST}.\\n\");\n      $config{LDAPREPPASSSET}=\"set\";\n    }\n    if (checkLdapReplicationEnabled($config{zimbra_ldap_userdn},$config{LDAPADMINPASS})) {\n      detail (\"ldap configuration not complete. Unable to verify ldap replication is enabled on $config{LDAPHOST}\\n\");\n      $failedcheck++;\n    } else {\n      detail (\"ldap replication ability verified\\n\");\n    }\n  }\n  return ($failedcheck > 0) ? 0 : 1;\n}\n\nsub checkLdapBind() {\n  my ($binduser,$bindpass) = @_;\n\n  detail( \"Checking ldap on $config{LDAPHOST}:$config{LDAPPORT}\");\n  my $ldap;\n  my $ldap_secure = (($config{LDAPPORT} == \"636\") ? \"s\" : \"\");\n  my $ldap_url = \"ldap${ldap_secure}://$config{LDAPHOST}:$config{LDAPPORT}\";\n  unless($ldap = Net::LDAP->new($ldap_url)) {\n    detail(\"failed: Unable to contact ldap at $ldap_url: $!\");\n    return 1;\n  }\n\n  if ($ldap_secure ne \"s\" && $config{zimbra_require_interprocess_security}) {\n    $starttls = 1;\n    my $result = $ldap->start_tls(verify=>'none');\n    if ($result->code()) {\n      detail(\"Unable to startTLS: $!\\n\");\n      detail(\"Disabling the requirement for interprocess security.\\n\");\n      $config{zimbra_require_interprocess_security} = 0;\n      $config{ZIMBRA_REQ_SECURITY}=\"no\";\n      $starttls = 0;\n    }\n  } else {\n    $starttls = 0;\n  }\n  my $result = $ldap->bind($binduser, password => $bindpass);\n  if ($result->code()) {\n    detail (\"Unable to bind to $ldap_url with user $binduser: $!\");\n    return 1;\n  } else {\n    $ldap->unbind;\n    detail (\"Verified ldap running at $ldap_url\\n\");\n    if ($newinstall) {\n      setLocalConfig(\"ldap_url\", $ldap_url);\n      setLocalConfig(\"ldap_starttls_supported\", $starttls);\n      setLocalConfig(\"zimbra_require_interprocess_security\", $config{zimbra_require_interprocess_security});\n    }\n    setLocalConfig(\"ssl_allow_untrusted_certs\", \"true\") if ($newinstall);\n    return 0;\n  }\n\n}\n\nsub checkLdapReplicationEnabled() {\n  my ($binduser,$bindpass) = @_;\n  detail( \"Checking ldap replication is enabled on $config{LDAPHOST}:$config{LDAPPORT}\");\n  my $ldap;\n  my $ldap_secure = (($config{LDAPPORT} == \"636\") ? \"s\" : \"\");\n  my $ldap_url = \"ldap${ldap_secure}://$config{LDAPHOST}:$config{LDAPPORT}\";\n  unless($ldap = Net::LDAP->new($ldap_url)) {\n    detail(\"failed: Unable to contact ldap at $ldap_url: $!\");\n    return 1;\n  }\n  if ($ldap_secure ne \"s\" && $starttls) {\n    my $result = $ldap->start_tls(verify=>'none');\n    if ($result->code()) {\n      detail(\"Unable to startTLS: $!\\n\");\n      detail(\"Disabling the requirement for interprocess security.\\n\");\n      $config{zimbra_require_interprocess_security} = 0;\n      $config{ZIMBRA_REQ_SECURITY}=\"no\";\n      $starttls = 0;\n    }\n  }\n  my $result = $ldap->bind($binduser, password => $bindpass);\n  if ($result->code()) {\n    detail (\"Unable to bind to $ldap_url with user $binduser: $!\");\n    return 1;\n  } else {\n    my $result = $ldap->search(base=>\"cn=accesslog\", scope=>\"base\", filter=>\"cn=accesslog\", attrs=>['cn']);\n    if ($result->code()) {\n      detail(\"Unable to find accesslog database on master.\\n\");\n      if ($config{LDAPREPLICATIONTYPE} eq \"replica\") {\n        detail(\"Please run zmldapenablereplica on the master.\\n\");\n      } elsif ($config{LDAPREPLICATIONTYPE} eq \"mmr\") {\n        detail(\"Please run zmldapenable-mmr on the master.\\n\");\n      }\n      return 1;\n    } else {\n      detail(\"Verified ability to query accesslog on master.\\n\");\n    }\n  }\n  return 0;\n}\n\nsub runAsRoot {\n  my $cmd = shift;\n  if ($cmd =~ /ldappass/ || $cmd =~ /init/ || $cmd =~ /zmprov -r -m -l ca/) {\n    # Suppress passwords in log file\n    my $c = (split ' ', $cmd)[0];\n    detail ( \"*** Running as root user: $c\\n\" );\n  } else {\n    detail ( \"*** Running as root user: $cmd\\n\" );\n  }\n  my $rc;\n  $rc = 0xffff & system(\"$cmd >> $logfile 2>&1\");\n  return $rc;\n}\n\nsub runAsZimbra {\n  my $cmd = shift;\n  if ($cmd =~ /ldappass/ || $cmd =~ /init/ || $cmd =~ /zmprov -r -m -l ca/ || $cmd =~ /zmlicense/) {\n    # Suppress passwords in log file\n    my $c = (split ' ', $cmd)[0];\n    detail ( \"*** Running as zimbra user: $c\\n\" );\n  } else {\n    detail ( \"*** Running as zimbra user: $cmd\\n\" );\n  }\n  my $rc;\n  $rc = 0xffff & system(\"$SU \\\"$cmd\\\" >> $logfile 2>&1\");\n  return $rc;\n}\n\nsub runAsZimbraWithOutput {\n  my $cmd = shift;\n  if ($cmd =~ /ldappass/ || $cmd =~ /init/ || $cmd =~ /zmprov -r -m -l ca/) {\n    # Suppress passwords in log file\n    my $c = (split ' ', $cmd)[0];\n    detail ( \"*** Running as zimbra user: $c\\n\" );\n  } else {\n    detail ( \"*** Running as zimbra user: $cmd\\n\" );\n  }\n  system(\"$SU \\\"$cmd\\\"\");\n  my $exit_value = $? >> 8;\n  my $signal_num = $? & 127;\n  my $dumped_core = $? & 128;\n  detail (\"DEBUG: exit status from cmd was $exit_value\") if $debug;\n  return $exit_value;\n}\n\nsub getLocalConfig {\n  my ($key,$force) = @_;\n\n  return $main::loaded{lc}{$key}\n    if (exists $main::loaded{lc}{$key} && !$force);\n\n  detail ( \"Getting local config $key\" );\n  my $val = qx(/opt/zimbra/bin/zmlocalconfig -x -s -m nokey ${key} 2> /dev/null);\n  chomp $val;\n  detail (\"DEBUG: LC Loaded $key=$val\") if $debug;\n  $main::loaded{lc}{$key} = $val;\n  return $val;\n}\n\nsub getLocalConfigRaw {\n  my ($key,$force) = @_;\n\n  return $main::loaded{lc}{$key}\n    if (exists $main::loaded{lc}{$key} && !$force);\n\n  detail ( \"Getting local config $key\" );\n  my $val = qx(/opt/zimbra/bin/zmlocalconfig -s -m nokey ${key} 2> /dev/null);\n  chomp $val;\n  detail (\"DEBUG: LC Loaded $key=$val\") if $debug;\n  $main::loaded{lc}{$key} = $val;\n  return $val;\n}\n\nsub deleteLocalConfig {\n  my $key = shift;\n\n  detail ( \"Deleting local config $key\" );\n  my $rc = runAsZimbra(\"/opt/zimbra/bin/zmlocalconfig -u ${key} 2> /dev/null\");\n  if ($rc == 0) {\n    detail (\"DEBUG: deleted localconfig key $key\") if $debug;\n    delete($main::loaded{lc}{$key}) if (exists $main::loaded{lc}{$key});\n    return 1;\n  } else {\n    detail (\"DEBUG: failed to deleted localconfig key $key\") if $debug;\n    return undef\n  }\n}\n\nsub setLocalConfig {\n  my $key = shift;\n  my $val = shift;\n\n  if (exists $main::saved{lc}{$key} && $main::saved{lc}{$key} eq $val) {\n    detail(\"Skipping update of unchanged value for $key=$val.\");\n    return;\n  }\n  detail ( \"Setting local config $key to $val\" );\n  $main::saved{lc}{$key} = $val;\n  $main::loaded{lc}{$key} = $val;\n  $val =~ s/\\$/\\\\\\$/g;\n  runAsZimbra(\"/opt/zimbra/bin/zmlocalconfig -f -e ${key}=\\'${val}\\' 2> /dev/null\");\n}\n\nsub updateKeyValue {\n  my ($sec,$key,$val,$sub) = @_;\n  if ($key =~ /^\\+(.*)/) {\n    # TODO remove duplicates\n    $main::loaded{$sec}{$sub}{$1}=\"$main::loaded{$sec}{$sub}{$1}\\n$val\";\n    $main::saved{$sec}{$sub}{$1}=$main::loaded{$sec}{$sub}{$1};\n  } elsif ($key =~ /^-(.*)/) {\n    if (exists $main::loaded{$sec}{$sub}{$1}) {\n      my %tmp = map { $_ => 1 } split(/\\n/, $main::loaded{$sec}{$sub}{$1});\n      delete $tmp{$val};\n      $main::loaded{$sec}{$sub}{$1}=join \"\\n\", keys %tmp;\n      $main::saved{$sec}{$sub}{$1}=$main::loaded{$sec}{$sub}{$1};\n    }\n  } else {\n    $main::loaded{$sec}{$sub}{$key}=$val;\n    $main::saved{$sec}{$sub}{$key}=$val;\n  }\n}\n\nsub ifKeyValueEquate {\n  my ($sec,$key,$val,$sub) = @_;\n  $key=$1 if ($key =~ /^[+|-](.*)/);\n  detail(\"Checking to see if $key=$val has changed for $sec $sub\\n\") if $debug;\n  if (exists $main::saved{$sec}{$sub}{$key} && $main::saved{$sec}{$sub}{$key} eq $val) {\n    #detail(\"DEBUG: \\\"$main::saved{$sec}{$sub}{$key}\\\" eq \\\"$val\\\"\\n\") if $debug;\n    return 1;\n  } else {\n    #detail(\"DEBUG: \\\"$main::saved{$sec}{$sub}{$key}\\\" ne \\\"$val\\\"\\n\") if $debug;\n    return 0;\n  }\n}\n\n#\n#  setLdapGlobalConfig(key, val [, key, val ...])\n#\nsub setLdapGlobalConfig {\n  my $zmprov_arg_str;\n  my $sec=\"gcf\";\n  while (@_){\n    my $key = shift;\n    my $val = shift;\n    detail(\"entering function: $sec $key=$val\\n\");\n    if (ifKeyValueEquate($sec,$key,$val,$sec)) {\n      detail(\"Skipping update of unchanged value for $key=$val.\");\n    } else {\n      detail(\"Updating cached global config attribute $key=$val\");\n      updateKeyValue($sec,$key,$val,$sec);\n      $zmprov_arg_str .= \" $key \\'$val\\'\";\n    }\n  }\n  if ($zmprov_arg_str) {\n    my $rc = runAsZimbra(\"$ZMPROV mcf $zmprov_arg_str\");\n    return $rc;\n  }\n}\n\n#\n# setLdapServerConfig([server,] key, val [, key, val ...])\n#\nsub setLdapServerConfig {\n  my $zmprov_arg_str;\n  my $sec=\"gs\";\n  my $server;\n\n  if (($#_ % 2) == 0) {\n    $server = shift;\n  } else {\n    $server = $config{HOSTNAME};\n  }\n  return undef if ($server eq \"\");\n  while (@_) {\n    my $key = shift;\n    my $val = shift;\n\n    if (ifKeyValueEquate($sec,$key,$val,$server)) {\n      detail(\"Skipping update of unchanged value for $key=$val.\");\n    } else {\n      detail(\"Updating cached config attribute for Server $server: $key=$val\");\n      updateKeyValue($sec,$key,$val,$server);\n      $zmprov_arg_str .= \" $key \\'$val\\'\";\n    }\n  }\n\n  if ($zmprov_arg_str) {\n    my $rc = runAsZimbra(\"$ZMPROV ms $server $zmprov_arg_str\");\n    return $rc;\n  }\n}\n\n\n#\n# setLdapDomainConfig([domain,] key, val [, key, val ...])\n#\nsub setLdapDomainConfig {\n  my $zmprov_arg_str;\n  my $domain;\n\n  if (($#_ % 2) == 0) {\n    $domain = shift;\n  } else {\n    $domain = getLdapConfigValue(\"zimbraDefaultDomainName\");\n  }\n  return undef if ($domain eq \"\");\n\n  my $sec=\"domain\";\n  while (@_) {\n    my $key = shift;\n    my $val = shift;\n    if (ifKeyValueEquate($sec,$key,$val,$domain)) {\n      detail(\"Skipping update of unchanged value for $key=$val.\");\n    } else {\n      detail(\"Updating cached config attribute for Domain $domain: $key=$val\");\n      updateKeyValue($sec,$key,$val,$domain);\n      $zmprov_arg_str .= \" $key \\'$val\\'\";\n    }\n  }\n\n  if ($zmprov_arg_str) {\n    my $rc = runAsZimbra(\"$ZMPROV md $domain $zmprov_arg_str\");\n    return $rc;\n  }\n}\n\n#\n# setLdapCOSConfig([cos,] key, val [, key, val ...])\n#\nsub setLdapCOSConfig {\n  my $zmprov_arg_str;\n  my $cos;\n\n  if (($#_ % 2) == 0) {\n    $cos = shift;\n  } else {\n    $cos = 'default';\n  }\n\n  my $sec=\"gc\";\n  while (@_) {\n    my $key = shift;\n    my $val = shift;\n    if (ifKeyValueEquate($sec,$key,$val,$cos)) {\n      detail(\"Skipping update of unchanged value for $key=$val.\");\n\t} else {\n      detail(\"Updating cached config attribute for COS $cos: $key=$val\");\n      updateKeyValue($sec,$key,$val,$cos);\n      $zmprov_arg_str .= \" $key \\'$val\\'\";\n    }\n  }\n\n  if ($zmprov_arg_str) {\n    my $rc = runAsZimbra(\"$ZMPROV mc $cos $zmprov_arg_str\");\n    return $rc;\n  }\n}\n\n#\n# setLdapAccountConfig(acct, key, val [, key, val ...])\n#\nsub setLdapAccountConfig {\n  my $zmprov_arg_str;\n  my $acct;\n  if (($#_ % 2) == 0) {\n    $acct = shift;\n  }\n  return undef if ($acct eq \"\");\n\n  my $sec=\"acct\";\n  while (@_) {\n    my $key = shift;\n    my $val = shift;\n    if (ifKeyValueEquate($sec,$key,$val,$acct)) {\n      detail(\"Skipping update of unchanged value for $key=$val.\");\n    } else {\n      detail(\"Updating cached config attribute for Account $acct: $key=$val\");\n      updateKeyValue($sec,$key,$val,$acct);\n      $zmprov_arg_str .= \" $key \\'$val\\'\";\n    }\n  }\n\n  if ($zmprov_arg_str) {\n    my $rc = runAsZimbra(\"$ZMPROV ma $acct $zmprov_arg_str\");\n    return $rc;\n  }\n}\n\nsub configLCValues {\n\n  if ($configStatus{configLCValues} eq \"CONFIGURED\") {\n    configLog(\"configLCValues\");\n    return 0;\n  }\n\n  progress (\"Setting local config values...\");\n  setLocalConfig (\"zimbra_server_hostname\", lc($config{HOSTNAME}));\n  setLocalConfig (\"zimbra_require_interprocess_security\", $config{zimbra_require_interprocess_security});\n\n  if($newinstall) {\n    if ($config{LDAPPORT} == 636) {\n      setLocalConfig (\"ldap_master_url\", \"ldaps://$config{LDAPHOST}:$config{LDAPPORT}\");\n      setLocalConfig (\"ldap_url\", \"ldaps://$config{LDAPHOST}:$config{LDAPPORT}\");\n      setLocalConfig (\"ldap_starttls_supported\", 0);\n    } else {\n      setLocalConfig (\"ldap_master_url\", \"ldap://$config{LDAPHOST}:$config{LDAPPORT}\");\n      if ($config{ldap_url} eq \"\") {\n        setLocalConfig (\"ldap_url\", \"ldap://$config{LDAPHOST}:$config{LDAPPORT}\");\n        if ($config{zimbra_require_interprocess_security}) {\n          setLocalConfig (\"ldap_starttls_supported\", 1);\n        } else {\n          setLocalConfig (\"ldap_starttls_supported\", 0);\n        }\n      } else {\n        setLocalConfig (\"ldap_url\", \"$config{ldap_url}\");\n        if ($config{ldap_url} !~ /^ldaps/i && $config{zimbra_require_interprocess_security}) {\n          setLocalConfig (\"ldap_starttls_supported\", 1);\n        } else {\n          setLocalConfig (\"ldap_starttls_supported\", 0);\n        }\n      }\n    }\n  }\n\n  # set default zmprov bahaviour\n  if (isEnabled(\"zimbra-store\") && isStoreServiceNode()) {\n    setLocalConfig (\"zimbra_zmprov_default_to_ldap\", \"false\");\n  } else {\n    setLocalConfig (\"zimbra_zmprov_default_to_ldap\", \"true\");\n  }\n\n  setLocalConfig (\"ldap_port\", \"$config{LDAPPORT}\");\n  setLocalConfig (\"ldap_host\", \"$config{LDAPHOST}\");\n\n  my $uid = qx(id -u zimbra);\n  chomp $uid;\n  my $gid = qx(id -g zimbra);\n  chomp $gid;\n  setLocalConfig (\"zimbra_uid\", $uid);\n  setLocalConfig (\"zimbra_gid\", $gid);\n  setLocalConfig (\"zimbra_user\", \"zimbra\");\n\n  if (defined $config{AVUSER}) {\n    setLocalConfig (\"av_notify_user\", $config{AVUSER})\n  }\n  if (defined $config{AVDOMAIN}) {\n    setLocalConfig (\"av_notify_domain\", $config{AVDOMAIN})\n  }\n\n  setLocalConfig (\"ssl_allow_untrusted_certs\", \"true\") if ($newinstall);\n  setLocalConfig (\"ssl_allow_mismatched_certs\", \"true\") if ($newinstall);\n  setLocalConfig (\"ssl_default_digest\", $config{ssl_default_digest});\n  setLocalConfig (\"mailboxd_java_heap_size\", $config{MAILBOXDMEMORY});\n  setLocalConfig (\"mailboxd_directory\", $config{mailboxd_directory});\n  setLocalConfig (\"mailboxd_keystore\", $config{mailboxd_keystore});\n  setLocalConfig (\"mailboxd_server\", $config{mailboxd_server});\n  setLocalConfig (\"mailboxd_truststore\", \"$config{mailboxd_truststore}\");\n  setLocalConfig (\"mailboxd_truststore_password\", \"$config{mailboxd_truststore_password}\");\n  setLocalConfig (\"mailboxd_keystore_password\", \"$config{mailboxd_keystore_password}\");\n  setLocalConfig (\"zimbra_ldap_userdn\", \"$config{zimbra_ldap_userdn}\");\n  setLocalConfig (\"ldap_dit_base_dn_config\", \"$config{ldap_dit_base_dn_config}\")\n    if ($config{ldap_dit_base_dn_config} ne \"cn=zimbra\");\n\n  configLog (\"configLCValues\");\n\n  progress (\"done.\\n\");\n\n}\n\nsub configCASetup {\n\n  if ($configStatus{configCASetup} eq \"CONFIGURED\" && -d \"/opt/zimbra/ssl/zimbra/ca\" ) {\n    configLog(\"configCASetup\");\n    return 0;\n  }\n\n  if ($config{LDAPHOST} ne $config{HOSTNAME}) {\n    # fetch it from ldap if ldap has been configed\n    progress(\"Updating ldap_root_password and zimbra_ldap_password...\");\n    setLocalConfig (\"ldap_root_password\", $config{LDAPROOTPASS});\n    setLocalConfig (\"zimbra_ldap_password\", $config{LDAPADMINPASS});\n    progress ( \"done.\\n\" );\n  }\n  progress ( \"Setting up CA...\" );\n  if (! $newinstall) {\n    if (-f \"/opt/zimbra/conf/ca/ca.pem\") {\n      my $rc = runAsRoot(\"/opt/zimbra/common/bin/openssl verify -purpose sslserver -CAfile /opt/zimbra/conf/ca/ca.pem /opt/zimbra/conf/ca/ca.pem | egrep \\\"^error 10\\\"\");\n      $needNewCert = \"-new\" if ($rc == 0);\n    }\n  }\n\n  # regenerate the certificate authority if this is the ldap master and\n  # either the ca is expired from the test above or the ca directory doesn't exist.\n  my $needNewCA;\n  if (isLdapMaster()) {\n    $needNewCA = \"-new\" if (! -d \"/opt/zimbra/ssl/zimbra/ca\" || $needNewCert eq \"-new\");\n  }\n\n  # we are going to download a new CA or otherwise create one so we need to regenerate the self signed cert.\n  $needNewCert = \"-new\" if (! -d \"/opt/zimbra/ssl/zimbra/ca\");\n\n  my $rc = runAsZimbra(\"/opt/zimbra/bin/zmcertmgr createca $needNewCA\");\n  if ($rc != 0) {\n    progress ( \"failed.\\n\" );\n    exit 1;\n  } else {\n    progress ( \"done.\\n\" );\n  }\n\n  progress ( \"Deploying CA to /opt/zimbra/conf/ca ...\" );\n  my $rc = runAsZimbra(\"/opt/zimbra/bin/zmcertmgr deployca -localonly\");\n  if ($rc != 0) {\n    progress ( \"failed.\\n\" );\n    exit 1;\n  } else {\n    progress ( \"done.\\n\" );\n  }\n\n\n  configLog(\"configCASetup\");\n}\n\nsub configSetupLdap {\n\n  if ($configStatus{configSetupLdap} eq \"CONFIGURED\") {\n    detail(\"ldap already configured bypassing configuration\\n\");\n    configLog(\"configSetupLdap\");\n    return 0;\n  }\n\n  if (!$ldapConfigured && isEnabled(\"zimbra-ldap\") && ! -f \"/opt/zimbra/.enable_replica\" && $newinstall && ($config{LDAPHOST} eq $config{HOSTNAME})) {\n    progress ( \"Initializing ldap...\" ) ;\n    if (my $rc = runAsZimbra(\"/opt/zimbra/libexec/zmldapinit \\'$config{LDAPROOTPASS}\\' \\'$config{LDAPADMINPASS}\\'\")) {\n      progress ( \"failed. ($rc)\\n\" );\n      failConfig();\n    } else {\n      progress ( \"done.\\n\" );\n      if ($ldapRepChanged == 1) {\n         progress ( \"Setting replication password...\" );\n         runAsZimbra (\"/opt/zimbra/bin/zmldappasswd -l \\'$config{LDAPREPPASS}\\'\");\n         progress ( \"done.\\n\" );\n      }\n      if ($ldapPostChanged == 1) {\n         progress ( \"Setting Postfix password...\" );\n         runAsZimbra (\"/opt/zimbra/bin/zmldappasswd -p \\'$config{LDAPPOSTPASS}\\'\");\n         progress ( \"done.\\n\" );\n      }\n      if ($ldapAmavisChanged == 1) {\n         progress ( \"Setting amavis password...\" );\n         runAsZimbra (\"/opt/zimbra/bin/zmldappasswd -a \\'$config{LDAPAMAVISPASS}\\'\");\n         progress ( \"done.\\n\" );\n      }\n      if ($ldapNginxChanged == 1) {\n         progress ( \"Setting nginx password...\" );\n         runAsZimbra (\"/opt/zimbra/bin/zmldappasswd -n \\'$config{ldap_nginx_password}\\'\");\n         progress ( \"done.\\n\" );\n      }\n      if ($ldapBesSearcherChanged == 1) {\n         progress ( \"Setting BES searcher password...\" );\n         runAsZimbra (\"/opt/zimbra/bin/zmldappasswd -b \\'$config{ldap_bes_searcher_password}\\'\");\n         progress ( \"done.\\n\" );\n      }\n    }\n    if ($config{FORCEREPLICATION} eq \"yes\") {\n      my $rc = runAsZimbra (\"/opt/zimbra/libexec/zmldapenablereplica\");\n      my $file=\"/opt/zimbra/.enable_replica\";\n      open(ER,\">>$file\");\n      close ER;\n    }\n    if (isNetwork()) {\n      setLdapGlobalConfig(\"zimbraRedoLogDeleteOnRollover\", \"FALSE\");\n    }\n  } elsif (isEnabled(\"zimbra-ldap\")) {\n    my $rc;\n    if ($newinstall) {\n      $rc = runAsZimbra (\"/opt/zimbra/libexec/zmldapapplyldif\");\n    }\n    if (!$newinstall) {\n      $rc = runAsZimbra (\"/opt/zimbra/libexec/zmldapupdateldif\");\n    }\n    # enable replica for both new and upgrade installs if we are adding ldap\n    if ($config{LDAPHOST} ne $config{HOSTNAME} || -f \"/opt/zimbra/.enable_replica\") {\n      progress(\"Updating ldap_root_password and zimbra_ldap_password...\");\n      setLocalConfig (\"ldap_root_password\", $config{LDAPROOTPASS});\n      setLocalConfig (\"zimbra_ldap_password\", $config{LDAPADMINPASS});\n      setLocalConfig (\"ldap_replication_password\", \"$config{LDAPREPPASS}\");\n      if($newinstall && $config{LDAPREPLICATIONTYPE} eq \"mmr\") {\n        if ($ldapPostChanged == 1) {\n           progress ( \"Setting Postfix password...\" );\n           runAsZimbra (\"/opt/zimbra/bin/zmldappasswd -p \\'$config{LDAPPOSTPASS}\\'\");\n           progress ( \"done.\\n\" );\n        }\n        if ($ldapAmavisChanged == 1) {\n           progress ( \"Setting amavis password...\" );\n           runAsZimbra (\"/opt/zimbra/bin/zmldappasswd -a \\'$config{LDAPAMAVISPASS}\\'\");\n           progress ( \"done.\\n\" );\n        }\n        if ($ldapNginxChanged == 1) {\n           progress ( \"Setting nginx password...\" );\n           runAsZimbra (\"/opt/zimbra/bin/zmldappasswd -n \\'$config{ldap_nginx_password}\\'\");\n           progress ( \"done.\\n\" );\n        }\n      }\n      progress(\"done.\\n\");\n      progress ( \"Enabling ldap replication...\" );\n      if ( ! -f \"/opt/zimbra/.enable_replica\" ) {\n         if ($newinstall && $config{LDAPREPLICATIONTYPE} eq \"mmr\") {\n           setLocalConfig (\"ldap_is_master\", \"true\");\n           my $ldapMasterUrl = getLocalConfig (\"ldap_master_url\");\n           my $proto = \"ldap\";\n           if ($config{LDAPPORT} == \"636\") {\n             $proto=\"ldaps\";\n           }\n           setLocalConfig(\"ldap_url\", \"$proto://$config{HOSTNAME}:$config{LDAPPORT} $ldapMasterUrl\");\n           if ($ldapMasterUrl !~ /\\/$/) {\n             $ldapMasterUrl=$ldapMasterUrl.\"/\";\n           }\n           runAsZimbra (\"/opt/zimbra/bin/ldap start\");\n           $rc = runAsZimbra (\"/opt/zimbra/libexec/zmldapenable-mmr -s $config{LDAPSERVERID} -m $ldapMasterUrl\");\n         } else {\n           $rc = runAsZimbra (\"/opt/zimbra/libexec/zmldapenablereplica\");\n         }\n         my $file=\"/opt/zimbra/.enable_replica\";\n         open(ER,\">>$file\");\n         close ER;\n      }\n      if ($rc == 0) {\n        if (!isEnabled(\"zimbra-store\")) {\n          $config{DOCREATEADMIN} = \"no\";\n        }\n        $config{DOCREATEDOMAIN} = \"no\";\n        progress ( \"done.\\n\" );\n        progress(\"Stopping ldap...\");\n        runAsZimbra (\"/opt/zimbra/bin/ldap stop\");\n        progress(\"done.\\n\");\n        startLdap();\n      } else {\n        progress (\"failed.\\n\");\n        progress (\"You will have to correct the problem and manually enable replication.\\n\");\n        progress (\"Disabling ldap on $config{HOSTNAME}...\");\n        my $rc = setLdapServerConfig(\"-zimbraServiceEnabled\", \"ldap\");\n        progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n        progress(\"Stopping ldap...\");\n        runAsZimbra (\"/opt/zimbra/bin/ldap stop\");\n        progress(\"done.\\n\");\n      }\n    }\n\n\n    # zmldappasswd starts ldap and re-applies the ldif\n    if ($ldapRootPassChanged || $ldapAdminPassChanged || $ldapRepChanged || $ldapPostChanged || $ldapAmavisChanged || $ldapNginxChanged || $ldapBesSearcherChanged) {\n      if ($ldapRootPassChanged) {\n         progress ( \"Setting ldap root password...\" );\n         runAsZimbra (\"/opt/zimbra/bin/zmldappasswd -r $config{LDAPROOTPASS}\");\n         progress ( \"done.\\n\" );\n      }\n      if ($ldapAdminPassChanged) {\n         progress ( \"Setting ldap admin password...\" );\n         if ($config{LDAPHOST} eq $config{HOSTNAME} ) {\n           runAsZimbra (\"/opt/zimbra/bin/zmldappasswd $config{LDAPADMINPASS}\");\n         } else {\n           setLocalConfig (\"zimbra_ldap_password\", \"$config{LDAPADMINPASS}\");\n         }\n         progress ( \"done.\\n\" );\n      }\n      if ($ldapRepChanged == 1) {\n         progress ( \"Setting replication password...\" );\n         if ($config{LDAPHOST} eq $config{HOSTNAME} ) {\n           runAsZimbra (\"/opt/zimbra/bin/zmldappasswd -l $config{LDAPREPPASS}\");\n         } else {\n           setLocalConfig (\"ldap_replication_password\", \"$config{LDAPREPPASS}\");\n         }\n         progress ( \"done.\\n\" );\n      }\n      if ($ldapPostChanged == 1) {\n         progress ( \"Setting Postfix password...\" );\n         if ($config{LDAPHOST} eq $config{HOSTNAME} ) {\n           runAsZimbra (\"/opt/zimbra/bin/zmldappasswd -p $config{LDAPPOSTPASS}\");\n         } else {\n           setLocalConfig (\"ldap_postfix_password\", \"$config{LDAPPOSTPASS}\");\n         }\n         progress ( \"done.\\n\" );\n      }\n      if ($ldapAmavisChanged == 1) {\n         progress ( \"Setting amavis password...\" );\n         if ($config{LDAPHOST} eq $config{HOSTNAME} ) {\n           runAsZimbra (\"/opt/zimbra/bin/zmldappasswd -a $config{LDAPAMAVISPASS}\");\n         } else {\n           setLocalConfig (\"ldap_amavis_password\", \"$config{LDAPAMAVISPASS}\");\n        }\n         progress ( \"done.\\n\" );\n      }\n      if ($ldapNginxChanged == 1) {\n         progress ( \"Setting nginx password...\" );\n         if ($config{LDAPHOST} eq $config{HOSTNAME} ) {\n           runAsZimbra (\"/opt/zimbra/bin/zmldappasswd -n $config{ldap_nginx_password}\");\n         } else {\n           setLocalConfig (\"ldap_nginx_password\", \"$config{ldap_nginx_password}\");\n        }\n         progress ( \"done.\\n\" );\n      }\n      if ($ldapBesSearcherChanged == 1) {\n         progress ( \"Setting BES Searcher password...\" );\n         if ($config{LDAPHOST} eq $config{HOSTNAME} ) {\n           runAsZimbra (\"/opt/zimbra/bin/zmldappasswd -b $config{ldap_bes_searcher_password}\");\n         } else {\n           setLocalConfig (\"ldap_bes_searcher_password\", \"$config{ldap_bes_searcher_password}\");\n        }\n         progress ( \"done.\\n\" );\n      }\n    } else {\n      progress(\"Stopping ldap...\");\n      runAsZimbra (\"/opt/zimbra/bin/ldap stop\");\n      progress(\"done.\\n\");\n      startLdap();\n    }\n\n\n  } else {\n    detail(\"Updating ldap user passwords\\n\");\n    setLocalConfig (\"ldap_root_password\", $config{LDAPROOTPASS});\n    setLocalConfig (\"zimbra_ldap_password\", $config{LDAPADMINPASS});\n    setLocalConfig (\"ldap_replication_password\", \"$config{LDAPREPPASS}\");\n    setLocalConfig (\"ldap_postfix_password\", \"$config{LDAPPOSTPASS}\");\n    setLocalConfig (\"ldap_amavis_password\", \"$config{LDAPAMAVISPASS}\");\n    setLocalConfig (\"ldap_nginx_password\", \"$config{ldap_nginx_password}\");\n    setLocalConfig (\"ldap_bes_searcher_password\", \"$config{ldap_bes_searcher_password}\");\n  }\n\n  configLog(\"configSetupLdap\");\n  return 0;\n\n}\n\nsub configLDAPSchemaVersion {\n  return if ($haveSetLdapSchemaVersion);\n  if (isEnabled(\"zimbra-ldap\")) {\n    progress (\"Updating zimbraLDAPSchemaVersion to version '$ldapSchemaVersion'\\n\");\n    setLdapGlobalConfig('zimbraLDAPSchemaVersion', $ldapSchemaVersion);\n    $haveSetLdapSchemaVersion = 1;\n  }\n}\n\nsub configSetupEphemeralBackend {\n  if (exists($config{EphemeralBackendURL})) {\n    setLdapGlobalConfig(\"zimbraEphemeralBackendURL\", \"$config{EphemeralBackendURL}\")\n  }\n  configLog(\"configSetupEphemeralBackend\");\n  return 0;\n}\n\nsub configSaveCA {\n\n  if ($configStatus{configSaveCA} eq \"CONFIGURED\") {\n    configLog(\"configSaveCA\");\n    return 0;\n  }\n  progress ( \"Saving CA in ldap...\" );\n  my $rc = runAsZimbra(\"/opt/zimbra/bin/zmcertmgr deployca\");\n  if ($rc != 0) {\n    progress ( \"failed.\\n\" );\n    exit 1;\n  } else {\n    progress ( \"done.\\n\" );\n  }\n  configLog(\"configSaveCA\");\n}\n\nsub configCreateCert {\n\n  if ($configStatus{configCreateCert} eq \"CONFIGURED\" && -d \"/opt/zimbra/ssl/zimbra/server\") {\n    configLog(\"configCreateCert\");\n    return 0;\n  }\n\n  if (!$newinstall) {\n    my $rc = runAsZimbra(\"/opt/zimbra/bin/zmcertmgr verifycrt comm > /dev/null 2>&1\");\n    if ($rc != 0) {\n      $rc = runAsZimbra(\"/opt/zimbra/bin/zmcertmgr verifycrt self > /dev/null 2>&1\");\n      if ($rc != 0) {\n        progress(\"Warning: No valid SSL certificates were found.\\n\");\n        progress(\"New self-signed certificates will be generated and installed.\\n\");\n        $needNewCert = \"-new\" if ($rc != 0);\n        $ssl_cert_type=\"self\";\n      }\n    } else {\n      $ssl_cert_type=\"comm\";\n      $needNewCert=\"\";\n    }\n  }\n\n  my $rc;\n  if (isInstalled(\"zimbra-imapd\")) {\n    if ( !-f \"$config{imapd_keystore}\" && !-f \"/opt/zimbra/conf/server.crt\" ) {\n      progress ( \"Creating SSL zimbra-imapd certificate...\" );\n      $rc = runAsZimbra(\"/opt/zimbra/bin/zmcertmgr createcrt $needNewCert\");\n      if ($rc != 0) {\n        progress ( \"failed.\\n\" );\n        exit 1;\n      } else {\n        progress ( \"done.\\n\" );\n      }\n    } elsif ( $needNewCert ne \"\" && $ssl_cert_type eq \"self\") {\n      progress ( \"Creating new zimbra-imapd SSL certificate...\" );\n      $rc = runAsZimbra(\"/opt/zimbra/bin/zmcertmgr createcrt $needNewCert\");\n      if ($rc != 0) {\n        progress ( \"failed.\\n\" );\n        exit 1;\n      } else {\n        progress ( \"done.\\n\" );\n      }\n    }\n  }\n\n  if (isInstalled(\"zimbra-store\")) {\n    if ( !-f \"$config{mailboxd_keystore}\" && !-f \"/opt/zimbra/ssl/zimbra/server/server.crt\" ) {\n      if (!-d \"$config{mailboxd_directory}\") {\n        qx(mkdir -p $config{mailboxd_directory}/etc);\n        qx(chown -R zimbra:zimbra $config{mailboxd_directory});\n        qx(chmod 744 $config{mailboxd_directory}/etc);\n      }\n      progress ( \"Creating SSL zimbra-store certificate...\" );\n      $rc = runAsZimbra(\"/opt/zimbra/bin/zmcertmgr createcrt $needNewCert\");\n      if ($rc != 0) {\n        progress ( \"failed.\\n\" );\n        exit 1;\n      } else {\n        progress ( \"done.\\n\" );\n      }\n    } elsif ( $needNewCert ne \"\" && $ssl_cert_type eq \"self\") {\n      progress ( \"Creating new zimbra-store SSL certificate...\" );\n      $rc = runAsZimbra(\"/opt/zimbra/bin/zmcertmgr createcrt $needNewCert\");\n      if ($rc != 0) {\n        progress ( \"failed.\\n\" );\n        exit 1;\n      } else {\n        progress ( \"done.\\n\" );\n      }\n    }\n  }\n\n  if (isInstalled(\"zimbra-ldap\")) {\n    if ( !-f \"/opt/zimbra/conf/slapd.crt\" && !-f \"/opt/zimbra/ssl/zimbra/server/server.crt\") {\n      progress ( \"Creating zimbra-ldap SSL certificate...\" );\n      $rc = runAsZimbra(\"/opt/zimbra/bin/zmcertmgr createcrt $needNewCert\");\n      if ($rc != 0) {\n        progress ( \"failed.\\n\" );\n        exit 1;\n      } else {\n        progress ( \"done.\\n\" );\n      }\n    } elsif ( $needNewCert ne \"\" && $ssl_cert_type eq \"self\") {\n      progress ( \"Creating new zimbra-ldap SSL certificate...\" );\n      $rc = runAsZimbra(\"/opt/zimbra/bin/zmcertmgr createcrt $needNewCert\");\n      if ($rc != 0) {\n        progress ( \"failed.\\n\" );\n        exit 1;\n      } else {\n        progress ( \"done.\\n\" );\n      }\n    }\n  }\n\n  if (isInstalled(\"zimbra-mta\")) {\n    if ( !-f \"/opt/zimbra/conf/smtpd.crt\" && !-f \"/opt/zimbra/ssl/zimbra/server/server.crt\") {\n      progress ( \"Creating zimbra-mta SSL certificate...\" );\n      $rc = runAsZimbra(\"/opt/zimbra/bin/zmcertmgr createcrt $needNewCert\");\n      if ($rc != 0) {\n        progress ( \"failed.\\n\" );\n        exit 1;\n      } else {\n        progress ( \"done.\\n\" );\n      }\n    } elsif ( $needNewCert ne \"\" && $ssl_cert_type eq \"self\") {\n      progress ( \"Creating new zimbra-mta SSL certificate...\" );\n      $rc = runAsZimbra(\"/opt/zimbra/bin/zmcertmgr createcrt $needNewCert\");\n      if ($rc != 0) {\n        progress ( \"failed.\\n\" );\n        exit 1;\n      } else {\n        progress ( \"done.\\n\" );\n      }\n    }\n  }\n\n  if (isInstalled(\"zimbra-proxy\")) {\n    if ( !-f \"/opt/zimbra/conf/nginx.crt\" && !-f \"/opt/zimbra/ssl/zimbra/server/server.crt\") {\n      progress ( \"Creating zimbra-proxy SSL certificate...\" );\n      $rc = runAsZimbra(\"/opt/zimbra/bin/zmcertmgr createcrt $needNewCert\");\n      if ($rc != 0) {\n        progress ( \"failed.\\n\" );\n        exit 1;\n      } else {\n        progress ( \"done.\\n\" );\n      }\n    } elsif ( $needNewCert ne \"\" && $ssl_cert_type eq \"self\") {\n      progress ( \"Creating new zimbra-proxy SSL certificate...\" );\n      $rc = runAsZimbra(\"/opt/zimbra/bin/zmcertmgr createcrt $needNewCert\");\n      if ($rc != 0) {\n        progress ( \"failed.\\n\" );\n        exit 1;\n      } else {\n        progress ( \"done.\\n\" );\n      }\n    }\n  }\n\n  if (isInstalled(\"zimbra-onlyoffice\")) {\n    if ( !-f \"/opt/zimbra/ssl/zimbra/server/server.crt\") {\n      progress ( \"Creating SSL certificate...\" );\n      $rc = runAsZimbra(\"/opt/zimbra/bin/zmcertmgr createcrt $needNewCert\");\n      if ($rc != 0) {\n        progress ( \"failed.\\n\" );\n        exit 1;\n      } else {\n        progress ( \"done.\\n\" );\n      }\n    } elsif ( $needNewCert ne \"\" && $ssl_cert_type eq \"self\") {\n      progress ( \"Creating new SSL certificate...\" );\n      $rc = runAsZimbra(\"/opt/zimbra/bin/zmcertmgr createcrt $needNewCert\");\n      if ($rc != 0) {\n        progress ( \"failed.\\n\" );\n        exit 1;\n      } else {\n        progress ( \"done.\\n\" );\n      }\n    }\n  }\n\n  if (isInstalled(\"zimbra-license-daemon\")) {\n\t  if ( !-f \"/opt/zimbra/ssl/zimbra/server/server.crt\") {\n\t\t  progress ( \"Creating SSL certificate...\" );\n\t\t  $rc = runAsZimbra(\"/opt/zimbra/bin/zmcertmgr createcrt $needNewCert\");\n\t\t  if ($rc != 0) {\n\t\t\t  progress ( \"failed.\\n\" );\n\t\t\t  exit 1;\n\t\t  } else {\n\t\t\t  progress ( \"done.\\n\" );\n\t\t  }\n\t  } elsif ( $needNewCert ne \"\" && $ssl_cert_type eq \"self\") {\n\t\t  progress ( \"Creating new SSL certificate...\" );\n\t\t  $rc = runAsZimbra(\"/opt/zimbra/bin/zmcertmgr createcrt $needNewCert\");\n\t\t  if ($rc != 0) {\n\t\t\t  progress ( \"failed.\\n\" );\n\t\t\t  exit 1;\n\t\t  } else {\n\t\t\t  progress ( \"done.\\n\" );\n\t\t  }\n\t  }\n  }\n  configLog(\"configCreateCert\");\n}\n\nsub configSaveCert {\n\n  if ($configStatus{configSaveCert} eq \"CONFIGURED\") {\n    configLog(\"configSaveCert\");\n    return 0;\n  }\n  progress ( \"Saving SSL Certificate in ldap...\" );\n  my $rc = runAsZimbra(\"/opt/zimbra/bin/zmcertmgr savecrt $ssl_cert_type\");\n  if ($rc != 0) {\n    progress ( \"failed.\\n\" );\n    exit 1;\n  } else {\n    progress ( \"done.\\n\" );\n  }\n  configLog(\"configSaveCert\");\n}\n\nsub configInstallCert {\n  my $rc;\n  if ($configStatus{configInstallCertStore} eq \"CONFIGURED\" && $needNewCert eq \"\") {\n    configLog(\"configInstallCertStore\");\n  } elsif (isInstalled(\"zimbra-store\")) {\n    if (! (-f \"$config{mailboxd_keystore}\") || $needNewCert ne \"\") {\n      progress (\"Installing mailboxd SSL certificates...\");\n      detail(\"$config{mailboxd_keystore} didn't exist.\")\n        if (! -f \"$config{mailboxd_keystore}\");\n      detail(\"$needNewCert was ne \\\"\\\".\")\n        if ($needNewCert ne \"\");\n      $rc = runAsZimbra(\"/opt/zimbra/bin/zmcertmgr deploycrt $ssl_cert_type\");\n      if ($rc != 0) {\n        progress ( \"failed.\\n\" );\n        exit 1;\n      } else {\n        progress ( \"done.\\n\" );\n        configLog(\"configInstallCertStore\");\n      }\n    } else {\n      configLog(\"configInstallCertStore\");\n    }\n  }\n\n  if ($configStatus{configInstallCertImap} eq \"CONFIGURED\" && $needNewCert eq \"\") {\n    configLog(\"configInstallCertImap\");\n  } elsif (isInstalled(\"zimbra-imapd\")) {\n    if (! (-f \"$config{imapd_keystore}\") || $needNewCert ne \"\") {\n      progress (\"Installing imapd SSL certificates...\");\n      detail(\"$config{imapd_keystore} didn't exist.\")\n        if (! -f \"$config{imapd_keystore}\");\n      detail(\"$needNewCert was ne \\\"\\\".\")\n        if ($needNewCert ne \"\");\n      $rc = runAsZimbra(\"/opt/zimbra/bin/zmcertmgr deploycrt $ssl_cert_type\");\n      if ($rc != 0) {\n        progress ( \"failed.\\n\" );\n        exit 1;\n      } else {\n        progress ( \"done.\\n\" );\n        configLog(\"configInstallCertImap\");\n      }\n    } else {\n      configLog(\"configInstallCertImap\");\n    }\n  }\n\n  if ($configStatus{configInstallCertMTA} eq \"CONFIGURED\" && $needNewCert eq \"\") {\n    configLog(\"configInstallCertMTA\");\n  } elsif (isInstalled(\"zimbra-mta\")) {\n\n    if (! (-f \"/opt/zimbra/conf/smtpd.key\" ||\n      -f \"/opt/zimbra/conf/smtpd.crt\" ) || $needNewCert ne \"\")  {\n      progress (\"Installing MTA SSL certificates...\");\n      $rc = runAsZimbra(\"/opt/zimbra/bin/zmcertmgr deploycrt $ssl_cert_type\");\n      if ($rc != 0) {\n        progress ( \"failed.\\n\" );\n        exit 1;\n      } else {\n        progress ( \"done.\\n\" );\n        configLog(\"configInstallCertMTA\");\n      }\n    } else {\n      configLog(\"configInstallCertMTA\");\n    }\n  }\n\n  if ($configStatus{configInstallCertLDAP} eq \"CONFIGURED\" && $needNewCert eq \"\") {\n    configLog(\"configInstallCertLDAP\");\n  } elsif (isInstalled(\"zimbra-ldap\")) {\n    if (! (-f \"/opt/zimbra/conf/slapd.key\" ||\n      -f \"/opt/zimbra/conf/slapd.crt\" ) || $needNewCert ne \"\") {\n      progress (\"Installing LDAP SSL certificate...\");\n      $rc = runAsZimbra(\"/opt/zimbra/bin/zmcertmgr deploycrt $ssl_cert_type\");\n      if ($rc != 0) {\n        progress ( \"failed.\\n\" );\n        exit 1;\n      } else {\n        progress ( \"done.\\n\" );\n        stopLdap() if ($ldapConfigured);\n        startLdap() if ($ldapConfigured);\n        configLog(\"configInstallCertLDAP\");\n      }\n    } else {\n      configLog(\"configInstallCertLDAP\");\n    }\n  }\n\n  if ($configStatus{configInstallCertProxy} eq \"CONFIGURED\" && $needNewCert eq \"\") {\n    configLog(\"configInstallCertProxy\");\n  } elsif (isInstalled(\"zimbra-proxy\")) {\n    if (! (-f \"/opt/zimbra/conf/nginx.key\" ||\n      -f \"/opt/zimbra/conf/nginx.crt\")  || $needNewCert ne \"\") {\n      progress (\"Installing Proxy SSL certificate...\");\n      $rc = runAsZimbra(\"/opt/zimbra/bin/zmcertmgr deploycrt $ssl_cert_type\");\n      if ($rc != 0) {\n        progress ( \"failed.\\n\" );\n        exit 1;\n      } else {\n        progress ( \"done.\\n\" );\n        configLog(\"configInstallCertProxy\");\n      }\n    } else {\n      configLog(\"configInstallCertProxy\");\n    }\n  }\n\n}\n\nsub configCreateServerEntry {\n\n  if ($configStatus{configCreateServerEntry} eq \"CONFIGURED\") {\n    configLog(\"configCreateServerEntry\");\n    return 0;\n  }\n\n  progress ( \"Creating server entry for $config{HOSTNAME}...\" );\n  my $serverId = getLdapServerValue(\"zimbraId\");\n  if ($serverId ne \"\") {\n    progress(\"already exists.\\n\");\n  } else {\n    my $rc = runAsZimbra(\"$ZMPROV cs $config{HOSTNAME}\");\n    progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n  }\n  progress ( \"Setting Zimbra IP Mode...\" );\n  my $rc = setLdapServerConfig(\"zimbraIPMode\", $config{zimbraIPMode});\n  progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n  my $rc = runAsZimbra(\"/opt/zimbra/libexec/zmiptool >/dev/null 2>/dev/null\");\n\n  configLog(\"configCreateServerEntry\");\n}\n\nsub configSpellServer {\n  if ($configStatus{configSpellServer} eq \"CONFIGURED\") {\n    configLog(\"configSpellServer\");\n    return 0;\n  }\n\n  if ($config{USESPELL} eq \"yes\") {\n    progress ( \"Setting spell check URL...\" );\n    my $rc = setLdapServerConfig(\"zimbraSpellCheckURL\", $config{SPELLURL});\n    progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n  }\n\n  configLog(\"configSpellServer\");\n}\n\nsub configConvertdURL {\n  my $tmpval = getLdapConfigValue(\"zimbraConvertdURL\");\n  if ( $tmpval eq \"\" ) {\n    my $host;\n    if (!$newinstall) {\n      $host = $config{zimbra_server_hostname};\n    } else {\n      $host = lc($config{HOSTNAME});\n    }\n    progress(\"Setting convertd URL...\");\n    my $rc = setLdapGlobalConfig(\"zimbraConvertdURL\", \"http://$host:7047/convert\");\n    progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n\n  }\n}\n\nsub configSetStoreDefaults {\n  if(isEnabled(\"zimbra-proxy\") || $config{zimbraMailProxy} eq \"TRUE\" || $config{zimbraWebProxy} eq \"TRUE\") {\n    $config{zimbraReverseProxyLookupTarget}=\"TRUE\";\n  }\n  # for mailstore split, set zimbraReverseProxyAvailableLookupTargets on service-only nodes\n  if ($newinstall && isStoreServiceNode()) {\n\tmy $adding=0;\n\tprogress(\"Checking current setting of zimbraReverseProxyAvailableLookupTargets\\n\");\n\tmy $zrpALT = getLdapConfigValue(\"zimbraReverseProxyAvailableLookupTargets\");\n\tif ($zrpALT ne \"\") {\n\t  $adding=1;\n\t} else {\n\t  progress(\"Querying LDAP for other mailstores\\n\");\n\t  # query LDAP to see if there are other mailstores.  If there are none, add this\n\t  # new service node to zimbraReverseProxyAvailableLookupTargets.  Otherwise do not\n\t  my $count = countReverseProxyLookupTargets();\n\t  if (!defined($count) || $count == 0) {\n\t\t$adding=1;\n\t  }\n\t}\n\tif ($adding) {\n\t  progress(\"Adding $config{HOSTNAME} to zimbraReverseProxyAvailableLookupTargets\\n\");\n\t  setLdapGlobalConfig(\"+zimbraReverseProxyAvailableLookupTargets\", $config{HOSTNAME});\n\t}\n  }\n  $config{zimbraMtaAuthTarget}=\"TRUE\";\n  if (!isStoreServiceNode()) {\n    $config{zimbraMtaAuthTarget}=\"FALSE\";\n  }\n  if ($newinstall && isNetwork() && isStoreServiceNode()) {\n    setLdapGlobalConfig(\"+zimbraReverseProxyUpstreamEwsServers\", \"$config{HOSTNAME}\");\n  }\n  if ($newinstall && isStoreWebNode()) {\n    setLdapGlobalConfig(\"+zimbraReverseProxyUpstreamLoginServers\", \"$config{HOSTNAME}\");\n  }\n  setLdapServerConfig(\"zimbraReverseProxyLookupTarget\", $config{zimbraReverseProxyLookupTarget});\n  setLdapServerConfig(\"zimbraMtaAuthTarget\", $config{zimbraMtaAuthTarget});\n  my $upstream=\"-u\";\n  if ($config{zimbra_require_interprocess_security}) {\n    $upstream=\"-U\";\n  }\n  if ($newinstall && ($config{zimbraWebProxy} eq \"TRUE\" || $config{zimbraMailProxy} eq \"TRUE\")) {\n      if ($config{zimbraMailProxy} eq \"TRUE\") {\n           runAsZimbra(\"/opt/zimbra/libexec/zmproxyconfig $upstream -m -e -o \".\n                       \"-i $config{IMAPPORT}:$config{IMAPPROXYPORT}:$config{IMAPSSLPORT}:$config{IMAPSSLPROXYPORT} \".\n                       \"-p $config{POPPORT}:$config{POPPROXYPORT}:$config{POPSSLPORT}:$config{POPSSLPROXYPORT} -H $config{HOSTNAME}\");\n    }\n    if ($config{zimbraWebProxy} eq \"TRUE\") {\n           runAsZimbra(\"/opt/zimbra/libexec/zmproxyconfig $upstream -w -e -o \".\n                       \"-a $config{HTTPPORT}:$config{HTTPPROXYPORT}:$config{HTTPSPORT}:$config{HTTPSPROXYPORT} -H $config{HOSTNAME}\");\n    }\n  }\n\n  if ($config{zimbraVersionCheckServer} eq \"\" && isStoreServiceNode()) {\n    my $serverId = getLdapServerValue(\"zimbraId\");\n    setLdapGlobalConfig(\"zimbraVersionCheckServer\", $serverId);\n  }\n\n  # this should probably be in a global config section\n  setLdapGlobalConfig(\"zimbraVersionCheckSendNotifications\",\n    $config{zimbraVersionCheckSendNotifications});\n  setLdapGlobalConfig(\"zimbraVersionCheckNotificationEmail\",\n    $config{zimbraVersionCheckNotificationEmail});\n  setLdapGlobalConfig(\"zimbraVersionCheckNotificationEmailFrom\",\n    $config{zimbraVersionCheckNotificationEmailFrom});\n\n  setLdapGlobalConfig(\"zimbraVersionCheckInterval\", \"0\")\n    if ($config{VERSIONUPDATECHECKS} eq \"FALSE\");\n\n\n}\n\nsub isStoreWebNode {\n    if ($installedWebapps{\"zimbra\"} eq \"Enabled\" || $installedWebapps{\"zimbraAdmin\"} eq \"Enabled\") {\n        return 1;\n    } else {\n        return 0;\n    }\n}\n\nsub isStoreServiceNode {\n    if ($installedWebapps{\"service\"} eq \"Enabled\") {\n        return 1;\n    } else {\n        return 0;\n    }\n}\n\nsub configSetServicePorts {\n\n  if ($configStatus{configSetServicePorts} eq \"CONFIGURED\") {\n    configLog(\"configSetServicePorts\");\n    return 0;\n  }\n\n  progress ( \"Setting service ports on $config{HOSTNAME}...\" );\n  if ($config{MAILPROXY} eq \"FALSE\") {\n    if ($config{IMAPPORT} == 7143 && $config{IMAPPROXYPORT} == $config{IMAPPORT}) {\n      $config{IMAPPROXYPORT} = 143;\n    }\n    if ($config{IMAPSSLPORT} == 7993 && $config{IMAPSSLPROXYPORT} == $config{IMAPSSLPORT}) {\n      $config{IMAPSSLPROXYPORT} = 993;\n    }\n    if ($config{POPPORT} == 7110 && $config{POPPROXYPORT} == $config{POPPORT}) {\n      $config{POPPROXYPORT} = 110;\n    }\n    if ($config{POPSSLPORT} == 7995 && $config{POPSSLPROXYPORT} == $config{POPSSLPORT}) {\n      $config{POPSSLPORT} = 995;\n    }\n  }\n  setLdapServerConfig($config{HOSTNAME},\n    \"zimbraImapBindPort\", $config{IMAPPORT},\n    \"zimbraImapSSLBindPort\", $config{IMAPSSLPORT},\n    \"zimbraImapProxyBindPort\", $config{IMAPPROXYPORT},\n    \"zimbraImapSSLProxyBindPort\", $config{IMAPSSLPROXYPORT}\n\t);\n  setLdapServerConfig($config{HOSTNAME},\n    \"zimbraPop3BindPort\", $config{POPPORT},\n    \"zimbraPop3SSLBindPort\", $config{POPSSLPORT},\n    \"zimbraPop3ProxyBindPort\", $config{POPPROXYPORT},\n    \"zimbraPop3SSLProxyBindPort\", $config{POPSSLPROXYPORT}\n    );\n  if ($config{HTTPPROXY} eq \"FALSE\") {\n    if ($config{HTTPPORT} == 8080 && $config{HTTPPROXYPORT} == $config{HTTPPORT}) {\n      $config{HTTPPROXYPORT} = 80;\n    }\n    if ($config{HTTPSPORT} == 8443 && $config{HTTPSPROXYPORT} == $config{HTTPSPORT}){\n      $config{HTTPSPROXYPORT} = 443;\n    }\n  }\n  setLdapServerConfig($config{HOSTNAME},\n    \"zimbraMailPort\", $config{HTTPPORT},\n    \"zimbraMailSSLPort\", $config{HTTPSPORT},\n    \"zimbraMailProxyPort\", $config{HTTPPROXYPORT},\n    \"zimbraMailSSLProxyPort\", $config{HTTPSPROXYPORT},\n    \"zimbraMailMode\", $config{MODE}\n    );\n  setLocalConfig(\"zimbra_mail_service_port\", $config{HTTPPORT});\n\n  progress ( \"done.\\n\" );\n  configLog(\"configSetServicePorts\");\n}\n\nsub configSetKeyboardShortcutsPref {\n  if ($configStatus{zimbraPrefUseKeyboardShortcuts} eq \"CONFIGURED\") {\n    configLog(\"zimbraPrefUseKeyboardShortcuts\");\n    return 0;\n  }\n  progress ( \"Setting Keyboard Shortcut Preferences...\");\n  my $rc = setLdapCOSConfig(\"zimbraPrefUseKeyboardShortcuts\", $config{USEKBSHORTCUTS});\n  progress (($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n  configLog(\"zimbraPrefUseKeyboardShortcuts\");\n}\n\nsub configSetDNSCacheDefaults {\n  if ($configStatus{zimbraDNSCache} eq \"CONFIGURED\") {\n    configLog(\"zimbraDNSCache\");\n    return 0;\n  }\n  progress ( \"Setting Master DNS IP address(es)...\");\n  my @IPs = split (' ', $config{zimbraDNSMasterIP});\n  my $rc;\n  foreach my $ip (@IPs) {\n    chomp ($ip);\n    $ip =~s/\"//g;\n    $ip =~s/'//g;\n    $rc=main::runAsZimbra(\"$ZMPROV ms $config{HOSTNAME} +zimbraDNSMasterIP $ip\");\n  }\n  progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n  progress( \"Setting DNS cache tcp lookup preference...\");\n  $rc=main::runAsZimbra(\"$ZMPROV ms $config{HOSTNAME} zimbraDNSUseTCP $config{zimbraDNSUseTCP}\");\n  progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n  progress( \"Setting DNS cache udp lookup preference...\");\n  $rc=main::runAsZimbra(\"$ZMPROV ms $config{HOSTNAME} zimbraDNSUseUDP $config{zimbraDNSUseUDP}\");\n  progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n  progress( \"Setting DNS tcp upstream preference...\");\n  $rc=main::runAsZimbra(\"$ZMPROV ms $config{HOSTNAME} zimbraDNSTCPUpstream $config{zimbraDNSTCPUpstream}\");\n  progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n  configLog(\"zimbraDNSCache\");\n}\n\nsub configSetTimeZonePref {\n  if ($configStatus{zimbraPrefTimeZoneId} eq \"CONFIGURED\") {\n    configLog(\"zimbraPrefTimeZoneId\");\n    return 0;\n  }\n  if($config{LDAPHOST} eq $config{HOSTNAME}) {\n    progress ( \"Setting TimeZone Preference...\");\n    my $rc = setLdapCOSConfig(\"zimbraPrefTimeZoneId\", $config{zimbraPrefTimeZoneId});\n    progress (($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n  }\n  configLog(\"zimbraPrefTimeZoneId\");\n}\n\nsub configSetCEFeatures {\n  foreach my $feature (qw(Tasks Briefcases)) {\n    my $key = \"zimbraFeature${feature}Enabled\";\n    my $val = ($config{$key} eq \"Enabled\" ? \"TRUE\" : \"FALSE\");\n    if ($configStatus{$key} eq \"CONFIGURED\") {\n      configLog($key);\n      next;\n    }\n    progress ( \"Setting $key=$val...\");\n    my $rc = setLdapCOSConfig($key, $val);\n    progress (($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n    configLog($key);\n  }\n}\n\nsub configSetNEFeatures {\n  return unless isNetwork();\n}\n\nsub configInitDomainAdminGroups {\n  return if ($config{DOCREATEDOMAIN} eq \"no\");\n  main::progress (\"Setting up default domain admin UI components...\");\n\n  $config{zimbraDefaultDomainName} = getLdapConfigValue(\"zimbraDefaultDomainName\") || $config{CREATEDOMAIN};\n  my $domainGroup = \"zimbraDomainAdmins\\@\".\n    (($newinstall) ? \"$config{CREATEDOMAIN}\" : \"$config{zimbraDefaultDomainName}\");\n  my $rc = main::runAsZimbra(\"$ZMPROV cdl $domainGroup \".\n    \"zimbraIsAdminGroup TRUE \".\n    \"zimbraHideInGal TRUE \".\n    \"zimbraMailStatus disabled \".\n    \"displayname 'Zimbra Domain Admins' \".\n    \"zimbraAdminConsoleUIComponents accountListView \".\n    \"zimbraAdminConsoleUIComponents aliasListView \".\n    \"zimbraAdminConsoleUIComponents DLListView \".\n    \"zimbraAdminConsoleUIComponents resourceListView \".\n    \"zimbraAdminConsoleUIComponents saveSearch \");\n  main::progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n\n  main::progress (\"Granting group $domainGroup domain right +domainAdminConsoleRights on $config{zimbraDefaultDomainName}...\");\n  $rc = main::runAsZimbra(\"$ZMPROV grr domain $config{zimbraDefaultDomainName} grp $domainGroup +domainAdminConsoleRights\");\n  main::progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n\n  main::progress (\"Granting group $domainGroup global right +domainAdminZimletRights...\");\n  $rc = main::runAsZimbra(\"$ZMPROV grr global grp $domainGroup +domainAdminZimletRights\");\n  main::progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n\n  main::progress (\"Setting up global distribution list admin UI components..\");\n  $domainGroup = \"zimbraDLAdmins\\@\".\n    (($newinstall) ? \"$config{CREATEDOMAIN}\" : \"$config{zimbraDefaultDomainName}\");\n  my $rc = main::runAsZimbra(\"$ZMPROV cdl $domainGroup \".\n    \"zimbraIsAdminGroup TRUE \".\n    \"zimbraHideInGal TRUE \".\n    \"zimbraMailStatus disabled \".\n    \"displayname 'Zimbra DL Admins' \".\n    \"zimbraAdminConsoleUIComponents DLListView \");\n  main::progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n\n  main::progress (\"Granting group $domainGroup global right +adminConsoleDLRights...\");\n  $rc = main::runAsZimbra(\"$ZMPROV grr global grp $domainGroup +adminConsoleDLRights\");\n  main::progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n  main::progress (\"Granting group $domainGroup global right +listAccount...\");\n  $rc = main::runAsZimbra(\"$ZMPROV grr global grp $domainGroup +listAccount\");\n  main::progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n\n}\n\nsub configInitBackupPrefs {\n  if (isEnabled(\"zimbra-store\") && isNetwork()) {\n    foreach my $recip (split(/\\n/, $config{zimbraBackupReportEmailRecipients})) {\n      setLdapGlobalConfig(\"+zimbraBackupReportEmailRecipients\", $recip);\n    }\n    foreach my $sender (split(/\\n/, $config{zimbraBackupReportEmailSender})) {\n      setLdapGlobalConfig(\"+zimbraBackupReportEmailSender\", $sender);\n    }\n  }\n}\n\nsub setProxyBits {\n  detail(\"Setting Proxy pieces\\n\");\n  my $zimbraReverseProxyMailHostQuery =\n        \"\\(\\|\\(zimbraMailDeliveryAddress=\\${USER}\\)\\(zimbraMailAlias=\\${USER}\\)\\(zimbraId=\\${USER}\\)\\)\";\n  my $zimbraReverseProxyDomainNameQuery =\n        '\\(\\&\\(zimbraVirtualIPAddress=\\${IPADDR}\\)\\(objectClass=zimbraDomain\\)\\)';\n  my $zimbraReverseProxyPortQuery =\n        '\\(\\&\\(zimbraServiceHostname=\\${MAILHOST}\\)\\(objectClass=zimbraServer\\)\\)';\n\n  my @zmprov_args = ();\n  push(@zmprov_args, ('zimbraReverseProxyMailHostQuery', $zimbraReverseProxyMailHostQuery))\n    if(getLdapConfigValue(\"zimbraReverseProxyMailHostQuery\") eq \"\");\n\n  push(@zmprov_args, ('zimbraReverseProxyPortQuery', $zimbraReverseProxyPortQuery))\n    if(getLdapConfigValue(\"zimbraReverseProxyPortQuery\") eq \"\");\n\n  push(@zmprov_args, ('zimbraReverseProxyDomainNameQuery', $zimbraReverseProxyDomainNameQuery))\n    if(getLdapConfigValue(\"zimbraReverseProxyDomainNameQuery\") eq \"\");\n\n  push(@zmprov_args, ('zimbraMemcachedBindPort', '11211'))\n    if(getLdapConfigValue(\"zimbraMemcachedBindPort\") eq \"\");\n\n  push(@zmprov_args, ('zimbraReverseProxyMailHostAttribute', 'zimbraMailHost'))\n    if(getLdapConfigValue(\"zimbraReverseProxyMailHostAttribute\") eq \"\");\n\n  push(@zmprov_args, ('zimbraReverseProxyPop3PortAttribute', 'zimbraPop3BindPort'))\n    if(getLdapConfigValue(\"zimbraReverseProxyPop3PortAttribute\") eq \"\");\n\n  push(@zmprov_args, ('zimbraReverseProxyPop3SSLPortAttribute', 'zimbraPop3SSLBindPort'))\n    if(getLdapConfigValue(\"zimbraReverseProxyPop3SSLPortAttribute\") eq \"\");\n\n  push(@zmprov_args, ('zimbraReverseProxyImapPortAttribute', 'zimbraImapBindPort'))\n    if(getLdapConfigValue(\"zimbraReverseProxyImapPortAttribute\") eq \"\");\n\n  push(@zmprov_args, ('zimbraReverseProxyImapSSLPortAttribute', 'zimbraImapSSLBindPort'))\n    if(getLdapConfigValue(\"zimbraReverseProxyImapSSLPortAttribute\") eq \"\");\n\n  push(@zmprov_args, ('zimbraReverseProxyDomainNameAttribute', 'zimbraDomainName'))\n    if(getLdapConfigValue(\"zimbraReverseProxyDomainNameAttribute\") eq \"\");\n\n  push(@zmprov_args, ('zimbraImapCleartextLoginEnabled', 'FALSE'))\n    if(getLdapConfigValue(\"zimbraImapCleartextLoginEnabled\") eq \"\");\n\n  push(@zmprov_args, ('zimbraPop3CleartextLoginEnabled', 'FALSE'))\n    if(getLdapConfigValue(\"zimbraPop3CleartextLoginEnabled\") eq \"\");\n\n  push(@zmprov_args, ('zimbraReverseProxyAuthWaitInterval', '10s'))\n    if(getLdapConfigValue(\"zimbraReverseProxyAuthWaitInterval\") eq \"\");\n\n  push(@zmprov_args, ('zimbraReverseProxyIPLoginLimit', '0'))\n    if(getLdapConfigValue(\"zimbraReverseProxyIPLoginLimit\") eq \"\");\n\n  push(@zmprov_args, ('zimbraReverseProxyIPLoginLimitTime', '3600'))\n    if(getLdapConfigValue(\"zimbraReverseProxyIPLoginLimitTime\") eq \"\");\n\n  push(@zmprov_args, ('zimbraReverseProxyUserLoginLimit', '0'))\n    if(getLdapConfigValue(\"zimbraReverseProxyUserLoginLimit\") eq \"\");\n\n  push(@zmprov_args, ('zimbraReverseProxyUserLoginLimitTime', '3600'))\n    if(getLdapConfigValue(\"zimbraReverseProxyUserLoginLimitTime\") eq \"\");\n\n  push(@zmprov_args, ('zimbraMailProxyPort', '0'))\n    if(getLdapConfigValue(\"zimbraMailProxyPort\") eq \"\");\n\n  push(@zmprov_args, ('zimbraMailSSLProxyPort', '0'))\n    if(getLdapConfigValue(\"zimbraMailSSLProxyPort\") eq \"\");\n\n  push(@zmprov_args, ('zimbraReverseProxyHttpEnabled', 'FALSE'))\n    if(getLdapConfigValue(\"zimbraReverseProxyHttpEnabled\") eq \"\");\n\n  push(@zmprov_args, ('zimbraReverseProxyMailEnabled', 'TRUE'))\n    if(getLdapConfigValue(\"zimbraReverseProxyMailEnabled\") eq \"\");\n\n  setLdapGlobalConfig( @zmprov_args );\n\n}\n\nsub configSetProxyPrefs {\n   if (isEnabled(\"zimbra-proxy\")) {\n     if ($config{STRICTSERVERNAMEENABLED} eq \"yes\") {\n        progress(\"Enabling strict server name enforcement on $config{HOSTNAME}...\");\n        runAsZimbra(\"$ZMPROV ms $config{HOSTNAME} zimbraReverseProxyStrictServerNameEnabled TRUE\");\n        progress(\"done.\\n\");\n     } else {\n        progress(\"Disabling strict server name enforcement on $config{HOSTNAME}...\");\n        runAsZimbra(\"$ZMPROV ms $config{HOSTNAME} zimbraReverseProxyStrictServerNameEnabled FALSE\");\n        progress(\"done.\\n\");\n     }\n     if ($config{MAILPROXY} eq \"FALSE\" && $config{HTTPPROXY} eq \"FALSE\") {\n        $enabledPackages{\"zimbra-proxy\"} = \"Disabled\";\n     } else {\n       my $upstream=\"-u\";\n       if ($config{zimbra_require_interprocess_security}) {\n         $upstream=\"-U\";\n       }\n       if($config{MAILPROXY} eq \"TRUE\") {\n         runAsZimbra(\"/opt/zimbra/libexec/zmproxyconfig $upstream -m -e -o \".\n                     \"-i $config{IMAPPORT}:$config{IMAPPROXYPORT}:$config{IMAPSSLPORT}:$config{IMAPSSLPROXYPORT} \".\n                     \"-p $config{POPPORT}:$config{POPPROXYPORT}:$config{POPSSLPORT}:$config{POPSSLPROXYPORT} -H $config{HOSTNAME}\");\n       } else {\n         runAsZimbra(\"/opt/zimbra/libexec/zmproxyconfig -m -d -o \".\n                     \"-i $config{IMAPPORT}:$config{IMAPPROXYPORT}:$config{IMAPSSLPORT}:$config{IMAPSSLPROXYPORT} \".\n                     \"-p $config{POPPORT}:$config{POPPROXYPORT}:$config{POPSSLPORT}:$config{POPSSLPROXYPORT} -H $config{HOSTNAME}\");\n       }\n       if ($config{HTTPPROXY} eq \"TRUE\" ) {\n         runAsZimbra(\"/opt/zimbra/libexec/zmproxyconfig $upstream -w -e -o \".\n                     \" -x $config{PROXYMODE} \".\n                     \"-a $config{HTTPPORT}:$config{HTTPPROXYPORT}:$config{HTTPSPORT}:$config{HTTPSPROXYPORT} -H $config{HOSTNAME}\");\n       } else {\n         runAsZimbra(\"/opt/zimbra/libexec/zmproxyconfig -w -d -o \".\n                     \"-x $config{MODE} \".\n                     \"-a $config{HTTPPORT}:$config{HTTPPROXYPORT}:$config{HTTPSPORT}:$config{HTTPSPROXYPORT} -H $config{HOSTNAME}\");\n       }\n     }\n     if (!(isEnabled(\"zimbra-store\"))) {\n       my @storetargets;\n       detail(\"Running $ZMPROV garpu\");\n       open(ZMPROV, \"$ZMPROV garpu 2>/dev/null|\");\n       chomp(@storetargets = <ZMPROV>);\n       close(ZMPROV);\n       if ( $storetargets[0] !~ /nginx-lookup/ ) {\n         progress(\"WARNING: There is currently no mailstore to proxy. Proxy will restart once one becomes available.\\n\");\n       }\n     }\n     if (!(isEnabled(\"zimbra-memcached\"))) {\n       my @memcachetargets;\n       detail(\"Running $ZMPROV gamcs\");\n       open(ZMPROV, \"$ZMPROV gamcs 2>/dev/null|\");\n       chomp(@memcachetargets = <ZMPROV>);\n       close(ZMPROV);\n       if ( $memcachetargets[0] !~ /:11211/ ) {\n         progress(\"WARNING: There are currently no memcached servers for the proxy.  Proxy will start once one becomes available.\\n\");\n       }\n     }\n   } else {\n     runAsZimbra(\"/opt/zimbra/libexec/zmproxyconfig -m -d -o \".\n                 \"-i $config{IMAPPORT}:$config{IMAPPROXYPORT}:$config{IMAPSSLPORT}:$config{IMAPSSLPROXYPORT} \".\n                 \"-p $config{POPPORT}:$config{POPPROXYPORT}:$config{POPSSLPORT}:$config{POPSSLPROXYPORT} -H $config{HOSTNAME}\");\n     runAsZimbra(\"/opt/zimbra/libexec/zmproxyconfig -w -d -o \".\n                 \"-x $config{MODE} \".\n                 \"-a $config{HTTPPORT}:$config{HTTPPROXYPORT}:$config{HTTPSPORT}:$config{HTTPSPROXYPORT} -H $config{HOSTNAME}\");\n   }\n}\n\nsub removeNetworkComponents {\n    my $components = getLdapConfigValue(\"zimbraComponentAvailable\");\n    my @zmprov_args = ();\n    foreach my $component (split(/\\n/,$components)) {\n      push(@zmprov_args, ('-zimbraComponentAvailable', $component))\n        if ($component =~ /HSM|convertd|archiving|hotbackup/);\n\n      if ($component =~ /convertd/) {\n        my $rc = 0;\n        progress (\"Removing convertd mime tree from ldap...\");\n        my $ldap_pass = getLocalConfig(\"zimbra_ldap_password\");\n        my $ldap_master_url = getLocalConfig(\"ldap_master_url\");\n        my $ldap;\n        my @masters=split(/ /, $ldap_master_url);\n        my $master_ref=\\@masters;\n        unless($ldap = Net::LDAP->new($master_ref)) {\n          detail(\"Unable to contact $ldap_master_url: $!\");\n          $rc = 1;\n        }\n        my $ldap_dn = $config{zimbra_ldap_userdn};\n        my $ldap_base = \"\";\n\n        my $result = $ldap->bind($ldap_dn, password => $ldap_pass);\n        if ($result->code()) {\n          detail(\"ldap bind failed for $ldap_dn\");\n          $rc = 1;\n        } else {\n          $result = $ldap->modify('cn=text/enriched,cn=mime,cn=config,cn=zimbra',\n            replace => [ 'zimbraMimeHandlerClass' => 'TextEnrichedHandler' ] );\n\n          $result = $ldap->modify('cn=text/plain,cn=mime,cn=config,cn=zimbra',\n            replace => [ 'zimbraMimeHandlerClass' => 'TextPlainHandler' ] );\n\n          $result = $ldap->modify('cn=all,cn=mime,cn=config,cn=zimbra',\n            changes => [\n              replace => [ 'zimbraMimeHandlerClass' => 'UnknownTypeHandler' ],\n              delete => [ 'zimbraMimeHandlerExtension' => []]\n            ] );\n\n          $result = $ldap->delete('cn=application/x-zip-compressed,cn=mime,cn=config,cn=zimbra');\n          $result = $ldap->delete('cn=application/zip,cn=mime,cn=config,cn=zimbra');\n          $result = $ldap->delete('cn=text/rtf,cn=mime,cn=config,cn=zimbra');\n          $result = $ldap->delete('cn=unsupported,cn=mime,cn=config,cn=zimbra');\n\n          $result = $ldap->unbind;\n          $result = $ldap->disconnect;\n        }\n        progress (($rc == 0) ? \"done.\\n\" : \"failed. This may impact system functionality.\\n\");\n\n        progress (\"Removing convertd from zimbraServiceEnabled list...\");\n        my $rc = setLdapServerConfig($config{HOSTNAME}, '-zimbraServiceEnabled', 'convertd');\n        progress (($rc == 0) ? \"done.\\n\" : \"failed. This may impact system functionality.\\n\");\n      }\n    }\n\tif (@zmprov_args) {\n      progress (\"Removing network components from ldap...\");\n      my $rc = setLdapGlobalConfig( @zmprov_args );\n      progress (($rc == 0) ? \"done.\\n\" : \"failed. This may impact system functionality.\\n\");\n    }\n    foreach my $zimlet (qw(com_zimbra_backuprestore com_zimbra_convertd com_zimbra_domainadmin com_zimbra_hsm com_zimbra_license com_zimbra_mobilesync zimbra_xmbxsearch com_zimbra_xmbxsearch com_zimbra_smime_cert_admin com_zimbra_delegatedadmin com_zimbra_smime com_zimbra_two_factor_auth)) {\n      system(\"rm -rf $config{mailboxd_directory}/webapps/service/zimlet/$zimlet\")\n        if (-d \"$config{mailboxd_directory}/webapps/service/zimlet/$zimlet\" );\n      system(\"rm -rf /opt/zimbra/zimlets-deployed/$zimlet\")\n        if (-d \"/opt/zimbra/zimlets-deployed/$zimlet\" );\n    }\n\n    if (isEnabled(\"zimbra-ldap\") && -x \"/opt/zimbra/libexec/zmconvertdmod\") {\n      progress (\"Removing convertd mime tree from ldap...\");\n      my $rc = runAsZimbra(\"/opt/zimbra/libexec/zmconvertdmod -d\");\n      progress (($rc == 0) ? \"done.\\n\" : \"failed. This may impact system functionality.\\n\");\n    }\n    setLdapGlobalConfig(\"zimbraReverseProxyUpstreamEwsServers\",\"\");\n}\n\nsub countReverseProxyLookupTargets {\n  my $count = 0;\n  my $ldap_pass = getLocalConfig(\"zimbra_ldap_password\");\n  my $ldap_master_url = getLocalConfig(\"ldap_master_url\");\n  my $ldap;\n  my @masters=split(/ /, $ldap_master_url);\n  my $master_ref=\\@masters;\n\n  unless($ldap = Net::LDAP->new($master_ref)) {\n    detail(\"Unable to contact $ldap_master_url: $!\");\n    return;\n  }\n  my $ldap_dn = $config{zimbra_ldap_userdn};\n  my $ldap_base = \"\";\n\n  my $result = $ldap->bind($ldap_dn, password => $ldap_pass);\n  if ($result->code()) {\n    detail(\"ldap bind failed for $ldap_dn\");\n    return;\n  } else {\n    detail(\"ldap bind done for $ldap_dn\");\n    progress(\"Searching LDAP for reverseProxyLookupTargets...\");\n    $result = $ldap->search(base => 'cn=zimbra', filter => '(zimbraReverseProxyLookupTarget=TRUE)', attrs => ['1.1']);\n\n    progress (($result->code()) ? \"failed.\\n\" : \"done.\\n\");\n    return if ($result->code());\n    $count = $result->count;\n  }\n  return \"$count\";\n}\n\nsub countUsers {\n  return $main::loaded{stats}{numAccts}\n    if (exists $main::loaded{stats}{numAccts});\n  my $count = 0;\n  my $ldap_pass = getLocalConfig(\"zimbra_ldap_password\");\n  my $ldap_master_url = getLocalConfig(\"ldap_master_url\");\n  my $ldap;\n  my @masters=split(/ /, $ldap_master_url);\n  my $master_ref=\\@masters;\n  unless($ldap = Net::LDAP->new($master_ref)) {\n    detail(\"Unable to contact $ldap_master_url: $!\");\n    return undef;\n  }\n  my $ldap_dn = $config{zimbra_ldap_userdn};\n  my $ldap_base = \"\";\n\n  my $result = $ldap->bind($ldap_dn, password => $ldap_pass);\n  if ($result->code()) {\n    detail(\"ldap bind failed for $ldap_dn\");\n    return undef;\n  } else {\n    detail(\"ldap bind done for $ldap_dn\");\n    progress(\"Searching LDAP for zimbra accounts...\");\n    $result = $ldap->search(filter => \"(objectclass=zimbraAccount)\", \\\n      attrs => ['zimbraMailDeliveryAddress']);\n    progress (($result->code()) ? \"failed.\\n\" : \"done.\\n\");\n    return undef if ($result->code());\n    $count = $result->count;\n  }\n  $result = $ldap->unbind;\n  $main::loaded{stats}{numAccts} = $count\n    if ($count > 0);\n  return(($count > 0) ? \"$count\" : undef);\n}\n\nsub removeNetworkZimlets {\n  my $ldap_pass = getLocalConfig(\"zimbra_ldap_password\");\n  my $ldap_master_url = getLocalConfig(\"ldap_master_url\");\n  my $ldap;\n  my @masters=split(/ /, $ldap_master_url);\n  my $master_ref=\\@masters;\n  unless($ldap = Net::LDAP->new($master_ref)) {\n    detail(\"Unable to contact $ldap_master_url: $!\");\n    return 1;\n  }\n  my $ldap_dn = $config{zimbra_ldap_userdn};\n  my $ldap_base = \"cn=zimlets,$config{ldap_dit_base_dn_config}\";\n\n  my $result = $ldap->bind($ldap_dn, password => $ldap_pass);\n  if ($result->code()) {\n    detail(\"ldap bind failed for $ldap_dn\");\n    return 1;\n  } else {\n    detail(\"ldap bind done for $ldap_dn\");\n    progress(\"Checking for network zimlets in LDAP...\");\n    $result = $ldap->search(base => $ldap_base, scope => 'one', filter => \"(|(cn=com_zimbra_backuprestore)(cn=com_zimbra_domainadmin)(cn=com_zimbra_mobilesync)(cn=com_zimbra_hsm)(cn=com_zimbra_convertd)(cn=com_zimbra_license)(cn=zimbra_xmbxsearch)(cn=com_zimbra_xmbxsearch)(cn=com_zimbra_smime)(cn=com_zimbra_smime_cert_admin)(cn=com_zimbra_two_factor_auth))\", attrs => ['cn']);\n    progress (($result->code()) ? \"failed.\\n\" : \"done.\\n\");\n    return $result if ($result->code());\n\n    detail(\"Processing ldap search results\");\n    progress(\"Removing network zimlets...\\n\");\n    foreach my $entry ($result->all_entries) {\n      my $zimlet = $entry->get_value('cn');\n      if ( $zimlet ne \"\" ) {\n        progress(\"\\tRemoving $zimlet...\");\n        my $rc = runAsZimbra(\"/opt/zimbra/bin/zmzimletctl -l undeploy $zimlet\");\n        progress (($rc == 0) ? \"done.\\n\" : \"failed. This may impact system functionality.\\n\");\n      }\n    }\n    progress(\"Finished removing network zimlets.\\n\");\n  }\n  $result = $ldap->unbind;\n  return 0;\n}\n\nsub zimletCleanup {\n  my $ldap_pass = getLocalConfig(\"zimbra_ldap_password\");\n  my $ldap_master_url = getLocalConfig(\"ldap_master_url\");\n  my $ldap;\n  my @masters=split(/ /, $ldap_master_url);\n  my $master_ref=\\@masters;\n  unless($ldap = Net::LDAP->new($master_ref)) {\n    detail(\"Unable to contact $ldap_master_url: $!\");\n    return 1;\n  }\n  my $ldap_dn = $config{zimbra_ldap_userdn};\n  my $ldap_base = \"cn=zimlets,$config{ldap_dit_base_dn_config}\";\n\n  my $result = $ldap->bind($ldap_dn, password => $ldap_pass);\n  if ($result->code()) {\n    detail(\"ldap bind failed for $ldap_dn\");\n    return 1;\n  } else {\n    detail(\"ldap bind done for $ldap_dn\");\n    $result = $ldap->search(base => $ldap_base, scope => 'one', filter => \"(|(cn=convertd)(cn=hsm)(cn=hotbackup)(cn=zimbra_cert_manager)(cn=com_zimbra_search)(cn=zimbra_xmbxsearch)(cn=com_zimbra_domainadmin)(cn=com_zimbra_tinymce)(cn=com_zimbra_tasksreminder)(cn=com_zimbra_linkedin)(cn=com_zimbra_social)(cn=com_zimbra_dnd)(cn=com_zextras_chat_open)(cn=com_zextras_talk)(cn=com_zimbra_smime)(cn=zimbra-zimlet-restore-contacts)(cn=zimbra-zimlet-duplicate-contacts))\", attrs => ['cn']);\n    return $result if ($result->code());\n    detail(\"Processing ldap search results\");\n    foreach my $entry ($result->all_entries) {\n      my $zimlet = $entry->get_value('cn');\n      if ( $zimlet ne \"\" ) {\n        detail(\"Removing $zimlet\");\n        runAsZimbra(\"/opt/zimbra/bin/zmzimletctl -l undeploy $zimlet\");\n        system(\"rm -rf $config{mailboxd_directory}/webapps/service/zimlet/$zimlet\")\n          if (-d \"$config{mailboxd_directory}/webapps/service/zimlet/$zimlet\" );\n\tsystem(\"rm -rf /opt/zimbra/jetty/webapps/zimbra/public/${zimlet}.jarx\")\n\t  if (-f \"/opt/zimbra/jetty/webapps/zimbra/public/${zimlet}.jarx\" );\n\tsystem(\"rm -rf /opt/zimbra/zimlets-deployed/$zimlet\")\n\t  if (-d \"/opt/zimbra/zimlets-deployed/$zimlet\" );\n\tsystem(\"rm -rf /opt/zimbra/zimlets-network/${zimlet}.zip\")\n\t  if (-f \"/opt/zimbra/zimlets-network/${zimlet}.zip\" );\n\tsystem(\"rm -rf /opt/zimbra/zimlets/${zimlet}.zip\")\n\t  if (-f \"/opt/zimbra/zimlets/${zimlet}.zip\" );\n      }\n    }\n  }\n  $result = $ldap->unbind;\n  return 0;\n}\n\nsub configInstallZimlets {\n\n  if ($configStatus{configInstallZimlets} eq \"CONFIGURED\") {\n    configLog(\"configInstallZimlets\");\n    return 0;\n  }\n\n  my $zimlet_directory = getLocalConfig(\"zimlet_directory\") || \"/opt/zimbra/zimlets-deployed\";\n  my $zimlet_properties = getLocalConfig(\"zimlet_properties_directory\") || \"/opt/zimbra/zimlets-properties\";\n  my (undef,undef,$uid,$gid) = getpwnam(\"zimbra\");\n\n  mkdir($zimlet_directory)\n    if (! -d $zimlet_directory);\n  chown($uid,$gid, $zimlet_directory);\n  chmod(0755, $zimlet_directory);\n\n  system(\"/bin/rm -rf $zimlet_properties\")\n    if ( -d $zimlet_properties);\n\n  # remove deprecated zimlets on upgrades\n  if (!$newinstall) {\n    progress(\"Checking for deprecated zimlets...\");\n    progress((zimletCleanup()) ? \"failed.\\n\" : \"done.\\n\");\n  }\n\n  # remove any Network zimlets if we are upgrading to a FOSS version\n  if (isFoss() && !$newinstall) {\n    removeNetworkZimlets();\n  }\n\n  # Install zimlets\n  if (opendir DIR, \"/opt/zimbra/zimlets\") {\n    progress ( \"Installing common zimlets...\\n\" );\n    my @core_zimlets = (qw(com_zimbra_dnd com_zimbra_url com_zimbra_date com_zimbra_email com_zimbra_attachcontacts com_zimbra_attachmail));\n    my @zimlets = grep { !/^\\./ } readdir(DIR);\n    foreach my $zimletfile (@zimlets) {\n      my $zimlet = $zimletfile;\n      $zimlet =~ s/\\.zip$//;\n      progress  (\"\\t$zimlet...\");\n      my $rc = runAsZimbra (\"/opt/zimbra/bin/zmzimletctl -l deploy zimlets/$zimletfile\");\n      if ($rc == 0) {\n        setLdapCOSConfig(\"+zimbraZimletAvailableZimlets\", \"!$zimlet\")\n          if (grep(/$zimlet/, @core_zimlets));\n        progress(\"done.\\n\");\n      } else {\n        progress(\"failed. This may impact system functionality.\\n\");\n      }\n\n    }\n    progress ( \"Finished installing common zimlets.\\n\" );\n  }\n\n  # Install zimlets\n  if (opendir DIR, \"/opt/zimbra/zimlets-network\") {\n    progress ( \"Installing network zimlets...\\n\" );\n    my @zimlets = grep { !/^\\./ } readdir(DIR);\n    foreach my $zimletfile (@zimlets) {\n      my $zimlet = $zimletfile;\n      $zimlet =~ s/\\.zip$//;\n      progress  (\"\\t$zimlet...\");\n      my $rc = runAsZimbra (\"/opt/zimbra/bin/zmzimletctl -l deploy zimlets-network/$zimletfile\");\n      progress (($rc == 0) ? \"done.\\n\" : \"failed. This may impact system functionality.\\n\");\n      # disable click2call zimlets by default.  #73987\n      setLdapCOSConfig(\"+zimbraZimletAvailableZimlets\", \"-$zimlet\")\n        if ($zimlet =~ /click2call/);\n    }\n    progress ( \"Finished installing network zimlets.\\n\" );\n  }\n\n  # Reinstall extras that are deployed on upgrade\n  if (!$newinstall) {\n    my $ldap_pass = getLocalConfig(\"zimbra_ldap_password\");\n    my $ldap_master_url = getLocalConfig(\"ldap_master_url\");\n    my $ldap;\n    my @masters=split(/ /, $ldap_master_url);\n    my $master_ref=\\@masters;\n    unless($ldap = Net::LDAP->new($master_ref)) {\n      detail(\"Unable to contact $ldap_master_url: $!\");\n      return 1;\n    }\n    my $ldap_dn = $config{zimbra_ldap_userdn};\n    my $ldap_base = \"cn=zimlets,$config{ldap_dit_base_dn_config}\";\n\n    my $result = $ldap->bind($ldap_dn, password => $ldap_pass);\n    if ($result->code()) {\n      detail(\"ldap bind failed for $ldap_dn\");\n      return 1;\n    } else {\n      detail(\"ldap bind done for $ldap_dn\");\n      progress(\"Getting list of all zimlets...\");\n      $result = $ldap->search(base => $ldap_base, scope => 'one', filter => '(objectClass=zimbraZimletEntry)', attrs => ['cn']);\n      progress (($result->code()) ? \"failed.\\n\" : \"done.\\n\");\n      return $result if ($result->code());\n\n      progress(\"Updating non-standard zimlets...\\n\");\n      foreach my $entry ($result->all_entries) {\n        my $zimlet = $entry->get_value('cn');\n        foreach my $type (qw(zimlets-admin-extra zimlets-experimental zimlets-extra)) {\n          if (-e \"/opt/zimbra/${type}/${zimlet}.zip\") {\n           progress  (\"\\t$zimlet...\");\n           my $rc = runAsZimbra (\"/opt/zimbra/bin/zmzimletctl -l deploy ${type}/${zimlet}.zip\");\n           progress (($rc == 0) ? \"done.\\n\" : \"failed. This may impact system functionality.\\n\");\n          }\n        }\n      }\n      progress(\"Finished updating non-standard zimlets.\\n\");\n    $result = $ldap->unbind;\n    }\n  }\n\n  configLog(\"configInstallZimlets\");\n}\n\nsub configCreateDomain {\n\n  if ($configStatus{configCreateDomain} eq \"CONFIGURED\") {\n    configLog(\"configCreateDomain\");\n    return 0;\n  }\n\n  if (!$ldapConfigured && isEnabled(\"zimbra-ldap\")) {\n    if ($config{DOCREATEDOMAIN} eq \"yes\") {\n      progress ( \"Creating domain $config{CREATEDOMAIN}...\" );\n      my $domainId = getLdapDomainValue(\"zimbraId\");\n      if ($domainId ne \"\") {\n        progress(\"already exists.\\n\");\n      } else {\n        my $rc = runAsZimbra(\"$ZMPROV cd $config{CREATEDOMAIN}\");\n        progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n      }\n\n      progress(\"Setting default domain name...\");\n      my $rc = setLdapGlobalConfig(\"zimbraDefaultDomainName\", $config{CREATEDOMAIN});\n      progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n    }\n\n    configInitDomainAdminGroups()\n      if (isNetwork() && isLdapMaster() && isZCS());\n  }\n  if (isEnabled(\"zimbra-store\")) {\n    if ($config{DOCREATEADMIN} eq \"yes\") {\n      $config{CREATEADMIN} = lc($config{CREATEADMIN});\n      my ($u,$d) = split ('@', $config{CREATEADMIN});\n\n      progress (\"Creating domain $d...\");\n      my $domainId = getLdapDomainValue(\"zimbraId\",$d);\n      if ($domainId ne \"\") {\n        progress(\"already exists.\\n\");\n      } else {\n        my $rc = runAsZimbra(\"$ZMPROV cd $d\");\n        progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n      }\n\n      progress (\"Creating admin account $config{CREATEADMIN}...\");\n      my $acctId = getLdapAccountValue(\"zimbraId\", $config{CREATEADMIN});\n      if ($acctId ne \"\") {\n        progress(\"already exists.\\n\");\n      } else {\n        my $rc = runAsZimbra(\"$ZMPROV ca \".\n          \"$config{CREATEADMIN} \\'$config{CREATEADMINPASS}\\' \".\n          \"zimbraAdminConsoleUIComponents cartBlancheUI \".\n          \"description \\'Administrative Account\\' \".\n          \"zimbraIsAdminAccount TRUE\");\n        progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n      }\n\n      # no root/postmaster accounts on web-only nodes\n      if (isStoreServiceNode()) {\n        progress ( \"Creating root alias...\" );\n        my $rc = runAsZimbra(\"$ZMPROV aaa \".\n        \"$config{CREATEADMIN} root\\@$config{CREATEDOMAIN}\");\n        progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n\n        progress ( \"Creating postmaster alias...\" );\n        $rc = runAsZimbra(\"$ZMPROV aaa \".\n        \"$config{CREATEADMIN} postmaster\\@$config{CREATEDOMAIN}\");\n        progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n      }\n\n    }\n\n    if ($config{DOTRAINSA} eq \"yes\") {\n      $config{TRAINSASPAM} = lc($config{TRAINSASPAM});\n      progress ( \"Creating user $config{TRAINSASPAM}...\" );\n      my $acctId = getLdapAccountValue(\"zimbraId\", $config{TRAINSASPAM});\n      if ($acctId ne \"\") {\n        progress(\"already exists.\\n\");\n      } else {\n        my $pass = genRandomPass();\n        my $rc = runAsZimbra(\"$ZMPROV ca \".\n          \"$config{TRAINSASPAM} \\'$pass\\' \".\n          \"amavisBypassSpamChecks TRUE \".\n          \"zimbraAttachmentsIndexingEnabled FALSE \".\n          \"zimbraIsSystemResource TRUE \".\n          \"zimbraIsSystemAccount TRUE \".\n          \"zimbraHideInGal TRUE \".\n          \"zimbraMailQuota 0 \".\n          \"description \\'System account for spam training.\\'\");\n        progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n      }\n\n      $config{TRAINSAHAM} = lc($config{TRAINSAHAM});\n      progress ( \"Creating user $config{TRAINSAHAM}...\" );\n      my $acctId = getLdapAccountValue(\"zimbraId\", $config{TRAINSAHAM});\n      if ($acctId ne \"\") {\n        progress(\"already exists.\\n\");\n      } else {\n        my $pass = genRandomPass();\n        my $rc = runAsZimbra(\"$ZMPROV ca \".\n          \"$config{TRAINSAHAM} \\'$pass\\' \".\n          \"amavisBypassSpamChecks TRUE \".\n          \"zimbraAttachmentsIndexingEnabled FALSE \".\n          \"zimbraIsSystemResource TRUE \".\n          \"zimbraIsSystemAccount TRUE \".\n          \"zimbraHideInGal TRUE \".\n          \"zimbraMailQuota 0 \".\n          \"description \\'System account for Non-Spam (Ham) training.\\'\");\n        progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n      }\n\n      $config{VIRUSQUARANTINE} = lc($config{VIRUSQUARANTINE});\n      progress ( \"Creating user $config{VIRUSQUARANTINE}...\" );\n      my $acctId = getLdapAccountValue(\"zimbraId\", $config{VIRUSQUARANTINE});\n      if ($acctId ne \"\") {\n        progress(\"already exists.\\n\");\n      } else {\n        my $pass = genRandomPass();\n        my $rc = runAsZimbra(\"$ZMPROV ca \".\n          \"$config{VIRUSQUARANTINE} \\'$pass\\' \".\n          \"amavisBypassSpamChecks TRUE \".\n          \"zimbraAttachmentsIndexingEnabled FALSE \".\n          \"zimbraIsSystemResource TRUE \".\n          \"zimbraIsSystemAccount TRUE \".\n          \"zimbraHideInGal TRUE \".\n          \"zimbraMailMessageLifetime 30d \".\n          \"zimbraMailQuota 0 \".\n          \"description \\'System account for Anti-virus quarantine.\\'\");\n        progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n      }\n\n      progress ( \"Setting spam training and Anti-virus quarantine accounts...\" );\n      my $rc = setLdapGlobalConfig(\n        'zimbraSpamIsSpamAccount', \"$config{TRAINSASPAM}\",\n        'zimbraSpamIsNotSpamAccount', \"$config{TRAINSAHAM}\",\n        'zimbraAmavisQuarantineAccount', \"$config{VIRUSQUARANTINE}\"\n        );\n      progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n    }\n  }\n  configLog(\"configCreateDomain\");\n}\n\nsub configInitSql {\n\n  if ($configStatus{configInitSql} eq \"CONFIGURED\") {\n    configLog(\"configInitSql\");\n    return 0;\n  }\n\n  if (!$sqlConfigured &&\n    (isEnabled(\"zimbra-store\") ||\n      (isEnabled(\"zimbra-onlyoffice\") && $newinstall && !isEnabled(\"zimbra-store\"))\n    )\n    ) {\n    progress ( \"Initializing store sql database...\" );\n    runAsZimbra (\"/opt/zimbra/libexec/zmmyinit --mysql_memory_percent $config{MYSQLMEMORYPERCENT}\");\n    progress ( \"done.\\n\" );\n    progress ( \"Setting zimbraSmtpHostname for $config{HOSTNAME}...\" );\n\n    #SMTP host can be one or more values seperated by comma or space.\n    my @smtphost = split /[,\\s]+/, $config{SMTPHOST};\n    foreach(@smtphost) {\n       my $rc = setLdapServerConfig(\"+zimbraSmtpHostname\", $_);\n       progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n    }\n  }\n  configLog(\"configInitSql\");\n}\n\nsub configInitLogger {\n\n  if ($configStatus{configInitLogger} eq \"CONFIGURED\") {\n    configLog(\"configInitLogger\");\n    return 0;\n  }\n\n  if (isEnabled(\"zimbra-logger\")) {\n    setLdapGlobalConfig(\"zimbraLogHostname\", $config{HOSTNAME});\n    setLocalConfig (\"smtp_source\", $config{SMTPSOURCE});\n    setLocalConfig (\"smtp_destination\", $config{SMTPDEST});\n  }\n  configLog(\"configInitLogger\");\n}\n\nsub configInitCore {\n\n  if ($configStatus{configInitCore} eq \"CONFIGURED\") {\n    configLog(\"configInitCore\");\n    return 0;\n  }\n  if (isEnabled(\"zimbra-core\")) {\n    progress ( \"Initializing core config...\" );\n    if(isNetwork()) {\n      if ($config{RUNVMHA} eq \"yes\") {\n        push(@enabledServiceList, ('zimbraServiceEnabled', 'vmware-ha'));\n      }\n    }\n  }\n  configLog(\"configInitCore\");\n}\n\nsub configInitMta {\n\n  if ($configStatus{configInitMta} eq \"CONFIGURED\") {\n    configLog(\"configInitMta\");\n    return 0;\n  }\n\n  if (isEnabled(\"zimbra-mta\")) {\n    progress ( \"Initializing mta config...\" );\n\n    setLocalConfig(\"postfix_mail_owner\", $config{postfix_mail_owner});\n    setLocalConfig(\"postfix_setgid_group\", $config{postfix_setgid_group});\n\n    runAsZimbra (\"/opt/zimbra/libexec/zmmtainit $config{LDAPHOST} $config{LDAPPORT}\");\n    progress ( \"done.\\n\" );\n    if (isZCS()) {\n      push(@installedServiceList, ('zimbraServiceInstalled', 'amavis'));\n      push(@installedServiceList, ('zimbraServiceInstalled', 'antivirus'));\n      push(@installedServiceList, ('zimbraServiceInstalled', 'antispam'));\n      push(@installedServiceList, ('zimbraServiceInstalled', 'opendkim'));\n      push(@enabledServiceList, ('zimbraServiceEnabled', 'amavis'));\n      if ($config{RUNAV} eq \"yes\") {\n        push(@enabledServiceList, ('zimbraServiceEnabled', 'antivirus'));\n      }\n      if ($config{RUNARCHIVING} eq \"yes\") {\n        push(@installedServiceList, ('zimbraServiceInstalled', 'archiving'));\n        push(@enabledServiceList, ('zimbraServiceEnabled', 'archiving'));\n      }\n      if ($config{RUNSA} eq \"yes\") {\n        push(@enabledServiceList, ('zimbraServiceEnabled', 'antispam'));\n      }\n      if ($config{RUNDKIM} eq \"yes\") {\n        push(@enabledServiceList, ('zimbraServiceEnabled', 'opendkim'));\n      }\n      if ($config{RUNCBPOLICYD} eq \"yes\") {\n        push(@enabledServiceList, ('zimbraServiceEnabled', 'cbpolicyd'));\n      }\n    }\n    setLdapServerConfig(\"zimbraMtaMyNetworks\", $config{zimbraMtaMyNetworks})\n      if ($config{zimbraMtaMyNetworks} ne \"\");\n\n\n  }\n  configLog(\"configInitMta\");\n}\n\nsub configInitSnmp {\n\n  if ($configStatus{configInitSnmp} eq \"CONFIGURED\") {\n    configLog(\"configInitSnmp\");\n    return 0;\n  }\n\n  if (isEnabled(\"zimbra-snmp\")) {\n    progress ( \"Configuring SNMP...\" );\n    setLocalConfig (\"snmp_notify\", $config{SNMPNOTIFY});\n    setLocalConfig (\"smtp_notify\", $config{SMTPNOTIFY});\n    setLocalConfig (\"snmp_trap_host\", $config{SNMPTRAPHOST});\n    setLocalConfig (\"smtp_source\", $config{SMTPSOURCE});\n    setLocalConfig (\"smtp_destination\", $config{SMTPDEST});\n    runAsZimbra (\"/opt/zimbra/libexec/zmsnmpinit\");\n    progress ( \"done.\\n\" );\n  }\n  configLog(\"configInitSnmp\");\n}\n\nsub configInitGALSyncAccts {\n\n  if ($configStatus{configInitGALSyncAccts} eq \"CONFIGURED\") {\n    configLog(\"configInitGALSyncAccts\");\n    return 0;\n  }\n\n  return 1 unless\n    (isEnabled(\"zimbra-ldap\") && $config{LDAPHOST} eq $config{HOSTNAME});\n\n  #if ($config{ENABLEGALSYNCACCOUNTS} eq \"yes\") {\n    #progress(\"Creating galsync accounts in all domains...\");\n    #my $rc = runAsZimbra(\"zmjava com.zimbra.cs.account.ldap.upgrade.LdapUpgrade -b 14531 -v\");\n    #progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n    #configLog(\"configInitGALSyncAccts\") if ($rc == 0);\n  #}\n}\n\nsub configCreateDefaultDomainGALSyncAcct {\n\n  if ($configStatus{configCreateDefaultGALSyncAcct} eq \"CONFIGURED\") {\n    configLog(\"configCreateDefaultGALSyncAcct\");\n    return 0;\n  }\n\n    if (isEnabled(\"zimbra-store\")) {\n    progress(\"Creating galsync account for default domain...\");\n    my $zimbra_server = getLocalConfig (\"zimbra_server_hostname\");\n    my $default_domain = (($newinstall) ? \"$config{CREATEDOMAIN}\" : \"$config{zimbraDefaultDomainName}\");\n    my $galsyncacct = \"galsync.\" . lc(genRandomPass()) . '@' . $default_domain ;\n    my $rc = runAsZimbra(\"/opt/zimbra/bin/zmgsautil createAccount -a $galsyncacct -n InternalGAL --domain $default_domain -s $zimbra_server -t zimbra -f _InternalGAL\");\n    progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n    configLog(\"configCreateDefaultDomainGALSyncAcct\") if ($rc == 0);\n  }\n}\n\nsub configImap {\n  progress(\"Enabling IMAP protocol for zimbra-imapd service...\");\n  runAsZimbra(\"$ZMPROV mcf zimbraRemoteImapServerEnabled TRUE\");\n  progress(\"done.\\n\");\n  progress(\"Enabling IMAPS protocol for zimbra-imapd service...\");\n  runAsZimbra(\"$ZMPROV mcf zimbraRemoteImapSSLServerEnabled TRUE\");\n  progress(\"done.\\n\");\n  if ($config{DOADDUPSTREAMIMAP} eq \"yes\") {\n    progress(\"Adding $config{HOSTNAME} to list of zimbraReverseProxyUpstreamImapServers...\");\n    runAsZimbra(\"$ZMPROV mcf +zimbraReverseProxyUpstreamImapServers $config{HOSTNAME}\");\n    progress(\"done.\\n\");\n    progress(\"Disabling IMAP protocol in mailboxd...\");\n    runAsZimbra(\"$ZMPROV mcf zimbraImapServerEnabled FALSE\");\n    progress(\"done.\\n\");\n    progress(\"Disabling IMAPS protocol in mailboxd...\");\n    runAsZimbra(\"$ZMPROV mcf zimbraImapSSLServerEnabled FALSE\");\n    progress(\"done.\\n\");\n  }\n}\n\nsub configSetEnabledServices {\n\n  if ($configStatus{configSetEnabledServices} eq \"CONFIGURED\") {\n    configLog(\"configSetEnabledServices\");\n    return 0;\n  }\n\n  foreach my $p (keys %installedPackages) {\n    if ($p eq \"zimbra-core\") {\n      push(@installedServiceList, ('zimbraServiceInstalled','stats'));\n      if(isNetwork()) {\n        if ( -x \"/usr/lib/vmware-tools/sbin64/vmware-checkvm\" || $config{INSTVMHA} eq \"yes\") {\n          my $rc = runAsRoot(\"/usr/lib/vmware-tools/sbin64/vmware-checkvm\");\n          if ($rc == 0 || $config{INSTVMHA} eq \"yes\") {\n            push(@installedServiceList, ('zimbraServiceInstalled','vmware-ha'));\n          }\n        }\n      }\n      next;\n    }\n    if ($p eq \"zimbra-apache\") {next;}\n    if ($p eq \"zimbra-archiving\") {next;}\n    $p =~ s/zimbra-//;\n    if ($p eq \"store\") {$p = \"mailbox\";}\n    if ($p eq \"license-daemon\") {\n\t    if (isInstalled(\"zimbra-${p}\")) {\n\t\t    $p = \"license-daemon\";\n\t    } else {\n\t\t    next;\n\t    }\n    }\n    push(@installedServiceList, ('zimbraServiceInstalled', \"$p\"));\n  }\n\n  foreach my $p (keys %enabledPackages) {\n    if ($p eq \"zimbra-core\") {\n      push(@enabledServiceList, ('zimbraServiceEnabled', 'stats'));\n      next;\n    }\n    if ($p eq \"zimbra-apache\") {next;}\n    if ($p eq \"zimbra-archiving\") {next;}\n    if ($enabledPackages{$p} eq \"Enabled\") {\n      $p =~ s/zimbra-//;\n      if ($p eq \"store\") {\n        $p = \"mailbox\";\n        # Add zimbra-store webapps to service list\n        foreach my $app (@webappList) {\n          if ($installedWebapps{$app} eq \"Enabled\") {\n            push(@enabledServiceList, 'zimbraServiceEnabled', \"$app\");\n          }\n        }\n      }\n      if ($p eq \"license-daemon\") {\n\t      if (isInstalled(\"zimbra-${p}\")) {\n\t\t      $p = \"license-daemon\";\n\t      } else {\n\t\t      next;\n\t      }\n      }\n      push(@enabledServiceList, 'zimbraServiceEnabled', \"$p\");\n    }\n  }\n\n  progress ( \"Setting services on $config{HOSTNAME}...\" );\n  setLdapServerConfig($config{HOSTNAME}, @installedServiceList);\n  setLdapServerConfig($config{HOSTNAME}, @enabledServiceList);\n  progress ( \"done.\\n\" );\n\n  my $rc = runAsZimbra(\"/opt/zimbra/libexec/zmiptool >/dev/null 2>/dev/null\");\n\n  configLog(\"configSetEnabledServices\");\n}\n\nsub failConfig {\n  progress (\"\\n\\nERROR\\n\\n\");\n  progress (\"\\n\\nConfiguration failed\\n\\n\");\n  progress (\"Please address the error and re-run /opt/zimbra/libexec/zmsetup.pl to\\n\");\n  progress (\"complete the configuration.\\n\");\n  progress (\"\\nErrors have been logged to $logfile\\n\\n\");\n  exit 1;\n}\n\nsub applyConfig {\n\n  defineInstallWebapps();\n  if (!(defined ($options{c})) && $newinstall ) {\n    if (askYN(\"Save configuration data to a file?\", \"Yes\") eq \"yes\") {\n      saveConfig();\n    }\n    if (askYN(\"The system will be modified - continue?\", \"No\") eq \"no\") {\n      return 1;\n    }\n  } else {\n    saveConfig();\n  }\n  progress ( \"Operations logged to $logfile\\n\" );\n\n  if ($newinstall) {\n    open (H, \">>/opt/zimbra/.install_history\");\n    print H time(),\": CONFIG SESSION START\\n\";\n    # This is the postinstall config\n    configLog (\"BEGIN\");\n  }\n\n  # On split store node setups, the unused webapps need to be removed before\n  # applying any other configuration in order to ensure the installedWebapps\n  # variables are properly setup for later steps.\n  if (isEnabled(\"zimbra-store\")) {\n    removeUnusedWebapps();\n  }\n\n  configLCValues();\n\n  configInitCore();\n\n  # About SSL\n  #\n  # On the master ldap server, create a ca and a cert\n  # On store and MTA servers, just create a cert.\n  #\n  # Non-ldap masters use the master CA, which they get from ldap\n  # but ldap won't start without a cert.\n  #\n  # so - ldap - create CA, create cert, init ldap, store CA in ldap\n  #\n  # non-ldap - fetch CA, create cert\n\n  configCASetup();\n\n  configCreateCert();\n\n  configInstallCert();\n\n  if ($ldapReplica) {\n    configCreateServerEntry();\n  }\n\n  configSetupLdap();\n\n  if (!$ldapReplica) {\n    configCreateServerEntry();\n  }\n\n  configSaveCA();\n\n  configSaveCert();\n\n  # Added the following for bug 103803. Could not just add the cert as a globalConfigValue\n  # for zimbraSSldHParam.  See bug 104244.\n  setLdapGlobalConfig(\"zimbraSSLDHParam\", \"/opt/zimbra/conf/dhparam.pem.zcs\") if $newinstall;\n\n  if (isEnabled(\"zimbra-store\")) {\n\n    configSpellServer();\n\n    configSetServicePorts();\n\n    configSetKeyboardShortcutsPref() if (!$newinstall);\n\n    configInitBackupPrefs();\n\n    configSetCEFeatures() if isZCS();\n\n    configSetNEFeatures() if isNetwork();\n\n    configSetStoreDefaults();\n  }\n  configSetupEphemeralBackend();\n\n  if (isNetwork() && isEnabled(\"zimbra-convertd\")) {\n    configConvertdURL();\n    runAsZimbra(\"/opt/zimbra/libexec/zmconvertdmod -e\");\n  }\n\n  if (isEnabled(\"zimbra-dnscache\")) {\n    configSetDNSCacheDefaults();\n  }\n\n  configLDAPSchemaVersion();\n\n  if (isEnabled(\"zimbra-ldap\")) {\n    configSetTimeZonePref();\n\n    # 32295\n    setLdapGlobalConfig(\"zimbraSkinLogoURL\", \"http://www.zimbra.com\")\n      if isFoss();\n  }\n\n  if ($newinstall && isInstalled(\"zimbra-proxy\")) {\n    configSetProxyPrefs();\n  }\n\n  if( (!$newinstall) && isInstalled(\"zimbra-ldap\") ){\n    setProxyBits();\n  }\n\n  configInitMta();\n\n  configureLicenseDaemonService();\n\n  configSetEnabledServices();\n\n  if (isEnabled(\"zimbra-store\")) {\n    if (isStoreServiceNode()) {\n      addServerToHostPool();\n    }\n    # bug 100730\n    if ($config{UIWEBAPPS} eq \"no\") {\n      setLdapServerConfig($config{HOSTNAME}, \"zimbraReverseProxyHttpEnabled\", \"FALSE\");\n    }\n  }\n\n  configCreateDomain();\n\n\n  # onlyoffice\n  if (isEnabled(\"zimbra-onlyoffice\") && !isEnabled(\"zimbra-store\")\n    && ( $newinstall || $configStatus{configOnlyoffice} ne \"CONFIGURED\") ) {\n    ##create the directories required\n    createDirForStandaloneOnlyoffice();\n\n    setLocalConfig (\"mysql_bind_address\", '127.0.0.1');\n    if ( !-e \"/etc/sudoers.d/02_zimbra-store\") {\n      system(\"echo \\\"%zimbra ALL=NOPASSWD:/opt/zimbra/libexec/zmmailboxdmgr\\\" > /etc/sudoers.d/02_zimbra-store\");\n      system(\"chmod 440 /etc/sudoers.d/02_zimbra-store\");\n    }\n  }\n\n  configInitSql();\n\n  configInitLogger();\n\n  configInitSnmp();\n\n  configInitGALSyncAccts();\n\n  setupSyslog();\n\n  postinstall::configure();\n\n  qx(touch /opt/zimbra/.bash_history);\n  qx(chown zimbra:zimbra /opt/zimbra/.bash_history);\n\n  if (isFoss() && !$newinstall) {\n    startLdap() if ($ldapConfigured);\n    removeNetworkComponents();\n  }\n\n  setLdapServerConfig($config{HOSTNAME}, 'zimbraServerVersion', $curVersion);\n  setLdapServerConfig($config{HOSTNAME}, 'zimbraServerVersionMajor', $curVersionMajor);\n  setLdapServerConfig($config{HOSTNAME}, 'zimbraServerVersionMinor', $curVersionMinor);\n  setLdapServerConfig($config{HOSTNAME}, 'zimbraServerVersionMicro', $curVersionMicroMicro);\n  setLdapServerConfig($config{HOSTNAME}, 'zimbraServerVersionType', $curVersionType);\n  setLdapServerConfig($config{HOSTNAME}, 'zimbraServerVersionBuild', $curVersionBuild);\n\n  if (isEnabled(\"zimbra-imapd\")) {\n    configImap();\n  }\n\n  if (getLdapConfigValue(\"zimbraLicenseNotificationEmail\") eq \"\") {\n          progress(\"Setting zimbraLicenseNotificationEmail...\");\n          setLdapGlobalConfig(\"zimbraLicenseNotificationEmail\", $config{CREATEADMIN});\n          progress(\"done.\\n\");\n  }\n\n  configureOnlyoffice();\n\n  if ($config{STARTSERVERS} eq \"yes\") {\n    # bug 6270\n    if (isEnabled(\"zimbra-store\")) {\n      qx(chown zimbra:zimbra /opt/zimbra/redolog/redo.log)\n        if (($platform =~ m/DEBIAN/ || $platform =~ m/UBUNTU/) && ! $newinstall);\n    }\n\n    sub prevVersionBelow880 {\n      if (($prevVersionMajor < 8) || ($prevVersionMajor = 8 && $prevVersionMinor < 8)) {\n        return 1;\n      }\n    }\n\n    # Disable zextras modules\n    my $zimbraNetworkModulesNGEnabled = getLdapServerValue(\"zimbraNetworkModulesNGEnabled\");\n    if ($zimbraNetworkModulesNGEnabled eq \"TRUE\"){\n       setLdapServerConfig($config{HOSTNAME}, 'zimbraNetworkModulesNGEnabled', 'FALSE');\n    }\n\n    my $zimbraNetworkAdminEnabled = getLdapServerValue(\"zimbraNetworkAdminEnabled\");\n    if ($zimbraNetworkAdminEnabled eq \"TRUE\"){\n       setLdapServerConfig($config{HOSTNAME}, 'zimbraNetworkAdminEnabled', 'FALSE');\n    }\n\n    my $zimbraNetworkAdminNGEnabled = getLdapServerValue(\"zimbraNetworkAdminNGEnabled\");\n    if ($zimbraNetworkAdminNGEnabled eq \"TRUE\"){\n       setLdapServerConfig($config{HOSTNAME}, 'zimbraNetworkAdminNGEnabled', 'FALSE');\n    }\n\n    my $zimbraNetworkMobileNGEnabled = getLdapServerValue(\"zimbraNetworkMobileNGEnabled\");\n    if ($zimbraNetworkMobileNGEnabled eq \"TRUE\"){\n       setLdapServerConfig($config{HOSTNAME}, 'zimbraNetworkMobileNGEnabled', 'FALSE');\n    }\n\n    enableTLSv1_3();\n    addJDK17Options();\n    runAsZimbra (\"/opt/zimbra/bin/zmcontrol stop\" );\n    if (isInstalled(\"zimbra-license-daemon\")) {\n\t    runAsZimbra (\"/opt/zimbra/bin/zmlicensectl --service stop\");\n    }\n    if (isInstalled(\"zimbra-ldap\") && isEnabled(\"zimbra-ldap\")) {\n\t    startLdap();\n    }\n    progress (\"Starting servers...\");\n    runAsZimbra (\"/opt/zimbra/bin/zmlicensectl --service start\") if isLicenseDaemonConfigured();\n    runAsZimbra (\"/opt/zimbra/bin/zmcontrol start\");\n    qx($SU \"/opt/zimbra/bin/zmcontrol status\");\n    progress ( \"done.\\n\" );\n    if ($skip_activation_check =~ /^yes$/i) {\n\t    progress (\"Skipping license activation.\\n\");\n    } else {\n\t    activateLicense();\n    }\n\n    # Initialize application server specific items\n    # only after the application server is running.\n    if (isEnabled(\"zimbra-store\")) {\n      progress(\"Enabling jetty logging...\");\n      system(\"/opt/zimbra/libexec/zmjettyenablelogging > /dev/null 2>&1\");\n      progress(\"done.\\n\");\n\n      configInstallZimlets();\n\n      progress ( \"Restarting mailboxd...\");\n      runAsZimbra(\"/opt/zimbra/bin/zmmailboxdctl restart\");\n      progress ( \"done.\\n\" );\n    }\n    if ($newinstall && isStoreServiceNode()) {\n      configCreateDefaultDomainGALSyncAcct();\n    } else {\n      if ($newinstall) {\n        progress (\"Skipping creation of default domain GAL sync account - not a service node.\\n\");\n      } else {\n        progress ( \"Skipping creation of default domain GAL sync account - existing install detected.\\n\" );\n      }\n    }\n  } else {\n    progress ( \"WARNING: Document and Zimlet initialization skipped because Application Server was not configured to start.\\n\".\n               \"WARNING: galsync account creation for default domain skipped because Application Server was not configured to start.\\n\")\n      if (isEnabled(\"zimbra-store\"));\n  }\n\n  postinstall::notifyZimbra();\n\n  setupCrontab();\n\n  if ($newinstall) {\n    runAsZimbra (\"/opt/zimbra/bin/zmsshkeygen\");\n    runAsZimbra (\"/opt/zimbra/bin/zmupdateauthkeys\");\n  } else {\n    runAsZimbra (\"/opt/zimbra/bin/zmupdateauthkeys\");\n  }\n\n  configLog (\"END\");\n\n  print H time(),\": CONFIG SESSION COMPLETE\\n\";\n\n  close H;\n\n  getSystemStatus();\n\n  progress ( \"\\n\\n\" );\n  chmod 0600, $logfile;\n  if (-d \"/opt/zimbra/log\") {\n    main::progress(\"Moving $logfile to /opt/zimbra/log\\n\");\n    system(\"cp -f $logfile /opt/zimbra/log/\");\n    system(\"chown zimbra:zimbra /opt/zimbra/log/$logFileName\");\n  } else {\n    progress ( \"Operations logged to $logfile\\n\" );\n  }\n  progress ( \"\\n\\n\" );\n  # cleanup license option files\n  unlink($license_file) if -e $license_file;\n  unlink(\"/opt/zimbra/conf/ZCSLicense.xml\") if -e \"/opt/zimbra/conf/ZCSLicense.xml\";\n  unlink(\"/opt/zimbra/conf/ZCSLicense-Trial.xml\") if -e \"/opt/zimbra/conf/ZCSLicense-Trial.xml\";\n  unlink($skip_activation_file) if -e $skip_activation_file;\n  if (!defined ($options{c})) {\n    ask(\"Configuration complete - press return to exit\", \"\");\n    print \"\\n\\n\";\n    close LOGFILE;\n    exit 0;\n  }\n}\n\nsub configureOnlyoffice {\n    # create onlyoffice db and configure it\n  if (isEnabled(\"zimbra-onlyoffice\") ) {\n    #enable preview\n    setLdapCOSConfig(\"zimbraFeatureViewInHTMLEnabled\", \"TRUE\");\n    # configure onlyoffice\n    print \"Configuring Onlyoffice...\\n\";\n    open(my $py, \"|-\", \"/opt/zimbra/onlyoffice/bin/zmonlyofficeconfig\");\n    while (<$py>) {\n\t     print \"$py\";\n    }\n    close($py);\n\n    if ($configStatus{configOnlyoffice} eq \"CONFIGURED\") {\n      configLog(\"configOnlyoffice\");\n      return 0;\n    }\n\n    if ($configStatus{configOnlyoffice} ne \"CONFIGURED\" || $newinstall) {\n          qx(chmod +x /opt/zimbra/onlyoffice/bin/zmonlyofficeconfig);\n          qx(chmod 775 /opt/zimbra/onlyoffice/bin/process_id.json);\n          qx(chown -R zimbra:zimbra /opt/zimbra/onlyoffice/documentserver/);\n          qx(chown zimbra:zimbra /opt/zimbra/onlyoffice/bin/process_id.json);\n\n          # on new install\n          if (zmupgrade::startSql()) { return 1; }\n          createOnlyofficeDB();\n\n          # set the config value zimbraDocumentServerHost\n          # if standalone server :\n          #    1. global config already present, do not override\n          #    2. global config not present, this server name goes as global config\n          # if not standalone:\n          #    set the server host name at server level config\n          if (isEnabled(\"zimbra-store\") && $config{ONLYOFFICESTANDALONE} eq \"no\") {\n            setLdapServerConfig($config{HOSTNAME}, 'zimbraDocumentServerHost', $config{HOSTNAME});\n          } else {\n              my $tmpval = getLdapConfigValue(\"zimbraDocumentServerHost\");\n              if ($tmpval eq \"\") {\n                setLdapGlobalConfig(\"zimbraDocumentServerHost\", $config{HOSTNAME});\n              } else {\n                setLdapGlobalConfig(\"zimbraDocumentServerHost\", $config{ONLYOFFICEHOSTNAME});\n              }\n          }\n          configLog(\"configOnlyoffice\");\n    }\n  }\n}\n\nsub removePackage {\n\tmy $pkg = shift;\n\tmy $pkgrm;\n\tif ($platform =~ /^DEBIAN/ || $platform =~ /^UBUNTU/) {\n\t\t$pkgrm = \"dpkg --purge\";\n\t} else {\n\t\t$pkgrm = \"yum -y --disablerepo=* erase -v\";\n\t}\n\tif (isInstalled($pkg)) {\n\t\tprogress (\"Removing $pkg from this host...\");\n\t\tmy $rc = 0xffff & system (\"$pkgrm $pkg > /dev/null 2>&1\");\n\t\tprogress (($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n\t}\n}\n\nsub configureLicenseDaemonService {\n\tif (isEnabled(\"zimbra-license-daemon\")) {\n\t\tprogress ( \"Configuring license daemon service...\\n\" );\n\t\tmy $licenseDaemonServerHost = getLdapConfigValue(\"zimbraLicenseDaemonServerHost\");\n\t\tif ($licenseDaemonServerHost ne \"\" && $licenseDaemonServerHost ne $config{HOSTNAME}) {\n\t\t\tprogress(\"WARNING: license-daemon service already installed on $licenseDaemonServerHost\\n\");\n\t\t\tremovePackage(\"zimbra-lds-patch\");\n\t\t\tremovePackage(\"zimbra-license-daemon\");\n\t\t} else {\n\t\t\tprogress(\"Setting zimbraLicenseDaemonServerHost...\");\n\t\t\tmy $rc = setLdapGlobalConfig(\"zimbraLicenseDaemonServerHost\", $config{HOSTNAME});\n\t\t\tprogress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n\t\t}\n\t\tprogress ( \"done.\\n\" );\n\t}\n}\n\nsub createDirForStandaloneOnlyoffice {\n\n  my (undef,undef,$uid,$gid) = getpwnam(\"zimbra\");\n\n  my @dir_to_create = ('/opt/zimbra/index', '/opt/zimbra/store', '/opt/zimbra/data/tmp/mysql', '/opt/zimbra/mailboxd', 'opt/zimbra/common/conf');\n  foreach my $dir (@dir_to_create) {\n      eval { make_path($dir) };\n      if ($@) {\n        print \"Couldn't create $dir: $@\";\n      } else {\n        chown($uid,$gid, $dir);\n        chmod(0755, $dir);\n      }\n  }\n}\n\nsub createOnlyofficeDB {\n\n  my $mysql_root_pass = getLocalConfig (\"mysql_root_password\");\n  progress ( \"Creating onlyoffice database...\" );\n  runAsZimbra (\"exec /opt/zimbra/common/bin/mysql -S /opt/zimbra/data/tmp/mysql/mysql.sock -u root --password=$mysql_root_pass < /opt/zimbra/onlyoffice/bin/createdb.sql\");\n  progress ( \"done.\\n\" );\n}\n\nsub configLog {\n  my $stage = shift;\n  my $msg = time().\": CONFIGURED $stage\\n\";\n  print H $msg;\n  #progress ($msg);\n}\n\nsub setupSyslog {\n  progress (\"Setting up syslog.conf...\");\n  if ( -f \"/opt/zimbra/libexec/zmsyslogsetup\") {\n    my $rc = runAsRoot(\"/opt/zimbra/libexec/zmsyslogsetup\");\n    if ($rc) {\n      progress (\"Failed\\n\");\n      } else {\n      progress (\"done.\\n\");\n    }\n  } else {\n    progress (\"Failed\\n\");\n  }\n  configLog(\"setupSyslog\");\n}\n\nsub setupCrontab {\n  my @backupSchedule=();\n  my $nohsm=1;\n  progress (\"Setting up zimbra crontab...\");\n  if ( -x \"/opt/zimbra/bin/zmschedulebackup\") {\n    detail(\"Getting current backup schedule in restorable format.\");\n    @backupSchedule = (qx($SU \"zmschedulebackup -s\" 2>> $logfile));\n    for (my $i=0;$i<=$#backupSchedule;$i++) {\n      $backupSchedule[$i] =~ s/\"/\\\\\"/g;\n    }\n    if (scalar @backupSchedule == 0) {\n      detail(\"Backup schedule was not previously defined\");\n    } else {\n      detail(\"Retrieved backup schedule:\\n @backupSchedule\");\n    }\n  }\n  detail(\"crontab: Taking a copy of zimbra user crontab file.\");\n  if ($platform =~ /SUSE/i) {\n    if (-e '/var/spool/cron/tabs/zimbra') {\n      qx(cp -f /var/spool/cron/tabs/zimbra /tmp/crontab.zimbra.orig);\n    } else {\n      unlink(\"/tmp/crontab.zimbra.orig\");\n      qx(touch /tmp/crontab.zimbra.orig);\n    }\n  } else {\n    qx(crontab -u zimbra -l > /tmp/crontab.zimbra.orig 2> /dev/null);\n  }\n  $nohsm  = 0xffff & system(\"grep '/opt/zimbra/bin/zmhsm[[:space:]]\\\\+-t' /tmp/crontab.zimbra.orig > /dev/null 2>&1\");\n  if (!$nohsm) {\n    detail(\"HSM is in use, no backup schedule required\");\n  }\n  detail(\"crontab: Looking for ZIMBRASTART in existing crontab entry.\");\n  my $rc = 0xffff & system(\"grep ZIMBRASTART /tmp/crontab.zimbra.orig > /dev/null 2>&1\");\n  if ($rc) {\n    detail(\"crontab: ZIMBRASTART not found truncating zimbra crontab and starting fresh.\");\n    qx(cp -f /dev/null /tmp/crontab.zimbra.orig 2>> $logfile);\n  }\n  detail(\"crontab: Looking for ZIMBRAEND in existing crontab entry.\");\n  $rc = 0xffff & system(\"grep ZIMBRAEND /tmp/crontab.zimbra.orig > /dev/null 2>&1\");\n  if ($rc) {\n    detail(\"crontab: ZIMBRAEND not found truncating zimbra crontab and starting fresh.\");\n    qx(cp -f /dev/null /tmp/crontab.zimbra.orig);\n  }\n  detail(\"crontab: Getting existing backup and custom entries from crontab file.\");\n  qx(cat /tmp/crontab.zimbra.orig | sed -e '/# ZIMBRASTART/,/# ZIMBRAEND/d' > /tmp/crontab.zimbra.proc);\n  detail(\"crontab: Adding zimbra-core specific crontab entries\");\n  qx(cp -f /opt/zimbra/conf/crontabs/crontab /tmp/crontab.zimbra);\n\n  if (isEnabled(\"zimbra-ldap\")) {\n    detail(\"crontab: Adding zimbra-ldap specific crontab entries\");\n    qx(cat /opt/zimbra/conf/crontabs/crontab.ldap >> /tmp/crontab.zimbra 2>> $logfile);\n  }\n\n  if (isEnabled(\"zimbra-store\")) {\n    detail(\"crontab: Adding zimbra-store specific crontab entries\");\n    qx(cat /opt/zimbra/conf/crontabs/crontab.store >> /tmp/crontab.zimbra 2>> $logfile);\n  }\n\n  if (isEnabled(\"zimbra-logger\")) {\n    detail(\"crontab: Adding zimbra-logger specific crontab entries\");\n    qx(cat /opt/zimbra/conf/crontabs/crontab.logger >> /tmp/crontab.zimbra 2>> $logfile);\n  }\n\n  if (isEnabled(\"zimbra-mta\")) {\n    detail(\"crontab: Adding zimbra-mta specific crontab entries\");\n    qx(cat /opt/zimbra/conf/crontabs/crontab.mta >> /tmp/crontab.zimbra 2>> $logfile);\n  }\n\n  detail(\"crontab: adding backup block\");\n  qx(echo \"# ZIMBRAEND -- DO NOT EDIT ANYTHING BETWEEN THIS LINE AND ZIMBRASTART\" >> /tmp/crontab.zimbra);\n  detail(\"crontab: Adding backup and custom entries to crontab.\");\n  qx(cat /tmp/crontab.zimbra.proc >> /tmp/crontab.zimbra);\n  detail(\"crontab: installing new crontab\");\n  qx(crontab -u zimbra /tmp/crontab.zimbra 2> /dev/null);\n  if ( -x \"/opt/zimbra/bin/zmschedulebackup\" && scalar @backupSchedule > 0) {\n    detail(\"crontab: Restoring previous backup schedule.\");\n    for (my $i=0;$i<=$#backupSchedule;$i++) {\n      chomp($backupSchedule[$i]);\n      if ($i == 0) {\n        detail(\"crontab: $SU \\\"/opt/zimbra/bin/zmschedulebackup -R $backupSchedule[$i]\\\"\");\n        runAsZimbra(\"/opt/zimbra/bin/zmschedulebackup -R $backupSchedule[$i]\");\n      } else {\n        detail(\"crontab: $SU \\\"/opt/zimbra/bin/zmschedulebackup -A $backupSchedule[$i]\\\"\");\n        runAsZimbra(\"/opt/zimbra/bin/zmschedulebackup -A $backupSchedule[$i]\");\n      }\n    }\n  } elsif ( -f \"/opt/zimbra/bin/zmschedulebackup\" && scalar @backupSchedule == 0 && !$newinstall && $nohsm) {\n    detail(\"crontab: No backup schedule found: installing default schedule.\");\n    qx($SU \"/opt/zimbra/bin/zmschedulebackup -D\" >> $logfile 2>&1);\n  }\n\n  progress (\"done.\\n\");\n  configLog(\"setupCrontab\");\n}\n\nsub getSystemMemory {\n  my $os = lc qx(uname -s);\n  chomp($os);\n  return \"unknown\" unless $os;\n  my $mem;\n  if ($os eq \"linux\") {\n    $mem = qx(cat /proc/meminfo | grep ^MemTotal: | awk '{print \\$2}');\n    chomp($mem);\n    $mem = sprintf \"%0.1f\", $mem/(1024*1024);\n  } elsif ($os eq \"darwin\") {\n    $mem = qx(sysctl hw.memsize | awk '{print \\$NF}');\n    chomp($mem);\n    $mem = sprintf \"%0.1f\", $mem/(1024*1024*1024);\n  }\n  return $mem;\n}\n\nsub mysqlMemoryPercent {\n  my $system_mem = shift;\n  my $os = lc qx(uname -s);\n  chomp($os);\n  my $percent = 30;\n  return $percent;\n}\n\nsub mailboxdMemoryMB {\n  my $system_mem = shift;\n  my $memory;\n  if ($system_mem > 16) {\n    $memory = 0.2*$system_mem;\n  } else {\n    $memory = 0.25*$system_mem;\n  }\n  return int($memory*1024);\n}\n\nsub addServerToHostPool {\n  progress ( \"Adding $config{HOSTNAME} to zimbraMailHostPool in default COS...\" );\n  my $id = getLdapServerValue(\"zimbraId\", $config{HOSTNAME});\n  my $hp = getLdapCOSValue(\"zimbraMailHostPool\");\n\n  if ($id eq \"\") {\n    progress(\"failed. Couldn't find a server entry for $config{HOSTNAME}\\n\");\n    return undef;\n  }\n  $hp.=(($hp eq \"\") ? \"$id\" : \"\\n$id\");\n\n  my %k;\n  my @zmprov_args = ();\n  foreach my $serverid (split(/\\n/, $hp)) {\n    $k{$serverid}=1;\n  }\n  foreach my $host (keys %k) {\n    push(@zmprov_args, ('zimbraMailHostPool', $host));\n  }\n  my $rc = setLdapCOSConfig('default', @zmprov_args);\n  progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n}\n\nsub mainMenu {\n  my %mm = ();\n  $mm{createsub} = \\&createMainMenu;\n\n  displayMenu(\\%mm);\n}\n\nsub stopLdap {\n  main::progress(\"Stopping ldap...\");\n  my $rc = runAsZimbra(\"/opt/zimbra/bin/ldap stop\");\n  main::progress(($rc == 0) ? \"done.\\n\" : \"failed. ldap had exit status: $rc.\\n\");\n  sleep 5 unless $rc; # give it a chance to shutdown.\n  return $rc;\n}\n\nsub startLdap {\n  main::detail(\"Checking ldap status....\");\n  my $rc = runAsZimbra(\"/opt/zimbra/bin/ldap status\");\n  main::detail(($rc == 0) ? \"already running.\\n\" : \"not running.\\n\");\n\n  if ($rc) {\n    main::progress(\"Checking ldap status....\");\n    $rc = runAsZimbra (\"/opt/zimbra/bin/ldap status\");\n    main::progress(($rc == 0) ? \"already running.\\n\" : \"not running.\\n\");\n\n    if ($rc) {\n      main::progress(\"Starting ldap...\");\n      $rc = runAsZimbra(\"/opt/zimbra/bin/ldap start\");\n      main::progress(($rc == 0) ? \"done.\\n\" : \"failed with exit code: $rc.\\n\");\n      if ($rc) {\n        system(\"$SU \\\"/opt/zimbra/bin/ldap start 2>&1 | grep failed\\\"\");\n        return $rc;\n      }\n    }\n  }\n  return 0;\n}\n\nsub resumeConfiguration {\n  progress ( \"\\n\\nNote\\n\\n\" );\n  progress ( \"The previous configuration appears to have failed to complete\\n\\n\");\n  if (askYN (\"Attempt to complete configuration now?\", \"yes\") eq \"yes\") {\n    applyConfig();\n  } else {\n    %configStatus = ();\n  }\n}\n\nsub enableTLSv1_3 {\n\tif (isInstalled(\"zimbra-proxy\") && isEnabled(\"zimbra-proxy\")) {\n\t\tprogress( \"Setting zimbraReverseProxySSLProtocols...\");\n\t\tmy $rc = main::runAsZimbra(\"$ZMPROV mcf +zimbraReverseProxySSLProtocols TLSv1.3\");\n\t\tprogress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n\t\tmy $proxysslciphers = getLdapConfigValue(\"zimbraReverseProxySSLCiphers\");\n\t\tif ($proxysslciphers eq \"ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128:AES256:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4\") {\n\t\t\tprogress( \"Setting zimbraReverseProxySSLCiphers...\");\n\t\t\tmy $rc = main::runAsZimbra(\"$ZMPROV mcf zimbraReverseProxySSLCiphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128:AES256:TLS_AES_256_GCM_SHA384:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4'\");\n\t\t\tprogress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n\t\t    }\n\t}\n\tif (isInstalled(\"zimbra-store\")) {\n\t\tprogress( \"Setting mailboxd_java_options...\");\n\t\tmy $mailboxd_java_options=getLocalConfigRaw(\"mailboxd_java_options\");\n\t\tmy $new_mailboxd_options=\"\";\n\t\tforeach my $option (split(/\\s+/, $mailboxd_java_options)) {\n\t\t\tif ($option =~ /-Dhttps.protocols/) {\n\t\t\t\t$new_mailboxd_options .= \" -Dhttps.protocols=TLSv1.2,TLSv1.3\";\n\t\t\t}\n\t\t\telsif ($option =~ /-Djdk.tls.client.protocols/) {\n\t\t\t\t$new_mailboxd_options .= \" -Djdk.tls.client.protocols=TLSv1.2,TLSv1.3\";\n\t\t\t}\n\t\t\telse{\n\t\t\t\t$new_mailboxd_options.=\" $option\";\n\t\t\t}\n\t\t      }\n\t\t$new_mailboxd_options =~ s/^\\s+//;\n\t\tmy $rc = setLocalConfig(\"mailboxd_java_options\", $new_mailboxd_options)if ($new_mailboxd_options ne \"\");\n\t\tprogress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n\t\tprogress( \"Setting zimbra_zmjava_options...\");\n\t\tmy $zimbra_zmjava_options=getLocalConfigRaw(\"zimbra_zmjava_options\");\n\t\tmy $new_zimbra_zmjava_options=\"\";\n\t\tforeach my $option (split(/\\s+/, $zimbra_zmjava_options)) {\n\t\t\tif ($option =~ /-Dhttps.protocols/) {\n\t\t\t\t$new_zimbra_zmjava_options .= \" -Dhttps.protocols=TLSv1.2,TLSv1.3\";\n\t\t\t}\n\t\t\telsif ($option =~ /-Djdk.tls.client.protocols/) {\n\t\t\t\t$new_zimbra_zmjava_options .= \" -Djdk.tls.client.protocols=TLSv1.2,TLSv1.3\";\n\t\t\t}\n\t\t\telse{\n\t\t\t\t$new_zimbra_zmjava_options.=\" $option\";\n\t\t\t}\n\t\t      }\n\t\t$new_zimbra_zmjava_options =~ s/^\\s+//;\n\t\tmy $rc = setLocalConfig(\"zimbra_zmjava_options\", $new_zimbra_zmjava_options)if ($new_zimbra_zmjava_options ne \"\");\n\t\tprogress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n\t}\n\tif (isInstalled(\"zimbra-ldap\")) {\n\t\tprogress( \"Setting ldap_common_tlsciphersuite...\");\n\t\tmy $rc = setLocalConfig(\"ldap_common_tlsciphersuite\", \"!aNULL:!eNULL:!RC4:!DES:!3DES:MEDIUM:HIGH\");\n\t\tprogress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n\t\tprogress( \"Setting ldap_common_tlsprotocolmin...\");\n\t\tmy $rc = setLocalConfig(\"ldap_common_tlsprotocolmin\", \"3.3\");\n\t\tprogress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n\t  }\n\tif (isInstalled(\"zimbra-mta\")) {\n\t\tprogress( \"Setting amavis_sslversion...\");\n\t\tmy $rc = setLocalConfig(\"amavis_sslversion\", \"!TLSv1\");\n\t\tprogress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n\t}\n}\n\nsub addJDK17Options {\n\tif (isInstalled(\"zimbra-core\")) {\n\t\tprogress( \"Setting java options...\");\n\t\tmy $java_options=getLocalConfigRaw(\"mailboxd_java_options\");\n\t\tmy $new_java_options=$java_options;\n\t\tif ($java_options !~ /-Djava.security.egd/) {\n\t\t\t$new_java_options = $new_java_options.\" -Djava.security.egd=file:/dev/./urandom\";\n\t\t}\n\t\tif ($java_options !~ /--add-opens java.base\\/java.lang=ALL-UNNAMED/) {\n\t\t\t$new_java_options = $new_java_options.\" --add-opens java.base/java.lang=ALL-UNNAMED\";\n\t\t}\n\t\tif ($java_options !~ /-Dcom.redhat.fips=false/) {\n\t\t\t$new_java_options = $new_java_options.\" -Dcom.redhat.fips=false\";\n\t\t}\n\t\t$new_java_options =~ s/^\\s+//;\n\t\tmy $rc = setLocalConfig(\"mailboxd_java_options\", $new_java_options)if ($new_java_options ne $java_options);\n\t\tprogress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n\t}\n}\n\nsub activateLicense {\n\tif (isNetwork() && isEnabled(\"zimbra-store\")) {\n\t\tif (! $newinstall ) {\n\t\t\tprogress (\"Activating license...\");\n\t\t\tmy $licensekey = getLdapConfigValue(\"zimbraNetworkRealtimeLicense\");\n\t\t\tif ($licensekey eq \"\") {\n\t\t\t\tchomp($licensekey = qx(cat $license_file)) if (-e $license_file);\n\t\t\t}\n\t\t\tif ($licensekey ne \"\") {\n\t\t\t\tmy $rc = runAsZimbra(\"/opt/zimbra/bin/zmlicense -l -a $licensekey >/dev/null\");\n\t\t\t\tif ($rc != 0) {\n\t\t\t\t\tprogress (\"failed to activate license.\\n\");\n\t\t\t\t} else {\n\t\t\t\t\tprogress (\"license successfully activated.\\n\");\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tprogress (\"license key not found.\\n\");\n\t\t\t}\n\t\t} else {\n\t\t\tif ($config{LICENSEACTIVATIONOPTION} eq \"1\") {\n\t\t\t\tprogress (\"Looking for valid license to activate...\");\n\t\t\t\tmy $licensekey = $config{LICENSEKEY};\n\t\t\t\tmy $rc = runAsZimbra(\"/opt/zimbra/bin/zmlicense -c >/dev/null\");\n\t\t\t\tif ($rc == 256 || $rc == 512) {\n\t\t\t\t\tmy $lic = 1;\n\t\t\t\t\tif ($licensekey ne \"\") {\n\t\t\t\t\t\t$rc = runAsZimbra(\"/opt/zimbra/bin/zmlicense -a $licensekey >/dev/null\");\n\t\t\t\t\t\tif ($rc != 0) {\n\t\t\t\t\t\t\t progress (\"failed to activate license.\\n\");\n\t\t\t\t\t\t\t  $lic = 0;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tprogress (\"license successfully activated.\\n\");\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tprogress (\"license key not found.\\n\");\n\t\t\t\t\t}\n\t\t\t\t\tif ($lic == 0){\n\t\t\t\t\t\tprogress (\"\\n*******ERROR\\n\\nFailed to activate a license - this will prevent your server from functioning properly\\n\");\n\t\t\t\t\t\tprogress (\"Please contact Zimbra to obtain a license\\n\");\n\t\t\t\t\t\task (\"Press RETURN to continue\",\"\");\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tprogress (\"license already activated.\\n\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n\n### end subs\n\n\n__END__\n"
  },
  {
    "path": "rpmconf/LicenseTool/Zimbra/Customer.pm",
    "content": "package Zimbra::Customer;\n\nsub new {\n\tmy $class = shift;\n\tmy $attrs = shift;\n\tmy $self = {};\n\tbless $self, $class;\n\tif (defined ($attrs)) {\n\t\t$self->{name} = $$attrs{name};\n\t\t$self->{id} = $$attrs{id};\n\t}\n\treturn $self;\n}\n\nsub toText {\n\tmy $self = shift;\n\tmy $verbose = shift;\n\tmy $txt = \"ID: $self->{id}\\n\";\n\t$txt .= \"Name: $self->{name}\\n\";\n\treturn $txt;\n}\n\nsub display {\n\tmy $self = shift;\n\tmy $verbose = shift;\n\tprint $self->toText($verbose);\n}\n\n1;\n"
  },
  {
    "path": "rpmconf/LicenseTool/Zimbra/License.pm",
    "content": "package Zimbra::License;\n\nuse strict;\n\nsub new {\n\tmy $class = shift;\n\tmy $attrs = shift;\n\tmy $self = {};\n\tbless $self, $class;\n\tif (defined ($attrs)) {\n\t\t$self->{id} = $$attrs{id};\n\t\t$self->{license_text} = $$attrs{license_text};\n\t\t$self->{license_version} = $$attrs{license_version};\n\t\t$self->{customer_id} = $$attrs{customer_id};\n\t\t$self->{expiration} = $$attrs{expiration};\n\t\t$self->{is_deleted} = $$attrs{is_deleted};\n\t\tforeach (keys %{$$attrs{options}}) {\n\t\t\t$self->{options}{$_} = $$attrs{options}{$_};\n\t\t}\n\t}\n\treturn $self;\n}\n\nsub toText {\n\tmy $self = shift;\n\tmy $verbose = shift;\n\treturn ($self->licenseToText($verbose));\n}\n\nsub licenseToText {\n\tmy $self = shift;\n\tmy $verbose = shift;\n\n\tmy $txt = \"\";\n\tif ($self->{is_deleted}) {\n\t\t$txt .= \"THIS LICENSE IS DELETED\\n\";\n\t}\n\tif ($verbose) {\n\t\t$txt .= $self->{license_text},\"\\n\";\n\t} else {\n\t\t$txt .= sprintf (\"License ID: %d\\n\", $self->{id});\n\t\t$txt .= sprintf (\"License Version: %d\\n\", $self->{license_version});\n\t\t$txt .= sprintf (\"Customer ID: %d\\n\", $self->{customer_id});\n\t\t$txt .= sprintf (\"Expiration: %s\\n\", $self->{expiration});\n\t\tforeach (sort keys %{$self->{options}}) {\n\t\t\t$txt .= sprintf (\"OPTION: %s %s\\n\", $_, $self->{options}{$_});\n\t\t}\n\t}\n\treturn $txt;\n}\n\nsub generate {\n\tmy $self = shift;\n\tprint \"Generating license...\";\n\n\t$self->{license_version} = Zimbra::LicenseKey::getCurrentKeyId();\n\n\t$self->{license_text} = Zimbra::LicenseKey::sign($self->licenseToText()).\"\\n\".$self->licenseToText();\n\n\tprint \"Done\\n\";\n\treturn 1;\n}\n\nsub display {\n\tmy $self = shift;\n\tmy $verbose = shift;\n\tprint $self->toText($verbose);\n}\n\nsub licenseSignature {\n\tmy $self = shift;\n\tmy @sig = split ('\\n',$self->{license_text});\n\tmy $s = \"\";\n\tforeach (@sig) {\n\t\tif (/^$/) {last;}\n\t\t$s .= $_.\"\\n\";\n\t}\n\treturn $s;\n}\n\nsub verify {\n\tmy $self = shift;\n\tmy $verbose = shift;\n\n\tmy $key = Zimbra::LicenseKey::getKey($self->{license_version});\n\n\treturn ($key->verify($self->licenseSignature(),$self->licenseToText()));\n\n\treturn 0;\n}\n\n1;\n"
  },
  {
    "path": "rpmconf/LicenseTool/Zimbra/LicenseKey.pm",
    "content": "package Zimbra::LicenseKey;\n\n# id                      INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,\n# pubkey          TEXT NOT NULL,\n# privkey         TEXT NOT NULL,\n# gendate         DATETIME NOT NULL,\n# expiredate      DATETIME NOT NULL,\n# is_expired      BOOL NOT NULL DEFAULT 0\n\nuse strict;\nuse Time::Local;\n\nsub new {\n\tmy $class = shift;\n\tmy $attrs = shift;\n\tmy $self = {};\n\tbless $self, $class;\n\t$self->{is_expired} = 0;\n\tif (defined $attrs) {\n\t\t$self->{is_expired} = $$attrs{is_expired};\n\t\t$self->{gendate} = sqlTimeToTs($$attrs{gendate});\n\t\t$self->{expiredate} = sqlTimeToTs($$attrs{expiredate});\n\t\t@{$self->{pubkey}} = ();\n\t\tforeach (split /\\n/, $$attrs{pubkey}) {\n\t\t\tpush @{$self->{pubkey}}, $_.\"\\n\";\n\t\t}\n\t\t@{$self->{privkey}} = ();\n\t\tforeach (split /\\n/, $$attrs{privkey}) {\n\t\t\tpush @{$self->{privkey}}, $_.\"\\n\";\n\t\t}\n\t\t$self->{id} = $$attrs{id};\n\t}\n\treturn $self;\n}\n\nsub toText {\n\tmy $self = shift;\n\tmy $verbose = shift;\n\n\tmy $txt = \"\";\n\tif ($self->{is_expired}) {\n\t\t$txt .= \"KEY EXPIRED\\n\\n\";\n\t}\n\t$txt .= \"ID: \";\n\tif (defined($self->{id})) {\n\t\t$txt .= $self->{id};\n\t} else {\n\t\t$txt .= \"NULL\";\n\t}\n\t$txt .= \"\\n\";\n\t$txt .= \"Created: \". tsToSqlTime($self->{gendate}). \"\\n\";\n\t$txt .= \"Expires: \". tsToSqlTime($self->{expiredate}). \"\\n\";\n\tif ($verbose) {\n\t\t$txt .= \"Private Key: \\n\";\n\t\t$txt .= \"\".Zimbra::LicenseKey::keyToString($self->{privkey});\n\t\t$txt .= \"Public Key: \\n\";\n\t\t$txt .= \"\".Zimbra::LicenseKey::keyToString($self->{pubkey});\n\t}\n\treturn $txt;\n}\n\nsub display {\n\tmy $self = shift;\n\tmy $verbose = shift;\n\n\tprint $self->toText($verbose);\n}\n\nsub keyToString {\n\tmy $key = shift;\n\tmy $rv = \"\";\n\tforeach (@{$key}) {\n\t\t$rv .= $_;\n\t}\n\treturn $rv;\n}\n\nsub generate {\n\tprint \"Generating key...\";\n\tmy $self = shift;\n\tmy $ed = shift;\n\tmy $gd = time();\n\tif ($ed eq \"\") {\n\t\t# default 365 days\n\t\t$ed = $gd + (60*60*24*365);\n\t} else {\n\t}\n\n\t$self->{'gendate'} = $gd;\n\t$self->{'expiredate'} = $ed;\n\t# id  set when we store it\n\n\t# Perl Openssl seems like too much trouble...\n\n\tmy $privtmpfile = \"/tmp/key.$$.pem\";\n\tmy $pubtmpfile = \"/tmp/pubkey.$$.pem\";\n\tmy $rc = 0xffff & system (\"openssl genrsa -out $privtmpfile 2048 2> /dev/null\");\n\t$rc = $rc >> 8;\n\tif ($rc) {\n\t\tprint \"FAILED\\n\";\n\t\treturn undef;\n\t}\n\topen KEY, \"$privtmpfile\" or return undef;\n\t@{$self->{'privkey'}} = <KEY>;\n\tclose KEY;\n\tmy $rc = 0xffff & system (\"openssl rsa -in $privtmpfile -pubout -out $pubtmpfile 2> /dev/null\");\n\t$rc = $rc >> 8;\n\tif ($rc) {\n\t\tprint \"FAILED\\n\";\n\t\treturn undef;\n\t}\n\topen KEY, \"$pubtmpfile\" or return undef;\n\t@{$self->{'pubkey'}} = <KEY>;\n\tclose KEY;\n\n\tunlink $privtmpfile;\n\tunlink $pubtmpfile;\n\t\n\t# pubkey, privkey\n\tprint \"Done\\n\";\n\treturn 1;\n}\n\nsub verify {\n\tmy $self = shift;\n\tmy $signature = shift;\n\tmy $plaintext = shift;\n\n\t#print \"Verifying $signature\\n\";\n\t#print \"Against $plaintext\\n\";\n\tmy $tmppkfile = \"/tmp/signkey.$$\";\n\topen K, \"> $tmppkfile\" or return undef;\n\tforeach (@{$self->{privkey}}) {\n\t\tprint K $_;\n\t}\n\tclose K;\n\n\tmy $tmpsnfile = \"/tmp/sn.$$\";\n\topen K, \"> $tmpsnfile\" or return undef;\n\tprint K $signature;\n\tclose K;\n\n\tmy $tmp64file = \"/tmp/64.$$\";\n\topen K, \"> $tmp64file\" or return undef;\n\tprint K $plaintext;\n\tclose K;\n\n\tmy $tmpsigfile = \"/tmp/sig.$$\";\n\t#print \"openssl base64 -d -in $tmpsnfile -out $tmpsigfile > /dev/null 2>&1\\n\\n\";\n\tmy $rc = 0xffff & system \n\t\t(\"openssl base64 -d -in $tmpsnfile -out $tmpsigfile > /dev/null 2>&1\");\n\n\t#print \"openssl dgst -prverify $tmppkfile -signature $tmpsigfile $tmp64file > /dev/null 2>&1\\n\\n\";\n\tmy $rc = 0xffff & system \n\t\t(\"openssl dgst -prverify $tmppkfile -signature $tmpsigfile $tmp64file > /dev/null 2>&1\");\n\t$rc = $rc >> 8;\n\tif ($rc) {\n\t\treturn undef;\n\t}\n\n\tunlink $tmppkfile;\n\tunlink $tmpsnfile;\n\tunlink $tmp64file;\n\tunlink $tmpsigfile;\n\n\treturn 1;\n}\n\nsub sign {\n\tmy ($text) = (@_);\n\tmy $key = getCurrentKey();\n\tif (!defined ($key)) {\n\t\tprint STDERR \"No key to sign with!\\n\\n\";\n\t\treturn undef;\n\t}\n\n\tmy $tmppkfile = \"/tmp/signkey.$$\";\n\tmy $tmpsnfile = \"/tmp/clear.$$\";\n\tmy $tmp64file = \"/tmp/64.$$\";\n\topen K, \"> $tmppkfile\" or return undef;\n\tforeach (@{$key->{privkey}}) {\n\t\tprint K $_;\n\t}\n\tclose K;\n\t\n\topen K, \"> $tmpsnfile\" or return undef;\n\tprint K $text;\n\tclose K;\n\n\t#print \"openssl dgst -sign $tmppkfile $tmpsnfile | openssl base64 -e -out $tmp64file\\n\";\n\tmy $rc = 0xffff & system (\"openssl dgst -sign $tmppkfile $tmpsnfile | openssl base64 -e -out $tmp64file\");\n\t$rc = $rc >> 8;\n\tif ($rc) {\n\t\tprint \"FAILED\\n\";\n\t\treturn undef;\n\t}\n\n\tmy $signed = \"\";\n\topen K, \"$tmp64file\" or return undef;\n\twhile (<K>) {\n\t\t$signed .= $_;\n\t}\n\tclose K;\n\n\tunlink $tmppkfile;\n\tunlink $tmpsnfile;\n\tunlink $tmp64file;\n\n\treturn $signed;\n\n}\n\nsub tsToSqlTime {\n\tmy $ts = shift;\n\tmy $dayTrunc = shift;\n\t# 2005-09-18 04:03:33\n\tmy @tm = localtime($ts);\n\n\t# Truncate at hours.\n\tif (defined($dayTrunc)) {\n\t\treturn sprintf (\"%4d-%02d-%02d %02d:%02d:%02d\",\n\t\t$tm[5]+1900,$tm[4]+1,$tm[3],0,0,0);\n\t} else {\n\t\treturn sprintf (\"%4d-%02d-%02d %02d:%02d:%02d\",\n\t\t$tm[5]+1900,$tm[4]+1,$tm[3],$tm[2],0,0);\n\t}\n}\n\nsub sqlTimeToTs { \n\tmy $sqlTime = shift;\n\t# 2005-09-18 04:03:33\n\treturn timelocal(substr($sqlTime,17,2),substr($sqlTime,14,2),\n\tsubstr($sqlTime,11,2),substr($sqlTime,8,2),\n\t(substr($sqlTime,5,2)-1),substr($sqlTime,0,4));\n}\n\n1;\n\n"
  },
  {
    "path": "rpmconf/LicenseTool/Zimbra/LicensingDB.pm",
    "content": "package Zimbra::LicensingDB;\n\nuse strict;\nuse DBI;\nuse Time::Local;\n\n#my $data_source=\"dbi:mysql:database=license;mysql_read_default_file=/opt/zimbra/conf/my.logger.cnf;mysql_socket=/opt/zimbra/logger/db/mysql.sock\";\nmy $data_source=\"dbi:mysql:database=license;mysql_read_default_file=/etc/my.cnf;mysql_socket=/var/lib/mysql/mysql.sock\";\n\nmy $username=\"license\";\nmy $password = \"licensing\";\n\nmy $dbh = DBI->connect($data_source, $username, $password, {PrintError=>0});\n\nif (!$dbh) {\n\tprint STDERR \"DB: Can't connect to $data_source: $DBI::errstr\\n\";\n\texit 1;\n}\n\nsub tsToSqlTime {\n\tmy $ts = shift;\n\tmy $dayTrunc = shift;\n\t# 2005-09-18 04:03:33\n\tmy @tm = localtime($ts);\n\n\t# Truncate at hours.\n\tif (defined($dayTrunc)) {\n\t\treturn sprintf (\"%4d-%02d-%02d %02d:%02d:%02d\",\n\t\t$tm[5]+1900,$tm[4]+1,$tm[3],0,0,0);\n\t} else {\n\t\treturn sprintf (\"%4d-%02d-%02d %02d:%02d:%02d\",\n\t\t$tm[5]+1900,$tm[4]+1,$tm[3],$tm[2],0,0);\n\t}\n}\n\nsub sqlTimeToTs {\n\tmy $sqlTime = shift;\n\t# 2005-09-18 04:03:33\n\treturn timelocal(substr($sqlTime,17,2),substr($sqlTime,14,2),\n\t\tsubstr($sqlTime,11,2),substr($sqlTime,8,2),\n\t\t(substr($sqlTime,5,2)-1),substr($sqlTime,0,4));\n}\n\nsub getCustomer {\n\tmy $id = shift;\n\tmy $statement = \"select id, name from customer where id=\\\"$id\\\"\";\n\tmy $customer = $dbh->selectrow_hashref($statement);\n\tif (defined($customer)) {\n\t\treturn $customer;\n\t} else {\n\t\treturn undef;\n\t}\n}\n\nsub putCustomer {\n\tmy $customer = shift;\n\tmy $statement = \"insert into customer (name) values (?)\";\n\tmy $sth = sqlExec ($statement, $customer->{name});\n\tif (!$sth) {\n\t\treturn undef;\n\t}\n\tmy $h = $dbh->selectrow_hashref(\"select max(id) as id from customer\");\n\tmy $id = $h->{id};\n\treturn $id;\n}\n\nsub getKeyIds {\n\tmy $statement = \"select id from sign_keys\";\n\tmy $ids = $dbh->selectall_arrayref($statement);\n\treturn $ids;\n}\n\nsub getCustomerIds {\n\tmy $statement = \"select id from customer\";\n\tmy $ids = $dbh->selectall_arrayref($statement);\n\treturn $ids;\n}\n\nsub getKey {\n\tmy $id = shift;\n\tmy $statement = \"select id, pubkey, privkey, gendate, expiredate, is_expired \".\n\t\t\"from sign_keys where id=\\\"$id\\\"\";\n\tmy $key = $dbh->selectrow_hashref($statement);\n\tif (defined($key)) {\n\t\treturn $key;\n\t} else {\n\t\treturn undef;\n\t}\n}\n\nsub putKey {\n\tmy $key = shift;\n\tmy $statement = \"insert into sign_keys (pubkey, privkey, gendate, expiredate, is_expired) \".\n\t\t\"values (?,?,?,?,?)\";\n\tmy $sth = sqlExec ($statement,\n\t\t\t\t\t\tZimbra::LicenseKey::keyToString($key->{pubkey}),\n\t\t\t\t\t\tZimbra::LicenseKey::keyToString($key->{privkey}),\n\t\t\t\t\t\ttsToSqlTime($key->{gendate}),\n\t\t\t\t\t\ttsToSqlTime($key->{expiredate}),\n\t\t\t\t\t\t$key->{is_expired});\n\tmy $h = $dbh->selectrow_hashref(\"select max(id) as id from sign_keys\");\n\tmy $id = $h->{id};\n\treturn $id;\n}\n\nsub getLicenseIds {\n\tmy $statement = \"select id from customer_license\";\n\tmy $ids = $dbh->selectall_arrayref($statement);\n\treturn $ids;\n}\n\nsub getLicense {\n\tmy $id = shift;\n\tmy $statement = \"select id, expiration, customer_id, license_text, license_version, is_deleted \".\n\t\t\"from customer_license where id=\\\"$id\\\"\";\n\tmy $license = $dbh->selectrow_hashref($statement);\n\tif (!defined($license)) {\n\t\treturn undef;\n\t}\n\t\n\t$statement = \"select name, value from license_details where license_id=\\\"$id\\\"\";\n\tmy $ary = $dbh->selectall_arrayref($statement);\n\tforeach my $row (@$ary) {\n\t\t#print \"$$row[0] == $$row[1]\\n\";\n\t\t$license->{options}{$$row[0]} = $$row[1];\n\t}\n\treturn $license;\n}\n\nsub updateLicense {\n\tmy $license = shift;\n\tmy $statement = \"update customer_license set customer_id=\\\"$license->{customer_id}\\\", \".\n\t\t\"expiration=\\\"$license->{expiration}\\\", \".\n\t\t\"license_text=\\'$license->{license_text}\\', \".\n\t\t\"license_version=\\\"$license->{license_version}\\\", \".\n\t\t\"is_deleted=\\\"$license->{is_deleted}\\\" \".\n\t\t\"where id=\\\"$license->{id}\\\"\";\n\tmy $sth = sqlExec ($statement);\n\tif (!$sth) {\n\t\treturn undef;\n\t}\n\n\t$statement = \"delete from license_details where license_id=\\\"$license->{id}\\\"\";\n\tmy $sth = sqlExec ($statement);\n\tif (!$sth) {\n\t\treturn undef;\n\t}\n\n\t$statement = \"insert into license_details (license_id, name, value) values (?,?,?)\";\n\n\tforeach (sort keys %{$license->{options}}) {\n\t\t$sth = sqlExec ($statement, $license->{id}, $_, $license->{options}{$_});\n\t\tif (!$sth) {\n\t\t\treturn undef;\n\t\t}\n\t}\n\treturn 1;\n}\n\nsub putLicense {\n\tmy $license = shift;\n\tmy $statement = \"insert into customer_license (customer_id, expiration, license_text, license_version) \".\n\t\t\"values (?,?,?,?)\";\n\tmy $sth = sqlExec ($statement, $license->{customer_id}, \n\t\t$license->{expiration}, \n\t\t$license->{license_text}, \n\t\t$license->{license_version});\n\tif (!$sth) {\n\t\treturn undef;\n\t}\n\tmy $h = $dbh->selectrow_hashref(\"select max(id) as id from customer_license\");\n\n\tmy $id = $h->{id};\n\treturn $id;\n\n\t$statement = \"insert into license_details (license_id, name, value) values (?,?,?)\";\n\n\tforeach (sort keys %{$license->{options}}) {\n\t\t$sth = sqlExec ($statement, $license->{id}, $_, $license->{options}{$_});\n\t\tif (!$sth) {\n\t\t\treturn undef;\n\t\t}\n\t}\n}\n\nsub sqlExec {\n\tmy $statement = shift;\n\tmy @args = @_;\n\n\tmy $sth = $dbh->prepare($statement);\n\n\t#print \"Executing $statement with @args\\n\\n\";\n\n\teval {\n\t\tif (!$sth->execute(@args) ) {\n\t\t\tdie $sth->errstr;\n\t\t}\n\t};\n\tif ($@) {\n\t\tprint \"Error executing $statement with @args\\n\";\n\t\tprint $sth->errstr,\"\\n\";\n\t\tprint \"$@\\n\";\n\t\treturn undef;\n\t}\n\n\treturn $sth;\n}\n\n1;\n"
  },
  {
    "path": "rpmconf/LicenseTool/db/create_license_db.sql",
    "content": "DROP DATABASE IF EXISTS license;\nCREATE DATABASE license;\n\nUSE license;\n\nGRANT ALL ON license.* to 'license' IDENTIFIED BY 'licensing';\nGRANT ALL ON license.* to 'license'@'localhost' IDENTIFIED BY 'licensing';\n\n# Customers\n\nCREATE TABLE customer (\n\tid\t \t\tINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,\n\tname \t\tVARCHAR(255) NOT NULL,\n\n\tUNIQUE INDEX i_name (name(100))\n);\n\n# Foreign keys (SF id, etc)\n\nCREATE TABLE fk (\n\tcustomer_id\t\tVARCHAR(255) NOT NULL,\n\tfk\t\t\t\tVARCHAR(255) NOT NULL,\n\tcomment\t\t\tVARCHAR(255),\n\n\tPRIMARY KEY (customer_id(100), fk(100))\n);\n\n# Keys\n\nCREATE TABLE sign_keys (\n\tid\t\t\tINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,\n\tpubkey\t\tTEXT NOT NULL,\n\tprivkey\t\tTEXT NOT NULL,\n\tgendate\t\tDATETIME NOT NULL,\n\texpiredate\tDATETIME NOT NULL,\n\tis_expired\tBOOL NOT NULL DEFAULT 0\n);\n\n# Licenses\n\nCREATE TABLE customer_license (\n\tid\t\t\t\t\tINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,\n\texpiration\t\t\tDATETIME NOT NULL,\n\tcustomer_id\t\t\tVARCHAR(255) NOT NULL,\n\tlicense_text\t\tTEXT,\n\tlicense_version\t\tINT UNSIGNED NOT NULL,\n\tis_deleted\t\t\tBOOL NOT NULL DEFAULT 0\n);\n\n# License Details\n\nCREATE TABLE license_details (\n\tlicense_id\t\t\tINT NOT NULL,\n\tname\t\t\t\tVARCHAR(64) NOT NULL,\n\tvalue\t\t\t\tVARCHAR(255) NOT NULL\n);\n\n# License info\n#\n# Customer Name\n# Customer ID\n# License ID\n# \n# Required fields\n# \tKey ID\n# \tGeneration date\n# \tExpiration date\n# \n"
  },
  {
    "path": "rpmconf/LicenseTool/zmlicensetool.pl",
    "content": "#!/usr/bin/perl\n\nuse strict;\nuse Zimbra::LicensingDB;\nuse Zimbra::License;\nuse Zimbra::LicenseKey;\nuse Zimbra::Customer;\n\nuse Getopt::Long;\n\nmy %options = ();\nmy %license_options = ();\n\nmy %actions = (\n\t'license_modify'\t=> \\&modifyLicense,\n\t'license_verify'\t=> \\&verifyLicense,\n\t'license_display'\t=> \\&displayLicense,\n\t'license_create'\t=> \\&createLicense,\n\t'license_list'\t\t=> \\&listLicenses,\n\t'key_delete'\t\t=> \\&deleteKey,\n\t'key_display'\t\t=> \\&displayKey,\n\t'key_create'\t\t=> \\&createKey,\n\t'key_list'\t\t\t=> \\&listKeys,\n\t'customer_modify'\t=> \\&modifyCustomer,\n\t'customer_display'\t=> \\&displayCustomer,\n\t'customer_create'\t=> \\&createCustomer,\n\t'customer_list'\t\t=> \\&listCustomers,\n);\n\nGetOptions (\n\t'help|h|?'\t\t=> \\$options{'help'},\n\t'verbose'\t\t=> \\$options{'verbose'},\n\t'id=s'\t\t\t=> \\$options{'id'},\n\t'display'\t\t=> sub { $options{'opt'} = 'display' },\n\t'create'\t\t=> sub { $options{'opt'} = 'create' },\n\t'list'\t\t\t=> sub { $options{'opt'} = 'list' },\n\t'verify'\t\t=> sub { $options{'opt'} = 'verify' },\n\t'modify'\t\t=> sub { $options{'opt'} = 'modify' },\n\t'delete'\t\t=> sub { $options{'opt'} = 'delete' },\n\t'key'\t\t\t=> sub { $options{'action'} = 'key' },\n\t'license'\t\t=> sub { $options{'action'} = 'license' },\n\t'customer'\t\t=> sub { $options{'action'} = 'customer' },\n\t'expiration=s'  => \\$options{'expiration'},\n\t'name=s'  \t\t=> \\$options{'name'},\n\t\"opt=s\"\t\t\t=> \\%license_options,\n\t);\n\nsetAction($options{'action'}, $options{'opt'});\n\nif (defined ($options{'help'}) ) {\n\tusage();\n}\n\nif (!defined ($actions{$options{'action'}})) {\n\tusage(\"Unknown command $options{'action'}\");\n}\n\n&{$actions{$options{'action'}}}();\n\nsub setAction {\n\tmy $act = shift;\n\tmy $opt = shift;\n\t$options{'action'} = \"${act}_${opt}\";\n\tif (!defined ($actions{$options{'action'}})) {\n\t\tusage(\"Unknown command $act\");\n\t}\n}\n\nsub displayCurrentKey {\n\tmy $key = getCurrentKey();\n\tif (!defined($key)) {\n\t\tdie \"Can't get current key\\n\";\n\t}\n\t$key->display($options{'verbose'});\n}\n\nsub displayKey {\n\n\tif (!defined ($options{'id'}) ) {\n\t\tusage (\"No key specified!\");\n\t}\n\tif ($options{'id'} =~ /current/i) {return displayCurrentKey()};\n\tmy $key = getKey($options{'id'});\n\tif (!defined($key)) {\n\t\tdie \"Can't get key $options{'id'}\\n\";\n\t}\n\t$key->display($options{'verbose'});\n}\n\nsub createKey {\n\tmy %attrs = ();\n\tmy $key = new Zimbra::LicenseKey;\n\tif (!$key->generate()) {\n\t\texit 1;\n\t}\n\tif (!putKey($key)) {\n\t\texit 1;\n\t}\n\t$key->display($options{'verbose'});\n}\n\nsub listKeys {\n\tmy $ids = getKeyIds();\n\n\tforeach (@$ids) {\n\t\tmy $key = getKey($$_[0]);\n\t\tif (!defined($key)) {\n\t\t\twarn \"Can't get key $$_[0]\\n\";\n\t\t}\n\t\t$key->display($options{'verbose'});\n\t}\n\n}\n\nsub verifyLicense {\n\tif (!defined($options{'id'})) {\n\t\tusage (\"Missing license id\");\n\t}\n\tmy $license = getLicense($options{'id'});\n\tif (!defined($license)) {\n\t\tusage (\"Can't get license $options{'id'}\\n\");\n\t}\n\n\tif ($license->verify($options{'verbose'})) {\n\t\tprint \"License verified\\n\";\n\t\texit 0;\n\t} else {\n\t\tprint \"Verification FAILED\\n\";\n\t\texit 1;\n\t}\n}\n\nsub displayLicense {\n\tif (!defined($options{'id'})) {\n\t\tusage (\"Missing license id\");\n\t}\n\n\tmy $license = getLicense($options{'id'});\n\tif (!defined($license)) {\n\t\tusage (\"Can't get license $options{'id'}\\n\");\n\t}\n\t$license->display($options{'verbose'});\n}\n\nsub createLicense {\n\tif (!defined($options{'id'})) {\n\t\tusage (\"Missing customer id\");\n\t}\n\tif (!defined($options{'expiration'})) {\n\t\tusage (\"Missing license expiration\");\n\t}\n\t$options{'expiration'} = \"$options{'expiration'} 00:00:00\";\n\n\tmy $customer = getCustomer($options{id});\n\tif (!defined ($customer)) {\n\t\tusage (\"Customer $options{id} not found!\");\n\t}\n\n\tmy $license = new Zimbra::License();\n\n\tif (!defined ($license)) {\n\t\tusage();\n\t}\n\t$license->{'customer_id'} = $customer->{'id'};\n\t$license->{'expiration'} = $options{'expiration'};\n\t$license->{license_version} = getCurrentKeyId();\n\n\tforeach (sort keys %license_options) {\n\t\t$license->{options}{$_} = $license_options{$_};\n\t}\n\n\tmy $id = putLicense($license);\n\n\tif (!$id) {\n\t\tusage (\"License creation failed\");\n\t}\n\n\tif (!$license->generate()) {\n\t\tusage (\"License generation failed!\");\n\t}\n\n\tif (!updateLicense($license)) {\n\t\tusage (\"License generation failed!\");\n\t}\n\n\t$license->display($options{'verbose'});\n\n}\n\nsub createCustomer {\n\tif (!defined($options{'name'})) {\n\t\tusage (\"Missing customer name\");\n\t}\n\tmy $customer = new Zimbra::Customer();\n\t$customer->{name} = $options{'name'};\n\tif (defined($customer)) {\n\t\tmy $id = putCustomer($customer);\n\t\tif ($id) {\n\t\t\t$customer->display($options{'verbose'});\n\t\t}\n\t}\n}\n\nsub displayCustomer {\n\tif (!defined ($options{'id'}) ) {\n\t\tusage (\"No customer specified!\");\n\t}\n\tmy $customer = getCustomer($options{'id'});\n\tif (defined($customer)) {\n\t\t$customer->display($options{'verbose'});\n\t}\n}\n\nsub listCustomers {\n\tmy $ids = getCustomerIds();\n\n\tforeach (@$ids) {\n\t\tmy $customer = getCustomer($$_[0]);\n\t\tif (!defined($customer)) {\n\t\t\twarn \"Can't get customer $$_[0]\\n\";\n\t\t}\n\t\t$customer->display($options{'verbose'});\n\t}\n}\n\nsub listLicenses {\n\tmy $ids = getLicenseIds();\n\n\tforeach (@$ids) {\n\t\tmy $license = getLicense($$_[0]);\n\t\tif (!defined($license)) {\n\t\t\twarn \"Can't get license $$_[0]\\n\";\n\t\t}\n\t\t$license->display($options{'verbose'});\n\t}\n}\n\n\nsub modifyLicense {\n\tif (!defined($options{'id'})) {\n\t\tusage (\"Missing license id\");\n\t}\n\n\tmy $customer;\n\n\tmy $license = getLicense($options{'id'});\n\tif (!defined($license)) {\n\t\tusage (\"Can't get license $options{'id'}\\n\");\n\t}\n\n\tif (defined ($options{'expiration'})) {\n\t\t$license->{'expiration'} = $options{'expiration'}.\" 00:00:00\";\n\t}\n\n\tif (defined ($license_options{'customer'})) {\n\t\t$customer = getCustomer($license_options{'customer'});\n\t\tif (!defined($customer)) {\n\t\t\tusage (\"Can't get customer $license_options{'customer'}\\n\");\n\t\t}\n\t\t$license->{'customer_id'} = $customer->{'id'};\n\n\t\tdelete $license_options{'customer'};\n\t}\n\n\tif (defined ($license_options{'is_deleted'})) {\n\t\t$license->{'is_deleted'} = $license_options{'is_deleted'};\n\n\t\tdelete $license_options{'is_deleted'};\n\t}\n\n\tforeach (keys %license_options) {\n\t\t$license->{options}{$_} = $license_options{$_};\n\t}\n\n\tif (!$license->generate()) {\n\t\tusage (\"License generation failed!\");\n\t}\n\n\tif (!updateLicense($license)) {\n\t\tusage (\"License generation failed!\");\n\t}\n\n\t$license->display($options{'verbose'});\n}\n\nsub usage {\n\tmy $msg = shift;\n\tprint STDERR $msg;\n\tprint STDERR \"\\n\";\n\tprint STDERR<<EOF;\nUSAGE: $0 <command> <subcommand> <options> [--verbose]\nCommand is one of:\n  --key          key operations\n    key subcommands:\n      --list     list keys\n      --create   create key\n      --delete   delete key\n      --display --id <id> display key <id>\n\n  --customer     customer operations\n      --list     list customers\n      --create   --name <customer name> create customer\n      --display --id <id> display customer <id>\n\n  --license      license operations\n      --list     list licenses\n      --display --id <id> display license <id>\n      --verify  --id <id> verify license <id>\n      --create   create license\n        --create --id <customer_id> --expiration <YYYY-MM-DD> [--opt key=val]\n      --modify \n        --modify --id <license_id> [--expiration <YYYY-MM-DD>] [--opt key=val]\nEOF\n\n\texit 1;\n}\n\n## Db Access commands\n\nsub getCustomerIds {\n\tmy $ids = Zimbra::LicensingDB::getCustomerIds();\n\treturn $ids;\n}\n\nsub getCustomer {\n\tmy $id = shift;\n\t#print \"Fetching customer $id from database...\";\n\tmy $attrs = Zimbra::LicensingDB::getCustomer($id);\n\tif (defined ($attrs)) {\n\t\tmy $customer = new Zimbra::Customer($attrs);\n\t\t#print \"Done\\n\";\n\t\treturn $customer;\n\t}\n\t#print \"FAILED\\n\";\n\treturn undef;\n}\n\nsub putCustomer {\n\tmy $customer = shift;\n\t#print \"Storing customer $self->{name} in database...\";\n\t$customer->{id} = Zimbra::LicensingDB::putCustomer($customer);\n\tif (defined($customer->{id})) {\n\t\t#print \"Customer ID $customer->{id}...Done\\n\";\n\t\treturn 1;\n\t}\n\t#print \"FAILED\\n\";\n\treturn undef;\n}\n\nsub getCurrentKeyId {\n\tmy $ids = getKeyIds();\n\tif ($#$ids < 0) {return undef;}\n\tmy $curId = $$ids[$#$ids][0];\n\treturn $curId;\n}\n\nsub getCurrentKey {\n\tmy $id = getCurrentKeyId;\n\tif (!defined ($id)) {\n\t\treturn undef;\n\t}\n\treturn (getKey($id));\n}\n\nsub getKeyIds {\n\tmy $ids = Zimbra::LicensingDB::getKeyIds();\n\treturn $ids;\n}\n\nsub getKey {\n\tmy $keyId = shift;\n\t#print \"Fetching key $keyId from database...\";\n\tmy $attrs = Zimbra::LicensingDB::getKey($keyId);\n\tif (defined ($attrs)) {\n\t\tmy $key = new Zimbra::LicenseKey($attrs);\n\t\t#print \"Done\\n\";\n\t\treturn $key;\n\t}\n\t#print \"FAILED\\n\";\n\treturn undef;\n}\n\nsub putKey {\n\tmy $key = shift;\n\n\t#print \"Storing key in database...\";\n\t$key->{id} = Zimbra::LicensingDB::putKey($key);\n\tif (defined($key->{id})) {\n\t\t#print \"Key ID $key->{id}...Done\\n\";\n\t\treturn 1;\n\t}\n\t#print \"FAILED\\n\";\n\treturn undef;\n}\n\nsub getLicenseIds {\n\tmy $ids = Zimbra::LicensingDB::getLicenseIds();\n\treturn $ids;\n}\n\nsub getLicense {\n\tmy $id = shift;\n\tmy $attrs = Zimbra::LicensingDB::getLicense($id);\n\tif (defined($attrs)) {\n\t\tmy $license = new Zimbra::License($attrs);\n\t\treturn $license;\n\t}\n\treturn undef;\n}\n\nsub putLicense {\n\tmy $license = shift;\n\t#print \"Storing license in database...\";\n\t$license->{id} = Zimbra::LicensingDB::putLicense($license);\n\tif (defined($license->{id})) {\n\t\t#print \"License ID $license->{id}...Done\\n\";\n\t\treturn 1;\n\t}\n\t#print \"FAILED\\n\";\n\treturn undef;\n}\n\nsub updateLicense {\n\tmy $license = shift;\n\t#print \"Storing license in database...\";\n\tif (Zimbra::LicensingDB::updateLicense($license)) {\n\t\treturn 1;\n\t}\n\t#print \"FAILED\\n\";\n\treturn undef;\n}   \n\n"
  },
  {
    "path": "rpmconf/Patch/bin/zmpatch.pl",
    "content": "#!/usr/bin/perl -w\n# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n#  \n\nuse strict;\nuse lib qw(/opt/zimbra/common/lib/perl5 lib corebuild/opt/zimbra/zimbramon/lib);\nuse Zimbra::Util::Common;\nuse XML::SAX;\nuse XML::Simple;\nuse Data::Dumper;\nuse Getopt::Long;\nuse File::Path;\nuse File::Copy;\nuse File::Basename;\nuse Time::localtime qw(ctime);\n\nmy %options = ();\n\nsub getDateStamp();\nsub progress($$$);\nsub detail($);\nsub debugLog($);\nsub getInstalledVersion();\nsub getInstalledType();\nsub usage;\nsub doPatchBuild();\nsub doPatchDeploy();\nsub doIncrementJSVersion();\n\nGetOptions (\"config=s\"  => \\$options{config},\n            \"verbose|v+\"  => \\$options{verbose},\n            \"debug|d+\"    => \\$options{debug},\n            \"help\"      => sub { usage(); },\n            \"dryrun|n\"  => \\$options{dryrun},\n            \"force\"  => \\$options{force},\n            \"build|b\"   => \\$options{build},\n            \"source=s\"  => \\$options{build_source},\n            \"target=s\"  => \\$options{build_target},\n            \"version=s\" => \\$options{build_version});\n\n($>) and usage() unless $options{build};\n\nmy $progName = \"zmpatch\";\nmy $patchBuildNumber;\nmy %versionInfo;\nmy ($platform, $zmtype, $config);\n$options{verbose} = 0 unless $options{verbose};\n\nif ($options{build}) {\n  usage() unless ($options{build_source} && $options{build_version});\n  $options{build_target}=\"$options{build_source}/ZimbraBuild/zcs-patch-$options{build_version}\" unless $options{build_target};\n}\n\nmy $logfile;\nif($options{build_source}) {\n  $logfile = \"$options{build_source}/logs/${progName}.\".getDateStamp().\".log\";\n} else {\n  $logfile = \"/tmp/${progName}.\".getDateStamp().\".log\";\n}\nopen LOGFILE, \">$logfile\" or die \"Can't open $logfile: $!\\n\";\n\nif($options{build_source}) {\n  unlink(\"$options{build_source}/log/${progName}.log\") if (-e \"$options{build_source}/log/${progName}.log\");\n  symlink($logfile, \"$options{build_source}/log/${progName}.log\");\n} else {\n  unlink(\"/tmp/${progName}.log\") if (-e \"/tmp/${progName}.log\");\n  symlink($logfile, \"/tmp/${progName}.log\");\n}\n\nif ($options{build}) {\n  if (-f \"$options{build_source}/ZimbraBuild/RE/BUILD\") {\n    open(BUILD, \"$options{build_source}/ZimbraBuild/RE/BUILD\");\n  } else {\n    progress(\"Unable to determine build number.\\n\", 0, 0);\n    exit 1;\n  }\n} else {\n  $zmtype=getInstalledType();\n  debugLog(\"Install type: $zmtype\\n\");\n  unless (-x \"/opt/zimbra/libexec/get_plat_tag.sh\") {\n    print \"ZCS Install not found.\\n\";\n    exit 1;\n  }\n  $platform = qx(/opt/zimbra/libexec/get_plat_tag.sh);\n  chomp($platform);\n  if (-f \"source/build\") {\n    open(BUILD, \"source/build\");\n  } else {\n    progress(\"Unable to determine build number.\\n\", 0, 0);\n    exit 1;\n  }\n}\n\n$patchBuildNumber = <BUILD>;\nchomp($patchBuildNumber);\nclose(BUILD);\n\nunless ($options{config} && -f $options{config}) {\n  progress(\"Missing config file.\\n\", 0, 0);\n  usage();\n  exit 1;\n}\n\nif ($options{config} && -f $options{config}) {\n  $config = XMLin($options{config}, ForceArray => [ 'name', 'patch', 'package', 'file', 'deletefile', 'zimlet','target', 'preinstall', 'postinstall'], KeyAttr => [ 'name', 'patch', 'package', 'source', 'version', 'postinstall', 'preinstall' ], SuppressEmpty => 1);\n  my $debug_text = Dumper($config);\n  debugLog($debug_text);\n  \n}\n\ndoPatchBuild() if ($options{build});\n\ndoPatchDeploy();\n\n\n\nclose(LOGFILE);\nexit(0);\n################################################################\n# Subroutines\n################################################################\n\nsub initPatchDir() { \n  my $bin_dir=$options{build_target}.\"/bin\";\n  my $conf_dir=$options{build_target}.\"/conf\";\n  my $src_dir=$options{build_target}.\"/source\";\n  make_path($bin_dir);\n  make_path($conf_dir);\n  make_path($src_dir);\n  copy(\"$options{build_source}/ZimbraBuild/rpmconf/Patch/bin/zmpatch.pl\", $bin_dir);\n  copy(\"$options{build_source}/ZimbraBuild/rpmconf/Patch/conf/zmpatch.xml\", $conf_dir);\n  copy(\"$options{build_source}/ZimbraBuild/rpmconf/Patch/installPatch.sh\", $options{build_target});\n  system(\"chmod 755 $options{build_target}/installPatch.sh\");\n  open(B, \">${src_dir}/build\");\n  print B \"$patchBuildNumber\\n\";\n  close(B);\n}\n\nsub doPatchBuild() {\n  progress(\"Building patch for release $options{build_version} in $options{build_target}\\n\", 0, 0);\n\n  initPatchDir();\n  \n  my $buildStatus=0;\n  foreach my $patch (keys %{$config->{patch}}) {\n    progress(\"$config->{patch}->{$patch}->{version}\\n\",1,1);\n\n    my $patchName=$config->{patch}->{$patch}->{version};\n\n    foreach my $package (keys %{$config->{patch}->{$patch}->{package}}) {\n      my $pref = $config->{patch}->{$patch}->{package}->{$package};\n      progress(\"$package\\n\",2,1);\n\n      foreach my $zimlet (keys %{$pref->{zimlet}}) {\n        my $zref = $pref->{zimlet}->{$zimlet};\n        progress(\"$zref->{target}[0]\\n\", 3,1);\n        my $zpath=\"$options{build_target}/source/$patchName/$package/\" . dirname($zref->{target}[0]);\n        unless (make_path($zpath)) {\n          progress(\"Failed to make_path $zpath.\\n\",3,0);\n          $buildStatus++;\n          next;\n        }\n        my $source=\"$options{build_source}/$zimlet\";\n        if (-f $source) {\n          copy($source,$zpath);\n        } else {\n          progress(\"Failed to copy $source\\n\",3,0);\n          $buildStatus++;\n        }\n      }\n\n      foreach my $file (keys %{$pref->{file}}) {\n        my $fref=$pref->{file}->{$file};\n        \n        foreach my $target (@{$fref->{target}}) {\n          my $fpath=\"$options{build_target}/source/$patchName/$package/\" . dirname($target);\n          progress(\"$target\\n\",3,1);\n          unless (make_path($fpath)) {\n            progress(\"Failed to make_path $fpath.\\n\",3,0);\n            $buildStatus++;\n            next;\n          }\n          my $source=\"$options{build_source}/$file\";\n          if (-f $source) {\n            copy($source,$fpath);\n          } else {\n            progress(\"Failed to copy $source\\n\",3,0);\n            $buildStatus++;\n          }\n        }\n      }\n      # future\n      #foreach my $file (keys %{$pref->{dir}}) {\n        #print \"$file\\n\";\n      #}\n    }\n\n  }\n  if(!$buildStatus) {\n    # Clean up zmpatch files on successful build\n    unlink(\"$logfile\");\n    unlink(\"/tmp/${progName}.log\");\n  }\n  exit($buildStatus);\n}\n\nsub doPatchDeploy() {\n  getInstalledVersion();\n  my $currentRelease = getReleaseString($versionInfo{current});\n  my $currentBuild = getVersionComponent($versionInfo{current},\"build\");\n  progress(\"Current Version: $versionInfo{current}\\n\", 0, 1);\n\n  if ($currentBuild > $patchBuildNumber) {\n    progress(\"Current install $currentRelease is newer than patch version.\\n\", 0, 1);\n    return undef;\n  }\n  if ($currentBuild == $patchBuildNumber && !$options{force}) {\n    progress(\"Current install $currentRelease is the same as patch version.\\n\", 0, 1);\n    return undef;\n  }\n  while () {\n    if ($config->{patch}->{$currentRelease}) {\n      print \"Found Patch for $currentRelease called $config->{patch}->{$currentRelease}->{version}\\n\";\n      deployPatch($currentRelease);\n      $currentRelease = $config->{patch}->{$currentRelease}->{version};\n    } else {\n      last;\n    }\n  }\n}\n\nsub deployPatch($) {\n  my ($v) = @_;\n  progress(\"Deploying patch for $v\\n\",1,1);\n  my $currentBuild=getVersionComponent($versionInfo{current},\"build\");\n  my $currentRelease = getReleaseString($versionInfo{current});\n  my $patch = $config->{patch}->{$v};\n  # check the build number range for validity\n  my $min = $patch->{buildnum}->{min};\n  my $max = $patch->{buildnum}->{max};\n  if (defined($min) && $currentBuild < $min) {\n    progress(\"Current install build is too low is not patchabled.\\n\",1,0);\n    progress(\"Min: $min Max: $max Current: $currentBuild\\n\",1,1);\n    return undef;\n  }\n\n  if (defined($max) && $currentBuild > $max) {\n    progress(\"Patch can not be applied. Current build $currentBuild exceeds max build value $max for patch.\\n\",1,0);\n    progress(\"Min: $min Max: $max Current: $currentBuild\\n\",1,1);\n    return undef;\n  } \n\n\n  # log an install session start\n  logSession(\"INSTALL SESSION START\");\n  # force this so the build number is always updated\n  # not all patches will have zimbra-core components\n  logSession(\"UPGRADED zimbra-core-${currentRelease}_${patchBuildNumber}\");\n\n  # do preinstall tasks \n\n  # loop through each package \n  foreach my $package (keys %{$patch->{package}}) {\n    # make sure package is installed\n    my $pref = $patch->{package}->{$package};\n    next unless (isInstalled($package)); \n    # deploy the zimlets\n    foreach my $zimlet (keys %{$pref->{zimlet}}) {\n      my $zref = $pref->{zimlet}->{$zimlet};\n      my $ztype = \"\";\n      if (defined $zref->{type})\n      {\n      \t$ztype = lc($zref->{type});\n      }\n      next if ($zmtype eq \"FOSS\" && $ztype eq \"network\");\n      my $zimletname=basename($zref->{target}[0]);\n      $zimletname =~ s/\\.zip//;\n      progress(\"$zimletname...\",2,1);\n\n      my $srcfile=\"./source/$patch->{version}/$package/$zref->{target}[0]\";\n      my $dstfile=$zref->{target}[0];\n      if (-f \"$srcfile\") {\n        debugLog(\"cp $srcfile $dstfile\");\n        copy($srcfile, $dstfile) unless $options{dryrun};\n      } else {\n        progress(\"skipped. No such file $srcfile.\\n\",0,1);\n      }\n      unless ($options{dryrun}) {\n        if (lc($zref->{deploy}) eq \"true\") {\n          my $rc;\n          progress(\"deployed...\",0,1) \n            unless (runAsZimbra(\"zmzimletctl -l deploy $dstfile\"));\n          runAsZimbra(\"zmprov flushcache zimlet\") \n           if (lc($zref->{flushcache}) eq \"true\");\n        }\n      }\n      progress(\"updated.\\n\", 0, 1);\n    }\n    progress(\"Updating files for package $package\\n\", 1, 0);\n    # deploy the files\n    foreach my $file (keys %{$pref->{file}}) {\n      my $fref = $pref->{file}->{$file};\n      my $ftype = \"\";\n      if (defined $fref->{type})\n      {\n      \t$ftype = lc($fref->{type});\n      }\n      next if ($zmtype eq \"FOSS\" && $ftype eq \"network\");\n      foreach my $dstfile (@{$fref->{target}}) {\n        progress(\"$dstfile...\",2,1); \n        my $srcfile=\"./source/$patch->{version}/$package/$dstfile\";\n        unless (-f \"$srcfile\") {\n          progress(\"No such source file $srcfile\\n\",0,1);\n          next;\n        }\n        debugLog(\"cp $srcfile $dstfile\");\n        copy($srcfile, $dstfile) unless $options{dryrun};\n        # verify the perms/ownershiA\n        my ($owner,$group,$mode);\n        unless ($options{dryrun}) {\n          chown($owner,$dstfile)\n            if ($owner = $fref->{perms}->{owner});\n          system(\"chgrp $group $dstfile\")\n            if ($group = $fref->{perms}->{group});\n          system(\"chmod $mode $dstfile\")\n            if ($mode = $fref->{perms}->{mode});\n        }\n        progress(\"copied.\\n\", 1, 1);\n      }\n    }\n    # Delete files if necessary\n    foreach my $deleteFile ($pref->{deletefile}) {\n      foreach my $dhash (@{$deleteFile}) {\n        foreach my $dstfile (@{$dhash->{target}}) {\n          progress(\"$dstfile...\",2,1);\n          debugLog(\"rm $dstfile\");\n          unlink($dstfile) unless $options{dryrun};\n          progress(\"deleted.\\n\", 1, 1);\n        }\n      }\n    }\n    # update the installed version of package\n    if ($package eq \"zimbra-store\") {\n      &doIncrementJSVersion();\n    }\n    logSession(\"UPGRADED $package-${currentRelease}_${patchBuildNumber}\")\n      unless ($package eq \"zimbra-core\");\n  }\n\n  # do postinstall tasks\n  foreach my $task (@{$patch->{postinstall}}) {\n    progress(\"Running $task...\",1,0);\n    if (runAsZimbra($task)) {\n      progress(\"failed.\\n\",1,0);\n    } else {\n      progress(\"done.\\n\",1,0);\n    }\n  }\n  \n  \n\n  # log an install session complete\n  logSession(\"INSTALL SESSION COMPLETE\");\n  logSession(\"CONFIG SESSION START\");\n  logSession(\"CONFIGURED BEGIN\");\n  logSession(\"CONFIGURED patch$patch->{version}\");\n  logSession(\"CONFIGURED END\");\n  logSession(\"CONFIG SESSION COMPLETE\");\n\n}\nsub logSession($) {\n  my ($msg) = @_;\n  return if $options{dryrun};\n  my $date = qx(date +%s);\n  chomp($date);\n  open(SESS, \">>/opt/zimbra/.install_history\");\n  print SESS \"$date: $msg\\n\";\n  close(SESS);\n}\n\nsub runAsZimbra {\n  my $cmd = shift;\n  my $SU = \"su - zimbra -c \";\n  detail ( \"*** Running as zimbra user: $cmd\\n\" );\n  my $rc;\n  $rc = 0xffff & system(\"$SU \\\"$cmd\\\" >> $logfile 2>&1\");\n  return $rc;\n}\n\nsub make_path($) {\n  my ($dir) = @_;\n  eval { mkpath($dir) };\n  debugLog(\"Couldn't create $dir: $@\") if ($@);\n  return (($@) ? undef : 1);\n}\n\nsub debugLog($) {\n  print \"@_\\n\" if $options{debug};\n}  \n\nsub usage {\n  ($>) and print STDERR \"Warning: $0 must be run as root!\\n\\n\";\n  print STDERR \"Usage: $0 [-h] -c <config file> -build\\n\";\n\n  print STDERR \"\\t--help|-h:          display this help message\\n\";\n  print STDERR \"\\t--config|-c <file>: patch configuration file.\\n\";\n  print STDERR \"\\t--verbose|-v:       verbose output.\\n\";\n  print STDERR \"\\t--debug|-d:         debug output.\\n\";\n  print STDERR \"\\t--dryrun|-n:        patch dryrun does not apply changes.\\n\\n\";\n\n  print STDERR \"   Developer Use Only\\n\";\n  print STDERR \"\\t--build|-b:                   build patch from source.\\n\";\n  print STDERR \"\\t--source <patch source>:      path to patch source.\\n\";\n  print STDERR \"\\t--target <patch destination>: destination path for patch.\\n\";\n  print STDERR \"\\t--version <patch version>:    target version of patch.\\n\\n\";\n\n  exit 1;\n}\n\nsub detail($) {\n  my $msg = shift;\n  my ($sub,$line) = (caller(1))[3,2];\n  my $date = ctime();\n  $msg =~ s/\\n$//;\n  $msg = \"$sub:$line $msg\" if $options{debug};\n  open(LOG, \">>$logfile\");\n  print LOG \"$date $msg\\n\";\n  close(LOG);\n  #qx(echo \"$date $msg\" >> $logfile);\n}\n\nsub progress($$$) {\n  my ($msg,$lvl,$verbosity) = @_;\n  $lvl=0 unless $lvl;\n  $verbosity=0 unless $verbosity;\n  #print \"$msg lvl: $lvl verbosity: $verbosity opt_verbose: $options{verbose}\\n\";\n  print \" \"x$lvl. \"$msg\" if ($options{verbose} >= $verbosity);\n  my ($sub,$line) = (caller(1))[3,2];\n  $msg = \"$sub:$line $msg\" if $options{debug};\n  detail ($msg);\n}\n\nsub getDateStamp() {\n  my ($sec,$min,$hour,$mday,$mon,$year) = localtime(time());\n  $year = 1900+$year;\n  $sec = sprintf(\"%02d\", $sec);\n  $min = sprintf(\"%02d\", $min);\n  $hour = sprintf(\"%02d\", $hour);\n  $mday = sprintf(\"%02d\", $mday);\n  $mon = sprintf(\"%02d\", $mon+1);\n  my $stamp = \"$mon$mday$year-$hour$min$sec\";\n  return $stamp;\n}\n\n\nsub getInstalledVersion() {\n  my %configStatus;\n  my %installStatus;\n  if (open H, \"/opt/zimbra/.install_history\") {\n\n    my @history = <H>;\n    close H;\n    foreach my $h (@history) {\n      next if ($h =~ /CONFIG SESSION COMPLETE/);\n      if ($h =~ /CONFIG SESSION START/) {\n        %configStatus = ();\n        next;\n      }\n      next if ($h =~ /INSTALL SESSION COMPLETE/);\n      if ($h =~ /INSTALL SESSION START/) {\n        %installStatus = ();\n        %configStatus = ();\n        next;\n      }\n      my ($d, $op, $stage) = split ' ', $h;\n      if ($op eq \"INSTALLED\" || $op eq \"UPGRADED\") {\n        my $v = $stage;\n        $stage =~ s/[-_]\\d.*//;\n        if ($stage eq \"zimbra-core\") {\n          $v =~ s/_HEAD.*//;\n          $v =~ s/^zimbra-core[-_]//;\n          if ($v =~ /\\.deb$/) {\n            my $orig_v=$v;\n            $v =~ s/^(\\d+\\.\\d+\\.\\d+\\.\\w+\\.\\w+)\\..*/$1/;\n            $v = reverse($v);\n            $v =~ s/\\./_/;\n            $v =~ s/\\./_/;\n            $v = reverse($v);\n            if ($v =~ /\\_deb$/) {\n              $v = $orig_v;\n              $v =~ s/^(\\d+\\.\\d+\\.[^_]*_[^_]+_[^.]+).*/$1/;\n            }\n          } else {\n            $v =~ s/^(\\d+\\.\\d+\\.[^_]*_[^_]+_[^.]+).*/$1/;\n          }\n          $versionInfo{current} = $v;\n        }\n      } elsif ($op eq \"CONFIGURED\") {\n        if ($stage eq \"END\") {\n          $versionInfo{previous} = $versionInfo{current};\n        }\n      }\n    }\n\n  }\n  progress(\"Previous version: $versionInfo{previous}\\n\",0,2);\n  progress(\"Current  version: $versionInfo{current}\\n\",0,2);\n  \n  return $versionInfo{current};\n}\n\nsub getInstalledType() {\n  return ((-f \"/opt/zimbra/bin/zmbackupquery\") ? \"NETWORK\" : \"FOSS\");\n}\n\nsub getReleaseString($) {\n  my ($version) = @_;\n  my ($major,$minor,$micro,$stage,$build) = \n    $version =~ /(\\d+)\\.(\\d+)\\.(\\d+)_([^_]*)_(\\d+)/;\n\n  return \"${major}.${minor}.${micro}_${stage}\";\n}\n\n  \n\nsub getVersionComponent($$) {\n  my ($version, $component) = @_;\n  my ($major,$minor,$micro,$stage,$build) = \n    $version =~ /(\\d+)\\.(\\d+)\\.(\\d+)_([^_]*)_(\\d+)/;\n  return $major if ($component eq \"major\");\n  return $minor if ($component eq \"minor\");\n  return $micro if ($component eq \"micro\");\n  return $stage if ($component eq \"stage\");\n  return $build if ($component eq \"build\");\n}\n\nsub isInstalled {\n  my $pkg = shift;\n\n  my $pkgQuery;\n\n  my $good = 0;\n  if ($platform =~ /^DEBIAN/ || $platform =~ /^UBUNTU/) {\n    $pkgQuery = \"dpkg -s $pkg\";\n  } else {\n    $pkgQuery = \"rpm -q $pkg\";\n  }\n\n  my $rc = 0xffff & system (\"$pkgQuery > /dev/null 2>&1\");\n  $rc >>= 8;\n  if (($platform =~ /^DEBIAN/ || $platform =~ /^UBUNTU/) && $rc == 0 ) {\n    $good = 1;\n    $pkgQuery = \"dpkg -s $pkg | egrep '^Status: ' | grep 'not-installed'\";\n    $rc = 0xffff & system (\"$pkgQuery > /dev/null 2>&1\");\n    $rc >>= 8;\n    return ($rc == $good);\n  } else {\n    return ($rc == $good);\n  }\n}\n\nsub doIncrementJSVersion() {\n  my $infile=\"/opt/zimbra/jetty/etc/zimbra.web.xml.in\";\n  my $outfile=\"/opt/zimbra/data/tmp/zimbra.web.xml.in.new\";\n  unlink(\"$outfile\") if (-e \"$outfile\");\n  open (IN, \"<$infile\");\n  open (OUT, \">$outfile\");\n  my $next=0;\n  \n  while (<IN>) {\n    if ($next == 0) {\n      if ($_ =~ m/<param-name>jsVersion<\\/param-name>/) {\n        $next = 1;\n      }\n      print OUT $_;\n    }\n    else {\n      my ($oldVersion) = $_ =~ /<param-value>(\\d+)<\\/param-value>/;\n      my $newVersion=$oldVersion+1;\n      $_ =~ s/$oldVersion/$newVersion/;\n      print OUT $_;\n      $next = 0;\n    }\n  }\n  close(IN);\n  close(OUT);\n  copy($outfile, $infile);\n  $infile=\"/opt/zimbra/jetty/etc/zimbraAdmin.web.xml.in\";\n  $outfile=\"/opt/zimbra/data/tmp/zimbraAdmin.web.xml.in.new\";\n  unlink(\"$outfile\") if (-e \"$outfile\");\n  open (IN, \"<$infile\");\n  open (OUT, \">$outfile\");\n  $next=0;\n  \n  while (<IN>) {\n    if ($next == 0) {\n      if ($_ =~ m/<param-name>jsVersion<\\/param-name>/) {\n        $next = 1;\n      }\n      print OUT $_;\n    }\n    else {\n      my ($oldVersion) = $_ =~ /<param-value>(\\d+)<\\/param-value>/;\n      my $newVersion=$oldVersion+1;\n      $_ =~ s/$oldVersion/$newVersion/;\n      print OUT $_;\n      $next = 0;\n    }\n  }\n  close(IN);\n  close(OUT);\n  copy($outfile, $infile);\n}\n"
  },
  {
    "path": "rpmconf/Patch/conf/zmpatch.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n * ***** BEGIN LICENSE BLOCK *****\n * Zimbra Collaboration Suite Server\n * Copyright (C) 2010, 2011, 2013, 2014, 2016 Synacor, Inc.\n *\n * The contents of this file are subject to the Common Public Attribution License Version 1.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at: https://www.zimbra.com/license\n * The License is based on the Mozilla Public License Version 1.1 but Sections 14 and 15\n * have been added to cover use of software over a computer network and provide for limited attribution\n * for the Original Developer. In addition, Exhibit A has been modified to be consistent with Exhibit B.\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied.\n * See the License for the specific language governing rights and limitations under the License.\n * The Original Code is Zimbra Open Source Web Client.\n * The Initial Developer of the Original Code is Zimbra, Inc.  All rights to the Original Code were\n * transferred by Zimbra, Inc. to Synacor, Inc. on September 14, 2015.\n *\n * All portions of the code are Copyright (C) 2010, 2011, 2013, 2014, 2016 Synacor, Inc. All Rights Reserved.\n * ***** END LICENSE BLOCK *****\n-->\n\n<!-- ZCS Patch configuration file\n<patch version=\"{zcs version}\" name=\"{patch name}>\n  <desc>Documentation</desc>\n  [<bug num=\"{bugzilla number}\"/>]\n  [<build min=\"{minimum build number}\" max=\"{maximum build patch applies to}\"/>]\n  <file name=\"{file to patch}\">\n    <source file=\"{path to source file}\"/>\n  </file>\n  [<preinstall></preinstall>]\n  [<postinstall></postinstall>]\n</patch>\n\n  patch version:  ZCS version this patch is applied against\n  patch name: Unique name of the patch within this patch version\n    desc: [optional] Documentation for the patch\n    bug num: [optional] Bugzilla numbers related to this patch\n    build: [optional]\n      min: Minimum build number this patch can be applied to within the release version\n      max: Maximum build number this patch can be applied to within the release version\n    file name: Name of the file to be patched\n      source file: Location of the source file used to build the patch\n    preinstall: [optional]\n    postinstall: [optional]\n  \n-->\n<patches>\n  <!-- <patch name=\"6.0.6_GA\" version=\"6.0.6_P1\">\n    <desc>Patch 6.0.6_P1</desc>\n    <bug>45545</bug>\n    <bug>45677</bug>\n    <bug>45852</bug>\n    <bug>45886</bug>\n    <bug>46476</bug>\n    <bug>44353</bug>\n    <package name=\"zimbra-store\">\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/lib/jars/zimbrastore.jar</source>\n        <target>/opt/zimbra/jetty/webapps/service/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/jetty/webapps/zimbra/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/lib/jars/zimbrastore.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/lib/jars/zimbracommon.jar</source>\n        <target>/opt/zimbra/jetty/common/lib/zimbracommon.jar</target>\n        <target>/opt/zimbra/lib/jars/zimbracommon.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file type=\"network\">\n        <source>ZimbraSyncCommon/build/zsynccommon.jar</source>\n        <target>/opt/zimbra/lib/ext/zimbrasync/zsynccommon.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <zimlet deploy=\"true\" flushcache=\"true\">\n        <source>Zimlet/build/dist/zimlets/com_zimbra_email.zip</source>\n        <target>/opt/zimbra/zimlets/com_zimbra_email.zip</target>\n      </zimlet>\n    </package>\n    <preinstall></preinstall>\n    <postinstall></postinstall>\n  </patch>\n  <patch name=\"6.0.7_GA\" version=\"6.0.7_P1\">\n    <desc>Patch 6.0.7_P1</desc>\n    <bug>46552</bug>\n    <bug>48146</bug>\n    <bug>48210</bug>\n    <bug>48296</bug>\n    <package name=\"zimbra-store\">\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/lib/jars/zimbrastore.jar</source>\n        <target>/opt/zimbra/jetty/webapps/service/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/jetty/webapps/zimbra/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/lib/jars/zimbrastore.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/NewWindow_2_all.js.zgz</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/js/NewWindow_2_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Calendar_all.js.zgz</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/js/Calendar_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/MailCore_all.js.zgz</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/js/MailCore_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/h/printmessage</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/h/printmessage</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n    </package>\n    <preinstall></preinstall>\n    <postinstall></postinstall>\n  </patch>\n  <patch name=\"6.0.8_GA\" version=\"6.0.8_P1\">\n    <desc>Patch 6.0.8_P1</desc>\n    <bug>49412</bug>\n    <bug>49624</bug>\n    <bug>50191</bug>\n    <package name=\"zimbra-store\">\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/lib/jars/zimbrastore.jar</source>\n        <target>/opt/zimbra/jetty/webapps/service/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/jetty/webapps/zimbra/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/lib/jars/zimbrastore.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Notebook_all.js.zgz</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/js/Notebook_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n    </package>\n    <preinstall></preinstall>\n    <postinstall></postinstall>\n  </patch>\n  <patch name=\"6.0.8_GA\" version=\"6.0.8_P2\">\n  <desc>Patch 6.0.8_P2</desc>\n  <bug>47488</bug>\n  <bug>49412</bug>\n  <bug>49624</bug>\n  <bug>50191</bug>\n  <bug>50398</bug>\n  <bug>50419</bug>\n  <bug>50603</bug>\n  <package name=\"zimbra-core\">\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/lib/jars/zimbracommon.jar</source>\n        <target>/opt/zimbra/lib/jars/zimbracommon.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/lib/jars/ical4j-0.9.16-patched.jar</source>\n        <target>/opt/zimbra/lib/jars/ical4j-0.9.16-patched.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n  </package>\n  <package name=\"zimbra-store\">\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/lib/jars/zimbrastore.jar</source>\n        <target>/opt/zimbra/jetty/webapps/service/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/jetty/webapps/zimbra/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/lib/jars/zimbrastore.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/lib/jars/zimbracommon.jar</source>\n        <target>/opt/zimbra/jetty/common/lib/zimbracommon.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/lib/jars/ical4j-0.9.16-patched.jar</source>\n        <target>/opt/zimbra/jetty/common/lib/ical4j-0.9.16-patched.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Notebook_all.js.zgz</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/js/Notebook_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n  </package>\n  <preinstall></preinstall>\n  <postinstall></postinstall>\n  </patch>\n  <patch name=\"6.0.8_GA\" version=\"6.0.8_P3\">\n  <desc>Patch 6.0.8_P3</desc>\n  <bug>47488</bug>\n  <bug>49412</bug>\n  <bug>49624</bug>\n  <bug>49717</bug>\n  <bug>49987</bug>\n  <bug>50191</bug>\n  <bug>50251</bug>\n  <bug>50398</bug>\n  <bug>50419</bug>\n  <bug>50517</bug>\n  <bug>50603</bug>\n  <bug>50785</bug>\n  <bug>50953</bug>\n  <bug>51092</bug>\n  <bug>51005</bug>\n  <bug>51175</bug>\n  <bug>51328</bug>\n  <package name=\"zimbra-core\">\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/lib/jars/zimbracommon.jar</source>\n        <target>/opt/zimbra/lib/jars/zimbracommon.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/lib/jars/ical4j-0.9.16-patched.jar</source>\n        <target>/opt/zimbra/lib/jars/ical4j-0.9.16-patched.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n  </package>\n  <package name=\"zimbra-store\">\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/lib/jars/zimbrastore.jar</source>\n        <target>/opt/zimbra/jetty/webapps/service/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/jetty/webapps/zimbra/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/lib/jars/zimbrastore.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/lib/jars/zimbracommon.jar</source>\n        <target>/opt/zimbra/jetty/common/lib/zimbracommon.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/lib/jars/ical4j-0.9.16-patched.jar</source>\n        <target>/opt/zimbra/jetty/common/lib/ical4j-0.9.16-patched.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Notebook_all.js.zgz</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/js/Notebook_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/NewWindow_2_all.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/js/NewWindow_2_all.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/NewWindow_2_all.js.zgz</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/js/NewWindow_2_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Startup1_2_all.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/js/Startup1_2_all.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Startup1_2_all.js.zgz</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/js/Startup1_2_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file type=\"network\">\n        <source>ZimbraBuild/storebuild/opt/zimbra/lib/ext/zimbrasync/zimbrasync.jar</source>\n        <target>/opt/zimbra/lib/ext/zimbrasync/zimbrasync.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file type=\"network\">\n        <source>ZimbraBuild/storebuild/opt/zimbra/lib/ext/zimbrahsm/zimbrahsm.jar</source>\n        <target>/opt/zimbra/lib/ext/zimbrahsm/zimbrahsm.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file type=\"network\">\n        <source>ZimbraBuild/storebuild/opt/zimbra/lib/ext/backup/zimbrabackup.jar</source>\n        <target>/opt/zimbra/lib/ext/backup/zimbrabackup.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file type=\"network\">\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/dl/view/ZaDLXFormView.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/dl/view/ZaDLXFormView.js</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file type=\"network\">\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/Admin_all.js.zgz</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/Admin_all.js.zgz</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file type=\"network\">\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/Admin_all.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/Admin_all.js</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n  </package>\n  <preinstall></preinstall>\n  <postinstall></postinstall>\n  </patch>\n  <patch name=\"7.0.1_GA\" version=\"7.0.1_P1\">\n  <desc>Patch 7.0.1_P1</desc>\n  <bug>57499</bug>\n  <bug>57684</bug>\n  <bug>57727</bug>\n  <bug>58024</bug>\n  <package name=\"zimbra-store\">\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/lib/jars/zimbrastore.jar</source>\n        <target>/opt/zimbra/jetty/webapps/service/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/jetty/webapps/zimbra/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/lib/jars/zimbrastore.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/bin/zmmailboxdctl</source>\n        <target>/opt/zimbra/bin/zmmailboxdctl</target>\n        <perms owner=\"root\" mode=\"755\"/>\n      </file>\n      <file>\n        <source>ZimbraTagLib/build/zimbrataglib.jar</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/WEB-INF/lib/zimbrataglib.jar</target>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/WEB-INF/lib/zimbrataglib.jar</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Mail_all.js.zgz</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/js/Mail_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/zimbraMail/mail/view/ZmComposeView.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/js/zimbraMail/mail/view/ZmComposeView.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Mail_all.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/js/Mail_all.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/NewWindow_2_all.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/js/NewWindow_2_all.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/NewWindow_2_all.js.zgz</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/js/NewWindow_2_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <zimlet deploy=\"true\" flushcache=\"true\">\n        <source>Zimlet/build/dist/zimlets/com_zimbra_email.zip</source>\n        <target>/opt/zimbra/zimlets/com_zimbra_email.zip</target>\n      </zimlet>\n  </package>\n  <preinstall></preinstall>\n  <postinstall></postinstall>\n  </patch>\n  <patch name=\"6.0.12_GA\" version=\"6.0.12_P2\">\n  <desc>Patch 6.0.12_P2</desc>\n  <bug>57684</bug>\n  <bug>57727</bug>\n  <bug>58024</bug>\n  <bug>58617</bug>\n  <package name=\"zimbra-store\">\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/lib/jars/zimbrastore.jar</source>\n        <target>/opt/zimbra/jetty/webapps/service/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/jetty/webapps/zimbra/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/lib/jars/zimbrastore.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/bin/zmmailboxdctl</source>\n        <target>/opt/zimbra/bin/zmmailboxdctl</target>\n        <perms owner=\"root\" mode=\"755\"/>\n      </file>\n      <file>\n        <source>ZimbraTagLib/build/zimbrataglib.jar</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/WEB-INF/lib/zimbrataglib.jar</target>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/WEB-INF/lib/zimbrataglib.jar</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n  </package>\n  <preinstall></preinstall>\n  <postinstall></postinstall>\n  </patch>\n  <patch name=\"6.0.12_GA\" version=\"6.0.12_P3\">\n  <desc>Patch 6.0.12_P3</desc>\n  <bug>57684</bug>\n  <bug>57727</bug>\n  <bug>58024</bug>\n  <bug>58617</bug>\n  <bug>60379</bug>\n  <package name=\"zimbra-store\">\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/lib/jars/zimbrastore.jar</source>\n        <target>/opt/zimbra/jetty/webapps/service/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/jetty/webapps/zimbra/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/lib/jars/zimbrastore.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/bin/zmmailboxdctl</source>\n        <target>/opt/zimbra/bin/zmmailboxdctl</target>\n        <perms owner=\"root\" mode=\"755\"/>\n      </file>\n      <file>\n        <source>ZimbraTagLib/build/zimbrataglib.jar</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/WEB-INF/lib/zimbrataglib.jar</target>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/WEB-INF/lib/zimbrataglib.jar</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/Admin_all.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/Admin_all.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/Admin_all.js.zgz</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/Admin_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/WEB-INF/classes/messages/ZaMsg.properties</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/WEB-INF/classes/messages/ZaMsg.properties</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/common/EmailAddr_FormItem.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/common/EmailAddr_FormItem.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/common/ZaOverviewPanelController.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/common/ZaOverviewPanelController.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/domains/controller/ZaDomainListController.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/domains/controller/ZaDomainListController.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/domains/model/ZaDomain.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/domains/model/ZaDomain.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/search/model/ZaSearch.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/search/model/ZaSearch.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n  </package>\n  <preinstall></preinstall>\n  <postinstall></postinstall>\n  </patch>\n  <patch name=\"6.0.13_GA\" version=\"6.0.13_P1\">\n  <desc>Patch 6.0.13_P1</desc>\n  <bug>60748</bug>\n  <package name=\"zimbra-store\">\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Startup1_1_all.js.zgz</source>\n        <target>/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Startup1_1_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"644\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Mail_all.js.zgz</source>\n        <target>/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Mail_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"644\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/NewWindow_1_all.js.zgz</source>\n        <target>/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/NewWindow_1_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"644\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/NewWindow_2_all.js.zgz</source>\n        <target>/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/NewWindow_2_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"644\"/>\n      </file>\n  </package>\n  <preinstall></preinstall>\n  <postinstall></postinstall>\n  </patch>\n  <patch name=\"7.1.1_GA\" version=\"7.1.1_P1\">\n  <desc>Patch 7.1.1_P1</desc>\n  <bug>57891</bug>\n  <bug>58733</bug>\n  <bug>60379</bug>\n  <bug>60403</bug>\n  <bug>60600</bug>\n  <bug>60632</bug>\n  <package name=\"zimbra-core\">\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/libexec/zmfixperms</source>\n        <target>/opt/zimbra/libexec/zmfixperms</target>\n        <perms owner=\"root\" mode=\"755\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/bin/zmconfigdctl</source>\n        <target>/opt/zimbra/bin/zmconfigdctl</target>\n        <perms owner=\"root\" mode=\"755\"/>\n      </file>\n  </package>\n  <package name=\"zimbra-store\">\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/lib/jars/zimbrastore.jar</source>\n        <target>/opt/zimbra/jetty/webapps/service/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/jetty/webapps/zimbra/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/lib/jars/zimbrastore.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/Admin_all.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/Admin_all.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/Admin_all.js.zgz</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/Admin_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/WEB-INF/classes/messages/ZaMsg.properties</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/WEB-INF/classes/messages/ZaMsg.properties</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/common/EmailAddr_FormItem.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/common/EmailAddr_FormItem.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/common/ZaOverviewPanelController.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/common/ZaOverviewPanelController.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/domains/controller/ZaDomainListController.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/domains/controller/ZaDomainListController.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/domains/model/ZaDomain.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/domains/model/ZaDomain.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/search/model/ZaSearch.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/search/model/ZaSearch.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file type=\"network\">\n        <source>ZimbraBuild/storebuild/opt/zimbra/lib/ext/zimbrasync/zimbrasync.jar</source>\n        <target>/opt/zimbra/lib/ext/zimbrasync/zimbrasync.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n  </package>\n  <preinstall></preinstall>\n  <postinstall></postinstall>\n  </patch>\n  <patch name=\"7.1.1_GA\" version=\"7.1.1_P2\">\n  <desc>Patch 7.1.1_P2</desc>\n  <bug>57891</bug>\n  <bug>58733</bug>\n  <bug>60364</bug>\n  <bug>60379</bug>\n  <bug>60403</bug>\n  <bug>60600</bug>\n  <bug>60632</bug>\n  <bug>60743</bug>\n  <bug>60748</bug>\n  <bug>60951</bug>\n  <bug>60952</bug>\n  <bug>61217</bug>\n  <package name=\"zimbra-core\">\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/lib/jars/zimbracommon.jar</source>\n        <target>/opt/zimbra/lib/jars/zimbracommon.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/libexec/zmfixperms</source>\n        <target>/opt/zimbra/libexec/zmfixperms</target>\n        <perms owner=\"root\" mode=\"755\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/bin/zmconfigdctl</source>\n        <target>/opt/zimbra/bin/zmconfigdctl</target>\n        <perms owner=\"root\" mode=\"755\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/zimbramon/pylibs/state.py</source>\n        <target>/opt/zimbra/zimbramon/pylibs/state.py</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/lib/jars/jython-2.5.2.jar</source>\n        <target>/opt/zimbra/lib/jars/jython-2.5.2.jar</target>\n        <perms owner=\"root\" mode=\"755\"/>\n      </file>\n      <deletefile>\n        <target>/opt/zimbra/lib/jars/jython-2.5.1.jar</target>\n      </deletefile>\n  </package>\n  <package name=\"zimbra-store\">\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/lib/jars/zimbrastore.jar</source>\n        <target>/opt/zimbra/jetty/webapps/service/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/jetty/webapps/zimbra/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/lib/jars/zimbrastore.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/Admin_all.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/Admin_all.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/Admin_all.js.zgz</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/Admin_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/WEB-INF/classes/messages/ZaMsg.properties</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/WEB-INF/classes/messages/ZaMsg.properties</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/common/EmailAddr_FormItem.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/common/EmailAddr_FormItem.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/common/ZaOverviewPanelController.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/common/ZaOverviewPanelController.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/domains/controller/ZaDomainListController.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/domains/controller/ZaDomainListController.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/domains/model/ZaDomain.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/domains/model/ZaDomain.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/search/model/ZaSearch.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/search/model/ZaSearch.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file type=\"network\">\n        <source>ZimbraBuild/storebuild/opt/zimbra/lib/ext/zimbrasync/zimbrasync.jar</source>\n        <target>/opt/zimbra/lib/ext/zimbrasync/zimbrasync.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Startup1_1_all.js.zgz</source>\n        <target>/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Startup1_1_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"644\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Mail_all.js.zgz</source>\n        <target>/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Mail_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"644\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/NewWindow_1_all.js.zgz</source>\n        <target>/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/NewWindow_1_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"644\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/NewWindow_2_all.js.zgz</source>\n        <target>/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/NewWindow_2_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"644\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/CalendarAppt_all.js.zgz</source>\n        <target>/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/CalendarAppt_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"644\"/>\n      </file>\n      <file type=\"network\">\n        <source>ZimbraBuild/storebuild/opt/zimbra/lib/ext/network/zimbranetwork.jar</source>\n        <target>/opt/zimbra/lib/ext/network/zimbranetwork.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/common/lib/zimbracommon.jar</source>\n        <target>/opt/zimbra/jetty/common/lib/zimbracommon.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n  </package>\n  <preinstall></preinstall>\n  <postinstall></postinstall>\n  </patch>\n  <patch name=\"7.1.1_GA\" version=\"7.1.1_P3\">\n  <desc>Patch 7.1.1_P3</desc>\n  <bug>57891</bug>\n  <bug>58733</bug>\n  <bug>60364</bug>\n  <bug>60379</bug>\n  <bug>60403</bug>\n  <bug>60600</bug>\n  <bug>60632</bug>\n  <bug>60743</bug>\n  <bug>60748</bug>\n  <bug>60951</bug>\n  <bug>60952</bug>\n  <bug>61209</bug>\n  <bug>61217</bug>\n  <bug>61247</bug>\n  <bug>61509</bug>\n  <bug>61647</bug>\n  <bug>61763</bug>\n  <package name=\"zimbra-core\">\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/lib/jars/zimbracommon.jar</source>\n        <target>/opt/zimbra/lib/jars/zimbracommon.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/libexec/zmfixperms</source>\n        <target>/opt/zimbra/libexec/zmfixperms</target>\n        <perms owner=\"root\" mode=\"755\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/bin/zmconfigdctl</source>\n        <target>/opt/zimbra/bin/zmconfigdctl</target>\n        <perms owner=\"root\" mode=\"755\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/zimbramon/pylibs/state.py</source>\n        <target>/opt/zimbra/zimbramon/pylibs/state.py</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/lib/jars/jython-2.5.2.jar</source>\n        <target>/opt/zimbra/lib/jars/jython-2.5.2.jar</target>\n        <perms owner=\"root\" mode=\"755\"/>\n      </file>\n      <deletefile>\n        <target>/opt/zimbra/lib/jars/jython-2.5.1.jar</target>\n      </deletefile>\n  </package>\n  <package name=\"zimbra-store\">\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/lib/jars/zimbrastore.jar</source>\n        <target>/opt/zimbra/jetty/webapps/service/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/jetty/webapps/zimbra/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/lib/jars/zimbrastore.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/Admin_all.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/Admin_all.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/Admin_all.js.zgz</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/Admin_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/WEB-INF/classes/messages/ZaMsg.properties</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/WEB-INF/classes/messages/ZaMsg.properties</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/common/EmailAddr_FormItem.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/common/EmailAddr_FormItem.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/common/ZaOverviewPanelController.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/common/ZaOverviewPanelController.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/domains/controller/ZaDomainListController.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/domains/controller/ZaDomainListController.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/domains/model/ZaDomain.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/domains/model/ZaDomain.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/search/model/ZaSearch.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/search/model/ZaSearch.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file type=\"network\">\n        <source>ZimbraBuild/storebuild/opt/zimbra/lib/ext/zimbrasync/zimbrasync.jar</source>\n        <target>/opt/zimbra/lib/ext/zimbrasync/zimbrasync.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Startup1_1_all.js.zgz</source>\n        <target>/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Startup1_1_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"644\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Mail_all.js.zgz</source>\n        <target>/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Mail_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"644\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/NewWindow_1_all.js.zgz</source>\n        <target>/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/NewWindow_1_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"644\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/NewWindow_2_all.js.zgz</source>\n        <target>/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/NewWindow_2_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"644\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/CalendarAppt_all.js.zgz</source>\n        <target>/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/CalendarAppt_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"644\"/>\n      </file>\n      <file type=\"network\">\n        <source>ZimbraBuild/storebuild/opt/zimbra/lib/ext/network/zimbranetwork.jar</source>\n        <target>/opt/zimbra/lib/ext/network/zimbranetwork.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/common/lib/zimbracommon.jar</source>\n        <target>/opt/zimbra/jetty/common/lib/zimbracommon.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file type=\"network\">\n        <source>ZimbraBuild/storebuild/opt/zimbra/lib/ext/backup/zimbrabackup.jar</source>\n        <target>/opt/zimbra/lib/ext/backup/zimbrabackup.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/m/mocompose</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/m/mocompose</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/WEB-INF/tags/mobile/moMessageAction.tag</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/WEB-INF/tags/mobile/moMessageAction.tag</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/WEB-INF/tags/mobile/moBriefcaseToolbar.tag</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/WEB-INF/tags/mobile/moBriefcaseToolbar.tag</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/WEB-INF/tags/mobile/moCalendarViewToolbar.tag</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/WEB-INF/tags/mobile/moCalendarViewToolbar.tag</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/WEB-INF/tags/mobile/moTaskToolbar.tag</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/WEB-INF/tags/mobile/moTaskToolbar.tag</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/WEB-INF/tags/mobile/moDisplayContact.tag</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/WEB-INF/tags/mobile/moDisplayContact.tag</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/WEB-INF/tags/mobile/moContactField.tag</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/WEB-INF/tags/mobile/moContactField.tag</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n  </package>\n  <preinstall></preinstall>\n  <postinstall></postinstall>\n  </patch> -->\n  <patch name=\"7.1.1_GA\" version=\"7.1.1_P4\">\n  <desc>Patch 7.1.1_P4</desc>\n  <bug>57891</bug>\n  <bug>58733</bug>\n  <bug>60364</bug>\n  <bug>60379</bug>\n  <bug>60403</bug>\n  <bug>60600</bug>\n  <bug>60632</bug>\n  <bug>60743</bug>\n  <bug>60748</bug>\n  <bug>60951</bug>\n  <bug>60952</bug>\n  <bug>61209</bug>\n  <bug>61217</bug>\n  <bug>61247</bug>\n  <bug>61509</bug>\n  <bug>61548</bug>\n  <bug>61634</bug>\n  <bug>61647</bug>\n  <bug>61763</bug>\n  <package name=\"zimbra-core\">\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/lib/jars/zimbracommon.jar</source>\n        <target>/opt/zimbra/lib/jars/zimbracommon.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/libexec/zmfixperms</source>\n        <target>/opt/zimbra/libexec/zmfixperms</target>\n        <perms owner=\"root\" mode=\"755\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/bin/zmconfigdctl</source>\n        <target>/opt/zimbra/bin/zmconfigdctl</target>\n        <perms owner=\"root\" mode=\"755\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/zimbramon/pylibs/state.py</source>\n        <target>/opt/zimbra/zimbramon/pylibs/state.py</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/lib/jars/jython-2.5.2.jar</source>\n        <target>/opt/zimbra/lib/jars/jython-2.5.2.jar</target>\n        <perms owner=\"root\" mode=\"755\"/>\n      </file>\n      <deletefile>\n        <target>/opt/zimbra/lib/jars/jython-2.5.1.jar</target>\n      </deletefile>\n  </package>\n  <package name=\"zimbra-store\">\n      <file>\n        <source>ZimbraBuild/corebuild/opt/zimbra/lib/jars/zimbrastore.jar</source>\n        <target>/opt/zimbra/jetty/webapps/service/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/jetty/webapps/zimbra/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/WEB-INF/lib/zimbrastore.jar</target>\n        <target>/opt/zimbra/lib/jars/zimbrastore.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/Admin_all.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/Admin_all.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/Admin_all.js.zgz</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/Admin_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/WEB-INF/classes/messages/ZaMsg.properties</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/WEB-INF/classes/messages/ZaMsg.properties</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/common/EmailAddr_FormItem.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/common/EmailAddr_FormItem.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/common/ZaOverviewPanelController.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/common/ZaOverviewPanelController.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/domains/controller/ZaDomainListController.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/domains/controller/ZaDomainListController.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/domains/model/ZaDomain.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/domains/model/ZaDomain.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/search/model/ZaSearch.js</source>\n        <target>/opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/search/model/ZaSearch.js</target>\n        <perms owner=\"zimbra\" mode=\"664\"/>\n      </file>\n      <file type=\"network\">\n        <source>ZimbraBuild/storebuild/opt/zimbra/lib/ext/zimbrasync/zimbrasync.jar</source>\n        <target>/opt/zimbra/lib/ext/zimbrasync/zimbrasync.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Startup1_1_all.js.zgz</source>\n        <target>/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Startup1_1_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"644\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Mail_all.js.zgz</source>\n        <target>/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Mail_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"644\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/NewWindow_1_all.js.zgz</source>\n        <target>/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/NewWindow_1_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"644\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/NewWindow_2_all.js.zgz</source>\n        <target>/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/NewWindow_2_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"644\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/CalendarAppt_all.js.zgz</source>\n        <target>/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/CalendarAppt_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"644\"/>\n      </file>\n      <file type=\"network\">\n        <source>ZimbraBuild/storebuild/opt/zimbra/lib/ext/network/zimbranetwork.jar</source>\n        <target>/opt/zimbra/lib/ext/network/zimbranetwork.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/common/lib/zimbracommon.jar</source>\n        <target>/opt/zimbra/jetty/common/lib/zimbracommon.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file type=\"network\">\n        <source>ZimbraBuild/storebuild/opt/zimbra/lib/ext/backup/zimbrabackup.jar</source>\n        <target>/opt/zimbra/lib/ext/backup/zimbrabackup.jar</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/m/mocompose</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/m/mocompose</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/WEB-INF/tags/mobile/moMessageAction.tag</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/WEB-INF/tags/mobile/moMessageAction.tag</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/WEB-INF/tags/mobile/moBriefcaseToolbar.tag</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/WEB-INF/tags/mobile/moBriefcaseToolbar.tag</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/WEB-INF/tags/mobile/moCalendarViewToolbar.tag</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/WEB-INF/tags/mobile/moCalendarViewToolbar.tag</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/WEB-INF/tags/mobile/moTaskToolbar.tag</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/WEB-INF/tags/mobile/moTaskToolbar.tag</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/WEB-INF/tags/mobile/moDisplayContact.tag</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/WEB-INF/tags/mobile/moDisplayContact.tag</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/WEB-INF/tags/mobile/moContactField.tag</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/WEB-INF/tags/mobile/moContactField.tag</target>\n        <perms owner=\"root\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Contacts_all.js.zgz</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/js/Contacts_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/NewWindow2_all.js.zgz</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/js/NewWindow2_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/MailCore_all.js.zgz</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/js/MailCore_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Preferences_all.js.zgz</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/js/Preferences_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Startup1_2_all.js.zgz</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/js/Startup1_2_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Share_all.js.zgz</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/js/Share_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Startup2_all.js.zgz</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/js/Startup2_all.js.zgz</target>\n        <perms owner=\"zimbra\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Extras_all.js.zgz</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/js/Extras_all.js.zgz</target\n        <perms owner=\"zimbra\" mode=\"444\"/>\n      </file>\n      <file>\n        <source>ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/WEB-INF/tags/ruby.tag</source>\n        <target>/opt/zimbra/jetty/webapps/zimbra/WEB-INF/tags/ruby.tag</target\n        <perms owner=\"zimbra\" mode=\"444\"/>\n      </file>\n  </package>\n  <preinstall></preinstall>\n  <postinstall></postinstall>\n  </patch>\n</patches>\n  \n"
  },
  {
    "path": "rpmconf/Patch/installPatch.sh",
    "content": "#!/bin/bash\n# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2010, 2012, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n# \nID=$(id -un)\nif [ x\"$ID\" != \"xroot\" ]; then\n  echo \"$0 must be run as root.\"\n  exit 1\nfi\n\nif [ $# -gt 1 ]\nthen\n  echo \"usage: $0 [--force]\"\n  exit 1\nfi\nif [ \"x$1\" != \"x--force\" -a \"x$1\" != \"x\" ]\nthen\n  echo \"usage: $0 [--force]\"\n  exit 1\nfi\n\n/usr/bin/perl bin/zmpatch.pl --config conf/zmpatch.xml --verbose $1\n"
  },
  {
    "path": "rpmconf/Patch/libexec/zmcurl807-updater.sh",
    "content": "#!/bin/bash\n\nif [ x`whoami` != xroot ]; then\n  echo Error: must be run as root user\n  exit 1\nfi\n\nVERSION=`su - zimbra -c 'zmcontrol -v'`\nVERSION=$(echo ${VERSION} | cut -d' ' -f2)\nVERSION=$(echo ${VERSION} | sed \"s/_.*//\")\nMAJOR=$(echo ${VERSION} | cut -d'.' -f1)\nMINOR=$(echo ${VERSION} | cut -d'.' -f2)\nPATCH=$(echo ${VERSION} | cut -d'.' -f3)\n\nif [ $MAJOR -ne 8 ]; then\n  echo \"Unsupported MAJOR version $MAJOR\"\n  exit 1\nfi\n\nif [ $MINOR -ne 0 ]; then\n  echo \"Unsupported MINOR version $MINOR\"\n  exit 1\nfi\n\nif [ $PATCH -lt 7 ]; then\n   echo \"Must be running 8.0.7\"\n   exit 1\nfi\n\nif [ $PATCH -gt 7 ]; then\n  echo \"Must be running 8.0.7\"\n  exit 1\nfi\n\nCURL_VERSION=7.35.0\n\nif [ ! -d \"/opt/zimbra/curl-${CURL_VERSION}\" ]; then\n  echo \"Error: Unable to patch this release\"\n  exit 1\nfi\n\nEGREP=`which egrep`\nif [ x$EGREP = \"x\" ]; then\n  echo \"Error: egrep not in path\"\n  exit 1\nfi\n\n$EGREP 7.36.0 /opt/zimbra/curl-${CURL_VERSION}/bin/curl >/dev/null\nRC=$?\n\nif [ $RC -eq 0 ]; then\n  echo \"Error: Already patched\"\n  exit 1\nfi\n\nONLINE=1\nif [ x\"$1\" = \"x-o\" -o x\"$1\" = \"x--offline\" ]; then\n  ONLINE=0\nfi\n\ncd /tmp\nPLAT=`/bin/sh /opt/zimbra/libexec/get_plat_tag.sh`\n\nif [ $ONLINE -eq 1 ]; then\n  if [ -d curl/$PLAT ]; then\n    rm -rf curl/$PLAT\n  fi\nfi\n\nmkdir -p curl/$PLAT\ncd curl/$PLAT\n\nif [ $ONLINE -eq 1 ]; then\n  WGET=`which wget`\n  if [ x\"$WGET\" = \"x\" ]; then\n    echo \"Error: wget not in path\"\n    exit 1\n  fi\nfi\n\nMD5SUM=`which md5sum`\nif [ x\"$MD5SUM\" = \"x\" ]; then\n  echo \"Error: md5sum not in path\"\n  exit 1\nfi\n\nif [ $ONLINE -eq 1 ]; then\n  echo \"Downloading patched curl\"\n  wget http://files.zimbra.com/downloads/8.0.${PATCH}_GA/curl/$PLAT/curl-${CURL_VERSION}.tgz >/dev/null 2>&1\n  RC=$?\n  \n  if [ $RC -ne 0 ]; then\n    echo \"Error: Unable to download curl\"\n    exit 1\n  fi\n  \n  wget http://files.zimbra.com/downloads/8.0.${PATCH}_GA/curl/$PLAT/curl-${CURL_VERSION}.tgz.md5sum >/dev/null 2>&1\n  RC=$?\n  \n  if [ $RC -ne 0 ]; then\n    echo \"Error: Unable to download md5sum\"\n    exit 1\n  fi\nfi\n\necho -n \"Validating patched curl: \"\nDOWNLOAD_SUM=`$MD5SUM curl-${CURL_VERSION}.tgz`\nGOOD_SUM=`cat curl-${CURL_VERSION}.tgz.md5sum`\n\nif [ \"$GOOD_SUM\" = \"$DOWNLOAD_SUM\" ]; then\n  echo \"success\"\nelse\n  echo \"ERROR: MD5SUM mismatch\"\n  echo \"Expected $GOOD_SUM\"\n  echo \"Got $DOWNLOAD_SUM\"\n  exit 1\nfi\n\necho -n \"Backing up old curl: \"\ncd /opt/zimbra\nmv curl-${CURL_VERSION} curl-${CURL_VERSION}.sslprotocol.$$\necho \"complete\"\n\necho -n \"Installing patched curl: \"\ntar xfz /tmp/curl/$PLAT/curl-${CURL_VERSION}.tgz\necho \"complete\"\n\necho \"Curl patch process complete.\"\necho \"Please restart Zimbra Collaboration Suite as the Zimbra user via zmcontrol restart\"\n"
  },
  {
    "path": "rpmconf/Patch/libexec/zmopenssl-updater.sh",
    "content": "#!/bin/bash\n\nif [ x`whoami` != xroot ]; then\n  echo Error: must be run as root user\n  exit 1\nfi\n\nSSL[0]='1.0.1d'\nSSL[1]='1.0.1e'\nSSL[2]='1.0.1e'\nSSL[3]='1.0.1e'\nSSL[4]='1.0.1f'\nVERSION=`su - zimbra -c 'zmcontrol -v'`\nif [[ $VERSION == *ZCA* ]]; then\n  VERSION=$(echo $VERSION|tr -d '\\n')\n  VERSION=$(expr \"$VERSION\" : '.*\\(ZCS Build.*\\)')\n  VERSION=$(echo ${VERSION} | cut -d' ' -f3)\nelse\n  VERSION=$(echo ${VERSION} | cut -d' ' -f2)\n  VERSION=$(echo ${VERSION} | sed \"s/_.*//\")\nfi\nMAJOR=$(echo ${VERSION} | cut -d'.' -f1)\nMINOR=$(echo ${VERSION} | cut -d'.' -f2)\nPATCH=$(echo ${VERSION} | cut -d'.' -f3)\n\nif [ $MAJOR -ne 8 ]; then\n  echo \"Unsupported MAJOR version $MAJOR\"\n  exit 1\nfi\n\nif [ $MINOR -ne 0 ]; then\n  echo \"Unsupported MINOR version $MINOR\"\n  exit 1\nfi\n\nif [ $PATCH -lt 3 ]; then\n   echo \"Must be running 8.0.3 or later\"\n   exit 1\nfi\n\nif [ $PATCH -gt 7 ]; then\n  echo \"Must be running 8.0.7 or earlier\"\n  exit 1\nfi\n\nARPATCH=$(expr $PATCH - 3)\nSSL_VERSION=${SSL[$ARPATCH]}\n\nif [ ! -d \"/opt/zimbra/openssl-${SSL_VERSION}\" ]; then\n  echo \"Error: Unable to patch this release\"\n  exit 1\nfi\n\nEGREP=`which egrep`\nif [ x$EGREP = \"x\" ]; then\n  echo \"Error: egrep not in path\"\n  exit 1\nfi\n\n$EGREP dtls1_process_heartbeat /opt/zimbra/openssl-${SSL_VERSION}/lib/libssl.so.1.0.0 >/dev/null\nRC=$?\n\nif [ $RC -eq 1 ]; then\n  echo \"Error: Already patched\"\n  exit 1\nfi\n\nONLINE=1\nif [ x\"$1\" = \"x-o\" -o x\"$1\" = \"x--offline\" ]; then\n  ONLINE=0\nfi\n\ncd /tmp\nPLAT=`/bin/sh /opt/zimbra/libexec/get_plat_tag.sh`\n\nif [ $ONLINE -eq 1 ]; then\n  if [ -d openssl/$PLAT ]; then\n    rm -rf openssl/$PLAT\n  fi\nfi\n\nmkdir -p openssl/$PLAT\ncd openssl/$PLAT\n\nif [ $ONLINE -eq 1 ]; then\n  WGET=`which wget`\n  if [ x\"$WGET\" = \"x\" ]; then\n    echo \"Error: wget not in path\"\n    exit 1\n  fi\nfi\n\nMD5SUM=`which md5sum`\nif [ x\"$MD5SUM\" = \"x\" ]; then\n  echo \"Error: md5sum not in path\"\n  exit 1\nfi\n\nif [ $ONLINE -eq 1 ]; then\n  echo \"Downloading patched openssl\"\n  wget http://files.zimbra.com/downloads/8.0.${PATCH}_GA/openssl/$PLAT/openssl-${SSL_VERSION}.tgz >/dev/null 2>&1\n  RC=$?\n  \n  if [ $RC -ne 0 ]; then\n    echo \"Error: Unable to download openssl\"\n    exit 1\n  fi\n  \n  wget http://files.zimbra.com/downloads/8.0.${PATCH}_GA/openssl/$PLAT/openssl-${SSL_VERSION}.tgz.md5sum >/dev/null 2>&1\n  RC=$?\n  \n  if [ $RC -ne 0 ]; then\n    echo \"Error: Unable to download md5sum\"\n    exit 1\n  fi\nfi\n\necho -n \"Validating patched openssl: \"\nDOWNLOAD_SUM=`$MD5SUM openssl-${SSL_VERSION}.tgz`\nGOOD_SUM=`cat openssl-${SSL_VERSION}.tgz.md5sum`\n\nif [ \"$GOOD_SUM\" = \"$DOWNLOAD_SUM\" ]; then\n  echo \"success\"\nelse\n  echo \"ERROR: MD5SUM mismatch\"\n  echo \"Expected $GOOD_SUM\"\n  echo \"Got $DOWNLOAD_SUM\"\n  exit 1\nfi\n\necho -n \"Backing up old openssl: \"\ncd /opt/zimbra\nmv openssl-${SSL_VERSION} openssl-${SSL_VERSION}.brokenheart.$$\necho \"complete\"\n\necho -n \"Installing patched openssl: \"\ntar xfz /tmp/openssl/$PLAT/openssl-${SSL_VERSION}.tgz\necho \"complete\"\n\necho \"OpenSSL patch process complete.\"\necho \"Please restart Zimbra Collaboration Suite as the Zimbra user via zmcontrol restart\"\n"
  },
  {
    "path": "rpmconf/Spec/Scripts/zimbra-core.post",
    "content": "#!/bin/bash\n# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n# \n# Create group, user for zimbra and postfix.\n\nH=`hostname --fqdn`\nI=`hostname -i`\n\n#Symlinks\nrm -f /opt/zimbra/java\nPLAT=`/opt/zimbra/libexec/get_plat_tag.sh`\nBIT=`echo $PLAT | awk -F_ '{print $2}'`\n\nif [ -d \"/opt/zimbra/logger/db\" ]; then\n  chown zimbra:zimbra /opt/zimbra/logger/db\nfi\n\nif [ -f \"/opt/zimbra/conf/ca/ca.pem\" ]; then\n  ln -f -s ca.pem /opt/zimbra/conf/ca/`openssl x509 -hash -noout -in /opt/zimbra/conf/ca/ca.pem`.0\nfi\n\nif [[ $PLAT == \"DEBIAN\"* || $PLAT == \"UBUNTU\"* ]]; then\n  sed -i -e '/^::1     ip6-localhost ip6-loopback localhost$/!s/::1     ip6-localhost ip6-loopback/::1     ip6-localhost ip6-loopback localhost/' /etc/hosts\n  sed -i -e 's/# session    required   pam_limits.so/session    required   pam_limits.so/' /etc/pam.d/su\n  pamtmp=`mktemp -t zpamtmp.XXXXXX 2> /dev/null` || { echo \"Failed to create tmpfile\"; exit 1; }\n  egrep -v -e '^session[[:space:]]+required[[:space:]]+pam_limits.so' /etc/pam.d/common-session >$pamtmp\n  echo \"session\trequired\tpam_limits.so\" >> $pamtmp\n  mv -f $pamtmp /etc/pam.d/common-session\n  chmod 640 /etc/pam.d/common-session\n  limitstmp=`mktemp -t zlimtmp.XXXXXX 2> /dev/null` || { echo \"Failed to create tmpfile\"; exit 1; }\n  egrep -v -e '^root.*nofile' /etc/security/limits.conf > $limitstmp\n  echo \"root soft nofile 524288\" >> $limitstmp\n  echo \"root hard nofile 524288\" >> $limitstmp\n  mv -f $limitstmp /etc/security/limits.conf\n  chmod 640 /etc/security/limits.conf\n  chown -R root:root /opt/zimbra/common/lib/perl5/Zimbra\nfi\n\nif [ -d /etc/logrotate.d ]; then\n\tcp -f /opt/zimbra/conf/zmlogrotate /etc/logrotate.d/zimbra\nfi\n\ncp -f /opt/zimbra/libexec/zimbra /etc/init.d/zimbra\nchmod 755 /etc/init.d/zimbra\nif [ -x /sbin/chkconfig ]; then\n\tchkconfig --del zimbra\n\tchkconfig --add zimbra \n\tchkconfig zimbra on\nelif [ -x /usr/sbin/update-rc.d ]; then\n        update-rc.d -f zimbra remove\n        update-rc.d zimbra start 99 2 5 . stop 01 0 1 6 .\nelse\n\trm -f /etc/rc*.d/S99zimbra\n\trm -f /etc/rc*.d/S89zimbra\n\trm -f /etc/rc*.d/K01zimbra\n\n  if [ -d /etc/rc0.d ]; then\n    ln -s /etc/init.d/zimbra /etc/rc0.d/S89zimbra\n    ln -s /etc/init.d/zimbra /etc/rc0.d/K01zimbra\n  fi\n  if [ -d /etc/rc1.d ]; then\n\tln -s /etc/init.d/zimbra /etc/rc1.d/K01zimbra\n  fi\n  if [ -d /etc/rc2.d ]; then\n\t  ln -s /etc/init.d/zimbra /etc/rc2.d/S99zimbra\n\t  ln -s /etc/init.d/zimbra /etc/rc2.d/K01zimbra\n  fi\n  if [ -d /etc/rc3.d ]; then\n\t  ln -s /etc/init.d/zimbra /etc/rc3.d/S99zimbra\n\t  ln -s /etc/init.d/zimbra /etc/rc3.d/K01zimbra\n  fi\n  if [ -d /etc/rc4.d ]; then\n\t  ln -s /etc/init.d/zimbra /etc/rc4.d/S99zimbra\n\t  ln -s /etc/init.d/zimbra /etc/rc4.d/K01zimbra\n  fi\n  if [ -d /etc/rc5.d ]; then\n\t  ln -s /etc/init.d/zimbra /etc/rc5.d/S99zimbra\n\t  ln -s /etc/init.d/zimbra /etc/rc5.d/K01zimbra\n  fi\n  if [ -d /etc/rc6.d ]; then\n\t  ln -s /etc/init.d/zimbra /etc/rc6.d/S89zimbra\n\t  ln -s /etc/init.d/zimbra /etc/rc6.d/K01zimbra\n  fi\n  \nfi\n\nmkdir -p /opt/zimbra/backup\nchown zimbra:zimbra /opt/zimbra/backup\nmkdir -p /opt/zimbra/log\nchown zimbra:zimbra /opt/zimbra/log\nmkdir -p /opt/zimbra/ssl\nchown zimbra:zimbra /opt/zimbra/ssl\nmkdir -p /opt/zimbra/.ssh\nchown zimbra:zimbra /opt/zimbra/.ssh\nmkdir -p /opt/zimbra/zmstat\nchown zimbra:zimbra /opt/zimbra/zmstat\n\negrep -q '^%zimbra[[:space:]]' /etc/sudoers\nif [ $? = 0 ]; then\n  sudotmp=`mktemp -t zsudoers.XXXXXX 2> /dev/null` || { echo \"Failed to create tmpfile\"; exit 1; }\n  SUDOMODE=`perl -e 'my $mode=(stat(\"/etc/sudoers\"))[2];if ($mode == \"0000\"){ $mode=33056 };printf(\"%04o\\n\",$mode & 07777);'`;\n  egrep -v -e '^%zimbra[[:space:]]' /etc/sudoers > $sudotmp\n  mv -f $sudotmp /etc/sudoers\n  chmod $SUDOMODE /etc/sudoers\nfi\n\nchmod 440 /etc/sudoers.d/01_zimbra\nchown root:root /etc/sudoers.d/01_zimbra\n\nchmod 440 /etc/sudoers.d/02_zimbra-core\nchown root:root /etc/sudoers.d/02_zimbra-core\n\nif [ -x \"/opt/zimbra/libexec/zmfixperms\" ]; then\n  /opt/zimbra/libexec/zmfixperms\nfi\n"
  },
  {
    "path": "rpmconf/Spec/Scripts/zimbra-core.pre",
    "content": "#!/bin/bash\n#\n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n#\n\nif [ \"`echo /etc/security/limits.d/*-nproc.conf`\" != \"/etc/security/limits.d/*-nproc.conf\" ]; then\n    echo \"zimbra soft nproc 278528\" > /etc/security/limits.d/10-zimbra.conf\n    echo \"zimbra hard nproc 278528\" >> /etc/security/limits.d/10-zimbra.conf\n    echo \"postfix soft nproc 278528\" >> /etc/security/limits.d/10-zimbra.conf\n    echo \"postfix hard nproc 278528\" >> /etc/security/limits.d/10-zimbra.conf\n    echo \"root soft nproc 278528\" >> /etc/security/limits.d/10-zimbra.conf\n    echo \"root hard nproc 278528\" >> /etc/security/limits.d/10-zimbra.conf\nfi\nif [ -f \"/etc/security/limits.conf\" ]; then\n    limitstmp=`mktemp -t limitstmp.XXXXXX 2> /dev/null` || { echo \"Failed to create tmpfile\"; exit 1; }\n    egrep -v -e '^zimbra.*nofile' /etc/security/limits.conf > $limitstmp\n    echo \"zimbra soft nofile 524288\" >> $limitstmp\n    echo \"zimbra hard nofile 524288\" >> $limitstmp\n    mv -f $limitstmp /etc/security/limits.conf\n    chmod 640 /etc/security/limits.conf\nelse\n    echo \"zimbra soft nofile 524288\" > /etc/security/limits.conf\n    echo \"zimbra hard nofile 524288\" >> /etc/security/limits.conf\n    chmod 640 /etc/security/limits.conf\nfi\n\nif [ -d \"/opt/zimbra/lib/ext/com_zimbra_ssdb_ephemeral_store\" ]; then\n\tif [ `ls -1 /opt/zimbra/lib/ext/com_zimbra_ssdb_ephemeral_store/zm-ssdb-ephemeral-store-*.jar 2>/dev/null | wc -l` -gt 0 ]; then\n\t\trm -rf /opt/zimbra/lib/ext/com_zimbra_ssdb_ephemeral_store/zm-ssdb-ephemeral-store-*.jar\n\tfi\nfi\n"
  },
  {
    "path": "rpmconf/Spec/Scripts/zimbra-dnscache.post",
    "content": "#!/bin/bash\n# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n# \n\n#Symlinks\n\nmkdir -p /opt/zimbra/data/dns/ca\nmkdir -p /opt/zimbra/data/dns/trust\nchown -R zimbra:zimbra /opt/zimbra/data/dns\n\nchown zimbra:zimbra /opt/zimbra/data\n\negrep -q '^%zimbra[[:space:]]' /etc/sudoers\nif [ $? = 0 ]; then\n  sudotmp=`mktemp -t zsudoers.XXXXXX 2> /dev/null` || { echo \"Failed to create tmpfile\"; exit 1; }\n  SUDOMODE=`perl -e 'my $mode=(stat(\"/etc/sudoers\"))[2];printf(\"%04o\\n\",$mode & 07777);'`\n  egrep -v '^%zimbra[[:space:]]' /etc/sudoers > $sudotmp\n  mv -f $sudotmp /etc/sudoers\n  chmod $SUDOMODE /etc/sudoers\nfi\nchmod 440 /etc/sudoers.d/02_zimbra-dnscache\nchown root:root /etc/sudoers.d/02_zimbra-dnscache\n"
  },
  {
    "path": "rpmconf/Spec/Scripts/zimbra-ldap.post",
    "content": "#!/bin/bash\n#\n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n#\n# Create group, user for zimbra and postfix.\n\nshopt -s nullglob\n\nmkdir -p /opt/zimbra/data/ldap/state/run\nmkdir -p /opt/zimbra/data/ldap/config\nmkdir -p /opt/zimbra/data/ldap/mdb/db\nchown -R zimbra:zimbra /opt/zimbra/data/ldap\n\nchown -R root:root /opt/zimbra/common/etc/openldap\n\nif [ -x /opt/zimbra/common/libexec/slapd ]; then\n    chown root:zimbra /opt/zimbra/common/libexec/slapd\n    chmod 750 /opt/zimbra/common/libexec/slapd\n\n    echo \"Set capability for /opt/zimbra/common/libexec/slapd\"\n    setcap CAP_NET_BIND_SERVICE=+ep /opt/zimbra/common/libexec/slapd\nfi"
  },
  {
    "path": "rpmconf/Spec/Scripts/zimbra-logger.post",
    "content": "#!/bin/bash\n# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n# \nif [ -x \"/opt/zimbra/libexec/zmfixperms\" ]; then\n  /opt/zimbra/libexec/zmfixperms\nfi\n"
  },
  {
    "path": "rpmconf/Spec/Scripts/zimbra-mta.post",
    "content": "#!/bin/bash\n# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n# \n\n#Symlinks\n\nPLAT=$(/opt/zimbra/libexec/get_plat_tag.sh)\nif [[ $PLAT == \"UBUNTU\"* || $PLAT == \"DEBIAN\"* ]]; then\n  if [ ! -e \"/usr/sbin/sendmail\" -o -L \"/usr/bin/sendmail\" ]; then\n     if [ -L \"/usr/bin/sendmail\" ]; then\n       if [ -x /bin/readlink ]; then\n         SMPATH=$(/bin/readlink /usr/sbin/sendmail)\n         if [ x$SMPATH = x\"/opt/zimbra/postfix/sbin/sendmail\" -o x$SMPATH = x\"/opt/zimbra/common/sbin/sendmail\" ]; then\n            /bin/rm -f /usr/sbin/sendmail\n            ln -s /opt/zimbra/common/sbin/sendmail /usr/sbin/sendmail\n          fi\n       fi\n     else\n       ln -s /opt/zimbra/common/sbin/sendmail /usr/sbin/sendmail\n     fi\n  fi\nfi\n\negrep -q '^%zimbra[[:space:]]' /etc/sudoers\nif [ $? = 0 ]; then\n  sudotmp=`mktemp -t zsudoers.XXXXXX 2> /dev/null` || { echo \"Failed to create tmpfile\"; exit 1; }\n  SUDOMODE=`perl -e 'my $mode=(stat(\"/etc/sudoers\"))[2];printf(\"%04o\\n\",$mode & 07777);'`\n  egrep -v '^%zimbra[[:space:]]' /etc/sudoers > $sudotmp\n  mv -f $sudotmp /etc/sudoers\n  chmod $SUDOMODE /etc/sudoers\nfi\nchmod 440 /etc/sudoers.d/02_zimbra-mta\nchown root:root /etc/sudoers.d/02_zimbra-mta\n\nchown zimbra:zimbra /opt/zimbra/common/conf/master.cf.in\nchmod 440 /opt/zimbra/common/conf/master.cf.in\nchown zimbra:zimbra /opt/zimbra/common/conf/tag_as_*.re.in\n\nmkdir -p /opt/zimbra/data/amavisd/db\nmkdir -p /opt/zimbra/data/amavisd/tmp\nmkdir -p /opt/zimbra/data/amavisd/var\nmkdir -p /opt/zimbra/data/amavisd/quarantine\nchown -R zimbra:zimbra /opt/zimbra/data/amavisd/*\n\nmkdir -p /opt/zimbra/data/opendkim\nchown -R zimbra:zimbra /opt/zimbra/data/opendkim\n\nmkdir -p /opt/zimbra/data/clamav/db\nchown -R zimbra:zimbra /opt/zimbra/data/clamav/db\n\nmkdir -p /opt/zimbra/data/postfix/spool/pid\nchown postfix:zimbra /opt/zimbra/data/postfix\nchown root:postfix /opt/zimbra/data/postfix/spool\nchown postfix:root /opt/zimbra/data/postfix/spool/pid\n\nchown zimbra:zimbra /opt/zimbra/data\n\nif [ ! -f /opt/zimbra/common/conf/main.cf ]; then\n\ttouch /opt/zimbra/common/conf/main.cf\n\tchown zimbra:zimbra /opt/zimbra/common/conf/main.cf\nfi\n\nif [ ! -e /etc/aliases -o -L /etc/aliases ]; then\n  if [ -L /etc/aliases ]; then\n    if [ -x /bin/readlink ]; then\n      SMPATH=$(/bin/readlink /etc/aliases)\n      if [ x$SMPATH = x\"/opt/zimbra/postfix/conf/aliases\" -o x$SMPATH = x\"/opt/zimbra/common/conf/aliases\" ]; then\n        rm -f /etc/aliases\n        ln -s /opt/zimbra/common/conf/aliases /etc/aliases\n      fi\n    fi\n  else\n    ln -s /opt/zimbra/common/conf/aliases /etc/aliases\n  fi\nfi\n\nif [ -x \"/opt/zimbra/libexec/zmfixperms\" ]; then\n  /opt/zimbra/libexec/zmfixperms\nfi\n\nchgrp zimbra /opt/zimbra/common/conf\nchmod g+w /opt/zimbra/common/conf\n"
  },
  {
    "path": "rpmconf/Spec/Scripts/zimbra-proxy.post",
    "content": "#!/bin/bash\n# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2007, 2008, 2009, 2010, 2012, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n# \n\nchown -R zimbra:zimbra /opt/zimbra/conf/nginx\n\nif [ -f /opt/zimbra/log/nginx.log ]; then\n    chown zimbra:zimbra /opt/zimbra/log/nginx.log\n    chmod 644 /opt/zimbra/log/nginx.log\nfi\n\nif [ -f /opt/zimbra/log/nginx.access.log ]; then\n    chown zimbra:zimbra /opt/zimbra/log/nginx.access.log\n    chmod 644 /opt/zimbra/log/nginx.access.log\nfi\n\nif [ -x /opt/zimbra/common/sbin/nginx ]; then\n    chown root:zimbra /opt/zimbra/common/sbin/nginx\n    chmod 750 /opt/zimbra/common/sbin/nginx\n\n    echo \"Set capability for /opt/zimbra/common/sbin/nginx\"\n    setcap CAP_NET_BIND_SERVICE=+ep /opt/zimbra/common/sbin/nginx\nfi\n\n"
  },
  {
    "path": "rpmconf/Spec/Scripts/zimbra-qa.post",
    "content": "#!/bin/bash\n# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2013, 2014, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n# \n\nchown -R zimbra:zimbra /opt/zimbra/qa\nchmod a+x /opt/zimbra/qa/scripts/*\n"
  },
  {
    "path": "rpmconf/Spec/Scripts/zimbra-snmp.post",
    "content": "#!/bin/bash\n# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n# \n\nmkdir -p /opt/zimbra/data/snmp/persist\nmkdir -p /opt/zimbra/data/snmp/state\nchown -R zimbra:zimbra /opt/zimbra/data/snmp\nchown zimbra:zimbra /opt/zimbra/data\nchown root:root /opt/zimbra/common/share/snmp/mibs/zimbra*.mib\nchown root:root /opt/zimbra/common/share/snmp/snmp.conf\nchown root:root /opt/zimbra/common/conf/snmp.conf\n"
  },
  {
    "path": "rpmconf/Spec/Scripts/zimbra-spell.post",
    "content": "#!/bin/bash\n# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n# \n\nchown root:root /opt/zimbra/data/httpd/htdocs/aspell.php\n"
  },
  {
    "path": "rpmconf/Spec/Scripts/zimbra-store.post",
    "content": "#!/bin/bash\n# \n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n# \n\nH=`hostname -s`\nI=`hostname -i`\n\nif [ -f /opt/zimbra/db/db.sql ]; then\n  mv /opt/zimbra/db/db.sql /opt/zimbra/db/db.sql.in\n  sed -e \"/server.hostname/ s/local/$H/\" /opt/zimbra/db/db.sql.in > /opt/zimbra/db/db.sql\n  chown zimbra:zimbra /opt/zimbra/db/db.sql*\n  chmod 440 /opt/zimbra/db/db.sql*\nfi\n\n( cd /opt/zimbra && rm -f jetty    && ln -s jetty_base jetty    )\n( cd /opt/zimbra && rm -f mailboxd && ln -s jetty_base mailboxd )\n\nmkdir -p /opt/zimbra/mailboxd/logs\nchown zimbra:zimbra /opt/zimbra/mailboxd/logs\n\nmkdir -p /opt/zimbra/redolog\nmkdir -p /opt/zimbra/store\nmkdir -p /opt/zimbra/index\nmkdir -p /opt/zimbra/backup\nchown zimbra:zimbra /opt/zimbra/redolog /opt/zimbra/store /opt/zimbra/index /opt/zimbra/backup \n\negrep -q '^%zimbra[[:space:]]' /etc/sudoers\nif [ $? = 0 ]; then\n  sudotmp=`mktemp -t zsudoers.XXXXXX 2> /dev/null` || { echo \"Failed to create tmpfile\"; exit 1; }\n  SUDOMODE=`perl -e 'my $mode=(stat(\"/etc/sudoers\"))[2];printf(\"%04o\\n\",$mode & 07777);'`\n  egrep -v -e '^%zimbra[[:space:]]'  /etc/sudoers > $sudotmp\n  mv -f $sudotmp /etc/sudoers\n  chmod $SUDOMODE /etc/sudoers\nfi\n\nchmod 440 /etc/sudoers.d/02_zimbra-store\nchown root:root /etc/sudoers.d/02_zimbra-store\n\nif [ -d \"/opt/zimbra/mailboxd/work/zimbra\" ]; then\n  find /opt/zimbra/mailboxd/work/zimbra -exec touch {} \\; 2> /dev/null\nfi\n\nif [ -x \"/opt/zimbra/libexec/zmfixperms\" ]; then\n  /opt/zimbra/libexec/zmfixperms\nfi\n"
  },
  {
    "path": "rpmconf/Spec/Scripts/zimbra-store.pre",
    "content": "#!/bin/bash\n#\n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013, 2014, 2015, 2016 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n#\n\nif [ -d \"/opt/zimbra/mailboxd/work/zimbra\" ]; then\n  rm -rf /opt/zimbra/mailboxd/work/zimbra > /dev/null 2>&1\nfi\n\nif [ -d \"/opt/zimbra/mailboxd/work/zimbraAdmin\" ]; then\n  rm -rf /opt/zimbra/mailboxd/work/zimbraAdmin > /dev/null 2>&1\nfi\n\nif [ -d \"/opt/zimbra/lib/ext/smime\" ]; then\n\tif [ `ls -1 /opt/zimbra/lib/ext/smime/zm-smime-*.jar 2>/dev/null | wc -l` -gt 0 ]; then\n\t\trm -rf /opt/zimbra/lib/ext/smime/zm-smime-*.jar > /dev/null 2>&1\n\tfi\nfi\n\nif [ -d \"/opt/zimbra/extensions-extra/openidconsumer\" ]; then\n\tif [ `ls -1 /opt/zimbra/extensions-extra/openidconsumer/zm-openid-consumer-store-*.jar 2>/dev/null | wc -l` -gt 0 ]; then\n\t\trm -rf /opt/zimbra/extensions-extra/openidconsumer/zm-openid-consumer-store-*.jar > /dev/null 2>&1\n\tfi\nfi\n"
  },
  {
    "path": "rpmconf/Spec/zimbra-apache.deb",
    "content": "Package: zimbra-apache\nVersion: @@VERSION@@\nDescription: Best email money can buy\nMaintainer: build@zimbra.com\nSection: Mail\nPriority: optional\nArchitecture: @@ARCH@@\nDepends: zimbra-core, zimbra-apache-components\n"
  },
  {
    "path": "rpmconf/Spec/zimbra-apache.spec",
    "content": "#\n# spec file for zimbra.rpm\n#\nSummary: Zimbra Apache HTTPD server\nName: zimbra-apache\nVersion: @@VERSION@@\nRelease: @@RELEASE@@\nLicense: Various\nGroup: Applications/Messaging\nURL: http://www.zimbra.com\nVendor: Zimbra, Inc.\nPackager: Zimbra, Inc.\nBuildRoot: /opt/zimbra\nAutoReqProv: no\nRequires: zimbra-core, zimbra-apache-components\n\n%description\nBest email money can buy\n\n%define __spec_install_pre /bin/true\n\n%define __spec_install_post /usr/lib/rpm/brp-compress /usr/lib/rpm/brp-strip-comment-note %{nil}\n\n%prep\n\n%build\n\n%install\n\n%pre\n\n%post\n\n%preun\n\n%postun\n\n%files\n"
  },
  {
    "path": "rpmconf/Spec/zimbra-core.deb",
    "content": "Package: zimbra-core\nVersion: @@VERSION@@\nDescription: Best email money can buy\nMaintainer: build@zimbra.com\nSection: mail\nPriority: optional\nArchitecture: @@ARCH@@\nDepends: zimbra-core-components@@MORE_DEPENDS@@\n"
  },
  {
    "path": "rpmconf/Spec/zimbra-core.spec",
    "content": "#\n# spec file for zimbra.rpm\n#\nSummary: Zimbra Core\nName: zimbra-core\nVersion: @@VERSION@@\nRelease: @@RELEASE@@\nLicense: Various\nGroup: Applications/Messaging\nURL: http://www.zimbra.com\nVendor: Zimbra, Inc.\nPackager: Zimbra, Inc.\nBuildRoot: /opt/zimbra\nAutoReqProv: no\nRequires: zimbra-core-components@@MORE_DEPENDS@@\n\n%description\nBest email money can buy\n\n%define __spec_install_pre /bin/true\n\n%define __spec_install_post /usr/lib/rpm/brp-compress /usr/lib/rpm/brp-strip-comment-note %{nil}\n\n%prep\n\n%build\n\n%install\n\n%pre\n\n%post\n\n%preun\n\n%postun\n\n%files\n"
  },
  {
    "path": "rpmconf/Spec/zimbra-dnscache.deb",
    "content": "Package: zimbra-dnscache\nVersion: @@VERSION@@\nDescription: Best email money can buy\nMaintainer: Zimbra Packaging Services <packaging-devel@zimbra.com>\nSection: Mail\nPriority: optional\nArchitecture: @@ARCH@@\nDepends: zimbra-core, zimbra-dnscache-components\n"
  },
  {
    "path": "rpmconf/Spec/zimbra-dnscache.spec",
    "content": "#\n# spec file for zimbra.rpm\n#\nSummary: Zimbra DNS cache\nName: zimbra-dnscache\nVersion: @@VERSION@@\nRelease: @@RELEASE@@\nLicense: ZPL and other\nGroup: Applications/Messaging\nURL: http://www.zimbra.com\nVendor: Zimbra, Inc.\nPackager: Zimbra, Inc.\nBuildRoot: /opt/zimbra\nAutoReqProv: no\nRequires: zimbra-core, zimbra-dnscache-components\n\n%description\nBest email money can buy\n\n%define __spec_install_pre /bin/true\n\n%define __spec_install_post /usr/lib/rpm/brp-compress /usr/lib/rpm/brp-strip-comment-note %{nil}\n\n%prep\n\n%build\n\n%install\n\n%pre\n\n%post\n\n%preun\n\n%postun\n\n%files\n"
  },
  {
    "path": "rpmconf/Spec/zimbra-imapd.deb",
    "content": "Package: zimbra-imapd\nVersion: @@VERSION@@\nDescription: Best email money can buy\nMaintainer: build@zimbra.com\nSection: Mail\nPriority: optional\nArchitecture: @@ARCH@@\nDepends: zimbra-core\n"
  },
  {
    "path": "rpmconf/Spec/zimbra-imapd.spec",
    "content": "#\n# spec file for zimbra-imapd.rpm\n#\nSummary: Zimbra IMAP\nName: zimbra-imapd\nVersion: @@VERSION@@\nRelease: @@RELEASE@@\nLicense: Various\nGroup: Applications/Messaging\nURL: http://www.zimbra.com\nVendor: Zimbra, Inc.\nPackager: Zimbra, Inc.\nBuildRoot: /opt/zimbra\nAutoReqProv: no\nrequires: zimbra-core\n\n%description\nBest email money can buy\n\n%define __spec_install_pre /bin/true\n\n%if 0%{?rhel} == 9\n%define __brp_ldconfig RPM_BUILD_ROOT=\"\" /usr/lib/rpm/redhat/brp-ldconfig\n%define __brp_mangle_shebangs RPM_BUILD_ROOT=\"\" /usr/lib/rpm/redhat/brp-mangle-shebangs\n%endif\n\n%prep\n\n%build\n\n%install\n\n%pre\n\n%post\n\n%preun\n\n%postun\n\n%files\n"
  },
  {
    "path": "rpmconf/Spec/zimbra-ldap.deb",
    "content": "Package: zimbra-ldap\nVersion: @@VERSION@@\nDescription: Best email money can buy\nMaintainer: build@zimbra.com\nSection: Mail\nPriority: optional\nArchitecture: @@ARCH@@\nDepends: zimbra-core, zimbra-ldap-components\n"
  },
  {
    "path": "rpmconf/Spec/zimbra-ldap.spec",
    "content": "#\n# spec file for zimbra.rpm\n#\nSummary: Zimbra LDAP\nName: zimbra-ldap\nVersion: @@VERSION@@\nRelease: @@RELEASE@@\nLicense: OpenLDAP\nGroup: Applications/Messaging\nURL: http://www.zimbra.com\nVendor: Zimbra, Inc.\nPackager: Zimbra, Inc.\nBuildRoot: /opt/zimbra\nAutoReqProv: no\nRequires: zimbra-core, zimbra-ldap-components\n\n%description\nBest email money can buy\n\n%define __spec_install_pre /bin/true\n\n%define __spec_install_post /usr/lib/rpm/brp-compress /usr/lib/rpm/brp-strip-comment-note %{nil}\n\n%prep\n\n%build\n\n%install\n\n%pre\n\n%post\n\n%preun\n\n%postun\n\n%files\n"
  },
  {
    "path": "rpmconf/Spec/zimbra-logger.deb",
    "content": "Package: zimbra-logger\nVersion: @@VERSION@@\nDescription: Best email money can buy\nMaintainer: build@zimbra.com\nSection: Mail\nPriority: optional\nArchitecture: @@ARCH@@\nDepends: zimbra-core\n"
  },
  {
    "path": "rpmconf/Spec/zimbra-logger.spec",
    "content": "#\n# spec file for zimbra.rpm\n#\nSummary: Zimbra Mail\nName: zimbra-logger\nVersion: @@VERSION@@\nRelease: @@RELEASE@@\nLicense: ZPL and other\nGroup: Applications/Messaging\nURL: http://www.zimbra.com\nVendor: Zimbra, Inc.\nPackager: Zimbra, Inc.\nBuildRoot: /opt/zimbra\nAutoReqProv: no\nrequires: zimbra-core\n\n%description\nBest email money can buy\n\n%define __spec_install_pre /bin/true\n\n%define __spec_install_post /usr/lib/rpm/brp-compress /usr/lib/rpm/brp-strip-comment-note %{nil}\n\n%prep\n\n%build\n\n%install\n\n%pre\n\n%post\n\n%preun\n\n%postun\n\n%files\n"
  },
  {
    "path": "rpmconf/Spec/zimbra-mta.deb",
    "content": "Package: zimbra-mta\nVersion: @@VERSION@@\nDescription: Best email money can buy\nMaintainer: build@zimbra.com\nSection: Mail\nPriority: optional\nArchitecture: @@ARCH@@\nDepends: zimbra-core, zimbra-mta-components\nProvides: mail-transport-agent\nConflicts: mail-transport-agent\nReplaces: mail-transport-agent\n"
  },
  {
    "path": "rpmconf/Spec/zimbra-mta.spec",
    "content": "#\n# spec file for zimbra.rpm\n#\nSummary: Zimbra MTA\nName: zimbra-mta\nVersion: @@VERSION@@\nRelease: @@RELEASE@@\nLicense: Various\nGroup: Applications/Messaging\nURL: http://www.zimbra.com\nVendor: Zimbra, Inc.\nPackager: Zimbra, Inc.\nBuildRoot: /opt/zimbra\nAutoReqProv: no\nprovides: @@MTA_PROVIDES@@\nrequires: zimbra-core, zimbra-mta-components\n\n%description\nBest email money can buy\n\n%define __spec_install_pre /bin/true\n\n%define __spec_install_post /usr/lib/rpm/brp-compress /usr/lib/rpm/brp-strip-comment-note %{nil}\n\n%prep\n\n%build\n\n%install\n\n%pre\n\n%post\n\n%preun\n\n%postun\n\n%files\n"
  },
  {
    "path": "rpmconf/Spec/zimbra-proxy.deb",
    "content": "Package: zimbra-proxy\nVersion: @@VERSION@@\nDescription: Best email money can buy\nMaintainer: build@zimbra.com\nSection: Mail\nPriority: optional\nArchitecture: @@ARCH@@\nDepends: zimbra-core, zimbra-proxy-components, zimbra-memcached\n"
  },
  {
    "path": "rpmconf/Spec/zimbra-proxy.spec",
    "content": "#\n# spec file for zimbra.rpm\n#\nSummary: Zimbra Proxy\nName: zimbra-proxy\nVersion: @@VERSION@@\nRelease: @@RELEASE@@\nLicense: ZPL and other\nGroup: Applications/Messaging\nURL: http://www.zimbra.com\nVendor: Zimbra, Inc.\nPackager: Zimbra, Inc.\nBuildRoot: /opt/zimbra\nAutoReqProv: no\nrequires: zimbra-core, zimbra-proxy-components, zimbra-memcached\n\n%description\nBest email money can buy\n\n%define __spec_install_pre /bin/true\n\n%define __spec_install_post /usr/lib/rpm/brp-compress /usr/lib/rpm/brp-strip-comment-note %{nil}\n\n%prep\n\n%build\n\n%install\n\n%pre\n\n%post\n\n%preun\n\n%postun\n\n%files\n"
  },
  {
    "path": "rpmconf/Spec/zimbra-qa.deb",
    "content": "Package: zimbra-qa\nVersion: @@VERSION@@\nDescription: Best email money can buy\nMaintainer: build@zimbra.com\nSection: Mail\nPriority: optional\nArchitecture: @@ARCH@@\nDepends: zimbra-core\n"
  },
  {
    "path": "rpmconf/Spec/zimbra-qa.spec",
    "content": "#\n# spec file for zimbra.rpm\n#\nSummary: Zimbra QA Tests\nName: zimbra-qatest\nVersion: @@VERSION@@\nRelease: @@RELEASE@@\nLicense: ZPL\nGroup: Applications/Messaging\nURL: http://www.zimbra.com\nVendor: Zimbra, Inc.\nPackager: Zimbra, Inc.\nBuildRoot: /opt/zimbra\nAutoReqProv: no\nrequires: zimbra-core\n\n%description\nBest email money can buy\n\n%define __spec_install_pre /bin/true\n\n%prep\n\n%build\n\n%install\n\n%pre\n\n%post\n\n%preun\n\n%postun\n\n%files\n"
  },
  {
    "path": "rpmconf/Spec/zimbra-snmp.deb",
    "content": "Package: zimbra-snmp\nVersion: @@VERSION@@\nDescription: Best email money can buy\nMaintainer: build@zimbra.com\nSection: Mail\nPriority: optional\nArchitecture: @@ARCH@@\nDepends: zimbra-core, zimbra-snmp-components\n"
  },
  {
    "path": "rpmconf/Spec/zimbra-snmp.spec",
    "content": "#\n# spec file for zimbra.rpm\n#\nSummary: Zimbra SNMP\nName: zimbra-snmp\nVersion: @@VERSION@@\nRelease: @@RELEASE@@\nLicense: Various\nGroup: Applications/Messaging\nURL: http://www.zimbra.com\nVendor: Zimbra, Inc.\nPackager: Zimbra, Inc.\nBuildRoot: /opt/zimbra\nAutoReqProv: no\nrequires: zimbra-core, zimbra-snmp-components\n\n%description\nBest email money can buy\n\n%define __spec_install_pre /bin/true\n\n%define __spec_install_post /usr/lib/rpm/brp-compress /usr/lib/rpm/brp-strip-comment-note %{nil}\n\n%prep\n\n%build\n\n%install\n\n%pre\n\n%post\n\n%preun\n\n%postun\n\n%files\n"
  },
  {
    "path": "rpmconf/Spec/zimbra-spell.deb",
    "content": "Package: zimbra-spell\nVersion: @@VERSION@@\nDescription: Best email money can buy\nMaintainer: build@zimbra.com\nSection: Mail\nPriority: optional\nArchitecture: @@ARCH@@\nDepends: zimbra-core, zimbra-spell-components\n"
  },
  {
    "path": "rpmconf/Spec/zimbra-spell.spec",
    "content": "#\n# spec file for zimbra.rpm\n#\nSummary: Zimbra Spell\nName: zimbra-spell\nVersion: @@VERSION@@\nRelease: @@RELEASE@@\nLicense: Various\nGroup: Applications/Messaging\nURL: http://www.zimbra.com\nVendor: Zimbra, Inc.\nPackager: Zimbra, Inc.\nBuildRoot: /opt/zimbra\nAutoReqProv: no\nrequires: zimbra-core, zimbra-spell-components\n\n%description\nBest email money can buy\n\n%define __spec_install_pre /bin/true\n\n%if 0%{?rhel} == 9\n%define __brp_ldconfig RPM_BUILD_ROOT=\"\" /usr/lib/rpm/redhat/brp-ldconfig\n%define __brp_mangle_shebangs RPM_BUILD_ROOT=\"\" /usr/lib/rpm/redhat/brp-mangle-shebangs\n%endif\n\n%prep\n\n%build\n\n%install\n\n%pre\n\n%post\n\n%preun\n\n%postun\n\n%files\n"
  },
  {
    "path": "rpmconf/Spec/zimbra-store.deb",
    "content": "Package: zimbra-store\nVersion: @@VERSION@@\nDescription: Best email money can buy\nMaintainer: build@zimbra.com\nSection: Mail\nPriority: optional\nArchitecture: @@ARCH@@\nDepends: zimbra-core, zimbra-store-components, zimbra-jetty-distribution (>= 9.4.57.v20241219-2.@@PKG_OS_TAG@@)@@MORE_DEPENDS@@\n"
  },
  {
    "path": "rpmconf/Spec/zimbra-store.spec",
    "content": "#\n# spec file for zimbra.rpm\n#\nSummary: Zimbra Mail\nName: zimbra-store\nVersion: @@VERSION@@\nRelease: @@RELEASE@@\nLicense: ZPL and other\nGroup: Applications/Messaging\nURL: http://www.zimbra.com\nVendor: Zimbra, Inc.\nPackager: Zimbra, Inc.\nBuildRoot: /opt/zimbra\nAutoReqProv: no\nrequires: zimbra-core, zimbra-store-components, zimbra-jetty-distribution >= 9.4.57.v20241219-2.@@PKG_OS_TAG@@@@MORE_DEPENDS@@\n\n%description\nBest email money can buy\n\n%define __spec_install_pre /bin/true\n\n%if 0%{?rhel} == 9\n%define __brp_ldconfig RPM_BUILD_ROOT=\"\" /usr/lib/rpm/redhat/brp-ldconfig\n%define __brp_mangle_shebangs RPM_BUILD_ROOT=\"\" /usr/lib/rpm/redhat/brp-mangle-shebangs\n%endif\n\n%prep\n\n%build\n\n%install\n\n%pre\n\n%post\n\n%preun\n\n%postun\n\n%files\n"
  },
  {
    "path": "rpmconf/Upgrade/zmupgrade.pm",
    "content": "#!/usr/bin/perl\n# vim: ts=2\n#\n# ***** BEGIN LICENSE BLOCK *****\n# Zimbra Collaboration Suite Server\n# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2021 Synacor, Inc.\n#\n# This program is free software: you can redistribute it and/or modify it under\n# the terms of the GNU General Public License as published by the Free Software Foundation,\n# version 2 of the License.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n# See the GNU General Public License for more details.\n# You should have received a copy of the GNU General Public License along with this program.\n# If not, see <https://www.gnu.org/licenses/>.\n# ***** END LICENSE BLOCK *****\n#\n\npackage zmupgrade;\n\nuse strict;\nuse lib \"/opt/zimbra/libexec/scripts\";\nuse lib \"/opt/zimbra/common/lib/perl5\";\nuse Migrate;\nuse Net::LDAP;\nuse IPC::Open3;\nuse FileHandle;\nuse File::Grep qw (fgrep);\nuse File::Path;\nuse XML::Simple;\n\nmy $zmlocalconfig=\"/opt/zimbra/bin/zmlocalconfig\";\nmy $type = qx(${zmlocalconfig} -m nokey convertd_stub_name 2> /dev/null);\nchomp $type;\nif ($type eq \"\") {$type = \"FOSS\";}\nelse {$type = \"NETWORK\";}\n\nmy $rundir = qx(dirname $0);\nchomp $rundir;\nmy $scriptDir = \"/opt/zimbra/libexec/scripts\";\n\nmy $lowVersion = 52;\n\n# Ensure to update the corresponding value in the zm-db-conf repository,\n# specifically in the file src/db/migration/zmdbupgrade.pl.\nmy $hiVersion = 118; # this should be set to the DB version expected by current server code\n\nmy $needSlapIndexing = 0;\nmy $mysqlcnfUpdated = 0;\n\nmy $platform = qx(/opt/zimbra/libexec/get_plat_tag.sh);\nchomp $platform;\nmy $addr_space = (($platform =~ m/\\w+_(\\d+)/) ? \"$1\" : \"32\");\nmy $su = \"su - zimbra -c\";\n\nmy $hn = qx($su \"${zmlocalconfig} -m nokey zimbra_server_hostname\");\nchomp $hn;\n\nmy $isLdapMaster = qx($su \"${zmlocalconfig} -m nokey ldap_is_master\");\nchomp($isLdapMaster);\n\nmy $ZMPROV = \"/opt/zimbra/bin/zmprov -r -m -l --\";\n\nmy %updateScripts = (\n  '65' => \"migrate20120611_7to8_bundle.pl\",             # this upgrades to 90 for 8_0_0_BETA\n  # 66-79 skipped for possible HELIX use\n  '80' => \"migrate20110314-MobileDevices.pl\",          # 8.0.0_BETA1\n  '81' => \"migrate20110330-RecipientsColumn.pl\",       # 8.0.0_BETA1\n  '82' => \"migrate20110705-PendingAclPush.pl\",         # 8.0.0_BETA1\n  '83' => \"migrate20110810-TagTable.pl\",               # 8.0.0_BETA1\n  '84' => \"migrate20110928-MobileDevices.pl\",          # 8.0.0_BETA2\n  '85' => \"migrate20110929-VersionColumn.pl\",          # 8.0.0_BETA2\n  '86' => \"migrate20120125-uuidAndDigest.pl\",          # 8.0.0_BETA2\n  '87' => \"migrate20120222-LastPurgeAtColumn.pl\",      # 8.0.0_BETA2\n  '88' => \"migrate20120229-DropIMTables.pl\",           # 8.0.0_BETA2\n  '89' => \"migrate20120319-Name255Chars.pl\",\n  '90' => \"migrate20120410-BlobLocator.pl\",\n  '91' => \"migrate20121009-VolumeBlobs.pl\",            # 8.0.1\n  '92' => \"migrate20130226_alwayson.pl\",               # 8.5.0\n  # 93-99 skipped for possible IRONMAIDEN use\n  '100' => \"migrate20140319-MailItemPrevFolders.pl\",   # 8.5.0\n  '101' => \"migrate20140328-EnforceTableCharset.pl\",   #8.5.0\n  '102' => \"migrate20140624-DropMysqlIndexes.pl\",      #8.5.0\n  '103' => \"migrate20150401-ZmgDevices.pl\",            #8.7.0\n  '104' => \"migrate20150515-DataSourcePurgeTables.pl\", #8.7.0\n  '105' => \"migrate20150623-ZmgDevices.pl\",            #8.7.0\n  '106' => \"migrate20150702-ZmgDevices.pl\",            #8.7.0\n  '107' => \"migrate20170301-ZimbraChat.pl\",            #8.7.6\n  '108' => \"migrate20180301-ZimbraChat.pl\",            #8.8.8\n  '109' => \"migrate20190401-ZimbraChat.pl\",            #8.8.15\n  '110' => \"migrate20190611-ZimbraChat.pl\",            #8.8.15\n  '111' => \"migrate20210506-BriefcaseApi.pl\",          #10.0.0\n  '112' => \"migrate20200625-MobileDevices.pl\",         #Zimbra X\n  '113' => \"migrate20210319-MobileDevices.pl\",         #Zimbra X\n  '114' => \"migrate20220721-AddMdmUpdateTimestamp.pl\", #10.0.0\n  '115' => \"migrate20220525-Volume.pl\",                #10.0.0\n  '116' => \"migrate20220729-FilesShareWithMeFolder.pl\",   #10.0.0\n  '117' => \"migrate20230224-UpdateOnlyOffice-7.2.1.pl\",   #10.0.0\n);\n\nmy %updateFuncs = (\n  \"7.0.0_GA\" => \\&upgrade700GA,\n  \"7.0.1_GA\" => \\&upgrade701GA,\n  \"7.1.0_GA\" => \\&upgrade710GA,\n  \"7.1.1_GA\" => \\&upgrade711GA,\n  \"7.1.3_GA\" => \\&upgrade713GA,\n  \"7.1.4_GA\" => \\&upgrade714GA,\n  \"7.2.0_GA\" => \\&upgrade720GA,\n  \"8.0.0_BETA1\" => \\&upgrade800BETA1,\n  \"8.0.0_BETA2\" => \\&upgrade800BETA2,\n  \"8.0.0_BETA3\" => \\&upgrade800BETA3,\n  \"8.0.0_BETA4\" => \\&upgrade800BETA4,\n  \"8.0.0_BETA5\" => \\&upgrade800BETA5,\n  \"8.0.0_GA\" => \\&upgrade800GA,\n  \"8.0.1_GA\" => \\&upgrade801GA,\n  \"8.0.2_GA\" => \\&upgrade802GA,\n  \"8.0.3_GA\" => \\&upgrade803GA,\n  \"8.0.4_GA\" => \\&upgrade804GA,\n  \"8.0.5_GA\" => \\&upgrade805GA,\n  \"8.0.6_GA\" => \\&upgrade806GA,\n  \"8.0.8_GA\" => \\&upgrade808GA,\n  \"8.5.0_BETA1\" => \\&upgrade850BETA1,\n  \"8.5.0_BETA2\" => \\&upgrade850BETA2,\n  \"8.5.0_BETA3\" => \\&upgrade850BETA3,\n  \"8.5.0_GA\" => \\&upgrade850GA,\n  \"8.5.1_GA\" => \\&upgrade851GA,\n  \"8.6.0_BETA1\" => \\&upgrade860BETA1,\n  \"8.6.0_BETA2\" => \\&upgrade860BETA2,\n  \"8.6.0_GA\" => \\&upgrade860GA,\n  \"8.7.0_BETA1\" => \\&upgrade870BETA1,\n  \"8.7.0_BETA2\" => \\&upgrade870BETA2,\n  \"8.7.0_RC1\" => \\&upgrade870RC1,\n  \"8.7.2_GA\" => \\&upgrade872GA,\n  \"8.8.6_GA\" => \\&upgrade886GA,\n  \"8.8.11_GA\" => \\&upgrade8811GA,\n  \"8.8.12_GA\" => \\&upgrade8812GA,\n  \"8.8.15_GA\" => \\&upgrade8815GA,\n);\n\nmy %updateMysql = (\n  \"8.0.0_BETA1\" => \\&doMysql55Upgrade,\n  \"8.5.0_BETA3\" => \\&doMysql56Upgrade,\n  \"8.7.0_BETA1\" => \\&doMariaDB101Upgrade,\n);\n\nsub version_cmp($$)\n{\n  my $left = shift;\n  my $right = shift;\n\n  $left =~ s/ALPHA/0./;\n  $right =~ s/ALPHA/0./;\n\n  $left =~ s/BETA/1./;\n  $right =~ s/BETA/1./;\n\n  $left =~ s/RC/2./;\n  $right =~ s/RC/2./;\n\n  $left =~ s/GA/3./;\n  $right =~ s/GA/3./;\n\n  my @left_a = split(/[._]/, $left, 5);\n  my @right_a = split(/[._]/, $right, 5);\n\n  for( my $i = 0; $i < 5; ++$i )\n  {\n    $left_a[$i] ||= 0;\n    $right_a[$i] ||= 0;\n\n    return -1\n     if( $left_a[$i] < $right_a[$i] );\n\n    return 1\n      if( $left_a[$i] > $right_a[$i] );\n  }\n\n  return 0;\n}\n\nmy ($startVersion,$startMajor,$startMinor,$startMicro);\nmy ($targetVersion,$targetMajor,$targetMinor,$targetMicro,$targetMicroMicro,$targetType);\n\nsub applicableVersions {\n  my $versionHash = shift;\n  my @versionOrder;\n  foreach my $key ( grep { !(version_cmp($_, $startVersion) < 0) } sort { version_cmp($a, $b); } keys %$versionHash) {\n    push(@versionOrder,$key);\n  }\n  return \\@versionOrder;\n}\n\nmy @packageList = (\n  \"zimbra-core\",\n  \"zimbra-ldap\",\n  \"zimbra-store\",\n  \"zimbra-mta\",\n  \"zimbra-snmp\",\n  \"zimbra-logger\",\n  \"zimbra-apache\",\n  \"zimbra-spell\",\n  );\n\nmy %installedPackages = ();\n\n#####################\n\nsub upgrade {\n  $startVersion = shift;\n  $targetVersion = shift;\n  $main::config{HOSTNAME}=$hn;\n  if (lc($isLdapMaster) eq \"true\" ) {\n     if(main::isInstalled(\"zimbra-ldap\")) {\n       $isLdapMaster = 1;\n     } else {\n       $isLdapMaster = 0;\n     }\n  } else {\n       $isLdapMaster = 0;\n  }\n  my ($startBuild,$targetBuild);\n  ($startVersion,$startBuild) = $startVersion =~ /(\\d+\\.\\d+\\.\\d+_[^_]*)_(\\d+)/;\n  ($targetVersion,$targetBuild) = $targetVersion =~ m/(\\d+\\.\\d+\\.\\d+_[^_]*)_(\\d+)/;\n  ($startMajor,$startMinor,$startMicro) =\n    $startVersion =~ /(\\d+)\\.(\\d+)\\.(\\d+_[^_]*)/;\n  ($targetMajor,$targetMinor,$targetMicro) =\n    $targetVersion =~ /(\\d+)\\.(\\d+)\\.(\\d+_[^_]*)/;\n  ($targetMicroMicro, $targetType) = $targetMicro =~ /(\\d+)_(.*)/;\n\n  if ($startMajor < 7) {\n    main::progress(\"ERROR: Upgrading from a ZCS version less than 7.0.0_GA is not supported\\n\");\n    return 1;\n  }\n\n  getInstalledPackages();\n\n  # Bug #73840 - need to delete /opt/zimbra/keyview before we try stopping services\n  if ((! main::isInstalled(\"zimbra-convertd\")) && (-l \"/opt/zimbra/keyview\")) {\n    unlink(\"/opt/zimbra/keyview\");\n  }\n\n  if (stopZimbra()) { return 1; }\n\n  if ($startVersion) {\n    main::progress(\"This appears to be $startVersion\\n\");\n  } else {\n      main::progress(\"ERROR: Unable to find initial version to upgrade from.\\n\");\n      main::progress(\"       This indicates a corrupted /opt/zimbra/.install_history file.\\n\");\n      main::progress(\"       DO NOT ATTEMPT UPGRADING AGAIN UNTIL THE FILE IS FIXED.\\n\");\n    return 1;\n  }\n\n  my $curSchemaVersion;\n\n  if (main::isInstalled(\"zimbra-store\") || main::isInstalled(\"zimbra-onlyoffice\")) {\n    if ($startMajor <= 7 || ($startMajor == 8 && $startMinor < 7))\n    {\n        # Bug 96857 - MySQL meta files (pid file, socket, ..) should not be placed in db directory\n        # temporary symlinks for relocation of key mysql files\n        symlink(\"/opt/zimbra/db/mysql.pid\", \"/opt/zimbra/log/mysql.pid\");\n        symlink(\"/opt/zimbra/db/mysql.sock\", \"/opt/zimbra/data/tmp/mysql/mysql.sock\");\n    }\n    foreach my $v (@{applicableVersions(\\%updateMysql)}) {\n      $updateMysql{$v}();\n    }\n\n    if (startSql()) { return 1; };\n\n    $curSchemaVersion = Migrate::getSchemaVersion();\n  }\n\n  main::setLocalConfig(\"ssl_allow_untrusted_certs\", \"true\") if ($startMajor <= 7 && $targetMajor >= 8);\n  # start ldap\n  if (main::isInstalled (\"zimbra-ldap\")) {\n    if($startMajor < 8) {\n      my $rc=&upgradeLdap(\"8.0.0_BETA3\");\n      if ($rc) { return 1; }\n    } elsif(($startMajor == 8 && $startMinor < 5)) {\n      my $rc=&upgradeLdap(\"8.5.0_BETA1\");\n      if ($rc) { return 1; }\n    } elsif (($startMajor == 8 && $startMinor <= 7)) {\n      my $rc=&upgradeLdap(\"8.7.0_BETA2\");\n      if ($rc) { return 1; }\n    }\n    if ($startMajor == 8 && $startMinor == 0 && $startMicro < 3) {\n      my $rc=&reloadLdap(\"8.0.3_GA\");\n      if ($rc) { return 1; }\n    }\n    if (startLdap()) {return 1;}\n  }\n\n  # Update our CA cert(s) for java/zmprov before we go further\n  main::runAsZimbra(\"/opt/zimbra/bin/zmcertmgr createca\");\n  main::runAsZimbra(\"/opt/zimbra/bin/zmcertmgr deployca -localonly\");\n\n  if (main::isInstalled(\"zimbra-store\") || main::isInstalled(\"zimbra-onlyoffice\")) {\n\n    doMysqlUpgrade();\n\n    doBackupRestoreVersionUpdate($startVersion);\n\n    if ($curSchemaVersion < $hiVersion) {\n      main::progress(\"Schema upgrade required from version $curSchemaVersion to $hiVersion.\\n\");\n    }\n\n    # the old slow painful way (ie lots of mysql invocations)\n    while ($curSchemaVersion >= $lowVersion && $curSchemaVersion < $hiVersion) {\n      if (runSchemaUpgrade ($curSchemaVersion)) { return 1; }\n      $curSchemaVersion = Migrate::getSchemaVersion();\n    }\n     if ( $startMajor = 7 && $targetMajor >= 8) {\n       # Bug #78297\n       my $imap_cache_data_files = \"/opt/zimbra/data/mailboxd/imap-*\";\n       system(\"/bin/rm -f ${imap_cache_data_files} 2> /dev/null\");\n     }\n    stopSql();\n  }\n\n  if($startVersion ne $targetVersion # if you are upgrading across versions\n  || $targetBuild > $startBuild)     # or you are upgrading across new builds of the same version\n  {\n    main::configLDAPSchemaVersion() if ($isLdapMaster);\n    foreach my $v (@{applicableVersions(\\%updateFuncs)}) {\n      main::progress(\"Applying updates for $v \\n\");\n      if (&{$updateFuncs{$v}}($startBuild, $targetVersion, $targetBuild)) {\n        main::progress(\"Something failed while applying updates for $v - exiting\\n\");\n        return 1;\n      }\n    }\n  }\n\n  if ($isLdapMaster) {\n    main::progress(\"Updating global config and COS's with attributes introduced after $startVersion...\");\n    main::progress((&runAttributeUpgrade($startVersion)) ? \"failed.\\n\" : \"done.\\n\");\n    main::setLdapGlobalConfig(\"zimbraVersionCheckLastResponse\", \"\");\n  }\n  if ($needSlapIndexing) {\n    main::detail(\"Updating slapd indices\\n\");\n    &indexLdap();\n  }\n  if (main::isInstalled (\"zimbra-ldap\")) {\n    stopLdap();\n  }\n\n  return 0;\n}\n\nsub upgrade700GA {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  if (main::isInstalled(\"zimbra-store\")) {\n    main::deleteLocalConfig(\"calendar_outlook_compatible_allday_events\");\n  }\n  return 0;\n}\n\nsub upgrade701GA {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  if (main::isInstalled(\"zimbra-store\")) {\n    #56318\n    my $mysql_mycnf = main::getLocalConfig(\"mysql_mycnf\");\n    if (!fgrep { /^max_allowed_packet/ } ${mysql_mycnf}) {\n      main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-allowed-packet --section=mysqld --key=max_allowed_packet --set --value=16777216 ${mysql_mycnf}\");\n    }\n    if ( -d \"/opt/zimbra/data/mailboxd/imap/cache\" ) {\n      system(\"/bin/rm -rf /opt/zimbra/data/mailboxd/imap/cache/* 2> /dev/null\");\n    }\n  }\n  return 0;\n}\n\nsub upgrade710GA {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  my $mysql_data_directory =\n    main::getLocalConfig(\"mysql_data_directory\") || \"/opt/zimbra/db/data\";\n  my $zimbra_tmp_directory =\n    main::getLocalConfig(\"zimbra_tmp_directory\") || \"/opt/zimbra/data/tmp\";\n  my $mysql_mycnf =\n    main::getLocalConfig(\"mysql_mycnf\") || \"/opt/zimbra/conf/my.cnf\";\n\n  if (main::isInstalled(\"zimbra-ldap\")) {\n    if ($isLdapMaster) {\n      runLdapAttributeUpgrade(\"53745\");\n      runLdapAttributeUpgrade(\"55649\");\n      runLdapAttributeUpgrade(\"57039\");\n      runLdapAttributeUpgrade(\"57425\");\n    }\n  }\n  if (main::isInstalled(\"zimbra-store\")) {\n    foreach my $i (qw(ib_logfile0 ib_logfile1)) {\n      my $dbfile=\"${mysql_data_directory}/${i}\";\n      main::detail(\"Moving $dbfile to ${zimbra_tmp_directory}/$i\");\n      system(\"mv -f ${dbfile} ${zimbra_tmp_directory}/$i\")\n        if (-f ${dbfile});\n    }\n    main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-log_file_size --section=mysqld --key=innodb_log_file_size --set --value=524288000 ${mysql_mycnf}\");\n    main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-dirty-pages --section=mysqld --key=innodb_max_dirty_pages_pct --set --value=30 ${mysql_mycnf}\");\n\n  }\n  return 0;\n}\n\nsub upgrade711GA {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  if (main::isInstalled(\"zimbra-ldap\")) {\n    if ($isLdapMaster) {\n      runLdapAttributeUpgrade(\"57855\");\n      runLdapAttributeUpgrade(\"58084\");\n      runLdapAttributeUpgrade(\"58481\");\n      runLdapAttributeUpgrade(\"58514\");\n      runLdapAttributeUpgrade(\"59720\");\n    }\n  }\n  if (main::isInstalled(\"zimbra-store\")) {\n    # 53272\n    if (-d \"/opt/zimbra/jetty/webapps/spnego\") {\n      system(\"rm -rf /opt/zimbra/jetty/webapps/spnego\");\n    }\n    if (-d \"/opt/zimbra/jetty/work/spnego\") {\n      system(\"rm -rf /opt/zimbra/jetty/work/spnego\");\n    }\n  }\n  return 0;\n}\n\nsub upgrade713GA {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  if (main::isInstalled(\"zimbra-ldap\")) {\n    if ($isLdapMaster) {\n      runLdapAttributeUpgrade(\"11562\");\n      runLdapAttributeUpgrade(\"63475\");\n    }\n    # 53301 - Fix ACLs for userCertificate for BES user and general usage\n    my $ldap_pass = qx($su \"zmlocalconfig -s -m nokey ldap_root_password\");\n    chomp($ldap_pass);\n    my $ldap;\n    unless($ldap = Net::LDAP->new('ldapi://%2fopt%2fzimbra%2fdata%2fldap%2fstate%2frun%2fldapi/')) {\n       main::progress(\"Unable to connect to ldapi: $!\\n\");\n    }\n    my $result = $ldap->bind(\"cn=config\", password => $ldap_pass);\n    my $dn=\"olcDatabase={2}mdb,cn=config\";\n    if ($isLdapMaster) {\n      $result = $ldap->search(\n                        base=> \"cn=accesslog\",\n                        filter=>\"(objectClass=*)\",\n                        scope => \"base\",\n                        attrs => ['1.1'],\n      );\n      my $size = $result->count;\n      if ($size > 0 ) {\n        $dn=\"olcDatabase={3}mdb,cn=config\";\n      }\n    }\n    $result = $ldap->search(\n      base=> \"$dn\",\n      filter=>\"(objectClass=*)\",\n      scope => \"base\",\n      attrs => ['olcAccess'],\n    );\n    my $entry=$result->entry($result->count-1);\n    my @attrvals=$entry->get_value(\"olcAccess\");\n    my $aclNumber=-1;\n    my $attrMod=\"\";\n\n    foreach my $attr (@attrvals) {\n      if ($attr =~ /zimbraDomainName/) {\n        ($aclNumber) = $attr =~ /^\\{(\\d+)\\}*/;\n        if ($attr !~ /uid=zmamavis,cn=appaccts,cn=zimbra/) {\n          $attrMod=$attr;\n          if ($attrMod =~ /by \\* read/) {\n            $attrMod =~ s/by \\* read/by dn.base=\"uid=zmamavis,cn=appaccts,cn=zimbra\" read  by \\* read/;\n          } else {\n            $attrMod =~ s/by \\* none/by dn.base=\"uid=zmamavis,cn=appaccts,cn=zimbra\" read  by \\* none/;\n          }\n        }\n      }\n    }\n\n    if ($aclNumber != -1 && $attrMod ne \"\") {\n      $result = $ldap->modify(\n          $dn,\n          delete => {olcAccess => \"{$aclNumber}\"},\n      );\n      $result = $ldap->modify(\n          $dn,\n          add =>{olcAccess=>\"$attrMod\"},\n      );\n    }\n    $result = $ldap->search(\n      base=> \"$dn\",\n      filter=>\"(objectClass=*)\",\n      scope => \"base\",\n      attrs => ['olcAccess'],\n    );\n    my $entry=$result->entry($result->count-1);\n    my @attrvals=$entry->get_value(\"olcAccess\");\n    my $aclNumber=-1;\n    my $attrMod=\"\";\n\n    my $fixup=0;\n    foreach my $attr (@attrvals) {\n      if ($attr =~ /homePhone,pager,mobile/) {\n        if ($attr !~ /userCertificate/) {\n          ($aclNumber) = $attr =~ /^\\{(\\d+)\\}*/;\n          $attrMod=$attr;\n        }\n      }\n      if ($attr =~ /homePhone,mobile,pager/) {\n        if ($attr !~ /userCertificate/) {\n          ($aclNumber) = $attr =~ /^\\{(\\d+)\\}*/;\n          $attrMod=$attr;\n          $fixup=1;\n        }\n      }\n    }\n\n    if ($aclNumber != -1 && $attrMod ne \"\") {\n      if ($fixup) {\n        $attrMod =~ s/homePhone,mobile,pager/homePhone,pager,mobile,userCertificate/;\n      } else {\n        $attrMod =~ s/homePhone,pager,mobile/homePhone,pager,mobile,userCertificate/;\n      }\n      $result = $ldap->modify(\n          $dn,\n          delete => {olcAccess => \"{$aclNumber}\"},\n      );\n      $result = $ldap->modify(\n          $dn,\n          add =>{olcAccess=>\"$attrMod\"},\n      );\n    }\n    $ldap->unbind;\n  }\n  if (main::isInstalled(\"zimbra-mta\")) {\n    my $mtaNetworks=main::getLdapServerValue(\"zimbraMtaMyNetworks\");\n    $mtaNetworks =~ s/,/ /g;\n    if ($mtaNetworks =~ m/127\\.0\\.0\\.0\\/8/) {\n      $mtaNetworks =~ s/ $//;\n      $mtaNetworks=$mtaNetworks . \" [::1]/128\";\n    }\n    main::setLdapServerConfig(\"zimbraMtaMyNetworks\", \"$mtaNetworks\");\n  }\n  return 0;\n}\n\nsub upgrade714GA {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  if (main::isInstalled(\"zimbra-ldap\")) {\n    # 43040, must be done on all LDAP servers\n    my $ldap_pass = qx($su \"zmlocalconfig -s -m nokey ldap_root_password\");\n    my $ldap;\n    chomp($ldap_pass);\n    unless($ldap = Net::LDAP->new('ldapi://%2fopt%2fzimbra%2fdata%2fldap%2fstate%2frun%2fldapi/')) {\n       main::progress(\"Unable to connect to ldapi: $!\\n\");\n    }\n    my $result = $ldap->bind(\"cn=config\", password => $ldap_pass);\n    unless($result->code()) {\n      $result = $ldap->modify( \"cn=config\", add => { 'olcTLSCACertificatePath' => '/opt/zimbra/conf/ca'});\n    }\n    $result = $ldap->unbind;\n  }\n  if (main::isInstalled(\"zimbra-mta\")) {\n    my @zimbraMtaRestriction = qx($su \"$ZMPROV gacf zimbraMtaRestriction\");\n    foreach my $restriction (@zimbraMtaRestriction) {\n      $restriction =~ s/zimbraMtaRestriction: //;\n      chomp $restriction;\n      if ($restriction =~ /^reject_invalid_hostname$/) {\n        main::runAsZimbra(\"$ZMPROV mcf -zimbraMtaRestriction reject_invalid_hostname\");\n        main::runAsZimbra(\"$ZMPROV mcf +zimbraMtaRestriction reject_invalid_helo_hostname\");\n      }\n      if ($restriction =~ /^reject_non_fqdn_hostname$/) {\n        main::runAsZimbra(\"$ZMPROV mcf -zimbraMtaRestriction reject_non_fqdn_hostname\");\n        main::runAsZimbra(\"$ZMPROV mcf +zimbraMtaRestriction reject_non_fqdn_helo_hostname\");\n      }\n      if ($restriction =~ /^reject_unknown_client$/) {\n        main::runAsZimbra(\"$ZMPROV mcf -zimbraMtaRestriction reject_unknown_client\");\n        main::runAsZimbra(\"$ZMPROV mcf +zimbraMtaRestriction reject_unknown_client_hostname\");\n      }\n      if ($restriction =~ /^reject_unknown_hostname$/) {\n        main::runAsZimbra(\"$ZMPROV mcf -zimbraMtaRestriction reject_unknown_hostname\");\n        main::runAsZimbra(\"$ZMPROV mcf +zimbraMtaRestriction reject_unknown_helo_hostname\");\n      }\n    }\n  }\n  if (main::isInstalled(\"zimbra-store\")) {\n    main::setLocalConfig(\"calendar_cache_enabled\", \"true\"); #66307\n  }\n  return 0;\n}\n\nsub upgrade720GA {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  main::setLocalConfig(\"ldap_read_timeout\", \"0\"); #70437\n  if (main::isInstalled(\"zimbra-store\")) {\n    # Bug #64466\n    my $imap_cache_data_directory = \"/opt/zimbra/data/mailboxd/imap\";\n    rmtree(\"${imap_cache_data_directory}\")\n      if ( -d \"${imap_cache_data_directory}/\");\n    if ( -d \"/opt/zimbra/zimlets-deployed/com_zimbra_smime/\") {\n      main::runAsZimbra(\"/opt/zimbra/bin/zmzimletctl -l undeploy com_zimbra_smime\");\n      system(\"rm -rf /opt/zimbra/mailboxd/webapps/service/zimlet/com_zimbra_smime\")\n        if (-d \"/opt/zimbra/mailboxd/webapps/service/zimlet/com_zimbra_smime\" );\n    }\n  }\n\n  return 0;\n}\n\nsub upgrade800BETA1 {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  # bug 59607 - migrate old zmmtaconfig variables to zmconfigd\n  foreach my $lc_var (qw(enable_config_restarts interval log_level listen_port debug watchdog watchdog_services)) {\n    my $val = main::getLocalConfig(\"zmmtaconfig_${lc_var}\");\n    if ($val ne \"\") {\n      main::setLocalConfig(\"zmconfigd_${lc_var}\", \"$val\");\n      main::deleteLocalConfig(\"zmmtaconfig_${lc_var}\");\n    }\n  }\n  if (main::isInstalled(\"zimbra-ldap\")) {\n    if ($isLdapMaster) {\n      runLdapAttributeUpgrade(\"57866\");\n      runLdapAttributeUpgrade(\"57205\");\n      runLdapAttributeUpgrade(\"57875\");\n    }\n    # 3884\n    main::progress(\"Adding dynamic group configuration\\n\");\n    main::runAsZimbra(\"perl -I${scriptDir} ${scriptDir}/migrate20110615-AddDynlist.pl\");\n    main::runAsZimbra(\"perl -I${scriptDir} ${scriptDir}/migrate20110721-AddUnique.pl\");\n    my $ldap_pass = qx($su \"zmlocalconfig -s -m nokey ldap_root_password\");\n    chomp($ldap_pass);\n    my $ldap;\n    unless($ldap = Net::LDAP->new('ldapi://%2fopt%2fzimbra%2fdata%2fldap%2fstate%2frun%2fldapi/')) {\n       main::progress(\"Unable to connect to ldapi: $!\\n\");\n    }\n    my $result = $ldap->bind(\"cn=config\", password => $ldap_pass);\n    my $dn=\"olcDatabase={2}mdb,cn=config\";\n    if ($isLdapMaster) {\n      $result = $ldap->search(\n                        base=> \"cn=accesslog\",\n                        filter=>\"(objectClass=*)\",\n                        scope => \"base\",\n                        attrs => ['1.1'],\n      );\n      my $size = $result->count;\n      if ($size > 0 ) {\n        $dn=\"olcDatabase={3}mdb,cn=config\";\n      }\n    }\n    $result = $ldap->search(\n      base=> \"$dn\",\n      filter=>\"(objectClass=*)\",\n      scope => \"base\",\n      attrs => ['olcDbIndex'],\n    );\n    my $entry=$result->entry($result->count-1);\n    my @attrvals=$entry->get_value(\"olcDbIndex\");\n    my $MzimbraMemberOf=1;\n    my $MzimbraSharedItem=1;\n\n    foreach my $attr (@attrvals) {\n      if ($attr =~ /zimbraMemberOf/) {\n        $MzimbraMemberOf=0;\n      }\n      if ($attr =~ /zimbraSharedItem/) {\n        $MzimbraSharedItem=0;\n      }\n    }\n\n    if ($MzimbraMemberOf) {\n      $result = $ldap->modify(\n          $dn,\n          add =>{olcDbIndex=>\"zimbraMemberOf eq\"},\n      );\n    }\n    if ($MzimbraSharedItem) {\n      $result = $ldap->modify(\n          $dn,\n          add =>{olcDbIndex=>\"zimbraSharedItem eq,sub\"},\n      );\n    }\n    $ldap->unbind;\n    if ($MzimbraMemberOf) {\n      &indexLdapAttribute(\"zimbraMemberOf\");\n    }\n    if ($MzimbraSharedItem) {\n      &indexLdapAttribute(\"zimbraSharedItem\");\n    }\n  }\n  return 0;\n}\n\nsub upgrade800BETA2 {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  if (main::isInstalled(\"zimbra-ldap\")) {\n    if ($isLdapMaster) {\n      runLdapAttributeUpgrade(\"63722\");\n      runLdapAttributeUpgrade(\"64380\");\n      runLdapAttributeUpgrade(\"65070\");\n      runLdapAttributeUpgrade(\"66001\");\n      runLdapAttributeUpgrade(\"60640\");\n    }\n    main::runAsZimbra(\"perl -I${scriptDir} ${scriptDir}/migrate20111019-UniqueZimbraId.pl\");\n  }\n  if (main::isEnabled(\"zimbra-store\")) {\n    if (startSql()) { return 1; }\n      main::runAsZimbra(\"perl -I${scriptDir} ${scriptDir}/migrate20111005-ItemIdCheckpoint.pl\");\n\n    # Bug: 60011\n    my $mysql_root_password=qx(/opt/zimbra/bin/zmlocalconfig -s -x -m nokey mysql_root_password);\n    my $mysql_socket=qx(/opt/zimbra/bin/zmlocalconfig -s -x -m nokey mysql_socket);\n    my $host=qx(hostname);\n    chomp $mysql_root_password;\n    chomp $mysql_socket;\n    chomp $host;\n\n    my $sql = <<FIX_RIGHTS_EOF;\n      SET PASSWORD FOR 'root'\\@'localhost' = PASSWORD('${mysql_root_password}');\n      SET PASSWORD FOR 'root'\\@'${host}' = PASSWORD('${mysql_root_password}');\n      SET PASSWORD FOR 'root'\\@'127.0.0.1' = PASSWORD('${mysql_root_password}');\n      SET PASSWORD FOR 'root'\\@'localhost.localdomain' = PASSWORD('${mysql_root_password}');\nFIX_RIGHTS_EOF\n\n    qx(/opt/zimbra/common/bin/mysql -S '$mysql_socket' -u root --password='$mysql_root_password' -e \"$sql\");\n    qx(/opt/zimbra/common/bin/mysql -S '$mysql_socket' -u root --password='$mysql_root_password' -e \"DROP USER ''\\@'localhost'; DROP USER ''\\@'${host}'\");\n    stopSql();\n\n    # 66663\n    my $cache_dir = main::getLocalConfig(\"calendar_cache_directory\");\n    system(\"rm -rf ${cache_dir}/* 2> /dev/null\")\n      if (-d ${cache_dir});\n  }\n  if (main::isInstalled(\"zimbra-proxy\")) {\n      main::runAsZimbra(\"$ZMPROV ms $hn -zimbraServiceInstalled imapproxy\");\n      main::runAsZimbra(\"$ZMPROV ms $hn +zimbraServiceInstalled proxy\");\n    if (main::isEnabled(\"zimbra-proxy\")) {\n      main::setLdapServerConfig($hn, '-zimbraServiceEnabled', 'imapproxy');\n      main::setLdapServerConfig($hn, '+zimbraServiceEnabled', 'proxy');\n    }\n  }\n\n  return 0;\n}\n\nsub upgrade800BETA3 {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  main::setLocalConfig(\"ldap_read_timeout\", \"0\"); #70437\n  main::detail(\"Removing /opt/zimbra/ssl/zimbra/{ca,server} to force creation or download of new ca and certificates.\");\n  system(\"rm -rf /opt/zimbra/ssl/zimbra/ca > /dev/null 2>&1\");\n  system(\"rm -rf /opt/zimbra/ssl/zimbra/server > /dev/null 2>&1\");\n  main::setLocalConfig(\"ssl_allow_untrusted_certs\", \"true\");\n  if (main::isInstalled(\"zimbra-ldap\")) {\n    # Delete unused BDB DB keys\n    foreach my $lc_var (qw(ldap_db_cachefree ldap_db_cachesize ldap_db_dncachesize ldap_db_idlcachesize ldap_db_shmkey ldap_overlay_syncprov_sessionlog)) {\n      my $val = main::getLocalConfig(\"${lc_var}\");\n      if ($val ne \"\") {\n        main::deleteLocalConfig(\"${lc_var}\");\n      }\n    }\n    foreach my $lc_var (qw(ldap_accesslog_cachefree ldap_accesslog_cachesize ldap_accesslog_dncachesize ldap_accesslog_idlcachesize ldap_accesslog_shmkey)) {\n      my $val = main::getLocalConfig(\"${lc_var}\");\n      if ($val ne \"\") {\n        main::deleteLocalConfig(\"${lc_var}\");\n      }\n    }\n    if ($isLdapMaster) {\n      runLdapAttributeUpgrade(\"68831\");\n      runLdapAttributeUpgrade(\"68891\");\n    }\n    main::runAsZimbra(\"perl -I${scriptDir} ${scriptDir}/migrate20120210-AddSearchNoOp.pl\");\n  }\n  if (main::isInstalled(\"zimbra-store\")) {\n    if (-e \"/opt/zimbra/jetty-6.1.22.z6/etc/jetty.keytab\") {\n      qx(mkdir -p /opt/zimbra/data/mailboxd/spnego);\n      qx(cp -pf /opt/zimbra/jetty-6.1.22.z6/etc/jetty.keytab /opt/zimbra/data/mailboxd/spnego/jetty.keytab);\n    }\n  }\n  if (main::isInstalled(\"zimbra-octopus\")) {\n    if (startSql()) { return 1; }\n    main::runAsZimbra(\"perl -I${scriptDir} ${scriptDir}/migrate20120209-octopusEvent.pl\");\n    stopSql();\n  }\n\n  return 0;\n}\n\nsub upgrade800BETA4 {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  if (main::isInstalled(\"zimbra-ldap\")) {\n    if ($isLdapMaster) {\n        runLdapAttributeUpgrade(\"68190\");\n        runLdapAttributeUpgrade(\"68394\");\n        runLdapAttributeUpgrade(\"72007\");\n    }\n    my $doIndex = &addLdapIndex(\"zimbraDomainAliasTargetID\",\"eq\");\n    if ($doIndex) {\n      &indexLdapAttribute(\"zimbraDomainAliasTargetID\");\n    }\n    $doIndex = &addLdapIndex(\"zimbraUCServiceId\",\"eq\");\n    if ($doIndex) {\n      &indexLdapAttribute(\"zimbraUCServiceId\");\n    }\n    $doIndex = &addLdapIndex(\"DKIMIdentity\", \"eq\");\n    if ($doIndex) {\n      &indexLdapAttribute(\"DKIMIdentity\");\n    }\n    $doIndex = &addLdapIndex(\"DKIMSelector\", \"eq\");\n    if ($doIndex) {\n      &indexLdapAttribute(\"DKIMSelector\");\n    }\n    my $ldap_pass = qx($su \"zmlocalconfig -s -m nokey ldap_root_password\");\n    chomp($ldap_pass);\n    my $ldap;\n    unless($ldap = Net::LDAP->new('ldapi://%2fopt%2fzimbra%2fdata%2fldap%2fstate%2frun%2fldapi/')) {\n       main::progress(\"Unable to connect to ldapi: $!\\n\");\n    }\n    my $result = $ldap->bind(\"cn=config\", password => $ldap_pass);\n    my $dn=\"olcDatabase={2}mdb,cn=config\";\n    if ($isLdapMaster) {\n      $result = $ldap->search(\n                        base=> \"cn=accesslog\",\n                        filter=>\"(objectClass=*)\",\n                        scope => \"base\",\n                        attrs => ['1.1'],\n      );\n      my $size = $result->count;\n      if ($size > 0 ) {\n        $dn=\"olcDatabase={3}mdb,cn=config\";\n      }\n    }\n    $result = $ldap->search(\n      base=> \"$dn\",\n      filter=>\"(objectClass=*)\",\n      scope => \"base\",\n      attrs => ['olcAccess'],\n    );\n    my $entry=$result->entry($result->count-1);\n    my @attrvals=$entry->get_value(\"olcAccess\");\n    my $aclNumber=-1;\n    my $attrMod=\"\";\n\n    foreach my $attr (@attrvals) {\n      if ($attr =~ /zimbraAllowFromAddress/) {\n        if ($attr !~ /DKIMIdentity/) {\n          ($aclNumber) = $attr =~ /^\\{(\\d+)\\}*/;\n          $attrMod=$attr;\n        }\n      }\n    }\n\n    if ($aclNumber != -1 && $attrMod ne \"\") {\n      $attrMod =~ s/zimbraAllowFromAddress/zimbraAllowFromAddress,DKIMIdentity,DKIMSelector,DKIMDomain,DKIMKey/;\n      $result = $ldap->modify(\n          $dn,\n          delete => {olcAccess => \"{$aclNumber}\"},\n      );\n      $result = $ldap->modify(\n          $dn,\n          add =>{olcAccess=>\"$attrMod\"},\n      );\n    }\n    $ldap->unbind;\n\n    my $toolthreads = main::getLocalConfig(\"ldap_common_toolthreads\");\n    if ($toolthreads == 1) {\n       main::setLocalConfig(\"ldap_common_toolthreads\", \"2\");\n    }\n    main::runAsZimbra(\"perl -I${scriptDir} ${scriptDir}/migrate20120507-UniqueDKIMSelector.pl\");\n  }\n  if (main::isInstalled(\"zimbra-proxy\")) {\n    # bug 32683\n    main::setLdapGlobalConfig(\"zimbraReverseProxySSLToUpstreamEnabled\", \"FALSE\");\n  }\n  foreach my $lc_var (qw(cbpolicyd_bind_host logger_mysql_bind_address logger_mysql_directory logger_mysql_data_directory logger_mysql_socket logger_mysql_pidfile logger_mysql_mycnf logger_mysql_errlogfile logger_mysql_port zimbra_logger_mysql_password)) {\n    main::deleteLocalConfig(\"$lc_var\");\n  }\n  return 0;\n}\n\nsub upgrade800BETA5 {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  if (main::isInstalled(\"zimbra-ldap\")) {\n    if ($isLdapMaster) {\n        runLdapAttributeUpgrade(\"67237\");\n    }\n  }\n  return 0;\n}\n\nsub upgrade800GA {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  if (main::isInstalled(\"zimbra-ldap\")) {\n    if ($isLdapMaster) {\n        runLdapAttributeUpgrade(\"75450\");\n        runLdapAttributeUpgrade(\"76427\");\n    }\n  }\n  if (main::isInstalled(\"zimbra-mta\")) {\n    my $cbpdb=\"/opt/zimbra/data/cbpolicyd/db/cbpolicyd.sqlitedb\";\n    if (-f $cbpdb) {\n      main::runAsZimbra(\"sqlite3 $cbpdb < ${scriptDir}/migrate20130227-UpgradeCBPolicyDSchema.sql >/dev/null 2>&1\");\n      main::runAsZimbra(\"sqlite3 $cbpdb < ${scriptDir}/migrate20130819-UpgradeQuotasTable.sql >/dev/null 2>&1\");\n    }\n  }\n  return 0;\n}\n\nsub upgrade801GA {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  if (main::isInstalled(\"zimbra-ldap\")) {\n    my $ldap_pass = qx($su \"zmlocalconfig -s -m nokey ldap_root_password\");\n    chomp($ldap_pass);\n    my $ldap;\n    unless($ldap = Net::LDAP->new('ldapi://%2fopt%2fzimbra%2fdata%2fldap%2fstate%2frun%2fldapi/')) {\n       main::progress(\"Unable to connect to ldapi: $!\\n\");\n    }\n    my $result = $ldap->bind(\"cn=config\", password => $ldap_pass);\n    my $dn=\"olcDatabase={2}mdb,cn=config\";\n    my $alog=0;\n    if ($isLdapMaster) {\n      $result = $ldap->search(\n                        base=> \"cn=accesslog\",\n                        filter=>\"(objectClass=*)\",\n                        scope => \"base\",\n                        attrs => ['1.1'],\n      );\n      my $size = $result->count;\n      if ($size > 0 ) {\n        $dn=\"olcDatabase={3}mdb,cn=config\";\n        $alog=1;\n      }\n    }\n    $result = $ldap->search(\n      base=> \"$dn\",\n      filter=>\"(objectClass=*)\",\n      scope => \"base\",\n      attrs => ['olcDbEnvFlags'],\n    );\n    my $entry=$result->entry($result->count-1);\n    my @attrvals=$entry->get_value(\"olcDbEnvFlags\");\n\n    if (!(@attrvals)) {\n      $result = $ldap->modify(\n          $dn,\n          add =>{olcDbEnvFlags=>[\"writemap\",\"nometasync\"]},\n      );\n    }\n    if ($isLdapMaster && $alog == 1) {\n      $result = $ldap->search(\n        base=> \"olcDatabase={2}mdb,cn=config\",\n        filter=>\"(objectClass=*)\",\n        scope => \"base\",\n        attrs => ['olcDbEnvFlags'],\n      );\n      my $entry=$result->entry($result->count-1);\n      my @attrvals=$entry->get_value(\"olcDbEnvFlags\");\n\n      if (!(@attrvals)) {\n        $result = $ldap->modify(\n            \"olcDatabase={2}mdb,cn=config\",\n            add =>{olcDbEnvFlags=>[\"writemap\",\"nometasync\"]},\n        );\n      }\n    }\n    $ldap->unbind;\n  }\n  return 0;\n}\n\nsub upgrade802GA {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  if (main::isInstalled(\"zimbra-ldap\")) {\n    if ($isLdapMaster) {\n      my $ldap_pass = qx($su \"zmlocalconfig -s -m nokey ldap_root_password\");\n      chomp($ldap_pass);\n      my $ldap;\n      unless($ldap = Net::LDAP->new('ldapi://%2fopt%2fzimbra%2fdata%2fldap%2fstate%2frun%2fldapi/')) {\n         main::progress(\"Unable to connect to ldapi: $!\\n\");\n      }\n      my $result = $ldap->bind(\"cn=config\", password => $ldap_pass);\n      $result = $ldap->modify(\n        \"uid=zmpostfix,cn=appaccts,cn=zimbra\",\n        replace => {\n          zimbraId => \"a8255e5f-142b-4aa0-8aab-f8591b6455ba\",\n        }\n      );\n      $ldap->unbind;\n    }\n  }\n\n  if (main::isInstalled(\"zimbra-mta\")) {\n    doAntiSpamMysql55Upgrade();\n    my $mtamilter = main::getLdapServerValue(\"zimbraMtaSmtpdMilters\");\n    my $miltervalue=\"inet:localhost:8465\";\n    if ($mtamilter ne \"\")  {\n      if ($mtamilter =~ /$miltervalue/) {\n        $mtamilter =~ s/$miltervalue//;\n        main::setLdapServerConfig(\"zimbraMtaSmtpdMilters\", \"$mtamilter\");\n      }\n    }\n  }\n  return 0;\n}\n\nsub upgrade803GA {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  if (main::isInstalled(\"zimbra-ldap\")) {\n     main::setLocalConfig(\"ldap_common_toolthreads\", \"2\");\n  }\n  if (main::isInstalled(\"zimbra-store\")) {\n    my $mailboxd_java_options=main::getLocalConfigRaw(\"mailboxd_java_options\");\n    if ($mailboxd_java_options =~ /-XX:MaxPermSize=128m/) {\n      $mailboxd_java_options =~ s/-XX:MaxPermSize=128m/-XX:MaxPermSize=350m/;\n      main::detail(\"Modified mailboxd_java_options=$mailboxd_java_options\");\n      main::setLocalConfig(\"mailboxd_java_options\", $mailboxd_java_options)\n    }\n  }\n  main::deleteLocalConfig(\"zimbra_dos_filter_max_requests_per_sec\");\n  return 0;\n}\n\nsub upgrade804GA {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  if (main::isInstalled(\"zimbra-ldap\")) {\n    my $ldap_pass = qx($su \"zmlocalconfig -s -m nokey ldap_root_password\");\n    chomp($ldap_pass);\n    my $ldap;\n    unless($ldap = Net::LDAP->new('ldapi://%2fopt%2fzimbra%2fdata%2fldap%2fstate%2frun%2fldapi/')) {\n       main::progress(\"Unable to connect to ldapi: $!\\n\");\n    }\n    my $result = $ldap->bind(\"cn=config\", password => $ldap_pass);\n    $result = $ldap->modify(\n      \"olcDatabase={2}mdb,cn=config\",\n      replace => {\n        olcDbCheckpoint => \"0 0\",\n      }\n    );\n    if ($isLdapMaster) {\n      $result = $ldap->modify(\n        \"olcDatabase={3}mdb,cn=config\",\n        replace => {\n          olcDbCheckpoint => \"0 0\",\n        }\n      );\n    }\n    $ldap->unbind;\n    main::deleteLocalConfig(\"ldap_db_checkpoint\");\n    main::deleteLocalConfig(\"ldap_accesslog_checkpoint\");\n    if ($isLdapMaster) {\n        runLdapAttributeUpgrade(\"75650\");\n    }\n  }\n  if (main::isInstalled(\"zimbra-mta\")) {\n    main::setLdapServerConfig($hn, '+zimbraServiceInstalled', 'opendkim');\n    main::setLdapServerConfig($hn, '+zimbraServiceEnabled', 'opendkim');\n    $main::config{RUNDKIM}=\"yes\";\n    main::deleteLocalConfig(\"cbpolicyd_timeout\");\n  }\n  if (main::isInstalled(\"zimbra-store\")) {\n    my $zimbraIPMode=main::getLdapServerValue(\"zimbraIPMode\");\n    my $mysql_mycnf = main::getLocalConfig(\"mysql_mycnf\");\n    if ($zimbraIPMode eq \"ipv4\") {\n        main::setLocalConfig(\"mysql_bind_address\", \"127.0.0.1\");\n        main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-bind --section=mysqld --key=bind-address --unset ${mysql_mycnf}\");\n        main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-bind --section=mysqld --key=bind-address --set --value=127.0.0.1 ${mysql_mycnf}\");\n    } elsif ($zimbraIPMode eq \"both\") {\n        main::setLocalConfig(\"mysql_bind_address\", \"::1\");\n        main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-bind --section=mysqld --key=bind-address --unset ${mysql_mycnf}\");\n        main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-bind --section=mysqld --key=bind-address --set --value=::1 ${mysql_mycnf}\");\n    } elsif ($zimbraIPMode eq \"ipv6\") {\n        main::setLocalConfig(\"mysql_bind_address\", \"::1\");\n        main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-bind --section=mysqld --key=bind-address --unset ${mysql_mycnf}\");\n        main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-bind --section=mysqld --key=bind-address --set --value=::1 ${mysql_mycnf}\");\n    }\n    my $mailboxd_java_options=main::getLocalConfigRaw(\"mailboxd_java_options\");\n    if ($mailboxd_java_options !~ /-Dorg.apache.jasper.compiler.disablejsr199/) {\n      $mailboxd_java_options = $mailboxd_java_options.\" -Dorg.apache.jasper.compiler.disablejsr199=true\";\n      main::detail(\"Modified mailboxd_java_options=$mailboxd_java_options\");\n      main::setLocalConfig(\"mailboxd_java_options\", $mailboxd_java_options)\n    }\n  }\n  return 0;\n}\n\nsub upgrade805GA {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  if (main::isInstalled(\"zimbra-mta\")) {\n    my $cbpdb=\"/opt/zimbra/data/cbpolicyd/db/cbpolicyd.sqlitedb\";\n    if (-f $cbpdb) {\n      main::runAsZimbra(\"sqlite3 $cbpdb < ${scriptDir}/migrate20130606-UpdateCBPolicydSchema.sql >/dev/null 2>&1\");\n    }\n  }\n  if (main::isInstalled(\"zimbra-proxy\")) {\n    my $rpeioa=main::getLocalConfig(\"zimbra_reverseproxy_externalroute_include_original_authusername\");\n    if(lc($rpeioa) eq \"true\") {\n      main::setLdapGlobalConfig(\"zimbraReverseProxyExternalRouteIncludeOriginalAuthusername\",\"TRUE\");\n    }\n  }\n  main::deleteLocalConfig(\"zimbra_reverseproxy_externalroute_include_original_authusername\");\n  return 0;\n}\n\nsub upgrade806GA {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  if (main::isZCA()) {\n    main::progress(\"ZCA Install detected.  Removing VAMI Components...\");\n    my $rc = main::runAsRoot(\"${scriptDir}/migrate20131014-removezca.pl\");\n    main::progress(($rc == 0) ? \"done.\\n\" : \"failed. exiting.\\n\");\n  }\n  my @zimbraStatThreadNamePrefix=qx($su \"$ZMPROV gacf zimbraStatThreadNamePrefix\");\n  if (! grep ( /qtp/, @zimbraStatThreadNamePrefix)) {\n    main::runAsZimbra(\"$ZMPROV mcf +zimbraStatThreadNamePrefix qtp\");\n  }\n  return 0;\n}\n\nsub upgrade808GA {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  my $ldap_read_timeout=main::getLocalConfig(\"ldap_read_timeout\");\n  if ($ldap_read_timeout == 0) {\n    main::deleteLocalConfig(\"ldap_read_timeout\"); #85299\n  }\n  if (main::isInstalled(\"zimbra-ldap\")) {\n    my $ldap_common_writetimeout=main::getLocalConfig(\"ldap_common_writetimeout\");\n    if ($ldap_common_writetimeout == 0) {\n      main::deleteLocalConfig(\"ldap_common_writetimeout\"); #85299\n    }\n  }\n  if (main::isInstalled(\"zimbra-mta\")) {\n    my @zimbraServiceInstalled=qx($su \"$ZMPROV gs $hn zimbraServiceInstalled\");\n    my @zimbraServiceEnabled=qx($su \"$ZMPROV gs $hn zimbraServiceEnabled\");\n    if (grep(/antivirus/, @zimbraServiceInstalled) || grep(/antispam/, @zimbraServiceInstalled) || grep(/archiving/, @zimbraServiceInstalled)) {\n      main::setLdapServerConfig($hn, '+zimbraServiceInstalled', 'amavis');\n    }\n    if (grep(/antivirus/, @zimbraServiceEnabled) || grep(/antispam/, @zimbraServiceEnabled) || grep(/archiving/, @zimbraServiceEnabled)) {\n      main::setLdapServerConfig($hn, '+zimbraServiceEnabled', 'amavis');\n    }\n  }\n  return 0;\n}\n\nsub upgrade850BETA1 {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  if (main::isInstalled(\"zimbra-store\")) {\n    my $mailboxd_java_options=main::getLocalConfigRaw(\"mailboxd_java_options\");\n    my $new_mailboxd_options=\"\";\n    if ($mailboxd_java_options =~ /-XX:\\+PrintGCTimeStamps/) {\n      foreach my $option (split(/\\s+/, $mailboxd_java_options)) {\n        $new_mailboxd_options.=\" $option\" if ($option !~ /^-XX:\\+PrintGCTimeStamps/);\n      }\n      $new_mailboxd_options .= \" -XX:+PrintGCDateStamps\"\n        unless ($mailboxd_java_options =~ /PrintGCDateStamps/);\n      $new_mailboxd_options =~ s/^\\s+//;\n      main::setLocalConfig(\"mailboxd_java_options\", $new_mailboxd_options)\n        if ($new_mailboxd_options ne \"\");\n    }\n    if (main::isNetwork()) {\n      my @zimbraReverseProxyUpstreamEwsServers=qx($su \"$ZMPROV gacf zimbraReverseProxyUpstreamEwsServers\");\n      if (! grep(/$hn/, @zimbraReverseProxyUpstreamEwsServers)) {\n        main::runAsZimbra(\"$ZMPROV mcf +zimbraReverseProxyUpstreamEwsServers $hn\");\n      }\n    }\n    main::setLdapServerConfig($hn, '+zimbraServiceEnabled', 'service');\n    main::setLdapServerConfig($hn, '+zimbraServiceEnabled', 'zimbra');\n    main::setLdapServerConfig($hn, '+zimbraServiceEnabled', 'zimbraAdmin');\n    main::setLdapServerConfig($hn, '+zimbraServiceEnabled', 'zimlet');\n    $main::config{SERVICEWEBAPP} = \"yes\";\n    $main::config{UIWEBAPPS} = \"yes\";\n    $main::installedWebapps{service} = \"Enabled\";\n    $main::installedWebapps{zimlet} = \"Enabled\";\n    $main::installedWebapps{zimbra} = \"Enabled\";\n    $main::installedWebapps{zimbraAdmin} = \"Enabled\";\n  }\n  if (main::isInstalled(\"zimbra-ldap\")) {\n    if ($isLdapMaster) {\n      runLdapAttributeUpgrade(\"81385\");\n    }\n  }\n  if (main::isInstalled(\"zimbra-mta\")) {\n    my $antispam_mysql_mycnf = main::getLocalConfig(\"antispam_mysql_mycnf\");\n    if ( -e ${antispam_mysql_mycnf} ) {\n      main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-as-table_cache-fixup --section=mysqld --key=table_cache --unset ${antispam_mysql_mycnf}\");\n      main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-as-table_open_cache-fixup --section=mysqld --key=table_open_cache --setmin --value=1200 ${antispam_mysql_mycnf}\");\n      main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-innodb_data_file_path-fixup --section=mysqld --set --key=innodb_data_file_path --value=ibdata1:10M:autoextend ${antispam_mysql_mycnf}\");\n    }\n    my $disclaimerEnabled = main::getLdapConfigValue(\"zimbraDomainMandatoryMailSignatureEnabled\");\n    if(lc($disclaimerEnabled) eq \"true\") {\n      unlink(\"/opt/zimbra/data/altermime/global-default.txt\");\n      unlink(\"/opt/zimbra/data/altermime/global-default.html\");\n      my @domains = qx($su \"$ZMPROV gad\");\n      foreach my $domain (@domains) {\n        chomp $domain;\n        main::runAsZimbra(\"/opt/zimbra/libexec/zmaltermimeconfig -e $domain\");\n      }\n    }\n    my $localxml = XMLin(\"/opt/zimbra/conf/localconfig.xml\");\n\n    my $lc_attr= $localxml->{key}->{amavis_max_servers}->{value};\n    if (defined($lc_attr) && $lc_attr+0 != 0) {\n      main::setLdapServerConfig($hn, 'zimbraAmavisMaxServers', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{clamav_max_threads}->{value};\n    if (defined($lc_attr) && $lc_attr+0 != 0) {\n      main::setLdapServerConfig($hn, 'zimbraClamAVMaxThreads', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{amavis_enable_dkim_verification}->{value};\n    if (defined($lc_attr) && lc($lc_attr) eq \"false\") {\n      main::setLdapServerConfig($hn, 'zimbraAmavisEnableDKIMVerification', \"FALSE\");\n    }\n    $lc_attr= $localxml->{key}->{amavis_originating_bypass_sa}->{value};\n    if (defined($lc_attr) && lc($lc_attr) eq \"true\") {\n      main::setLdapServerConfig($hn, 'zimbraAmavisOriginatingBypassSA', \"TRUE\");\n    }\n    $lc_attr= $localxml->{key}->{amavis_dspam_enabled}->{value};\n    if (defined($lc_attr) && (lc($lc_attr) eq \"yes\" || lc($lc_attr) eq \"true\")) {\n      main::setLdapServerConfig($hn, 'zimbraAmavisDSPAMEnabled', \"TRUE\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_enable_smtpd_policyd}->{value};\n    if (defined($lc_attr) && (lc($lc_attr) eq \"yes\" || lc($lc_attr) eq \"true\")) {\n      main::setLdapServerConfig($hn, 'zimbraPostfixEnableSmtpdPolicyd', \"TRUE\");\n    }\n    $lc_attr= $localxml->{key}->{cbpolicyd_min_servers}->{value};\n    if (defined($lc_attr) && $lc_attr != 4) {\n      main::setLdapServerConfig($hn, 'zimbraCBPolicydMinServers', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{cbpolicyd_min_spare_servers}->{value};\n    if (defined($lc_attr) && $lc_attr != 4) {\n      main::setLdapServerConfig($hn, 'zimbraCBPolicydMinSpareServers', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{cbpolicyd_max_servers}->{value};\n    if (defined($lc_attr) && $lc_attr != 25) {\n      main::setLdapServerConfig($hn, 'zimbraCBPolicydMaxServers', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{cbpolicyd_max_spare_servers}->{value};\n    if (defined($lc_attr) ne \"\" && $lc_attr != 12) {\n      main::setLdapServerConfig($hn, 'zimbraCBPolicydMaxSpareServers', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{cbpolicyd_max_requests}->{value};\n    if (defined($lc_attr) && $lc_attr != 1000) {\n      main::setLdapServerConfig($hn, 'zimbraCBPolicydMaxRequests', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{cbpolicyd_timeout_idle}->{value};\n    if (defined($lc_attr) && $lc_attr != 1020) {\n      main::setLdapServerConfig($hn, 'zimbraCBPolicydTimeoutIdle', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{cbpolicyd_timeout_busy}->{value};\n    if (defined($lc_attr) && $lc_attr != 120) {\n      main::setLdapServerConfig($hn, 'zimbraCBPolicydTimeoutBusy', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{cbpolicyd_bypass_timeout}->{value};\n    if (defined($lc_attr) && $lc_attr != 30) {\n      main::setLdapServerConfig($hn, 'zimbraCBPolicydBypassTimeout', \"TRUE\");\n    }\n    $lc_attr= $localxml->{key}->{cbpolicyd_bypass_mode}->{value};\n    if (defined($lc_attr) && lc($lc_attr) ne \"tempfail\" ) {\n      main::setLdapServerConfig($hn, 'zimbraCBPolicydBypassMode', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{cbpolicyd_module_accesscontrol}->{value};\n    if (defined($lc_attr) && (0+$lc_attr > 0  || lc($lc_attr) eq \"true\")) {\n      main::setLdapServerConfig($hn, 'zimbraCBPolicydAccessControlEnabled', \"TRUE\");\n    }\n    $lc_attr= $localxml->{key}->{cbpolicyd_module_greylisting}->{value};\n    if (defined($lc_attr) && (0+$lc_attr > 0  || lc($lc_attr) eq \"true\")) {\n      main::setLdapServerConfig($hn, 'zimbraCBPolicydGreylistingEnabled', \"TRUE\");\n    }\n    $lc_attr= $localxml->{key}->{cbpolicyd_module_greylisting_training}->{value};\n    if ($lc_attr ne \"\" && (0+$lc_attr > 0  || lc($lc_attr) eq \"true\")) {\n      main::setLdapServerConfig($hn, 'zimbraCBPolicydGreylistingTrainingEnabled', \"TRUE\");\n    }\n    $lc_attr= $localxml->{key}->{cbpolicyd_module_greylisting_defer_msg}->{value};\n    if (defined($lc_attr)) {\n      main::setLdapServerConfig($hn, 'zimbraCBPolicydGreylistingDeferMsg', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{cbpolicyd_module_greylisting_blacklist_msg}->{value};\n    if (defined($lc_attr)) {\n      main::setLdapServerConfig($hn, 'zimbraCBPolicydGreylistingBlacklistMsg', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{cbpolicyd_module_checkhelo}->{value};\n    if (defined($lc_attr) && (0+$lc_attr > 0 || lc($lc_attr) eq \"yes\" || lc($lc_attr) eq \"true\")) {\n      main::setLdapServerConfig($hn, 'zimbraCBPolicydCheckHeloEnabled', \"TRUE\");\n    }\n    $lc_attr= $localxml->{key}->{cbpolicyd_module_checkspf}->{value};\n    if (defined($lc_attr) && (0+$lc_attr > 0 || lc($lc_attr) eq \"yes\" || lc($lc_attr) eq \"true\")) {\n      main::setLdapServerConfig($hn, 'zimbraCBPolicydCheckSPFEnabled', \"TRUE\");\n    }\n    $lc_attr= $localxml->{key}->{cbpolicyd_module_quotas}->{value};\n    if (defined($lc_attr) && (0+$lc_attr == 0 || lc($lc_attr) eq \"no\" || lc($lc_attr) eq \"false\")) {\n      main::setLdapServerConfig($hn, 'zimbraCBPolicydQuotasEnabled', \"FALSE\");\n    }\n    $lc_attr= $localxml->{key}->{cbpolicyd_module_amavis}->{value};\n    if (defined($lc_attr) && (0+$lc_attr > 0 || lc($lc_attr) eq \"yes\" || lc($lc_attr) eq \"true\")) {\n      main::setLdapServerConfig($hn, 'zimbraCBPolicydAmavisEnabled', \"TRUE\");\n    }\n    $lc_attr= $localxml->{key}->{cbpolicyd_module_accounting}->{value};\n    if (defined($lc_attr) && (0+$lc_attr > 0 || lc($lc_attr) eq \"yes\" || lc($lc_attr) eq \"true\")) {\n      main::setLdapServerConfig($hn, 'zimbraCBPolicydAccountingEnabled', \"TRUE\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_always_add_missing_headers}->{value};\n    if (defined($lc_attr) && lc($lc_attr) eq \"no\") {\n      main::setLdapServerConfig($hn, 'zimbraMtaAlwaysAddMissingHeaders', \"no\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_broken_sasl_auth_clients}->{value};\n    if (defined($lc_attr) && lc($lc_attr) eq \"no\") {\n      main::setLdapServerConfig($hn, 'zimbraMtaBrokenSaslAuthClients', \"no\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_bounce_notice_recipient}->{value};\n    if (defined($lc_attr) && lc($lc_attr) ne \"postmaster\") {\n      main::setLdapServerConfig($hn, 'zimbraMtaBounceNoticeRecipient', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_bounce_queue_lifetime}->{value};\n    if (defined($lc_attr) && lc($lc_attr) ne \"5d\") {\n      main::setLdapServerConfig($hn, 'zimbraMtaBounceQueueLifetime', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_delay_warning_time}->{value};\n    if (defined($lc_attr) && lc($lc_attr) ne \"0h\") {\n      main::setLdapServerConfig($hn, 'zimbraMtaDelayWarningTime', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_header_checks}->{value};\n    if (defined($lc_attr)) {\n      if ($lc_attr =~ /\\$\\{zimbra_home\\}/) {\n        $lc_attr =~ s/\\$\\{zimbra_home\\}/\\/opt\\/zimbra/;\n      }\n      $lc_attr =~ s/, /,/g;\n      $lc_attr =~ s/\\s+/ /g;\n      foreach my $option (split(/,|\\s/, $lc_attr)) {\n        main::setLdapServerConfig($hn, '+zimbraMtaHeaderChecks', \"$option\");\n      }\n    }\n    $lc_attr= $localxml->{key}->{postfix_in_flow_delay}->{value};\n    if (defined($lc_attr) && lc($lc_attr) ne \"1s\") {\n      main::setLdapServerConfig($hn, 'zimbraMtaInFlowDelay', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_import_environment}->{value};\n    if (defined($lc_attr)) {\n      $lc_attr =~ s/, /,/g;\n      $lc_attr =~ s/\\s+/ /g;\n      foreach my $option (split(/,|\\s/, $lc_attr)) {\n        main::setLdapServerConfig($hn, '+zimbraMtaImportEnvironment', \"$option\");\n      }\n    }\n    $lc_attr= $localxml->{key}->{postfix_lmtp_connection_cache_destinations}->{value};\n    if (defined($lc_attr)) {\n      $lc_attr =~ s/, /,/g;\n      $lc_attr =~ s/\\s+/ /g;\n      foreach my $option (split(/,|\\s/, $lc_attr)) {\n        main::setLdapServerConfig($hn, '+zimbraMtaLmtpConnectionCacheDestinations', \"$option\");\n      }\n    }\n    $lc_attr= $localxml->{key}->{postfix_lmtp_connection_cache_time_limit}->{value};\n    if (defined($lc_attr) && lc($lc_attr) ne \"4s\") {\n      main::setLdapServerConfig($hn, 'zimbraMtaLmtpConnectionCacheTimeLimit', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_lmtp_host_lookup}->{value};\n    if (defined($lc_attr) && lc($lc_attr) ne \"dns\") {\n      $lc_attr =~ s/, /,/g;\n      $lc_attr =~ s/\\s+/ /g;\n      foreach my $option (split(/,|\\s/, $lc_attr)) {\n        main::setLdapServerConfig($hn, '+zimbraMtaLmtpHostLookup', \"$option\");\n      }\n    }\n    $lc_attr= $localxml->{key}->{postfix_queue_directory}->{value};\n    if (defined($lc_attr)) {\n      if ($lc_attr =~ /\\$\\{zimbra_home\\}/) {\n        $lc_attr =~ s/\\$\\{zimbra_home\\}/\\/opt\\/zimbra/;\n      }\n      main::setLdapServerConfig($hn, 'zimbraMtaQueueDirectory', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_maximal_backoff_time}->{value};\n    if (defined($lc_attr) && lc($lc_attr) ne \"4000s\") {\n      main::setLdapServerConfig($hn, 'zimbraMtaMaximalBackoffTime', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_minimal_backoff_time}->{value};\n    if (defined($lc_attr) && lc($lc_attr) ne \"300s\") {\n      main::setLdapServerConfig($hn, 'zimbraMtaMinimalBackoffTime', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_queue_run_delay}->{value};\n    if (defined($lc_attr) && lc($lc_attr) ne \"300s\") {\n      main::setLdapServerConfig($hn, 'zimbraMtaQueueRunDelay', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_milter_connect_timeout}->{value};\n    if (defined($lc_attr) && lc($lc_attr) ne \"30s\") {\n      main::setLdapServerConfig($hn, 'zimbraMtaMilterConnectTimeout', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_milter_content_timeout}->{value};\n    if (defined($lc_attr) && lc($lc_attr) ne \"300s\") {\n      main::setLdapServerConfig($hn, 'zimbraMtaMilterContentTimeout', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_milter_default_action}->{value};\n    if (defined($lc_attr) && lc($lc_attr) ne \"tempfail\") {\n      main::setLdapServerConfig($hn, 'zimbraMtaMilterDefaultAction', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_smtp_cname_overrides_servername}->{value};\n    if (defined($lc_attr) && lc($lc_attr) ne \"no\") {\n      main::setLdapServerConfig($hn, 'zimbraMtaSmtpCnameOverridesServername', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_smtp_helo_name}->{value};\n    if (defined($lc_attr) && lc($lc_attr) ne '$myhostname') {\n      main::setLdapServerConfig($hn, 'zimbraMtaSmtpHeloName', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_smtp_sasl_auth_enable}->{value};\n    if (defined($lc_attr) && lc($lc_attr) ne \"no\") {\n      main::setLdapServerConfig($hn, 'zimbraMtaSmtpSaslAuthEnable', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_smtp_tls_security_level}->{value};\n    if (defined($lc_attr) && lc($lc_attr) ne \"may\") {\n      main::setLdapServerConfig($hn, 'zimbraMtaSmtpTlsSecurityLevel', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_smtp_sasl_mechanism_filter}->{value};\n    if (defined($lc_attr)) {\n      $lc_attr =~ s/, /,/g;\n      $lc_attr =~ s/\\s+/ /g;\n      foreach my $option (split(/,|\\s/, $lc_attr)) {\n        main::setLdapServerConfig($hn, '+zimbraMtaSmtpSaslMechanismFilter', \"$option\");\n      }\n    }\n    $lc_attr= $localxml->{key}->{postfix_smtp_sasl_password_maps}->{value};\n    if (defined($lc_attr)) {\n      $lc_attr =~ s/, /,/g;\n      $lc_attr =~ s/\\s+/ /g;\n      main::setLdapServerConfig($hn, 'zimbraMtaSmtpSaslPasswordMaps', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_policy_time_limit}->{value};\n    if (defined($lc_attr)) {\n      main::setLdapServerConfig($hn, 'zimbraMtaPolicyTimeLimit', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_smtpd_banner}->{value};\n    if (defined($lc_attr)) {\n      main::setLdapServerConfig($hn, 'zimbraMtaSmtpdBanner', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_smtpd_proxy_timeout}->{value};\n    if (defined($lc_attr) && lc($lc_attr) ne \"100s\") {\n      main::setLdapServerConfig($hn, 'zimbraMtaSmtpdProxyTimeout', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_smtpd_reject_unlisted_recipient}->{value};\n    if (defined($lc_attr) && lc($lc_attr) ne \"no\") {\n      main::setLdapServerConfig($hn, 'zimbraMtaSmtpdRejectUnlistedRecipient', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_smtpd_reject_unlisted_sender}->{value};\n    if (defined($lc_attr) && lc($lc_attr) ne \"no\") {\n      main::setLdapServerConfig($hn, 'zimbraMtaSmtpdRejectUnlistedSender', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_smtpd_sasl_authenticated_header}->{value};\n    if (defined($lc_attr) && lc($lc_attr) ne \"no\") {\n      main::setLdapServerConfig($hn, 'zimbraMtaSmtpdSaslAuthenticatedHeader', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_smtpd_hard_error_limit}->{value};\n    if (defined($lc_attr) && $lc_attr != 20) {\n      main::setLdapServerConfig($hn, 'zimbraMtaSmtpdHardErrorLimit', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_smtpd_soft_error_limit}->{value};\n    if (defined($lc_attr) && $lc_attr != 10) {\n      main::setLdapServerConfig($hn, 'zimbraMtaSmtpdSoftErrorLimit', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_smtpd_error_sleep_time}->{value};\n    if (defined($lc_attr) && lc($lc_attr) ne \"1s\") {\n      main::setLdapServerConfig($hn, 'zimbraMtaSmtpdErrorSleepTime', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_smtpd_helo_required}->{value};\n    if (defined($lc_attr) && lc($lc_attr) ne \"yes\") {\n      main::setLdapServerConfig($hn, 'zimbraMtaSmtpdHeloRequired', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_smtpd_tls_loglevel}->{value};\n    if (defined($lc_attr) && $lc_attr != 1) {\n      main::setLdapServerConfig($hn, 'zimbraMtaSmtpdTlsLoglevel', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_virtual_alias_expansion_limit}->{value};\n    if (defined($lc_attr) && $lc_attr != 10000) {\n      main::setLdapServerConfig($hn, 'zimbraMtaVirtualAliasExpansionLimit', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_virtual_transport}->{value};\n    if (defined($lc_attr) && lc($lc_attr) ne \"error\") {\n      main::setLdapServerConfig($hn, 'zimbraMtaSmtpdVirtualTransport', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_notify_classes}->{value};\n    if (defined($lc_attr) && lc($lc_attr) ne \"resource,software\") {\n      $lc_attr =~ s/, /,/g;\n      $lc_attr =~ s/\\s+/ /g;\n      foreach my $option (split(/,|\\s/, $lc_attr)) {\n        main::setLdapServerConfig($hn, '+zimbraMtaNotifyClasses', \"$option\");\n      }\n    }\n    $lc_attr= $localxml->{key}->{postfix_propagate_unmatched_extensions}->{value};\n    if (defined($lc_attr) && lc($lc_attr) ne \"canonical\") {\n      $lc_attr =~ s/, /,/g;\n      $lc_attr =~ s/\\s+/ /g;\n      foreach my $option (split(/,|\\s/, $lc_attr)) {\n        main::setLdapServerConfig($hn, '+zimbraMtaPropagateUnmatchedExtensions', \"$option\");\n      }\n    }\n    $lc_attr= $localxml->{key}->{postfix_sender_canonical_maps}->{value};\n    if (defined($lc_attr)) {\n      if ($lc_attr =~ /\\$\\{zimbra_home\\}/) {\n        $lc_attr =~ s/\\$\\{zimbra_home\\}/\\/opt\\/zimbra/g;\n      }\n      $lc_attr =~ s/, /,/g;\n      $lc_attr =~ s/\\s+/ /g;\n      main::setLdapServerConfig($hn, 'zimbraMtaSenderCanonicalMaps', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_smtp_sasl_security_options}->{value};\n    if (defined($lc_attr) && lc($lc_attr) ne \"noplaintext,noanonymous\") {\n      $lc_attr =~ s/, /,/g;\n      $lc_attr =~ s/\\s+/ /g;\n      foreach my $option (split(/,|\\s/, $lc_attr)) {\n        main::setLdapServerConfig($hn, '+zimbraMtaSmtpSaslSecurityOptions', \"$option\");\n      }\n    }\n    $lc_attr= $localxml->{key}->{postfix_smtpd_sasl_security_options}->{value};\n    if (defined($lc_attr) && lc($lc_attr) ne \"noplaintext,noanonymous\") {\n      $lc_attr =~ s/, /,/g;\n      $lc_attr =~ s/\\s+/ /g;\n      foreach my $option (split(/,|\\s/, $lc_attr)) {\n        main::setLdapServerConfig($hn, '+zimbraMtaSmtpdSaslSecurityOptions', \"$option\");\n      }\n    }\n    $lc_attr= $localxml->{key}->{postfix_smtpd_sasl_tls_security_options}->{value};\n    if (defined($lc_attr)) {\n      $lc_attr =~ s/, /,/g;\n      $lc_attr =~ s/\\s+/ /g;\n      foreach my $option (split(/,|\\s/, $lc_attr)) {\n        main::setLdapServerConfig($hn, '+zimbraMtaSmtpdSaslTlsSecurityOptions', \"$option\");\n      }\n    }\n    $lc_attr= $localxml->{key}->{postfix_smtpd_client_restrictions}->{value};\n    if (defined($lc_attr)) {\n      main::setLdapServerConfig($hn, 'zimbraMtaSmtpdClientRestrictions', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_smtpd_data_restrictions}->{value};\n    if (defined($lc_attr)) {\n      main::setLdapServerConfig($hn, 'zimbraMtaSmtpdDataRestrictions', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_transport_maps}->{value};\n    if (defined($lc_attr)) {\n      if ($lc_attr =~ /\\$\\{zimbra_home\\}/) {\n        $lc_attr =~ s/\\$\\{zimbra_home\\}/\\/opt\\/zimbra/g;\n      }\n      $lc_attr =~ s/, /,/g;\n      $lc_attr =~ s/\\s+/ /g;\n      main::setLdapServerConfig($hn, 'zimbraMtaTransportMaps', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_virtual_alias_domains}->{value};\n    if (defined($lc_attr)) {\n      if ($lc_attr =~ /\\$\\{zimbra_home\\}/) {\n        $lc_attr =~ s/\\$\\{zimbra_home\\}/\\/opt\\/zimbra/g;\n      }\n      $lc_attr =~ s/, /,/g;\n      $lc_attr =~ s/\\s+/ /g;\n      main::setLdapServerConfig($hn, 'zimbraMtaVirtualAliasDomains', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_virtual_alias_maps}->{value};\n    if (defined($lc_attr)) {\n      if ($lc_attr =~ /\\$\\{zimbra_home\\}/) {\n        $lc_attr =~ s/\\$\\{zimbra_home\\}/\\/opt\\/zimbra/g;\n      }\n      $lc_attr =~ s/, /,/g;\n      $lc_attr =~ s/\\s+/ /g;\n      main::setLdapServerConfig($hn, 'zimbraMtaVirtualAliasMaps', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_virtual_mailbox_domains}->{value};\n    if (defined($lc_attr)) {\n      if ($lc_attr =~ /\\$\\{zimbra_home\\}/) {\n        $lc_attr =~ s/\\$\\{zimbra_home\\}/\\/opt\\/zimbra/g;\n      }\n      $lc_attr =~ s/, /,/g;\n      $lc_attr =~ s/\\s+/ /g;\n      main::setLdapServerConfig($hn, 'zimbraMtaVirtualMailboxDomains', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{postfix_virtual_mailbox_maps}->{value};\n    if (defined($lc_attr)) {\n      if ($lc_attr =~ /\\$\\{zimbra_home\\}/) {\n        $lc_attr =~ s/\\$\\{zimbra_home\\}/\\/opt\\/zimbra/g;\n      }\n      $lc_attr =~ s/, /,/g;\n      $lc_attr =~ s/\\s+/ /g;\n      main::setLdapServerConfig($hn, 'zimbraMtaVirtualMailboxMaps', \"$lc_attr\");\n    }\n    $lc_attr= $localxml->{key}->{sasl_smtpd_mech_list}->{value};\n    if (defined($lc_attr)) {\n      $lc_attr =~ s/, /,/g;\n      $lc_attr =~ s/\\s+/ /g;\n      foreach my $option (split(/,|\\s/, $lc_attr)) {\n        main::setLdapServerConfig($hn, '+zimbraMtaSaslSmtpdMechList', \"$option\");\n      }\n    }\n    $lc_attr= $localxml->{key}->{cbpolicyd_bind_port}->{value};\n    if (defined($lc_attr) && $lc_attr != 10031) {\n      main::setLdapServerConfig($hn, 'zimbraCBPolicydBindPort', \"TRUE\");\n    }\n    $lc_attr= $localxml->{key}->{cbpolicyd_log_level}->{value};\n    if (defined($lc_attr) && $lc_attr != 3) {\n      main::setLdapServerConfig($hn, 'zimbraCBPolicydLogLevel', \"TRUE\");\n    }\n  }\n  main::deleteLocalConfig(\"amavis_max_servers\");\n  main::deleteLocalConfig(\"clamav_max_threads\");\n  main::deleteLocalConfig(\"amavis_enable_dkim_verification\");\n  main::deleteLocalConfig(\"amavis_originating_bypass_sa\");\n  main::deleteLocalConfig(\"amavis_dspam_enabled\");\n  main::deleteLocalConfig(\"postfix_enable_smtpd_policyd\");\n  main::deleteLocalConfig(\"cbpolicyd_min_servers\");\n  main::deleteLocalConfig(\"cbpolicyd_min_spare_servers\");\n  main::deleteLocalConfig(\"cbpolicyd_max_servers\");\n  main::deleteLocalConfig(\"cbpolicyd_max_spare_servers\");\n  main::deleteLocalConfig(\"cbpolicyd_max_requests\");\n  main::deleteLocalConfig(\"cbpolicyd_timeout_idle\");\n  main::deleteLocalConfig(\"cbpolicyd_timeout_busy\");\n  main::deleteLocalConfig(\"cbpolicyd_bypass_timeout\");\n  main::deleteLocalConfig(\"cbpolicyd_bypass_mode\");\n  main::deleteLocalConfig(\"cbpolicyd_module_accesscontrol\");\n  main::deleteLocalConfig(\"cbpolicyd_module_greylisting\");\n  main::deleteLocalConfig(\"cbpolicyd_module_greylisting_training\");\n  main::deleteLocalConfig(\"cbpolicyd_module_greylisting_defer_msg\");\n  main::deleteLocalConfig(\"cbpolicyd_module_greylisting_blacklist_msg\");\n  main::deleteLocalConfig(\"cbpolicyd_module_checkhelo\");\n  main::deleteLocalConfig(\"cbpolicyd_module_checkspf\");\n  main::deleteLocalConfig(\"cbpolicyd_module_quotas\");\n  main::deleteLocalConfig(\"cbpolicyd_module_amavis\");\n  main::deleteLocalConfig(\"cbpolicyd_module_accounting\");\n  main::deleteLocalConfig(\"postfix_alias_maps\");\n  main::deleteLocalConfig(\"postfix_always_add_missing_headers\");\n  main::deleteLocalConfig(\"postfix_broken_sasl_auth_clients\");\n  main::deleteLocalConfig(\"postfix_bounce_notice_recipient\");\n  main::deleteLocalConfig(\"postfix_bounce_queue_lifetime\");\n  main::deleteLocalConfig(\"postfix_command_directory\");\n  main::deleteLocalConfig(\"postfix_daemon_directory\");\n  main::deleteLocalConfig(\"postfix_delay_warning_time\");\n  main::deleteLocalConfig(\"postfix_header_checks\");\n  main::deleteLocalConfig(\"postfix_in_flow_delay\");\n  main::deleteLocalConfig(\"postfix_import_environment\");\n  main::deleteLocalConfig(\"postfix_lmtp_connection_cache_destinations\");\n  main::deleteLocalConfig(\"postfix_lmtp_connection_cache_time_limit\");\n  main::deleteLocalConfig(\"postfix_lmtp_host_lookup\");\n  main::deleteLocalConfig(\"postfix_mailq_path\");\n  main::deleteLocalConfig(\"postfix_manpage_directory\");\n  main::deleteLocalConfig(\"postfix_newaliases_path\");\n  main::deleteLocalConfig(\"postfix_queue_directory\");\n  main::deleteLocalConfig(\"postfix_sendmail_path\");\n  main::deleteLocalConfig(\"postfix_maximal_backoff_time\");\n  main::deleteLocalConfig(\"postfix_minimal_backoff_time\");\n  main::deleteLocalConfig(\"postfix_queue_run_delay\");\n  main::deleteLocalConfig(\"postfix_milter_connect_timeout\");\n  main::deleteLocalConfig(\"postfix_milter_command_timeout\");\n  main::deleteLocalConfig(\"postfix_milter_content_timeout\");\n  main::deleteLocalConfig(\"postfix_milter_default_action\");\n  main::deleteLocalConfig(\"postfix_smtp_cname_overrides_servername\");\n  main::deleteLocalConfig(\"postfix_smtp_helo_name\");\n  main::deleteLocalConfig(\"postfix_smtp_sasl_auth_enable\");\n  main::deleteLocalConfig(\"postfix_smtp_tls_security_level\");\n  main::deleteLocalConfig(\"postfix_smtp_sasl_mechanism_filter\");\n  main::deleteLocalConfig(\"postfix_smtp_sasl_password_maps\");\n  main::deleteLocalConfig(\"postfix_policy_time_limit\");\n  main::deleteLocalConfig(\"postfix_smtpd_banner\");\n  main::deleteLocalConfig(\"postfix_smtpd_proxy_timeout\");\n  main::deleteLocalConfig(\"postfix_smtpd_reject_unlisted_recipient\");\n  main::deleteLocalConfig(\"postfix_smtpd_reject_unlisted_sender\");\n  main::deleteLocalConfig(\"postfix_smtpd_sasl_authenticated_header\");\n  main::deleteLocalConfig(\"postfix_smtpd_hard_error_limit\");\n  main::deleteLocalConfig(\"postfix_smtpd_soft_error_limit\");\n  main::deleteLocalConfig(\"postfix_smtpd_error_sleep_time\");\n  main::deleteLocalConfig(\"postfix_smtpd_helo_required\");\n  main::deleteLocalConfig(\"postfix_smtpd_tls_loglevel\");\n  main::deleteLocalConfig(\"postfix_smtpd_tls_cert_file\");\n  main::deleteLocalConfig(\"postfix_smtpd_tls_key_file\");\n  main::deleteLocalConfig(\"postfix_virtual_alias_expansion_limit\");\n  main::deleteLocalConfig(\"postfix_virtual_transport\");\n  main::deleteLocalConfig(\"postfix_notify_classes\");\n  main::deleteLocalConfig(\"postfix_propagate_unmatched_extensions\");\n  main::deleteLocalConfig(\"postfix_sender_canonical_maps\");\n  main::deleteLocalConfig(\"postfix_smtp_sasl_security_options\");\n  main::deleteLocalConfig(\"postfix_smtpd_sasl_security_options\");\n  main::deleteLocalConfig(\"postfix_smtpd_sasl_tls_security_options\");\n  main::deleteLocalConfig(\"postfix_smtpd_client_restrictions\");\n  main::deleteLocalConfig(\"postfix_smtpd_data_restrictions\");\n  main::deleteLocalConfig(\"postfix_transport_maps\");\n  main::deleteLocalConfig(\"postfix_virtual_alias_domains\");\n  main::deleteLocalConfig(\"postfix_virtual_alias_maps\");\n  main::deleteLocalConfig(\"postfix_virtual_mailbox_domains\");\n  main::deleteLocalConfig(\"postfix_virtual_mailbox_maps\");\n  main::deleteLocalConfig(\"sasl_smtpd_mech_list\");\n  main::deleteLocalConfig(\"cbpolicyd_bind_port\");\n  main::deleteLocalConfig(\"cbpolicyd_log_level\");\n  return 0;\n}\n\nsub upgrade850BETA2 {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  if (main::isInstalled(\"zimbra-ldap\")) {\n    if ($isLdapMaster) {\n      main::setLdapGlobalConfig(\"zimbraVersionCheckURL\",\"https://www.zimbra.com/aus/universal/update.php\");\n    }\n  }\n  if (main::isInstalled(\"zimbra-store\")) {\n    my $zimbra_log_directory = main::getLocalConfig(\"zimbra_log_directory\");\n    my $mysql_mycnf = main::getLocalConfig(\"mysql_mycnf\");\n    if ( -e ${mysql_mycnf} ) {\n      main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-general_log_file-fixup --section=mysqld --set --key=general_log_file --value=${zimbra_log_directory}/mysql-mailboxd.log ${mysql_mycnf}\");\n    }\n    my $mailboxd_java_options=main::getLocalConfigRaw(\"mailboxd_java_options\");\n    if ($mailboxd_java_options !~ /-Xloggc/) {\n      $mailboxd_java_options .= \" -Xloggc:/opt/zimbra/log/gc.log -XX:-UseGCLogFileRotation -XX:NumberOfGCLogFiles=20 -XX:GCLogFileSize=4096K\";\n      $mailboxd_java_options =~ s/^\\s+//;\n      main::setLocalConfig(\"mailboxd_java_options\", $mailboxd_java_options);\n    }\n    if (main::isStoreWebNode()) {\n      my @zimbraReverseProxyUpstreamLoginServers=qx($su \"$ZMPROV gacf zimbraReverseProxyUpstreamLoginServers\");\n      if (! grep(/$hn/, @zimbraReverseProxyUpstreamLoginServers)) {\n        main::runAsZimbra(\"$ZMPROV mcf +zimbraReverseProxyUpstreamLoginServers $hn\");\n      }\n    }\n  }\n  if (main::isInstalled(\"zimbra-mta\")) {\n    my $antispam_mysql_mycnf = main::getLocalConfig(\"antispam_mysql_mycnf\");\n    my $zimbra_log_directory = main::getLocalConfig(\"zimbra_log_directory\");\n    if ( -e ${antispam_mysql_mycnf} ) {\n      main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-antispam-general_log_file-fixup --section=mysqld --set --key=general_log_file --value=${zimbra_log_directory}/mysql-antispam.log ${antispam_mysql_mycnf}\");\n    }\n    my @zimbraServiceInstalled=qx($su \"$ZMPROV gs $hn zimbraServiceInstalled\");\n    my @zimbraServiceEnabled=qx($su \"$ZMPROV gs $hn zimbraServiceEnabled\");\n    if (grep(/antivirus/, @zimbraServiceInstalled) || grep(/antispam/, @zimbraServiceInstalled) || grep(/archiving/, @zimbraServiceInstalled)) {\n      main::setLdapServerConfig($hn, '+zimbraServiceInstalled', 'amavis');\n    }\n    if (grep(/antivirus/, @zimbraServiceEnabled) || grep(/antispam/, @zimbraServiceEnabled) || grep(/archiving/, @zimbraServiceEnabled)) {\n      main::setLdapServerConfig($hn, '+zimbraServiceEnabled', 'amavis');\n    }\n    if (-f \"/opt/zimbra/conf/sauser.cf\") {\n      qx(mv /opt/zimbra/conf/sauser.cf /opt/zimbra/data/spamassassin/localrules/sauser.cf);\n    }\n    if (-f \"/opt/zimbra/conf/sa/sauser.cf\") {\n      qx(mv /opt/zimbra/conf/sa/sauser.cf /opt/zimbra/data/spamassassin/localrules/sauser.cf);\n    }\n  }\n  return 0;\n}\n\nsub upgrade850BETA3 {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  if (main::isInstalled(\"zimbra-ldap\")) {\n    if ($isLdapMaster) {\n      runLdapAttributeUpgrade(\"85224\");\n      runLdapAttributeUpgrade(\"87674\");\n      runLdapAttributeUpgrade(\"88766\");\n      runLdapAttributeUpgrade(\"88098\");\n    }\n  }\n  if (main::isInstalled(\"zimbra-store\")) {\n    if (main::isStoreServiceNode()) {\n      my @zimbraReverseProxyAvailableLookupTargets=qx($su \"$ZMPROV gacf zimbraReverseProxyAvailableLookupTargets\");\n      if (! grep(/$hn/, @zimbraReverseProxyAvailableLookupTargets)) {\n        main::runAsZimbra(\"$ZMPROV mcf +zimbraReverseProxyAvailableLookupTargets $hn\");\n      }\n    }\n  }\n  if (main::isInstalled(\"zimbra-mta\")) {\n    my $antispam_mysql_mycnf = main::getLocalConfig(\"antispam_mysql_mycnf\");\n    if ( -e ${antispam_mysql_mycnf} ) {\n      main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-long-query-time-fixup --section=mysqld --unset --key=long-query-time ${antispam_mysql_mycnf}\");\n      main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-long_query_time-fixup --section=mysqld --set --key=long_query_time --value=1 ${antispam_mysql_mycnf}\");\n      main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-log-queries-not-using-indexes-fixup --section=mysqld --unset --key=log-queries-not-using-indexes ${antispam_mysql_mycnf}\");\n      main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-log_queries_not_using_indexes-fixup --section=mysqld --set --key=log_queries_not_using_indexes ${antispam_mysql_mycnf}\");\n    }\n  }\n  return 0;\n}\n\nsub upgrade850GA {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n\n  if (main::isInstalled(\"zimbra-ldap\")) {\n      main::runAsZimbra(\"perl -I${scriptDir} ${scriptDir}/migrate20140728-AddSSHA512.pl\");\n      if ($isLdapMaster) {\n        main::runAsZimbra(\"$ZMPROV mcf +zimbraSpamTrashAlias '/Deleted Messages'\");\n        main::runAsZimbra(\"$ZMPROV mcf +zimbraSpamTrashAlias '/Deleted Items'\");\n      }\n  }\n  return 0;\n}\n\nsub upgrade851GA {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  if (main::isInstalled(\"zimbra-ldap\")) {\n    if ($isLdapMaster) {\n      my $ldap_pass = qx($su \"zmlocalconfig -s -m nokey ldap_root_password\");\n      chomp($ldap_pass);\n      my $ldap;\n      unless($ldap = Net::LDAP->new('ldapi://%2fopt%2fzimbra%2fdata%2fldap%2fstate%2frun%2fldapi/')) {\n         main::progress(\"Unable to connect to ldapi: $!\\n\");\n      } else {\n        my $result = $ldap->bind(\"cn=config\", password => $ldap_pass);\n        $result = $ldap->search(\n          base=> \"cn=config,cn=zimbra\",\n          filter=>\"(&(objectClass=*)(zimbraDomainMandatoryMailSignatureText=*))\",\n          scope => \"base\",\n          attrs => ['zimbraDomainMandatoryMailSignatureText', 'zimbraDomainMandatoryMailSignatureHTML'],\n        );\n        my $totalcount=$result->count;\n        if ($totalcount > 0) {\n          my $entry=$result->entry($totalcount-1);\n          my $text_disclaimer = $entry->get_value(\"zimbraDomainMandatoryMailSignatureText\");\n          my $html_disclaimer = $entry->get_value(\"zimbraDomainMandatoryMailSignatureHTML\");\n          $result = $ldap->search(\n            base=> \"\",\n            filter=>\"(objectClass=zimbraDomain)\",\n            scope => \"sub\",\n          );\n          foreach $entry ($result->entries) {\n            $result = $ldap->modify(\n                $entry->dn,\n                add =>{\n                    zimbraAmavisDomainDisclaimerText=>$text_disclaimer,\n                    zimbraAmavisDomainDisclaimerHTML=>$html_disclaimer,\n                },\n            );\n          }\n          $result = $ldap->modify(\n            \"cn=config,cn=zimbra\",\n            delete=>['zimbraDomainMandatoryMailSignatureText','zimbraDomainMandatoryMailSignatureHTML']\n          );\n        }\n      }\n    }\n  }\n  return 0;\n}\n\nsub upgrade860BETA1 {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  my $ssl_default_digest = main::getLocalConfig(\"ssl_default_digest\");\n  if ($ssl_default_digest eq \"sha1\") {\n      main::setLocalConfig(\"ssl_default_digest\", \"sha256\");\n  }\n  if (main::isInstalled(\"zimbra-snmp\")) {\n    my $val = main::getLocalConfig(\"snmp_trap_host\");\n    if ($val =~ /\\@/) {\n      $val =~ s/.*\\@//;\n      main::setLocalConfig(\"snmp_trap_host\", \"$val\");\n    }\n  }\n  return 0;\n}\n\nsub upgrade860BETA2 {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  if (main::isInstalled(\"zimbra-ldap\")) {\n      main::runAsZimbra(\"perl -I${scriptDir} ${scriptDir}/migrate20141022-AddTLSBits.pl\");\n  }\n  if (main::isInstalled(\"zimbra-store\")) {\n      my @zimbraHttpContextPathBasedThreadPoolBalancingFilterRules=qx($su \"$ZMPROV gacf zimbraHttpContextPathBasedThreadPoolBalancingFilterRules\");\n      foreach my $zimbraHttpContextPathBasedThreadPoolBalancingFilterRule (@zimbraHttpContextPathBasedThreadPoolBalancingFilterRules) {\n        chomp($zimbraHttpContextPathBasedThreadPoolBalancingFilterRule);\n        (my $filterKey, my $filterValue) = split(/:\\s/,  $zimbraHttpContextPathBasedThreadPoolBalancingFilterRule);\n        if ($filterValue eq \"/service:min=10;max=80%\") {\n          main::runAsZimbra(\"$ZMPROV mcf -zimbraHttpContextPathBasedThreadPoolBalancingFilterRules '$filterValue'\");\n          main::runAsZimbra(\"$ZMPROV mcf +zimbraHttpContextPathBasedThreadPoolBalancingFilterRules '/service:max=80%'\");\n        }\n        elsif ($filterValue eq \"/zimbra:min=10;max=15%\") {\n          main::runAsZimbra(\"$ZMPROV mcf -zimbraHttpContextPathBasedThreadPoolBalancingFilterRules '$filterValue'\");\n          main::runAsZimbra(\"$ZMPROV mcf +zimbraHttpContextPathBasedThreadPoolBalancingFilterRules '/zimbra:max=15%'\");\n        }\n        elsif ($filterValue eq \"/zimbraAdmin:min=10;max=5%\") {\n          main::runAsZimbra(\"$ZMPROV mcf -zimbraHttpContextPathBasedThreadPoolBalancingFilterRules '$filterValue'\");\n          main::runAsZimbra(\"$ZMPROV mcf +zimbraHttpContextPathBasedThreadPoolBalancingFilterRules '/zimbraAdmin:max=5%'\");\n        }\n      }\n    }\n  return 0;\n}\n\nsub upgrade860GA {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  if(main::isInstalled(\"zimbra-ldap\")) {\n    if ($isLdapMaster) {\n      my $mtasmtpdprotocols=main::getLdapConfigValue(\"zimbraMtaSmtpdTlsProtocols\");\n      if ($mtasmtpdprotocols eq \"\") {\n        main::runAsZimbra(\"$ZMPROV mcf zimbraMtaSmtpdTlsProtocols '!SSLv2, !SSLv3'\");\n      }\n    }\n  }\n  if ( -d \"/opt/zimbra/zimlets-deployed/com_zimbra_linkedinimage/\") {\n    main::runAsZimbra(\"/opt/zimbra/bin/zmzimletctl -l undeploy com_zimbra_linkedinimage\");\n  }\n  return 0;\n}\n\nsub upgrade870BETA1 {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  if(main::isInstalled(\"zimbra-ldap\")) {\n    if ($isLdapMaster) {\n      # Bug 99616 - Update olcSpSessionLog\n      main::runAsZimbra(\"perl -I${scriptDir} ${scriptDir}/migrate20150930-AddSyncpovSessionlog.pl\");\n\n      # Bug 96921 - Update Jetty default SSL cipher excludes...\n      my $sslexcludeciph=main::getLdapConfigValue(\"zimbraSSLExcludeCipherSuites\") || \"\";\n      my $cursslexcl=join(\" \", sort split(\"\\n\", $sslexcludeciph));\n      my $oldsslexcl=join(\n        \" \",\n        sort qw(\n          SSL_RSA_WITH_DES_CBC_SHA\n          SSL_DHE_RSA_WITH_DES_CBC_SHA\n          SSL_DHE_DSS_WITH_DES_CBC_SHA\n          SSL_RSA_EXPORT_WITH_RC4_40_MD5\n          SSL_RSA_EXPORT_WITH_DES40_CBC_SHA\n          SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA\n          SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA\n        )\n      );\n      if ($cursslexcl eq $oldsslexcl) {\n        main::runAsZimbra(\"$ZMPROV mcf zimbraSSLExcludeCipherSuites '.*_RC4_.*'\");\n      }\n\n      # Bug 97332 - Some clients require SSLv2Hello support...\n      my $sslprot=main::getLdapConfigValue(\"zimbraMailboxdSSLProtocols\") || \"\";\n      my $cursslprot=join(\" \", sort split(\"\\n\", $sslprot));\n      my $oldsslprot=join(\" \", sort qw(TLSv1 TLSv1.1 TLSv1.2));\n      if ($cursslprot eq $oldsslprot) {\n        main::runAsZimbra(\"$ZMPROV mcf +zimbraMailboxdSSLProtocols SSLv2Hello\");\n      }\n    }\n  }\n  if (main::isInstalled(\"zimbra-proxy\")) {\n    my $proxysslciphers=main::getLdapConfigValue(\"zimbraReverseProxySSLCiphers\");\n    if ($proxysslciphers eq \"ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:AES128:AES256:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK\") {\n      main::runAsZimbra(\"$ZMPROV mcf zimbraReverseProxySSLCiphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128:AES256:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4'\");\n    }\n  }\n  if (main::isInstalled(\"zimbra-store\")) {\n    my $mailboxd_java_options=main::getLocalConfigRaw(\"mailboxd_java_options\");\n    my $new_mailboxd_options = $mailboxd_java_options;\n    $new_mailboxd_options =~ s/-XX:(?:Max|)PermSize=\\S*\\s?//g;\n    if ($new_mailboxd_options ne $mailboxd_java_options)\n    {\n      main::progress(\"Updating mailboxd_java_options to remove deprecated PermSize and MaxPermSize java options.\\n\");\n      main::setLocalConfig(\"mailboxd_java_options\", $new_mailboxd_options);\n    }\n\n    # Bug 80135 - Improved proxy timeout defaults...\n    my $proxy_reconnect_timeout = main::getLdapServerValue(\"zimbraMailProxyReconnectTimeout\");\n    if ($proxy_reconnect_timeout eq \"60\")  {\n      main::setLdapServerConfig($hn, 'zimbraMailProxyReconnectTimeout', '10');\n    }\n    # Bug 96857 -  MySQL meta files (pid file, socket, ..) should not be placed in db directory\n    unlink(\"/opt/zimbra/db/mysql.pid\") if (-e \"/opt/zimbra/db/mysql.pid\");\n    unlink(\"/opt/zimbra/db/mysql.sock\") if (-e \"/opt/zimbra/db/mysql.sock\");\n  }\n  my $localxml = XMLin(\"/opt/zimbra/conf/localconfig.xml\");\n  my $lc_attr= $localxml->{key}->{zimbra_class_database}->{value};\n  if (defined($lc_attr) && $lc_attr eq \"com.zimbra.cs.db.MySQL\") {\n    main::setLocalConfig(\"zimbra_class_database\", \"com.zimbra.cs.db.MariaDB\");\n  }\n\n  $lc_attr= $localxml->{key}->{short_term_all_effective_rights_cache_expiration}->{value};\n  if (defined($lc_attr) && $lc_attr+0 != 50000) {\n    main::setLdapServerConfig($hn, 'zimbraShortTermAllEffectiveRightsCacheExpiration', \"$lc_attr\".\"ms\");\n  }\n\n  $lc_attr= $localxml->{key}->{short_term_all_effective_rights_cache_size}->{value};\n  if (defined($lc_attr) && $lc_attr+0 != 128) {\n    main::setLdapServerConfig($hn, 'zimbraShortTermAllEffectiveRightsCacheSize', \"$lc_attr\");\n  }\n\n  $lc_attr= $localxml->{key}->{short_term_grantee_cache_expiration}->{value};\n  if (defined($lc_attr) && $lc_attr+0 != 50000) {\n    main::setLdapServerConfig($hn, 'zimbraShortTermGranteeCacheExpiration', \"$lc_attr\".\"ms\");\n  }\n\n  $lc_attr= $localxml->{key}->{short_term_grantee_cache_size}->{value};\n  if (defined($lc_attr) && $lc_attr+0 != 128) {\n    main::setLdapServerConfig($hn, 'zimbraShortTermGranteeCacheSize', \"$lc_attr\");\n  }\n\n  $lc_attr= $localxml->{key}->{zimbra_mailbox_throttle_reap_interval}->{value};\n  if (defined($lc_attr) && $lc_attr+0 != 60000) {\n    main::setLdapServerConfig($hn, 'zimbraMailboxThrottleReapInterval', \"$lc_attr\".\"ms\");\n  }\n\n  main::deleteLocalConfig(\"short_term_all_effective_rights_cache_expiration\");\n  main::deleteLocalConfig(\"short_term_all_effective_rights_cache_size\");\n  main::deleteLocalConfig(\"short_term_grantee_cache_expiration\");\n  main::deleteLocalConfig(\"short_term_grantee_cache_size\");\n  main::deleteLocalConfig(\"zimbra_mailbox_throttle_reap_interval\");\n\n  return 0;\n}\n\nsub upgrade870BETA2 {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  if (main::isInstalled(\"zimbra-mta\")) {\n    my $antispam_mysql_mycnf = main::getLocalConfig(\"antispam_mysql_mycnf\");\n    if ( -e ${antispam_mysql_mycnf} ) {\n      main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-mysql_basedir --section=mysqld --key=basedir --set --value='/opt/zimbra/common' ${antispam_mysql_mycnf}\");\n      main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-error-log --section=mysqld_safe --key=err-log --unset ${antispam_mysql_mycnf}\");\n      main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-error-log --section=mysqld_safe --key=log-error --set --value=/opt/zimbra/log/mysqld.log ${antispam_mysql_mycnf}\");\n    }\n    main::setLdapServerConfig($hn, 'zimbraMtaCommandDirectory', \"/opt/zimbra/common/sbin\");\n    main::setLdapServerConfig($hn, 'zimbraMtaDaemonDirectory', \"/opt/zimbra/common/libexec\");\n    main::setLdapServerConfig($hn, 'zimbraMtaMailqPath', \"/opt/zimbra/common/sbin/mailq\");\n    main::setLdapServerConfig($hn, 'zimbraMtaManpageDirectory', \"/opt/zimbra/common/share/man\");\n    main::setLdapServerConfig($hn, 'zimbraMtaNewaliasesPath', \"/opt/zimbra/common/sbin/newaliases\");\n    main::setLdapServerConfig($hn, 'zimbraMtaSendmailPath', \"/opt/zimbra/common/sbin/sendmail\");\n    # Bug 98771 - Add support for DANE\n    my $dns_setting = main::getLdapServerValue(\"zimbraMtaDnsLookupsEnabled\");\n    if (lc($dns_setting) eq \"false\")  {\n      main::setLdapServerConfig($hn, 'zimbraMtaSmtpDnsSupportLevel', 'disabled');\n    }\n    # Bug 98072 - We must clear zimbraMtaSenderCanonicalMaps on upgrade\n    main::setLdapServerConfig($hn, 'zimbraMtaSenderCanonicalMaps', \"\");\n    main::setLdapGlobalConfig('zimbraMtaSenderCanonicalMaps',\"\");\n    main::runAsZimbra(\"/opt/zimbra/bin/postconf -e sender_canonical_maps=''\");\n  }\n  if (main::isFoss()) {\n    main::setLdapServerConfig($hn, '-zimbraServiceEnabled', 'vmware-ha');\n  }\n\n  return 0;\n}\n\nsub upgrade870RC1 {\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  if (main::isInstalled(\"zimbra-ldap\")) {\n    if ($isLdapMaster) {\n      main::setLdapGlobalConfig(\"zimbraSSLDHParam\", \"/opt/zimbra/conf/dhparam.pem.zcs\");\n    }\n    my $ldap_pass = qx($su \"zmlocalconfig -s -m nokey ldap_root_password\");\n    chomp($ldap_pass);\n    my $ldap;\n    unless($ldap = Net::LDAP->new('ldapi://%2fopt%2fzimbra%2fdata%2fldap%2fstate%2frun%2fldapi/')) {\n       main::progress(\"Unable to connect to ldapi: $@\\n\");\n    }\n    my $result = $ldap->bind(\"cn=config\", password => $ldap_pass);\n    my $dn=\"olcDatabase={2}mdb,cn=config\";\n    if ($isLdapMaster) {\n      $result = $ldap->search(\n                        base => \"cn=accesslog\",\n                        filter => \"(objectClass=*)\",\n                        scope => \"base\",\n                        attrs => ['1.1'],\n      );\n      my $size = $result->count;\n      if ($size > 0 ) {\n        $dn=\"olcDatabase={3}mdb,cn=config\";\n      }\n    }\n    $result = $ldap->search(\n      base=> \"$dn\",\n      filter=>\"(objectClass=*)\",\n      scope => \"base\",\n      attrs => ['olcDbRtxnSize'],\n    );\n    my $entry = $result->entry($result->count-1);\n    my @attrvals = $entry->get_value(\"olcDbRtxnSize\");\n\n    if (!@attrvals) {\n      $result = $ldap->modify(\n          $dn,\n          add => {olcDbRtxnSize=>0},\n      );\n    }\n    $ldap->unbind;\n  }\n  return 0;\n}\n\nsub upgrade872GA {\n    my ($startBuild, $targetVersion, $targetBuild) = (@_);\n    return 0;\n}\n\nsub upgrade886GA {\n    my ($startBuild, $targetVersion, $targetBuild) = (@_);\n    if (main::isInstalled(\"zimbra-proxy\")) {\n        # In order to avoid breaking existing installations 'Strict Server Name Enforcement' capability\n        # will remain disabled during upgrades. The maintainer may enable it after the upgrade process\n        # has completed and after configuring the appropriate domain(s) with the relevant\n        # 'zimbraVirtualHostName' and 'zimbraVirtualIPAddress' entries. This maintains current\n        # behavior for all upgrades until the administrator decides to enable the strict name enforcement.\n        main::setLdapServerConfig($hn, 'zimbraReverseProxyStrictServerNameEnabled', \"FALSE\");\n    }\n    # ClientIpHash is now obsolete\n    upgradeLdapConfigValue(\"zimbraImapLoadBalancingAlgorithm\", \"AccountIdHash\", \"ClientIpHash\");\n    return 0;\n}\n\nsub upgrade8811GA {\n  print \"applying 8811GA upgrade changes\";\n  my ($startBuild, $targetVersion, $targetBuild) = (@_);\n  if (main::isInstalled(\"zimbra-ldap\")) {\n    my $doIndex = &addLdapIndex(\"zimbraOldMailAddress\",\"eq\");\n    if ($doIndex) {\n      &indexLdapAttribute(\"zimbraOldMailAddress\");\n    }\n    my $ldap_pass = qx($su \"zmlocalconfig -s -m nokey ldap_root_password\");\n    chomp($ldap_pass);\n    my $ldap;\n    unless($ldap = Net::LDAP->new('ldapi://%2fopt%2fzimbra%2fdata%2fldap%2fstate%2frun%2fldapi/')) {\n       main::progress(\"Unable to connect to ldapi: $!\\n\");\n    }\n    my $result = $ldap->bind(\"cn=config\", password => $ldap_pass);\n    my $dn=\"olcDatabase={2}mdb,cn=config\";\n    if ($isLdapMaster) {\n      $result = $ldap->search(\n                        base=> \"cn=accesslog\",\n                        filter=>\"(objectClass=*)\",\n                        scope => \"base\",\n                        attrs => ['1.1'],\n      );\n      my $size = $result->count;\n      if ($size > 0 ) {\n        $dn=\"olcDatabase={3}mdb,cn=config\";\n      }\n    }\n    $result = $ldap->search(\n      base=> \"$dn\",\n      filter=>\"(objectClass=*)\",\n      scope => \"base\",\n      attrs => ['olcAccess'],\n    );\n    my $entry=$result->entry($result->count-1);\n    my @attrvals=$entry->get_value(\"olcAccess\");\n    my $aclNumber=-1;\n    my $attrMod=\"\";\n\n    foreach my $attr (@attrvals) {\n      if ($attr =~ /zimbraMailCatchAllAddress/) {\n        if ($attr !~ /zimbraOldMailAddress/) {\n          ($aclNumber) = $attr =~ /^\\{(\\d+)\\}*/;\n          $attrMod=$attr;\n        }\n      }\n    }\n\n    if ($aclNumber != -1 && $attrMod ne \"\") {\n      $attrMod =~ s/zimbraMailCatchAllAddress/zimbraMailCatchAllAddress,zimbraOldMailAddress/;\n      $result = $ldap->modify(\n          $dn,\n          delete => {olcAccess => \"{$aclNumber}\"},\n      );\n      $result = $ldap->modify(\n          $dn,\n          add =>{olcAccess=>\"$attrMod\"},\n      );\n    }\n    $ldap->unbind;\n  }\n  return 0;\n}\n\nsub upgrade8812GA {\n   print \"applying 8812GA upgrade changes\\n\";\n\n   print \"Updating to CA certs path\\n\";\n\n  qx($su \"zmlocalconfig -e mailboxd_truststore=/opt/zimbra/common/lib/jvm/java/lib/security/cacerts\");\n  qx($su \"zmlocalconfig -e mailboxd_java_options='-server -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2 -Djdk.tls.client.protocols=TLSv1,TLSv1.1,TLSv1.2 -Djava.awt.headless=true -Dsun.net.inetaddr.ttl=$ENV{networkaddress_cache_ttl} -Dorg.apache.jasper.compiler.disablejsr199=true -XX:+UseG1GC -XX:SoftRefLRUPolicyMSPerMB=1 -XX:-OmitStackTraceInFastThrow -verbose:gc  -Xlog:gc*=debug,safepoint=info:file=/opt/zimbra/log/gc.log:time:filecount=20,filesize=10m -Djava.net.preferIPv4Stack=true'\");\n  return 0;\n}\n\nsub upgrade8815GA {\n   print \"applying 8815GA upgrade changes\\n\";\n\n   print \"Updating OWASP LC config\\n\";\n\n  main::deleteLocalConfig(\"zimbra_use_owasp_html_sanitizer\");\n  return 0;\n}\n\n\nsub stopZimbra {\n  main::progress(\"Stopping zimbra services...\");\n  my $rc1 = main::runAsZimbra(\"/opt/zimbra/bin/zmcontrol stop\");\n  main::progress(($rc1 == 0) ? \"done.\\n\" : \"failed. exiting.\\n\");\n  my $rc2 = 0;\n  if (main::isInstalled(\"zimbra-license-daemon\")) {\n\t  main::progress(\"Stopping license daemon service...\");\n\t  $rc2 = main::runAsZimbra(\"/opt/zimbra/bin/zmlicensectl --service stop\");\n\t  main::progress(($rc2 == 0) ? \"done.\\n\" : \"failed. exiting.\\n\");\n  }\n  my $exit_code = ($rc1 == 0 && $rc2 == 0) ? 0 : 1;\n  return $exit_code;\n}\n\nsub startLdap {\n  main::progress(\"Checking ldap status...\");\n  my $rc = main::runAsZimbra(\"/opt/zimbra/bin/ldap status\");\n  main::progress(($rc == 0) ? \"already running.\\n\" : \"not running.\\n\");\n\n  if ($rc) {\n    main::progress(\"Checking ldap status...\");\n    $rc = main::runAsZimbra(\"/opt/zimbra/bin/ldap status\");\n    main::progress(($rc == 0) ? \"already running.\\n\" : \"not running.\\n\");\n\n    if ($rc) {\n      main::progress(\"Starting ldap...\");\n      my $rc = main::runAsZimbra(\"/opt/zimbra/bin/ldap start\");\n      main::progress(($rc == 0) ? \"done.\\n\" : \"failed with exit code: $rc.\\n\");\n      if ($rc) {\n        system(\"$su \\\"/opt/zimbra/bin/ldap start 2>&1 | grep failed\\\"\");\n        return $rc;\n      }\n    }\n  }\n  return 0;\n}\n\nsub stopLdap {\n  main::progress(\"Stopping ldap...\");\n  my $rc = main::runAsZimbra(\"/opt/zimbra/bin/ldap stop\");\n  main::progress(($rc == 0) ? \"done.\\n\" : \"failed. ldap had exit status: $rc.\\n\");\n  sleep 5 unless $rc; # give it a chance to shutdown.\n  return $rc;\n}\n\nsub isSqlRunning {\n  my $rc = 0xffff & system(\"$su \\\"/opt/zimbra/bin/mysqladmin status > /dev/null 2>&1\\\"\");\n  $rc = $rc >> 8;\n  return($rc ? undef : 1);\n}\n\nsub startSql {\n\n  unless (isSqlRunning()) {\n    main::progress(\"Starting mysql...\");\n    my $rc = main::runAsZimbra(\"/opt/zimbra/bin/mysql.server start\");\n    my $timeout = sleep 10;\n    while (!isSqlRunning() && $timeout <= 1200 ) {\n      $rc = main::runAsZimbra(\"/opt/zimbra/bin/mysql.server start\");\n      $timeout += sleep 10;\n    }\n    main::progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n    return $rc if $rc;\n  }\n  return(isSqlRunning() ? 0 : 1);\n}\n\nsub stopSql {\n  if (isSqlRunning()) {\n    main::progress(\"Stopping mysql...\");\n    my $rc = main::runAsZimbra(\"/opt/zimbra/bin/mysql.server stop\");\n    my $timeout = sleep 10;\n    while (isSqlRunning() && $timeout <= 120 ) {\n      $rc = main::runAsZimbra(\"/opt/zimbra/bin/mysql.server stop\");\n      $timeout += sleep 10;\n    }\n    main::progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n    return $rc if $rc;\n  }\n  return(isSqlRunning() ? 1 : 0);\n}\n\nsub isLoggerSqlRunning {\n  my $rc = main::runAsZimbra(\"/opt/zimbra/bin/logmysqladmin status > /dev/null 2>&1\");\n  return($rc ? undef : 1);\n}\n\nsub startLoggerSql {\n  unless (isLoggerSqlRunning()) {\n    main::progress(\"Starting logger mysql...\");\n    my $rc = main::runAsZimbra(\"/opt/zimbra/bin/logmysql.server start\");\n    my $timeout = sleep 10;\n    while (!isLoggerSqlRunning() && $timeout <= 120 ) {\n      $rc = main::runAsZimbra(\"/opt/zimbra/bin/logmysql.server start\");\n      $timeout += sleep 10;\n    }\n    main::progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n    return $rc if $rc;\n  }\n  return(isLoggerSqlRunning() ? 0 : 1);\n}\n\nsub stopLoggerSql {\n  if (isLoggerSqlRunning()) {\n    main::progress(\"Stopping logger mysql...\");\n    my $rc = main::runAsZimbra(\"/opt/zimbra/bin/logmysql.server stop\");\n    my $timeout = sleep 10;\n    while (isLoggerSqlRunning() && $timeout <= 120 ) {\n      $rc = main::runAsZimbra(\"/opt/zimbra/bin/logmysql.server stop\");\n      $timeout += sleep 10;\n    }\n    main::progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n    return $rc if $rc;\n  }\n  return(isLoggerSqlRunning() ? 1 : 0);\n}\n\n\nsub runSchemaUpgrade {\n  my $curVersion = shift;\n\n  if (! defined ($updateScripts{$curVersion})) {\n    main::progress (\"Can't upgrade from version $curVersion - no script!\\n\");\n    return 1;\n  }\n\n  if (! -x \"${scriptDir}/$updateScripts{$curVersion}\" ) {\n    main::progress (\"Can't run ${scriptDir}/$updateScripts{$curVersion} - not executable!\\n\");\n    return 1;\n  }\n\n  main::progress (\"Running ${scriptDir}/$updateScripts{$curVersion}\\n\");\n  open(MIG, \"$su \\\"/usr/bin/perl -I${scriptDir} ${scriptDir}/$updateScripts{$curVersion}\\\" 2>&1|\");\n  while (<MIG>) {\n    main::progress($_);\n  }\n  close(MIG);\n  my $rc = $?;\n  if ($rc != 0) {\n    main::progress (\"Script failed with code $rc: $! - exiting\\n\");\n    return $rc;\n  }\n  return 0;\n}\n\nsub getInstalledPackages {\n\n  foreach my $p (@packageList) {\n    if (main::isInstalled($p)) {\n      $installedPackages{$p} = $p;\n    }\n  }\n\n}\n\nsub cleanPostfixLC {\n\n  my ($var,$val);\n  foreach $var (qw(command_directory daemon_directory mailq_path manpage_directory newaliases_path queue_directory sendmail_path)) {\n\n    $val = main::getLocalConfig(\"postfix_${var}\");\n    if ($val =~ /postfix-(\\d.*)\\//) {\n      main::detail(\"Removing $1 from postfix_${var}\");\n      $val =~ s/postfix-\\d.*\\//postfix\\//;\n      main::setLocalConfig(\"postfix_${var}\", \"$val\");\n    }\n  }\n}\n\nsub updateMySQLcnf {\n\n  return if ($mysqlcnfUpdated == 1);\n  my $mycnf = \"/opt/zimbra/conf/my.cnf\";\n  my $mysql_pidfile = main::getLocalConfig(\"mysql_pidfile\");\n  $mysql_pidfile = \"/opt/zimbra/db/mysql.pid\" if ($mysql_pidfile eq \"\");\n  if (-e \"$mycnf\") {\n    unless (open(MYCNF, \"$mycnf\")) {\n      Migrate::myquit(1, \"${mycnf}: $!\\n\");\n    }\n    my @CNF = <MYCNF>;\n    close(MYCNF);\n    my $i=0;\n    my $mycnfChanged = 0;\n    my $tmpfile = \"/tmp/my.cnf.$$\";;\n    my $zimbra_user = qx(${zmlocalconfig} -m nokey zimbra_user 2> /dev/null) || \"zimbra\";;\n    my $zimbra_tmp_directory = qx(${zmlocalconfig} -m nokey zimbra_tmp_directory 2> /dev/null) || \"/opt/zimbra/data/tmp\";\n    open(TMP, \">$tmpfile\");\n    foreach (@CNF) {\n      if (/^port/ && $CNF[$i+1] !~ m/^user/) {\n        print TMP;\n        print TMP \"user         = $zimbra_user\\n\";\n        $mycnfChanged=1;\n        next;\n      } elsif (/^err-log/ && $CNF[$i+1] !~ m/^pid-file/) {\n        print TMP;\n        print TMP \"pid-file = ${mysql_pidfile}\\n\";\n        $mycnfChanged=1;\n        next;\n      } elsif (/^thread_cache\\s+=\\s+(\\d+)$/) {\n        # 29475 fix thread_cache_size\n        if ($1 > 110) {\n          s/^thread_cache/thread_cache_size/g;\n          print TMP;\n        } else {\n          print TMP \"thread_cache_size = 110\\n\";\n          next;\n        }\n        $mycnfChanged=1;\n        next;\n      } elsif (/^thread_cache_size\\s+=\\s+(\\d+)$/) {\n        if ($1 < 110) {\n          $mycnfChanged=1;\n          print TMP \"thread_cache_size = 110\\n\";\n          next;\n        }\n      } elsif (/^max_connections\\s+=\\s+(\\d+)$/) {\n        if ($1 < 110) {\n          $mycnfChanged=1;\n          print TMP \"max_connections = 110\\n\";\n          next;\n        }\n      } elsif (/^skip-external-locking/) {\n        # 19749 remove skip-external-locking\n        print TMP \"external-locking\\n\";\n        $mycnfChanged=1;\n        next;\n     } elsif (/^innodb_open_files/) {\n        # 24906\n        print TMP;\n        print TMP \"innodb_max_dirty_pages_pct = 10\\n\"\n          unless(grep(/^innodb_max_dirty_pages_pct/, @CNF));\n        print TMP \"innodb_flush_method = O_DIRECT\\n\"\n          unless(grep(/^innodb_flush_method/, @CNF));\n        $mycnfChanged=1;\n        next;\n      } elsif (/^user/ && $CNF[$i+1] !~ m/^tmpdir/) {\n        print TMP;\n        print TMP \"tmpdir       = $zimbra_tmp_directory\\n\";\n        $mycnfChanged=1;\n        next;\n      }\n      print TMP;\n      $i++;\n    }\n    close(TMP);\n\n    if ($mycnfChanged) {\n      qx(mv $mycnf ${mycnf}.${startVersion});\n      qx(cp -f $tmpfile $mycnf);\n      qx(chmod 644 $mycnf);\n    }\n  }\n}\n\nsub clearTomcatWorkDir {\n\n  my $workDir = \"/opt/zimbra/tomcat/work\";\n  return unless (-d \"$workDir\");\n  system(\"find $workDir -type f -exec rm -f {} \\\\\\;\");\n\n}\n\nsub clearRedologDir($$) {\n  my ($redologDir, $version) = @_;\n  if (-d \"$redologDir\" && ! -e \"${redologDir}/${version}\") {\n    qx(mkdir ${redologDir}/${version});\n    qx(mv ${redologDir}/* ${redologDir}/${version}/ > /dev/null 2>&1);\n    qx(chown zimbra:zimbra $redologDir > /dev/null 2>&1);\n  }\n  return;\n}\n\nsub clearBackupDir($$) {\n  my ($backupDir, $version) = @_;\n  if (-e \"$backupDir\" && ! -e \"${backupDir}/${version}\") {\n    qx(mkdir ${backupDir}/${version});\n    qx(mv ${backupDir}/* ${backupDir}/${version} > /dev/null 2>&1);\n    qx(chown zimbra:zimbra $backupDir > /dev/null 2>&1);\n  }\n  return;\n}\n\nsub doMysql55Upgrade {\n    my $mysql_mycnf = main::getLocalConfig(\"mysql_mycnf\");\n    my $zimbra_log_directory = main::getLocalConfig(\"zimbra_log_directory\") || \"/opt/zimbra/log\";\n    main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion} --section=mysqld --unset --key=ignore-builtin-innodb ${mysql_mycnf}\");\n    main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion} --section=mysqld --unset --key=plugin-load ${mysql_mycnf}\");\n}\n\nsub doAntiSpamMysql55Upgrade {\n    my $antispam_mysql_mycnf = main::getLocalConfig(\"antispam_mysql_mycnf\");\n    my $zimbra_log_directory = main::getLocalConfig(\"zimbra_log_directory\") || \"/opt/zimbra/log\";\n    if ( -e ${antispam_mysql_mycnf} ) {\n        main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion} --section=mysqld --unset --key=ignore-builtin-innodb ${antispam_mysql_mycnf}\");\n        main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion} --section=mysqld --unset --key=plugin-load ${antispam_mysql_mycnf}\");\n    }\n}\n\nsub doMysql56Upgrade {\n    my $mysql_mycnf = main::getLocalConfig(\"mysql_mycnf\");\n    my $zimbra_log_directory = main::getLocalConfig(\"zimbra_log_directory\") || \"/opt/zimbra/log\";\n    main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-table_cache-fixup --section=mysqld --key=table_cache --unset ${mysql_mycnf}\");\n    main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-table_open_cache-fixup --section=mysqld --key=table_open_cache --setmin --value=1200 ${mysql_mycnf}\");\n    main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-innodb_data_file_path-fixup --section=mysqld --set --key=innodb_data_file_path --value=ibdata1:10M:autoextend ${mysql_mycnf}\");\n    main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-long-query-time-fixup --section=mysqld --unset --key=long-query-time ${mysql_mycnf}\");\n    main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-long_query_time-fixup --section=mysqld --set --key=long_query_time --value=1 ${mysql_mycnf}\");\n    main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-log-queries-not-using-indexes-fixup --section=mysqld --unset --key=log-queries-not-using-indexes ${mysql_mycnf}\");\n    main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-log_queries_not_using_indexes-fixup --section=mysqld --set --key=log_queries_not_using_indexes ${mysql_mycnf}\");\n}\n\nsub doMariaDB101Upgrade {\n    my $mysql_mycnf = main::getLocalConfig(\"mysql_mycnf\");\n    main::deleteLocalConfig(\"mysql_socket\");\n    main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-mysql_socket --section=mysqld --key=socket --set --value='/opt/zimbra/data/tmp/mysql/mysql.sock' ${mysql_mycnf}\");\n    main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-mysql_pidfile --section=mysqld --key=pid-file --set --value='/opt/zimbra/log/mysql.pid' ${mysql_mycnf}\");\n    main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-mysql_pidfile --section=mysqld_safe --key=pid-file --set --value='/opt/zimbra/log/mysql.pid' ${mysql_mycnf}\");\n    main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-mysql_basedir --section=mysqld --key=basedir --set --value='/opt/zimbra/common' ${mysql_mycnf}\");\n    main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-error-log --section=mysqld_safe --key=err-log --unset ${mysql_mycnf}\");\n    main::runAsZimbra(\"/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-error-log --section=mysqld_safe --key=log-error --set --value=/opt/zimbra/log/mysqld.log ${mysql_mycnf}\");\n}\n\nsub doMysqlUpgrade {\n    my $db_pass = main::getLocalConfig(\"mysql_root_password\");\n    my $zimbra_tmp = main::getLocalConfig(\"zimbra_tmp_directory\") || \"/opt/zimbra/data/tmp\";\n    my $mysql_socket = main::getLocalConfig(\"mysql_socket\");\n    my $mysql_mycnf = main::getLocalConfig(\"mysql_mycnf\");\n    my $mysqlUpgrade = \"/opt/zimbra/common/bin/mysql_upgrade\";\n    my $cmd = \"$mysqlUpgrade --defaults-file=$mysql_mycnf -S $mysql_socket --user=root --password=$db_pass\";\n    main::progress(\"Running mysql_upgrade...\");\n    main::runAsZimbra(\"$cmd > ${zimbra_tmp}/mysql_upgrade.out 2>&1\");\n    main::progress(\"done.\\n\");\n}\n\nsub doBackupRestoreVersionUpdate($) {\n  my ($startVersion) = @_;\n\n  my ($prevRedologVersion,$currentRedologVersion,$prevBackupVersion,$currentBackupVersion);\n  $prevRedologVersion = &Migrate::getRedologVersion;\n  $currentRedologVersion = qx($su \"zmjava com.zimbra.cs.redolog.util.GetVersion\");\n  chomp($currentRedologVersion);\n\n  return unless ($currentRedologVersion);\n\n  Migrate::insertRedologVersion($currentRedologVersion)\n    if ($prevRedologVersion eq \"\");\n\n  if ($prevRedologVersion != $currentRedologVersion) {\n    main::progress(\"Redolog version update required.\\n\");\n    Migrate::updateRedologVersion($prevRedologVersion,$currentRedologVersion);\n    main::progress(\"Redolog version update finished.\\n\");\n  }\n\n  if (-f \"/opt/zimbra/lib/ext/backup/zimbrabackup.jar\") {\n    $prevBackupVersion = &Migrate::getBackupVersion;\n    $currentBackupVersion = qx($su \"zmjava com.zimbra.cs.backup.util.GetVersion\");\n    chomp($currentBackupVersion);\n\n    return unless ($currentBackupVersion);\n\n    Migrate::insertBackupVersion($currentBackupVersion)\n      if ($prevBackupVersion eq \"\");\n\n    if ($prevBackupVersion != $currentBackupVersion) {\n      main::progress(\"Backup version update required.\\n\");\n      Migrate::updateBackupVersion($prevBackupVersion,$currentBackupVersion);\n      main::progress(\"Backup version update finished.\\n\");\n    }\n  }\n  my ($currentMajorBackupVersion,$currentMinorBackupVersion) = split(/\\./, $currentBackupVersion);\n  my ($prevMajorBackupVersion,$prevMinorBackupVersion) = split(/\\./, $prevBackupVersion);\n\n  # clear both directories only if the major backup version changed.\n  # backups are backwards compatible between minor versions\n  return if ($prevBackupVersion == $currentBackupVersion);\n  return if ($prevMajorBackupVersion >= $currentMajorBackupVersion);\n\n  main::progress(\"Moving /opt/zimbra/backup/* to /opt/zimbra/backup/${startVersion}-${currentBackupVersion}.\\n\");\n  clearBackupDir(\"/opt/zimbra/backup\", \"${startVersion}-${currentBackupVersion}\");\n  main::progress(\"Moving /opt/zimbra/redolog/* to /opt/zimbra/redolog/${startVersion}-${currentRedologVersion}.\\n\");\n  clearRedologDir(\"/opt/zimbra/redolog\", \"${startVersion}-${currentRedologVersion}\");\n\n}\n\nsub migrateTomcatLCKey {\n  my ($key,$defVal) = @_;\n  $defVal=\"\" unless $defVal;\n  my ($oldKey,$newKey,$oldVal);\n  $oldKey=\"tomcat_${key}\";\n  $newKey=\"mailboxd_${key}\";\n  $oldVal = main::getLocalConfig($oldKey);\n  if ($oldVal ne \"\") {\n    main::setLocalConfig(\"$newKey\", \"$oldVal\");\n  } elsif ($defVal ne \"\") {\n    main::setLocalConfig(\"$newKey\", \"$defVal\");\n  }\n  main::deleteLocalConfig(\"$oldKey\");\n}\n\nsub indexLdap {\n  if (main::isInstalled (\"zimbra-ldap\")) {\n    stopLdap();\n    main::runAsZimbra (\"/opt/zimbra/libexec/zmslapindex\");\n    if (startLdap()) {return 1;}\n  }\n  return;\n}\n\nsub indexLdapAttribute {\n  my ($key) = @_;\n  if (main::isInstalled (\"zimbra-ldap\")) {\n    stopLdap();\n    main::runAsZimbra (\"/opt/zimbra/libexec/zmslapindex $key\");\n    if (startLdap()) {return 1;}\n  }\n  return;\n}\n\nsub reloadLdap($) {\n  my ($upgradeVersion) = @_;\n  if (main::isInstalled (\"zimbra-ldap\")) {\n    if($main::migratedStatus{\"LdapReloaded$upgradeVersion\"} ne \"CONFIGURED\") {\n      my $ldifFile=\"/opt/zimbra/data/ldap/ldap-accesslog.bak\";\n      if (-d '/opt/zimbra/data/ldap/config/cn=config/olcDatabase={3}mdb') {\n        if (-f $ldifFile && -s $ldifFile) {\n          if (-d \"/opt/zimbra/data/ldap/accesslog\") {\n            main::progress(\"Loading accesslog DB...\");\n            if (-d \"/opt/zimbra/data/ldap/accesslog.prev\") {\n              qx(mv /opt/zimbra/data/ldap/accesslog.prev /opt/zimbra/data/ldap/accesslog.prev.$$);\n            }\n            qx(mv /opt/zimbra/data/ldap/accesslog /opt/zimbra/data/ldap/accesslog.prev);\n            qx(mkdir -p /opt/zimbra/data/ldap/accesslog/db);\n            qx(chown -R zimbra:zimbra /opt/zimbra/data/ldap);\n            my $rc;\n            $rc=main::runAsZimbra(\"/opt/zimbra/libexec/zmslapadd -a $ldifFile\");\n            if ($rc != 0) {\n              main::progress(\"slapadd import of accesslog db failed.\\n\");\n              return 1;\n            }\n            main::progress(\"done.\\n\");\n          }\n        } else {\n          main::progress(\"Creating new accesslog DB...\");\n          if (-d \"/opt/zimbra/data/ldap/accesslog.prev\") {\n            qx(mv /opt/zimbra/data/ldap/accesslog.prev /opt/zimbra/data/ldap/accesslog.prev.$$);\n          }\n          qx(mv /opt/zimbra/data/ldap/accesslog /opt/zimbra/data/ldap/accesslog.prev);\n          qx(mkdir -p /opt/zimbra/data/ldap/accesslog/db);\n          qx(chown -R zimbra:zimbra /opt/zimbra/data/ldap);\n          main::progress(\"done.\\n\");\n        }\n      }\n      $ldifFile=\"/opt/zimbra/data/ldap/ldap.bak\";\n      if (-f $ldifFile && -s $ldifFile) {\n        main::progress(\"Loading database...\");\n        if (-d \"/opt/zimbra/data/ldap/mdb.prev\") {\n          qx(mv /opt/zimbra/data/ldap/mdb.prev /opt/zimbra/data/ldap/mdb.prev.$$);\n        }\n        qx(mv /opt/zimbra/data/ldap/mdb /opt/zimbra/data/ldap/mdb.prev);\n        qx(mkdir -p /opt/zimbra/data/ldap/mdb/db);\n        qx(chown -R zimbra:zimbra /opt/zimbra/data/ldap);\n        my $rc;\n        $rc=main::runAsZimbra(\"/opt/zimbra/libexec/zmslapadd $ldifFile\");\n        if ($rc != 0) {\n          main::progress(\"slapadd import failed.\\n\");\n          return 1;\n        }\n        chmod 0640, $ldifFile;\n        main::progress(\"done.\\n\");\n      } else {\n        if (! -f $ldifFile) {\n          main::progress(\"Error: Unable to find /opt/zimbra/data/ldap/ldap.bak\\n\");\n        } else {\n          main::progress(\"Error: /opt/zimbra/data/ldap/ldap.bak is empty\\n\");\n        }\n        return 1;\n      }\n      main::configLog(\"LdapUpgraded$upgradeVersion\");\n    }\n    if (startLdap()) {return 1;}\n  }\n  return 0;\n}\n\nsub upgradeLdap($) {\n  my ($upgradeVersion) = @_;\n  if (main::isInstalled (\"zimbra-ldap\")) {\n    if($upgradeVersion eq \"8.7.0_BETA2\") {\n      if($main::migratedStatus{\"LdapUpgraded$upgradeVersion\"} ne \"CONFIGURED\") {\n        if (-f '/opt/zimbra/data/ldap/config/cn=config/cn=module{0}.ldif') {\n          my $infile=\"/opt/zimbra/data/ldap/config/cn\\=config/cn\\=module\\{0\\}.ldif\";\n          my $outfile=\"/tmp/mod0.ldif.$$\";\n          open(IN,\"<$infile\");\n          open(OUT,\">$outfile\");\n          while(<IN>) {\n            if ($_ =~ /^olcModulePath: \\/opt\\/zimbra\\/openldap\\/sbin\\/openldap/) {\n              print OUT \"olcModulePath: \\/opt\\/zimbra\\/common\\/libexec\\/openldap\\n\";\n              next;\n            }\n            if ($_ =~ /^# CRC32/) {\n              next;\n            }\n            print OUT $_;\n          }\n          close(OUT);\n          close(IN);\n          qx(mv $outfile $infile);\n          qx(chown zimbra:zimbra $infile);\n        }\n        main::configLog(\"LdapUpgraded$upgradeVersion\");\n      }\n    } elsif($upgradeVersion eq \"8.5.0_BETA1\") {\n      if($main::migratedStatus{\"LdapUpgraded$upgradeVersion\"} ne \"CONFIGURED\") {\n        unlink(\"/opt/zimbra/data/ldap/config/cn\\=config/cn\\=schema/cn\\=\\{7\\}pgp-keyserver.ldif\");\n        if (-f '/opt/zimbra/data/ldap/config/cn=config.ldif') {\n          my $infile=\"/opt/zimbra/data/ldap/config/cn\\=config.ldif\";\n          my $outfile=\"/tmp/config.ldif.$$\";\n          open(IN,\"<$infile\");\n          open(OUT,\">$outfile\");\n          while(<IN>) {\n            if ($_ =~ /^olcPidFile: /) {\n              print OUT \"olcPidFile: /opt/zimbra/data/ldap/state/run/slapd.pid\\n\";\n              next;\n            }\n            if ($_ =~ /^olcArgsFile: /) {\n              print OUT \"olcArgsFile: /opt/zimbra/data/ldap/state/run/slapd.args\\n\";\n              next;\n            }\n            if ($_ =~ /^# CRC32/) {\n              next;\n            }\n            print OUT $_;\n          }\n          close(OUT);\n          close(IN);\n          qx(mv $outfile $infile);\n        }\n        if (-f '/opt/zimbra/data/ldap/config/cn=config/cn=module{0}.ldif') {\n          my $infile=\"/opt/zimbra/data/ldap/config/cn\\=config/cn\\=module\\{0\\}.ldif\";\n          my $outfile=\"/tmp/mod0.ldif.$$\";\n          open(IN,\"<$infile\");\n          open(OUT,\">$outfile\");\n          while(<IN>) {\n            if ($_ =~ /^olcModulePath: \\/opt\\/zimbra\\/openldap\\/sbin\\/openldap/) {\n              print OUT \"olcModulePath: \\/opt\\/zimbra\\/common\\/libexec\\/openldap\\n\";\n              next;\n            }\n            if ($_ =~ /^# CRC32/) {\n              next;\n            }\n            print OUT $_;\n          }\n          close(OUT);\n          close(IN);\n          qx(mv $outfile $infile);\n          qx(chown zimbra:zimbra $infile);\n        }\n        main::configLog(\"LdapUpgraded$upgradeVersion\");\n      }\n    } else {\n      if($main::migratedStatus{\"LdapUpgraded$upgradeVersion\"} ne \"CONFIGURED\") {\n        # Fix LDAP schema for bug#62443\n        unlink(\"/opt/zimbra/data/ldap/config/cn\\=config/cn\\=schema/cn\\=\\{3\\}zimbra.ldif\");\n        unlink(\"/opt/zimbra/data/ldap/config/cn\\=config/cn\\=schema/cn\\=\\{4\\}amavisd.ldif\");\n        unlink(\"/opt/zimbra/data/ldap/config/cn\\=config/cn\\=schema/cn\\=\\{7\\}pgp-keyserver.ldif\");\n        my $ldifFile=\"/opt/zimbra/data/ldap/ldap.bak\";\n        if (-f $ldifFile && -s $ldifFile) {\n          chmod 0644, $ldifFile;\n          my $slapinfile = \"$ldifFile\";\n          my $slapoutfile = \"/opt/zimbra/data/ldap/ldap.80\";\n          main::progress(\"Upgrading ldap data...\");\n          open(IN,\"<$slapinfile\");\n          open(OUT,\">$slapoutfile\");\n          while(<IN>) {\n            if ($_ =~ /^zimbraChildAccount:/) {next;}\n            if ($_ =~ /^zimbraChildVisibleAccount:/) {next;}\n            if ($_ =~ /^zimbraPrefChildVisibleAccount:/) {next;}\n            if ($_ =~ /^zimbraPrefStandardClientAccessilbityMode:/) {next;}\n            if ($_ =~ /^objectClass: zimbraHsmGlobalConfig/) {next;}\n            if ($_ =~ /^objectClass: zimbraHsmServer/) {next;}\n            if ($_ =~ /^objectClass: organizationalPerson/) {\n              print OUT $_;\n              print OUT \"objectClass: inetOrgPerson\\n\";\n              next;\n            }\n            if ($_ =~ /^structuralObjectClass: organizationalPerson/) {\n              $_ =~ s/organizationalPerson/inetOrgPerson/;\n            }\n            print OUT $_;\n          }\n          close(IN);\n          close(OUT);\n          main::progress(\"done.\\n\");\n          my $infile;\n          my $outfile;\n          main::progress(\"Upgrading LDAP configuration database...\");\n          if (-d '/opt/zimbra/data/ldap/config/cn=config/olcDatabase={2}hdb') {\n            qx(mv /opt/zimbra/data/ldap/config/cn\\=config/olcDatabase\\=\\{2\\}hdb /opt/zimbra/data/ldap/config/cn\\=config/olcDatabase\\=\\{2\\}mdb);\n          }\n          if (-d '/opt/zimbra/data/ldap/config/cn=config/olcDatabase={3}hdb') {\n            qx(mv /opt/zimbra/data/ldap/config/cn\\=config/olcDatabase\\=\\{3\\}hdb /opt/zimbra/data/ldap/config/cn\\=config/olcDatabase\\=\\{3\\}mdb);\n            $infile=glob(\"/opt/zimbra/data/ldap/config/cn=config/olcDatabase=\\\\{3\\\\}mdb/olcOverlay=\\\\{*\\\\}syncprov.ldif\");\n            $outfile=\"/tmp/3syncprov.ldif.$$\";\n            open(IN,\"<$infile\");\n            open(OUT,\">$outfile\");\n            while(<IN>) {\n              if ($_ =~ /olcSpSessionlog:/) {\n                next;\n              }\n              if ($_ =~ /^# CRC32/) {\n                next;\n              }\n              print OUT $_;\n            }\n            close(OUT);\n            close(IN);\n            qx(mv $outfile $infile);\n          }\n          if (-f '/opt/zimbra/data/ldap/config/cn=config/cn=module{0}.ldif') {\n            $infile=\"/opt/zimbra/data/ldap/config/cn\\=config/cn\\=module\\{0\\}.ldif\";\n            $outfile=\"/tmp/mod0.ldif.$$\";\n            open(IN,\"<$infile\");\n            open(OUT,\">$outfile\");\n            while(<IN>) {\n              if ($_ =~ /^olcModuleLoad: \\{0\\}back_hdb.la/) {\n                print OUT \"olcModuleLoad: {0}back_mdb.la\\n\";\n                next;\n              }\n              if ($_ =~ /^olcModulePath: \\/opt\\/zimbra\\/openldap\\/sbin\\/openldap/) {\n                print OUT \"olcModulePath: \\/opt\\/zimbra\\/common\\/libexec\\/openldap\\n\";\n                next;\n              }\n              if ($_ =~ /^# CRC32/) {\n                next;\n              }\n              print OUT $_;\n            }\n            close(OUT);\n            close(IN);\n            qx(mv $outfile $infile);\n            qx(chown zimbra:zimbra $infile);\n          }\n          if (-f '/opt/zimbra/data/ldap/config/cn=config.ldif') {\n            $infile=\"/opt/zimbra/data/ldap/config/cn\\=config.ldif\";\n            $outfile=\"/tmp/config.ldif.$$\";\n            open(IN,\"<$infile\");\n            open(OUT,\">$outfile\");\n            while(<IN>) {\n              if ($_ =~ /^olcToolThreads: /) {\n                print OUT \"olcToolThreads: 2\\n\";\n                next;\n              }\n              if ($_ =~ /^olcPidFile: /) {\n                print OUT \"olcPidFile: /opt/zimbra/data/ldap/state/run/slapd.pid\\n\";\n                next;\n              }\n              if ($_ =~ /^olcArgsFile: /) {\n                print OUT \"olcArgsFile: /opt/zimbra/data/ldap/state/run/slapd.args\\n\";\n                next;\n              }\n              if ($_ =~ /^# CRC32/) {\n                next;\n              }\n              print OUT $_;\n            }\n            close(OUT);\n            close(IN);\n            qx(mv $outfile $infile);\n          }\n          if (-f '/opt/zimbra/data/ldap/config/cn=config/olcDatabase={3}hdb.ldif') {\n            qx(mv /opt/zimbra/data/ldap/config/cn\\=config/olcDatabase\\=\\{3\\}hdb.ldif /opt/zimbra/data/ldap/config/cn\\=config/olcDatabase=\\{3\\}mdb.ldif);\n            $infile=\"/opt/zimbra/data/ldap/config/cn\\=config/olcDatabase\\=\\{3\\}mdb.ldif\";\n            $outfile=\"/tmp/3mdb.ldif.$$\";\n            open(IN,\"<$infile\");\n            open(OUT,\">$outfile\");\n            while(<IN>) {\n              if ($_ =~ /^dn: olcDatabase=\\{3\\}hdb/) {\n                print OUT \"dn: olcDatabase={3}mdb\\n\";\n                next;\n              }\n              if ($_ =~ /^objectClass: olcHdbConfig/) {\n                print OUT \"objectClass: olcMdbConfig\\n\";\n                next;\n              }\n              if ($_ =~ /^olcDatabase: \\{3\\}hdb/) {\n                print OUT \"olcDatabase: {3}mdb\\n\";\n                next;\n              }\n              if ($_ =~ /^olcDbDirectory: \\/opt\\/zimbra\\/data\\/ldap\\/hdb\\/db/) {\n                print OUT \"olcDbDirectory: /opt/zimbra/data/ldap/mdb/db\\n\";\n                next;\n              }\n              if ($_ =~ /^structuralObjectClass: olcHdbConfig/) {\n                print OUT \"structuralObjectClass: olcMdbConfig\\n\";\n                next;\n              }\n              if ($_ =~ /^olcDbMode:/) {\n                print OUT $_;\n                print OUT \"olcDbMaxsize: 85899345920\\n\";\n                next;\n              }\n              if ($_ =~ /^olcDbCheckpoint:/) {\n                print OUT \"olcDbCheckpoint: 0 0\\n\";\n                print OUT \"olcDbEnvFlags: writemap\\n\";\n                print OUT \"olcDbEnvFlags: nometasync\\n\";\n                next;\n              }\n              if ($_ =~ /olcDbNoSync:/) {\n                print OUT \"olcDbNoSync: TRUE\\n\";\n                next;\n              }\n              if ($_ =~ /olcDbCacheSize:/) {\n                next;\n              }\n              if ($_ =~ /^olcDbConfig:/) {\n                next;\n              }\n              if ($_ =~ /^olcDbDirtyRead:/) {\n                next;\n              }\n              if ($_ =~ /^olcDbIDLcacheSize:/) {\n                next;\n              }\n              if ($_ =~ /^olcDbLinearIndex:/) {\n                next;\n              }\n              if ($_ =~ /^olcDbShmKey:/) {\n                next;\n              }\n              if ($_ =~ /^olcDbCacheFree:/) {\n                next;\n              }\n              if ($_ =~ /^olcDbDNcacheSize:/) {\n                next;\n              }\n              if ($_ =~ /^# CRC32/) {\n                next;\n              }\n              print OUT $_;\n            }\n            close(OUT);\n            close(IN);\n            qx(mv $outfile $infile);\n          }\n          if (-f '/opt/zimbra/data/ldap/config/cn=config/olcDatabase={2}hdb.ldif') {\n            qx(mv /opt/zimbra/data/ldap/config/cn\\=config/olcDatabase\\=\\{2\\}hdb.ldif /opt/zimbra/data/ldap/config/cn\\=config/olcDatabase\\=\\{2\\}mdb.ldif);\n            $infile=\"/opt/zimbra/data/ldap/config/cn\\=config/olcDatabase\\=\\{2\\}mdb.ldif\";\n            $outfile=\"/tmp/2mdb.ldif.$$\";\n            open(IN,\"<$infile\");\n            open(OUT,\">$outfile\");\n            while(<IN>) {\n              if ($_ =~ /^dn: olcDatabase=\\{2\\}hdb/) {\n                print OUT \"dn: olcDatabase={2}mdb\\n\";\n                next;\n              }\n              if ($_ =~ /^objectClass: olcHdbConfig/) {\n                print OUT \"objectClass: olcMdbConfig\\n\";\n                next;\n              }\n              if ($_ =~ /^olcDatabase: \\{2\\}hdb/) {\n                print OUT \"olcDatabase: {2}mdb\\n\";\n                next;\n              }\n              if ($_ =~ /^olcDbDirectory: \\/opt\\/zimbra\\/data\\/ldap\\/hdb\\/db/) {\n                print OUT \"olcDbDirectory: /opt/zimbra/data/ldap/mdb/db\\n\";\n                next;\n              }\n              if ($_ =~ /^structuralObjectClass: olcHdbConfig/) {\n                print OUT \"structuralObjectClass: olcMdbConfig\\n\";\n                next;\n              }\n              if ($_ =~ /^olcDbMode:/) {\n                print OUT $_;\n                print OUT \"olcDbMaxsize: 85899345920\\n\";\n                next;\n              }\n              if ($_ =~ /^olcDbCheckpoint:/) {\n                print OUT \"olcDbCheckpoint: 0 0\\n\";\n                print OUT \"olcDbEnvFlags: writemap\\n\";\n                print OUT \"olcDbEnvFlags: nometasync\\n\";\n                next;\n              }\n              if ($_ =~ /olcDbNoSync:/) {\n                print OUT \"olcDbNoSync: TRUE\\n\";\n                next;\n              }\n              if ($_ =~ /olcDbCacheSize:/) {\n                next;\n              }\n              if ($_ =~ /^olcDbConfig:/) {\n                next;\n              }\n              if ($_ =~ /^olcDbDirtyRead:/) {\n                next;\n              }\n              if ($_ =~ /^olcDbIDLcacheSize:/) {\n                next;\n              }\n              if ($_ =~ /^olcDbLinearIndex:/) {\n                next;\n              }\n              if ($_ =~ /^olcDbShmKey:/) {\n                next;\n              }\n              if ($_ =~ /^olcDbCacheFree:/) {\n                next;\n              }\n              if ($_ =~ /^olcDbDNcacheSize:/) {\n                next;\n              }\n              if ($_ =~ /^# CRC32/) {\n                next;\n              }\n              print OUT $_;\n            }\n            close(OUT);\n            close(IN);\n            qx(mv $outfile $infile);\n          }\n          main::progress(\"done.\\n\");\n\n          if (-d \"/opt/zimbra/data/ldap/accesslog\") {\n            main::progress(\"Creating new accesslog DB...\");\n            if (-d \"/opt/zimbra/data/ldap/accesslog.prev\") {\n              qx(mv /opt/zimbra/data/ldap/accesslog.prev /opt/zimbra/data/ldap/accesslog.prev.$$);\n            }\n            qx(mv /opt/zimbra/data/ldap/accesslog /opt/zimbra/data/ldap/accesslog.prev);\n            qx(mkdir -p /opt/zimbra/data/ldap/accesslog/db);\n            qx(chown -R zimbra:zimbra /opt/zimbra/data/ldap);\n            main::progress(\"done.\\n\");\n          }\n\n          main::progress(\"Loading database...\");\n          if (-d \"/opt/zimbra/data/ldap/mdb.prev\") {\n            qx(mv /opt/zimbra/data/ldap/mdb.prev /opt/zimbra/data/ldap/mdb.prev.$$);\n          }\n          qx(mv /opt/zimbra/data/ldap/mdb /opt/zimbra/data/ldap/mdb.prev);\n          qx(mkdir -p /opt/zimbra/data/ldap/mdb/db);\n          qx(chown -R zimbra:zimbra /opt/zimbra/data/ldap);\n          my $rc;\n          $rc=main::runAsZimbra(\"/opt/zimbra/libexec/zmslapadd $slapoutfile\");\n          if ($rc != 0) {\n            main::progress(\"slapadd import failed.\\n\");\n            return 1;\n          }\n          chmod 0640, $ldifFile;\n          main::progress(\"done.\\n\");\n        } else {\n          if (! -f $ldifFile) {\n            main::progress(\"Error: Unable to find /opt/zimbra/data/ldap/ldap.bak\\n\");\n          } else {\n            main::progress(\"Error: /opt/zimbra/data/ldap/ldap.bak is empty\\n\");\n          }\n          return 1;\n        }\n        main::configLog(\"LdapUpgraded$upgradeVersion\");\n      }\n    }\n    if (startLdap()) {return 1;}\n  }\n  return 0;\n}\n\nsub migrateLdap($) {\n  my ($migrateVersion) = @_;\n  if (main::isInstalled (\"zimbra-ldap\")) {\n    if($main::migratedStatus{\"LdapUpgraded$migrateVersion\"} ne \"CONFIGURED\") {\n      if (-f \"/opt/zimbra/data/ldap/ldap.bak\") {\n        my $infile = \"/opt/zimbra/data/ldap/ldap.bak\";\n        my $outfile = \"/opt/zimbra/data/ldap/ldap.80\";\n        if ( -s $infile ) {\n          open(IN,\"<$infile\");\n          open(OUT,\">$outfile\");\n          while(<IN>) {\n            if ($_ =~ /^zimbraChildAccount:/) {next;}\n            if ($_ =~ /^zimbraChildVisibleAccount:/) {next;}\n            if ($_ =~ /^zimbraPrefChildVisibleAccount:/) {next;}\n            if ($_ =~ /^zimbraPrefStandardClientAccessilbityMode:/) {next;}\n            if ($_ =~ /^objectClass: zimbraHsmGlobalConfig/) {next;}\n            if ($_ =~ /^objectClass: zimbraHsmServer/) {next;}\n            if ($_ =~ /^objectClass: organizationalPerson/) {\n              print OUT $_;\n              print OUT \"objectClass: inetOrgPerson\\n\";\n              next;\n            }\n            if ($_ =~ /^structuralObjectClass: organizationalPerson/) {\n              $_ =~ s/organizationalPerson/inetOrgPerson/;\n            }\n            print OUT $_;\n          }\n          close(IN);\n          close(OUT);\n        } else {\n          main::progress(\"LDAP backup file /opt/zimbra/data/ldap/ldap.bak is empty.\\n\");\n          main::progress(\"Valid LDAP backup file not found, exiting.\\n\");\n          return 1;\n        }\n        chmod 0644, $outfile if ( -s $outfile );\n\n        main::installLdapConfig();\n\n        main::progress(\"Migrating ldap data...\");\n        if (-d \"/opt/zimbra/data/ldap/mdb.prev\") {\n          qx(mv /opt/zimbra/data/ldap/mdb.prev /opt/zimbra/data/ldap/mdb.prev.$$);\n        }\n\n        qx(mv /opt/zimbra/data/ldap/mdb /opt/zimbra/data/ldap/mdb.prev);\n        qx(mkdir -p /opt/zimbra/data/ldap/mdb/db);\n        qx(chown -R zimbra:zimbra /opt/zimbra/data/ldap);\n        my $rc;\n        $rc=main::runAsZimbra(\"/opt/zimbra/libexec/zmslapadd $outfile\");\n        if ($rc != 0) {\n          main::progress(\"slapadd import failed.\\n\");\n          return 1;\n        }\n        chmod 0640, \"/opt/zimbra/data/ldap/ldap.bak\";\n        main::progress(\"done.\\n\");\n      } else {\n        stopLdap();\n        main::progress(\"Running slapindex...\");\n        my $rc = main::runAsZimbra(\"/opt/zimbra/libexec/zmslapindex\");\n        main::progress(($rc == 0) ? \"done.\\n\" : \"failed.\\n\");\n      }\n      main::configLog(\"LdapUpgraded$migrateVersion\");\n    }\n    if (startLdap()) {return 1;}\n  }\n  return 0;\n}\n\n# DeleteLdapTree\n# Requires Net::LDAP ref and DN\n# Returns Net::LDAP::Search ref\nsub DeleteLdapTree {\n  my ($handle, $dn) = @_;\n\n  # make sure it exists and get all the entries\n  my $result = $handle->search( base => $dn, scope => 'one', filter => \"(objectclass=*)\");\n  return $result if ($result->code());\n\n  # loop through the entries and recursively delete them\n  foreach my $entry($result->all_entries) {\n    my $ref = DeleteLdapTree($handle, $entry->dn());\n    return $ref if ($ref->code());\n  }\n\n  $result = $handle->delete($dn);\n  return $result;\n}\n\nsub migrateAmavisDB($) {\n  my ($toVersion) = @_;\n  my $amavisdBase = \"/opt/zimbra/amavisd-new\";\n  my $toDir = \"${amavisdBase}-$toVersion\";\n  main::progress(\"Migrating amavisd-new to version $toVersion\\n\");\n  foreach my $fromVersion (qw(2.5.2 2.4.3 2.4.1 2.3.3 2.3.1)) {\n    next if ($toVersion eq $fromVersion);\n    my $fromDir = \"${amavisdBase}-$fromVersion\";\n    main::progress(\"Checking $fromDir/db\\n\");\n    if ( -d \"$fromDir/db\" && -d \"$toDir\" && ! -e \"$toDir/db/cache.db\") {\n      main::progress(\"Migrating amavis-new db from version $fromVersion to $toVersion\\n\");\n      qx(rm -rf $toDir/db > /dev/null 2>&1);\n      qx(mv $fromDir/db $toDir/db);\n      qx(chown zimbra:zimbra $toDir/db);\n    }\n    main::progress(\"Checking $fromDir/.spamassassin\\n\");\n    if (-d \"$fromDir/.spamassassin/\" && -d \"$toDir\" && ! -e \"$toDir/.spamassassin/bayes_toks\" ) {\n      main::progress(\"Migrating amavis-new .spamassassin from version $fromVersion to $toVersion\\n\");\n      qx(rm -rf $toDir/.spamassassin > /dev/null 2>&1);\n      qx(mv $fromDir/.spamassassin $toDir/.spamassassin);\n      qx(chown zimbra:zimbra $toDir/.spamassassin);\n    }\n  }\n}\n\nsub relocateAmavisDB() {\n  my $toDir = \"/opt/zimbra/data/amavisd\";\n  my $fromDir = \"/opt/zimbra/amavisd-new-2.5.2\";\n  main::progress(\"Migrating Amavis database directory\\n\");\n  if ( -d \"$fromDir/db\" && -d \"$toDir\" && ! -e \"$toDir/db/cache.db\") {\n    qx(rm -rf $toDir/db > /dev/null 2>&1);\n    qx(mv $fromDir/db $toDir/db);\n    qx(chown zimbra:zimbra $toDir/db);\n  }\n  if (-d \"$fromDir/.spamassassin/\" && -d \"$toDir\" && ! -e \"$toDir/.spamassassain/bayes_toks\" ) {\n    qx(rm -rf $toDir/.spamassassin > /dev/null 2>&1);\n    qx(mv $fromDir/.spamassassin $toDir/.spamassassin);\n    qx(chown zimbra:zimbra $toDir/.spamassassin);\n  }\n}\n\nsub verifyDatabaseIntegrity {\n  if (-x \"/opt/zimbra/libexec/zmdbintegrityreport\") {\n    main::progress(\"Verifying integrity of databases.\\n\");\n    main::runAsZimbra(\"/opt/zimbra/libexec/zmdbintegrityreport -v -r\");\n  }\n  return;\n}\n\nsub upgradeAllGlobalAdminAccounts {\n\n  my @admins = qx($su \"$ZMPROV gaaa\");\n  main::detail(\"Upgrading ACLs for all admin accounts.\\n\");\n  my @adminUpgrades;\n  foreach my $admin (@admins) {\n    chomp $admin;\n    my $val = main::getLdapAccountValue(\"zimbraIsAdminAccount\",$admin);\n    if (lc($val) eq \"true\") {\n      push(@adminUpgrades,$admin);\n      next;\n    }\n  }\n  main::progress(\"Upgrading global admin accounts...\");\n  my $wfh= new FileHandle;\n  my $efh= new FileHandle;\n  my @errors;\n  main::detail(\"Executing $su $ZMPROV\");\n  if (my $pid = open3($wfh,undef,$efh,\"$su \\\"$ZMPROV\\\"\")) {\n    foreach my $admin (@adminUpgrades) {\n      main::detail(\"$ZMPROV ma $admin zimbraAdminConsoleUIComponents cartBlancheUI\");\n      print $wfh \"ma $admin zimbraAdminConsoleUIComponents cartBlancheUI\\n\";\n    }\n    print $wfh \"exit\\n\";\n    @errors = <$efh>;\n    main::detail(\"@errors\") if (scalar(@errors) != 0) ;\n    close($wfh);\n    close($efh);\n    waitpid $pid, 0;\n  }\n  main::progress(($? == 0 && scalar(@errors) == 0) ? \"done.\\n\" : \"failed.\\n\");\n}\n\nsub upgradeLdapConfigValue($$$) {\n  my ($key,$new_value,$cmp_value) = @_;\n  my $current_value = main::getLdapConfigValue($key);\n  if ($new_value eq \"\") {\n      $new_value=\"\\'\\'\";\n  }\n  main::setLdapGlobalConfig($key, $new_value)\n    if ($current_value eq $cmp_value);\n}\n\nsub addLdapIndex($$$) {\n  my ($index, $type) = @_;\n  my $ldap_pass = qx($su \"zmlocalconfig -s -m nokey ldap_root_password\");\n  chomp($ldap_pass);\n  my $ldap;\n  unless($ldap = Net::LDAP->new('ldapi://%2fopt%2fzimbra%2fdata%2fldap%2fstate%2frun%2fldapi/')) {\n    main::progress(\"Unable to connect to ldapi: $!\\n\");\n  }\n  my $result = $ldap->bind(\"cn=config\", password => $ldap_pass);\n  my $dn=\"olcDatabase={2}mdb,cn=config\";\n  if ($isLdapMaster) {\n    $result = $ldap->search(\n                      base=> \"cn=accesslog\",\n                      filter=>\"(objectClass=*)\",\n                      scope => \"base\",\n                      attrs => ['1.1'],\n    );\n    my $size = $result->count;\n    if ($size > 0 ) {\n      $dn=\"olcDatabase={3}mdb,cn=config\";\n    }\n  }\n  $result = $ldap->search(\n    base=> \"$dn\",\n    filter=>\"(objectClass=*)\",\n    scope => \"base\",\n    attrs => ['olcDbIndex'],\n  );\n  my $entry=$result->entry($result->count-1);\n  my @attrvals=$entry->get_value(\"olcDbIndex\");\n  my $hasIndex=0;\n\n  foreach my $attr (@attrvals) {\n    if ($attr =~ /$index/) {\n      $hasIndex=1;\n    }\n  }\n  if (!$hasIndex) {\n    $result = $ldap->modify(\n        $dn,\n        add =>{olcDbIndex=>\"$index $type\"},\n    );\n  }\n  $ldap->unbind;\n  return !$hasIndex;\n}\n\nsub upgradeLocalConfigValue($$$) {\n  my ($key,$new_value,$cmp_value) = @_;\n  my $current_value = main::getLocalConfig($key);\n  main::setLocalConfig(\"$key\", \"$new_value\")\n    if ($current_value eq $cmp_value);\n}\n\nsub runAttributeUpgrade($) {\n  my ($startVersion) = @_;\n  my $rc = main::runAsZimbra(\"zmjava com.zimbra.cs.account.ldap.upgrade.LdapUpgrade -b 27075 -v $startVersion\");\n  return $rc;\n}\n\nsub runLdapAttributeUpgrade($) {\n  my ($bug) = @_;\n  return if ($bug eq \"\");\n  my $rc = main::runAsZimbra(\"zmjava com.zimbra.cs.account.ldap.upgrade.LdapUpgrade -b $bug -v\");\n  return $rc;\n}\n\n1;\n"
  },
  {
    "path": "show_git_overrides.sh",
    "content": "#!/bin/bash\n\nif [ $# -lt 1 ]\nthen\n   echo \"Usage: $0 <cfg|cmd> [remote-branch]\"\n   exit 1\nfi\n\nCDPATH=\nSCRIPT_DIR=\"$(cd \"$(dirname \"$0\")\" && pwd)\"\n\nmain()\n{\n   local CFG=\"$1\"; shift;\n   local BR=\"$1\"; shift;\n\n   local i\n   for i in $SCRIPT_DIR/../*\n   do\n      if [ -d \"$i/.git\" ]; then\n         (\n            cd $i;\n            _J=$( git fetch --all )\n            if [ \"$BR\" ]\n            then\n               LOCAL_BRANCH=$( git branch -r | grep -w \"$BR\" | grep -v -e '->' | sed -e 's,^\\s*,,' -e 's,/, ,' | head -1 | awk '{ print $2 }')\n               REMOTE_BRANCH=$LOCAL_BRANCH\n               REMOTE_NAME=\n               REMOTE_URL=\n               REPO_NAME=$(git remote -v | awk '{ print $2; exit; }' | xargs -n1 '-I{}' -- basename '{}' .git)\n            else\n               LOCAL_BRANCH=$( git branch -vv | grep '^[*]' | sed -e 's/no branch/no-branch/' | awk '{ print $2 }')\n               REMOTE_BRANCH=$(git branch -vv | grep '^[*]' | grep -o '\\[[^]]*\\]' | sed -e 's,:.*\\],],' -e 's,^.,,' -e 's,\\]$,,' -e 's,[^/]*/,,')\n               REMOTE_NAME=$(  git branch -vv | grep '^[*]' | grep -o '\\[[^]]*\\]' | sed -e 's,:.*\\],],' -e 's,^.,,' -e 's,\\]$,,' -e 's,/.*,,')\n               REMOTE_URL=$(   git remote get-url \"$REMOTE_NAME\" 2>/dev/null)\n               REPO_NAME=$(basename \"$REMOTE_URL\" .git)\n            fi\n\n            if [ \"$LOCAL_BRANCH\" == \"(no-branch)\" ] || [ -z \"$LOCAL_BRANCH\" ] || [ -z \"$REPO_NAME\" ]\n            then\n               continue\n            fi\n\n            if [ \"$LOCAL_BRANCH\" != \"develop\" ]\n            then\n               if [ \"$CFG\" == \"cfg\" ]\n               then\n                  echo \"%GIT_OVERRIDES          = ${REPO_NAME}.branch=$LOCAL_BRANCH\"\n               else\n                  echo \"--git-overrides ${REPO_NAME}.branch=$LOCAL_BRANCH\"\n               fi\n            fi\n\n            if [ \"$LOCAL_BRANCH\" != \"$REMOTE_BRANCH\" ] && [ \"$REMOTE_BRANCH\" != \"develop\" ]\n            then\n               if [ \"$CFG\" == \"cfg\" ]\n               then\n                  echo \"%GIT_OVERRIDES          = ${REPO_NAME}.branch=$REMOTE_BRANCH\"\n               else\n                  echo \"# --git-overrides ${REPO_NAME}.branch=$REMOTE_BRANCH\"\n               fi\n            fi\n\n            if [ \"$REMOTE_URL\" ]\n            then\n               if ! grep -q -e \"/Zimbra\" -e \":Zimbra\" -e \"/zimbra/\" <(echo \"$REMOTE_URL\")\n               then\n                  if [ \"$CFG\" == \"cfg\" ]\n                  then\n                     echo \"%GIT_OVERRIDES          = ${REPO_NAME}.remote=my-${REPO_NAME}-rem\"\n                     echo \"%GIT_OVERRIDES          = my-${REPO_NAME}-rem.url-prefix=$REMOTE_URL\"\n                  else\n                     echo \"--git-overrides ${REPO_NAME}.remote=my-${REPO_NAME}-rem\"\n                     echo \"--git-overrides my-${REPO_NAME}-rem.url-prefix=$REMOTE_URL\"\n                  fi\n               fi\n            fi\n         )\n      fi\n   done\n}\n\nmain \"$@\"\n"
  }
]