Uninstalling Symantec Endpoint Anti-virus

zmbarker
Contributor

I am sure there are other methods to uninstall Symantec Anti-virus from a mac via Casper Policy, but this one works for my environment. I just thought I would share.

On your source computer (by source computer, I mean the computer that you use to build all your scripts/pkgs/dmgs)
1. Download the Symantec Removal Tool from Symantec. OLD LINK
[ftp://ftp.symantec.com/misc/tools/mactools/RemoveSymantecMacFiles.zip](ftp://ftp.symantec.com/misc/tools/mactools/RemoveSymantecMacFiles.zip)

  1. Extract the "SymantecRemovalTool.command" file and save it into a folder where you might keep all your scripts on the local computer. In my environment - All my computers have a folder called JAMF-CustomApps within /Library/Application Support/ NOTE: The file cannot be changed to a .sh script, when I tried I got errors.

  2. Now open Composer and drag 'n drop the "SymantecRemovalTool.command" from /Library/Application Support/JAMF-CustomApps/ into Composer window.

  3. Now create a PKG file with Composer, called "SymantecRemovalTool.PKG"

  4. Now open Casper Admin and drag 'n drop the "SymantecRemovalTool.PKG" into Casper Admin.

  5. Once you have saved the file in Casper Admin.

  6. Open the JSS and create a new policy.
    My policy looks like this:
    *General
    *
    policy name = "Uninstall - Symantec Endpoint Anti-virus"
    *Enable
    *
    Execution Frequency = Ongoing
    *Packages = SymantecRemovalTool.pkg *set to Install (Setting to Install will actually copy the .command file to the correct folder location.)
    *Maintenance = Update Inventory
    *
    File&Processes = Execute Command
    **** /Library/Application Support/JAMF-CustomApps/SymantecRemovalTool.command

Now setup Self-Service and you are ready to go.

1 ACCEPTED SOLUTION

zmbarker
Contributor

#!/bin/sh
# File Name: RemoveSymantecMacFiles.command Version=7.0.8
# Author: Corey Swertfager, Symantec Corporation
# Watermark ID: CB70-6840-3597-44-15-4
# Created: 10/04/2001
# Modified: 12/10/2013
#
# WARNING: This script will remove all files and folders created by
# Symantec OS X products (except Symantec Adminstration Console
# for Macintosh files) and any files within those folders.
# Therefore, you will lose ALL files that reside in those folders,
# including any that you have created.
#
# Usage: RemoveSymantecMacFiles.command [options] [volume ...]
#
# Summary: See ShowHelp() function.
#
# History: 5.00 - Ported code from version 4.27.
# Now removes crontab entries from any OS X boot volume.
# Now removes Symantec items from loginwindow.plist files.
# Now removes receipts from any volume.
# Now checks for Symantec kexts/processes in memory when
# determining when a restart is necessary.
# Added -f option to suppress output of removed files.
# Now shows names of files as they are removed, unless the
# -f option is specified.
# 5.01 - Now removes:
# /Library/Contextual Menu Items/SAVCMPlugIn.plugin
# 5.02 - Adjusted output when a folder/file cannot be removed.
# Removed warning when /Library/StartupItems remains.
# Now removes:
# /Library/Application Support/Symantec/Daemon/SymDaemon.bundle
# /Library/Application Support/Symantec/Daemon
# /Library/Application Support/Symantec/SymUIAgent
# /Library/Application Support/Symantec/WebFraud
# /Library/Contextual Menu Items/SymFileSecurityCM.plugin
# /Library/PrivateFrameworks/SymAppKitAdditions.framework
# /Library/PrivateFrameworks/SymBase.framework
# /Library/PrivateFrameworks/SymConfidential.framework
# /Library/PrivateFrameworks/SymSharedSettings.framework
# /Library/Receipts/SymConfidential.pkg
# /Library/Receipts/SymFileSecurity.pkg
# /Library/Receipts/SymSharedFrameworks.pkg
# /Library/Receipts/SymSharedSettings.pkg
# /private/etc/mach_init.d/SymSharedSettings.plist
# 5.03 - Now removes:
# /Applications/Norton Confidential.app
# /Library/Application Support/Symantec/IntrusionPrevention
# /Library/LaunchDaemons/com.symantec.symdaemon.plist
# /Library/LaunchDaemons/com.symantec.uiagent.bundle
# /Library/PrivateFrameworks/SymDaemon.framework
# /Library/PrivateFrameworks/SymInternetSecurity.framework
# /Library/PrivateFrameworks/SymUIAgent.framework
# /Library/PrivateFrameworks/SymUIAgentUI.framework
# /Library/Receipts/SymConfidentialData.pkg
# /Library/Receipts/SymDaemon.pkg
# /Library/Receipts/SymFileSecurity.pkg
# /Library/Receipts/SymInternetSecurity.pkg
# /Library/Receipts/SymIntrusionPrevention.pkg
# /Library/Receipts/SymNCOApplication.pkg
# /Library/Receipts/SymUIAgent.pkg
# /Library/Receipts/SymWebFraud.pkg
# /Library/Receipts/WCIDEngine.pkg
# /System/Library/Extensions/SymInternetSecurity.kext
# /System/Library/Extensions/SymIPS.kext
# /System/Library/SymInternetSecurity.kext
# 5.04 - Now removes:
# /Applications/Firefox.app/Contents/MacOS/extensions/{0e10f3d7-07f6-4f12-97b9-9b27e07139a5}
# /Library/Application Support/Symantec/Assistants/Norton Confidential
# /Library/Application Support/Symantec/Assistants/Symantec Setup Assistant.app
# /Library/Application Support/Symantec/Assistants/Symantec Setup Assistant.bundle
# /Library/Application Support/Symantec/Assistants
# /Library/Receipts/SymSetupAssistant.pkg
# 5.05 - Now removes:
# /Library/Preferences/com.symantec.sharedsettings
# 5.06 - Now removes:
# /Library/Application Support/Symantec/Settings
# 5.07 - Now removes:
# /Library/LaunchDaemons/com.symantec.uiagent.plist
# 5.08 - Now removes:
# /Library/Preferences/com.symantec.uninstaller.plist
# 5.09 - Now only removes when empty:
# /Library/Application Support/Symantec/Assistants
# /Library/Application Support/Symantec/Daemon
# 5.10 - Now removes:
# /Library/Application Support/Symantec/Daemon/error.log
# Added volume name to paths in progress.
# 5.11 - Now removes:
# /Applications/Firefox.app/Contents/MacOS/extensions/{29dd9c80-9ea1-4aaf-9305-a0314aba24e3}
# 5.12 - Now removes:
# /private/var/tmp/com.symantec.liveupdate.

# 5.13 - OSXvnc StartupItems are now filtered out during Symantec
# process checking.
# 5.14 - Modified for OS 10.5 compatibility.
# No longer removes empty /Library/StartupItems.
# Now removes:
# /Library/InputManagers/Norton Confidential for Safari
# Now removes files installed by NAV 11 build 1.
# 5.15 - Now removes:
# /.symSchedScanLockxz
# RemoveInvisibleFilesFromVolume functions now removes:
# /.SymAVQSFile
# Added DeleteLaunchdPlists function to remove Symantec
# Scheduler launchd plists.
# Added messaging when there are no Symantec crontab
# entries to delete.
# Renamed Remove function to RemoveItem.
# RemoveItem function can now match several files.
# Now removes additional files installed by NAV 11.
# A list of files deleted by this program is now appended
# to ReadMe.txt.
# All com.symantec. preferences are now shown when using
# the -L option to show all files that would be deleted.
# 5.16 - Now removes:
#
/Library/Preferences/com.symantec.nortonantivirus.
#
/Library/Preferences/com.symantec.nortonconfidential.
#
/Library/Preferences/com.symantec.schedScanResults
#
/Library/Preferences/com.symantec.symsched
# 5.17 - Adjusted grep filters in SymantecIsInMemory function.
# Now removes:
# /Applications/Norton AntiVirus.app
# 5.18 - Changed how ShowVersion is called for OS 10.5 compatibility.
# 5.19 - Now removes:
# /Library/Internet Plug-Ins/Norton Confidential for Safari.plugin
# 5.20 - Now removes:
# /Library/Receipts/SymantecAVDefs

# /private/tmp/com.symantec.liveupdate.restart
# 5.21 - Added output to DeleteSymantecLoginItems function.
# Revised output of -l and -L options.
# Now removes:
# /Library/Receipts/SymStuffit.pkg
# 5.22 - Now removes:
# /Library/Application Support/Symantec/Protector
# /Library/Receipts/SymProtector.pkg
# /Library/StartupItems/SymProtector
# 5.23 - Now removes:
# /Library/Receipts/SavLog.pkg
# 5.24 - Changed the assignment order of CRONDIR to account for
# cases where OS 10.5 was installed over OS 10.4.
# 5.25 - Now removes:
# /Library/Preferences/com.Symantec.SAVX.
# 5.26 - Now removes:
# /Library/Application Support/Symantec/Assistants/Client Firewall
# /Library/Application Support/Symantec/Assistants/SCF Assistant Startup.app
# /Library/Application Support/Symantec/DeepSight
# /Library/Application Support/Symantec/Firewall
# /Library/LaunchDaemons/com.symantec.deepsight-extractor.plist
# /Library/LaunchDaemons/com.symantec.npfbootstrap.plist
# /Library/PrivateFrameworks/SymFirewall.framework
# /Library/PrivateFrameworks/SymPersonalFirewall.framework
# /System/Library/Extensions/SymPersonalFirewall.kext
# /usr/bin/scfx
# 5.27 - Now removes:
# /Library/Application Support/Symantec/Daemon/debug.log
# /Library/Receipts/SymantecClientFirewall.pkg
# /Library/Receipts/SymFirewall.pkg
# /Library/Receipts/SymPersonalFirewallCore.pkg
# 5.28 - Now removes:
# /Library/Application Support/Symantec/Assistants/Norton Firewall
# /Library/Application Support/Symantec/Assistants/NPF Assistant Startup.app
# /Library/Receipts/NortonFirewall.pkg
# /Library/Receipts/SymPersonalFirewallUI.pkg
# /usr/bin/npfx
# 5.29 - Added ReceiptsTable variable and RunPredeleteScripts
# function to incorporate the running of predelete scripts.
# Added -e option to show predelete errors.
# 5.30 - Now removes:
# /Library/Application Support/Symantec/Assistants/NIS Assistant Startup.app
# /Library/Application Support/Symantec/Assistants/Norton Internet Security
# /Library/Receipts/NortonInternetSecurity.pkg
# 5.31 - Now removes temporary files used by this program.
# Added running of pre_delete scripts to RunPredeleteScripts functions.
# 5.32 - Adjusted DeleteSymantecLoginItems diff filtering.
# 5.33 - Now removes:
# /private/tmp/symask
# 5.34 - Now removes:
# /Library/LaunchDaemons/com.symantec
# /Library/Preferences/com.symantec

# [except com.symantec.sacm and com.symantec.smac]
# {each user's home directory}/Library/Preferences/com.symantec
# [except com.symantec.sacm
and com.symantec.smac]
# {each user's home directory}/Library/Preferences/Network/com.symantec

# /Library/Preferences/Network/com.symantec
# Added -x option to RemoveItem function.
# RemoveItem function now ignores letter case when a
# pattern or an exclusion is passed.
# Links in /Volumes are now ignored.
# 5.35 - Removed return statement that caused premature script end.
# 5.36 - Now removes items installed by NFS 100.001:
# /Library/Application Support/Symantec/Norton Family Safety
# /Library/Internet Plug-Ins/Norton Family Safety.plugin
# /Library/PreferencePanes/Norton Family Safety.prefPane
# /Library/Receipts/NFSCore.pkg
# 5.37 - Revised pattern to find Symantec processes.
# Now removes all Dev.pkg receipts.
# 5.38 - Now removes items installed by NSM 100.008:
# /Library/Application Support/Symantec/Norton Safety Minder
# /Library/Internet Plug-Ins/Norton Safety Minder.plugin
# /Library/PreferencePanes/Norton Safety Minder.prefPane
# /Library/PreferencePanes/Ribbon.Norton.prefPane
# /Library/Receipts/NSMCore.pkg
# 5.39 - Now removes:
# /Library/Caches/com.symantec

# /Library/Caches/Norton
# /Library/Caches/Symantec

# /Library/Logs/Norton
# /Library/Logs/Symantec

# /Library/Logs/SymDeepsight
# /Library/Logs/SymFWLog.log
# /Library/Logs/SymFWRules.log

# /Library/Preferences/wcid
# /private/var/tmp/com.symantec
# {each user's home directory}/Library/Caches/com.symantec

# {each user's home directory}/Library/Caches/Norton
# {each user's home directory}/Library/Caches/Symantec

# {each user's home directory}/Library/Preferences/wcid
# 5.40 - Fixed an erroneous "invalid password" error message.
# Non-removal of /opt is no longer considered an error
# (some third party programs install files into there).
# 5.41 - Updated Usage(s) comments.
# 5.42 - Now removes:
# /Library/PrivateFrameworks/SymWebKitUtils.framework
# 5.43 - Now removes:
# /Library/InputManagers/Norton Safety Minder
# 5.44 - Now removes:
# /var/db/receipts/com.symantec
# 5.45 - Now removes if empty folder:
# /Library/Preferences/Network
# Now removes:
# /Applications/Firefox.app/Contents/MacOS/extensions/nortonsafetyminder@symantec.com
# 5.46 - Added -d option.
# Updated help.
# 5.47 - Added running of predelete scripts stored in new Symantec
# Uninstaller's Receipt folder.
# Now removes:
# /Library/Application Support/Symantec/Uninstaller
# Added -Q and -QQ options.
# Added KillTerminal function.
# 5.48 - Restart prompt is now shown any time boot volume is checked
# and there are Symantec processes and/or kexts in memory,
# except when -l or -L is passed.
# Now removes:
# /Library/Application Support/Symantec/Registry
# /Library/Application Support/Symantec/Submissions
# /Library/Application Support/Symantec/SymWebKitUtils
# /Library/PrivateFrameworks/SymSubmission.framework
# /Library/Receipts/SymSubmission.pkg
# /Library/Receipts/SymWebKitUtils.pkg
# Now removes /Library/PrivateFrameworks/SymWebKitUtils.framework
# only if the framework does not contain SymWKULoader.dylib; its
# receipt is removed if SymWKULoader.dylib does not exist or if
# /Library/StartupItems/CleanUpSymWebKitUtils exists.
# 5.49 - Excluded /LiveUpdateAdminUtility/ from processes to find in
# SymantecIsInMemory function.
# 5.50 - Fixed RunPredeleteScripts function so that it runs more than
# just the first predelete script in Symantec Uninstaller's
# Receipts folder and allows for multiple predelete scripts in
# /Library/Receipts receipts.
# Now removes:
# /Library/InputManagers/SymWebKitUtils
# /Library/StartupItems/SymQuickMenuOSFix
# /Library/StartupItems/SymWebKitUtilsOSFix
# Restart prompt is now shown if CleanUpSymWebKitUtils exists in
# /Library/StartupItems.
# Running ofLiveUpdate.pkg predelete script is no longer skipped.
# 5.51 - Now removes:
# /Library/Application Support/Symantec/SEP
# /Library/Application Support/Symantec/SMC
# /Library/Application Support/Symantec/SNAC
# /Library/LaunchAgents/com.symantec

# /Library/Receipts/SMC.pkg
# /Library/Receipts/SNAC.pkg
# /Library/Receipts/Symantec Endpoint Protection.pkg
# /Library/Receipts/SymantecSAQuickMenu.pkg
# /Library/Services/ScanService.service
# /Library/Services [deleted if empty]
# /Library/StartupItems/SMC
# /usr/lib/libsymsea.1.0.0.dylib
# /usr/lib/libsymsea.dylib
# Adjusted RunPredeleteScripts function to limit predelete script
# names to those ending with predelete or pre_delete; doing so
# prevents a bus error by no longer running "predeletetool".
# 5.52 - Added -m option to use more program when -l, -L, or -R
# options are used.
# Removed -r option, which deleted only receipts.
# Added -R option to include folder contents when showing
# installed files.
# Progress shown when using the -l, -L, or -R options is
# now sent to standard error to facilitate piping the
# generated report to a file without piping progress.
# 5.53 - Now removes:
# /Library/ScriptingAdditions/SymWebKitUtils.osax
# /Library/ScriptingAdditions/SymWebKitUtilsSL.osax
# /usr/local/lib/libgecko3parsers.dylib
# /usr/local/lib [deleted if empty]
# /usr/local [deleted if empty]
# 5.54 - Now removes:
# /private/var/db/receipts/com.symantec
# 5.55 - Now removes:
# /Library/Receipts/LiveUpdate

# /Library/Application Support/Symantec/AntiVirus.kextcache
# RunPredeleteScripts function now also runs predelete scripts for
# receipts in ReceiptsTable that pass option -a.
# 5.56 - Now removes:
# /private/tmp/jlulogtemp
# /private/tmp/LiveUpdate.
# /private/tmp/liveupdate
# /private/tmp/lulogtemp
# /private/tmp/SymSharedFrameworks

# /private/var/db/receipts/$(SYM_SKU_REVDOMAIN).install.bom
# /private/var/db/receipts/$(SYM_SKU_REVDOMAIN).install.plist
# /private/var/tmp/com.Symantec
# 5.57 - Now removes:
# /Library/Application Support/nis_postuninstall.rb
# /Library/Application Support/nis_postuninstall.sh
# 5.58 - Now removes:
# /Library/Receipts/NSMCore.Universal.pkg
# 5.59 - Now removes:
# /Applications/Norton DNS Beta.app
# /Applications/Norton DNS.app
# /Library/Application Support/Symantec/Norton DNS
# /Library/LaunchDaemons/com.norton
# /private/var/log/nortondns.log
# {each user's home directory}/Library/Caches/com.norton
# {each user's home directory}/Library/Preferences/com.norton
# 5.60 - Now removes:
# /Library/Preferences/com.norton

# {each user's home directory}/Library/Preferences/com.norton
# The following removals were added in version 5.59, but the version
# history erroneously left off the trailing
:
# /Library/LaunchDaemons/com.norton
# {each user's home directory}/Library/Caches/com.norton

# The following removal were added in version 5.59, but the version
# history erroneously omitted its addition:
# /Library/Caches/com.norton
# 5.61 - Removed CurrentUserTempFile/ProcessArgumentsCalled.
# 5.62 - Modified for case-sensitive volume compatibility.
# Now removes (based on NIS 5.0 builds 8-12 boms):
# /Library/Application Support/Symantec/ErrorReporting
# /Library/PrivateFrameworks/SymLicensing.framework
# /Library/Receipts/NAV_App

# /Library/Receipts/NAV_AutoProtect
# /Library/Receipts/NortonFirewall

# /Library/Receipts/NortonInternetSecurity
# /Library/Receipts/NortonQuickMenu

# /Library/Receipts/SymantecSharedComponents
# /Library/Receipts/SymantecUninstaller

# /Library/Receipts/SymConfidential
# /Library/Receipts/SymDaemon

# /Library/Receipts/SymErrorReporting.pkg
# /Library/Receipts/SymFileSecurity
# /Library/Receipts/SymFirewall

# /Library/Receipts/SymIntrusionPrevention
# /Library/Receipts/SymNCOApplication

# /Library/Receipts/SymPersonalFirewallCore
# /Library/Receipts/SymPersonalFirewallUI

# /Library/Receipts/SymPseudoLicensing
# /Library/Receipts/SymSetupAssistant

# /Library/Receipts/SymSharedFrameworks
# /Library/Receipts/SymSharedSettings

# /Library/Receipts/SymUIAgent
# /Library/Receipts/SymWebFraud

# /Library/Services/SymSafeWeb.service
# /usr/bin/MigrateQTF
# 5.63 - Now removes:
# /usr/local/lib/libecomlodr.dylib
# 5.64 - Updated DeleteCrontabEntries to delete entries from both
# OS 10.4 and OS 10.5 crontab directories.
# 5.65 - Updated for NAV 12/NIS 5.
# 5.66 - Added check for launch location to suppress screen clearing, prompts,
# and quit message ("NOTE: If you double-clicked this script, quit Terminal
# application now.") when running from within app bundle or in support folder.
# Now removes:
# /Library/Receipts/SymLicensing
# 5.67 - Fixed "[: too many arguments" error.
# 5.68 - Now removes in all versions:
# /Library/Application Support/Symantec/Daemon/timer
# /Library/Application Support/Symantec/Licensing
# 5.69 - Now removes:
# /Preferences/ByHost/com.symantec

# {each user's home directory}/Preferences/ByHost/com.symantec
# 5.70 - Now removes:
# /Library/Application Support/Symantec/Daemon/timer.log
# 6.0.0 - 09/01/2011:
# Now designates when Symantec Uninstaller.app should not
# remove an item when using the -l or -R options.
# The -l and -R options are now equivalent.
# 6.0.1 - 09/11/2011:
# Updated file list.
# 6.0.2 - 09/16/2011:
# Updated file list.
# 6.0.3 - 10/07/2011:
# Now removes:
# /Library/Application Support/nav_postuninstall.rb
# /Library/Application Support/nsm_postuninstall.rb
# /Library/Application Support/o2spy.log
# /Library/Application Support/Symantec/NortonM
# /Library/PrivateFrameworks/PlausibleDatabase.framework
# /Library/PrivateFrameworks/SymOxygen.framework
# 6.0.4 - 11/08/2011:
# Now removes:
# /Library/Application Support/nav_uninstalldashboard

# /Library/Application Support/symantec_uninstalldashboard
# 6.0.5 - 11/17/2011:
# Now removes:
# /Library/Application Support/Symantec/SymSAQuickMenu
# 6.0.6 - 12/06/2011:
# Now removes:
# /Library/PrivilegedHelperTools/NATRemoteLock.app
# /Library/Receipts/NATRemoteLock.pkg
# /Library/Receipts/NATSDPlugin.pkg
# /Library/Receipts/nortonantitheftPostflight.pkg
# /Library/Receipts/PredeleteTool.pkg
# /Library/Receipts/SymOxygen.pkg
# /usr/lib/libwpsapi.dylib
# 6.0.7 - 12/14/2011:
# Now removes:
# /Library/Receipts/nortonanti-theftPostflight.pkg
# /private/var/db/NATSqlDatabase.db
# 6.0.8 - 02/28/2012:
# Now removes:
# /private/tmp/com.symantec.liveupdate.reboot
# 6.0.9 - 03/30/2012:
# Now removes:
# /private/var/db/receipts/com.Symantec

# 6.0.10 - 06/19/2012 - Corey Swertfager:
# Now removes:
# /Applications/Norton Zone
# /Library/Application Support/nav_uninstalldashboard

# /Library/Application Support/symantec_uninstalldashboard
# /Library/Caches/com.apple.Safari/Extensions/Norton

# /Library/Caches/com.apple.Safari/Extensions/Symantec
# /Library/Internet Plug-Ins/NortonSafetyMinderBF.plugin
# /Library/Preferences/Norton Zone
# /Library/Receipts/ZoneStandalone.pkg
# {each user's home directory}/Library/Caches/com.apple.Safari/Extensions/Norton

# {each user's home directory}/Library/Caches/com.apple.Safari/Extensions/Symantec
# {each user's home directory}/Library/Preferences/Norton Zone
# Now actually removes (added missing quotes to RemoveItem calls):
# /Library/Application Support/nav_uninstalldashboard

# /Library/Application Support/symantec_uninstalldashboard
# 6.0.11 - 06/19/2012 - Corey Swertfager:
# Now removes:
# /Library/Application Support/NortonZone
# {each user's home directory}/Library/Application Support/NortonZone
# 6.0.12 - 07/06/2012 - Corey Swertfager:
#
Modified grep calls with regular expressions that contain pattern "$|"
# to instead use extended regular expression "$|" for OS 10.8 compatibility,
# fixing the problem of predelete scripts not being run on OS 10.8.
# Now removes:
# /usr/local/bin/KeyGenerator
# 6.0.13 - 08/03/2012 - Corey Swertfager:
#
Now removes:
# /Library/Application Support/Symantec/Mexico
# /Library/Frameworks/mach_inject_bundle.framework
# 6.0.14 - 08/27/2012 - Corey Swertfager:
# Now removes Norton Zone saved sessions.
# 6.0.15 - 08/31/2012 - Corey Swertfager:
#
Removed logic that attempted to remove:
# {each user's home directory}/Library/Norton Zone
# 6.0.16 - 10/08/2012 - Corey Swertfager:
# Now removes:
# {each user's home directory}/Library/Application Support/Symantec
# /Library/Internet Plug-Ins/NortonInternetSecurityBF.plugin
#
Now makes a second attempt to remove:
# /Library/Application Support/Symantec/ErrorReporting
# /Library/Application Support/Symantec [deleted if empty]
# 6.0.17 - 10/11/2012 - Corey Swertfager:
# Now removes:
# /Library/Application Support/Symantec/NisLaunch
# 6.0.18 - 10/19/2012 - Corey Swertfager:
# Now removes:
# {each user's home directory}/Library/Safari/Extensions/NortonSafetyMinderBF
# 6.0.19 - 03/12/2013 - Corey Swertfager:
#
Now removes:
# /Library/Application Support/Symantec/Daemon [deleted whether empty or not]
# /Library/PrivilegedHelperTools/com.symantec
#
Added KillNortonZone function.
# Added watermark ID.
# 6.0.20 - 03/15/2013 - Corey Swertfager:
#
Now removes Norton Zone from loginwindow.plist files.
# Revamped DeleteSymantecLoginItems function to account
# for varying key values.
#
KillNortonZone function now only runs killall Finder
# if Norton Zone process was killed.
# 6.0.21 - 04/26/2013 - Corey Swertfager:
# Now removes:
# /Library/Application Support/Symantec/Silo
# /usr/local/bin/MigrateQTF
# /usr/local/bin [deleted if empty]
# 6.0.22 - 05/10/2013 - Corey Swertfager:
#
Now removes:
# /var/log/luxtool.log
# 6.0.23 - 05/14/2013 - Corey Swertfager:
#
Now removes:
# /var/log/mexd.log
# 6.0.24 - 05/28/2013 - Corey Swertfager:
# Now removes:
# /Library/Application Support/nat

# /Library/Application Support/nav

# /Library/Application Support/nis

# /Library/Application Support/nsm

# /Library/Application Support/norton

# /Library/Application Support/Symantec/Norton Anti-Theft
# /usr/local/bin/CoreLocationProviderTest
# /usr/local/bin/LocationProviderInterfaceTest
# /usr/local/bin/LocationProviderTest
# /usr/local/bin/SkyhookProviderTest
# 6.0.25 - 05/28/2013 - Corey Swertfager:
#
Now removes:
# /Applications/Norton
# /predelete (installed by Norton Anti-Theft)
# {each user's home directory}/Application Support/Symantec
# {each user's home directory}/Application Support [deleted if empty]
# 6.1.0 - 06/28/2013 - Corey Swertfager:
#
ProcessArguments 1.0.1 is now used to process arguments to allow
# options to be combined in one argument that begins with a single
# hyphen (e.g., passing -ab to script would be equivalent to passing
# -a and -b separately; --ab would be treated as a single option).
# The -QQ and -re remain separate arguments for backwards compatibility.
# Added -r option to restart automatically (equivalent to deprecated
# -re option).
#
Now removes, even when not empty:
# /Library/Application Support/Symantec
# Now removes:
# /Applications/GatherSymantecInfo
# /Library/Application Support/Norton

# /private/var/tmp/symantec_error_report
# /usr/local/lib/libcx_lib.so
# /usr/local/lib/liblux.so.1
# /usr/local/lib/libnlucallback.dylib
# {each user's home directory}/Library/Application Support/Norton

# {each user's home directory}/Library/Saved Application State/com.symantec
#
Now removes Symantec Administration Console for Macintosh files.
# Updated help: changed "Administration Console for Macintosh" to
# "Endpoint Protection".
# 6.1.1 - 07/10/2013 - Corey Swertfager:
#
Now removes:
# {each user's home directory}/Library/Logs/Symantec
# 6.1.2 - 07/11/2013 - Corey Swertfager:
#
Now removes:
# /usr/local/lib/liblux.so.
# 6.1.3 - 07/14/2013 - Corey Swertfager:
#
Updated ReadMe.txt.
# Now removes:
# {each user's home directory}/Library/Safari/Extensions/Norton

# 7.0.0 - 07/19/2013 - Corey Swertfager:
# Now removes:
# /private/etc/symantec
# /var/log/lux.log

# Updated version to make sure tools updater finds this program.
# 7.0.1 - 08/19/2013 - Corey Swertfager:
#
Now removes:
# /var/log/du.log
# /var/log/dulux.log

# /var/log/lut.log
# /var/log/mexd.log

# /var/log/microdef.log
#
Now removes logs listed in:
# /Library/Application Support/Symantec/Silo/NFM/LiveUpdate/Conf
# /private/etc/symantec/defutils.conf
# /private/etc/symantec/dulux.logging.conf
# /private/etc/symantec/lux.logging.conf
# /private/etc/symantec/microdef.logging.conf
# 7.0.2 - 09/05/2013 - Corey Swertfager:
# Now removes:
# /Library/Extensions/FileSecurity.kext
# /Library/Extensions/SymAPComm.kext
# /Library/Extensions/SymFirewall.kext
# /Library/Extensions/SymInternetSecurity.kext
# /Library/Extensions/SymIPS.kext
# /Library/Extensions/SymPersonalFirewall.kext
# 7.0.3 - 09/05/2013 - Corey Swertfager:
#
Updated for NIS 6.
# 7.0.4 - 10/15/2013 - Corey Swertfager:
# Now removes for all versions:
# /Library/Extensions/ndcengine.kext
# /Library/Extensions/NortonForMac.kext
# /Library/PrivateFrameworks/SymSEP.framework
# /System/Library/Extensions/ndcengine.kext
# /System/Library/Extensions/NortonForMac.kext
# /usr/bin/nortonscanner
# /usr/bin/nortonsettings
# /usr/lib/libsymsea.
dylib
# /usr/local/bin/nortonsettings
# /var/root/Applications/Norton Internet Security.app
# 7.0.5 - 10/28/2013 - Corey Swertfager:
# Updated read me.
# 7.0.6 - 11/05/2013 - Corey Swertfager:
#
Updated read me.
# 7.0.7 - 12/03/2013 - Corey Swertfager:
# Now removes:
# /Library/Logs/o2spy.log
# 7.0.8 - 12/10/2013 - Corey Swertfager:
#
Now removes com.norton.NFM.auth from login keychains.
# * Renamed RemoveNortonZoneSavedSessions function to
# RemoveLoginKeychainPasswords.

# Variable Initializations

PATH=/bin:/sbin:/usr/bin:/usr/sbin
AbbreviatedScriptName=basename "$0" .command
AutoRunScript=true
AutoRunScript=false
CurrentVolumeBeingUsed="/"
FilesRemovedList="/private/tmp/${AbbreviatedScriptName}RemovesThese.txt"
FilesRemovedFilesOnlyList="/private/tmp/${AbbreviatedScriptName}RemovesThese-FilesOnly.txt"
FilesRemovedListOfOld="/Users/Shared/${AbbreviatedScriptName}RemovesThese.txt"
FilesWereSaved=false
FinishedExitCode=0
FullScriptName=basename "$0"
LANG=""
LaunchLocationGrepPattern='/Library/Application Support/Symantec/Uninstaller|.app/Contents/Resources'
LogFile="/private/tmp/${AbbreviatedScriptName}Log.txt"
LogFileOfOld="/Users/Shared/${AbbreviatedScriptName}Log.txt"
# ----- LoginKeychainPasswordsToDelete BEGIN ------------------------------------------------
# (2 fields, tab delimited):
# Item to delete / help text to show
LoginKeychainPasswordsToDelete="com.norton.NFM.auth Norton Internet Security account info
com.norton.mexico.auth Norton Zone saved sessions"
# ----- LoginKeychainPasswordsToDelete END --------------------------------------------------
# ----- NotRemovedBySymantecUninstaller BEGIN ------------------------------------------------
# A list of paths or partial paths that aren't removed by Symantec Uninstaller.app.
# Add only items that cannot be isolated by the -u option.
NotRemovedBySymantecUninstaller='/Library/LaunchDaemons/com.symantec.nis.uninstall.plist
/Library/Logs/SymantecTestPatchers.log'
# ----- NotRemovedBySymantecUninstaller END --------------------------------------------------
NotRemovedBySymantecUninstallerText=" [should not be removed by Symantec Uninstaller.app]"
PublicVersion=true
# ----- ReceiptsTable BEGIN ------------------------------------------------
# (2 fields, tab delimited):
# Receipt name / Receipt option (-a = delete receipt*, -s = skip run of predelete script)
ReceiptsTable='
# Check to make sure there are no vague receipts that may be used by
# third party software before releasing to the public.
# This line may need to be removed to avoid deleting third party files:
CompatibilityCheck.pkg
# This line may need to be removed to avoid deleting third party files:
Decomposer.pkg
# This line may need to be removed to avoid deleting third party files:
DeletionTracking.pkg
FileSaver.pkg
LiveUpdate -a
NATRemoteLock.pkg
NATSDPlugin.pkg
NAVContextualMenu.pkg
NAVcorporate.pkg
NAVDefs.pkg
NAVEngine.pkg
NAVWidget.pkg
navx.pkg
NAV_App -a
NAV_AutoProtect -a
NFSCore.pkg
NISLaunch.pkg
Norton AntiVirus Application.pkg
Norton AntiVirus Product Log.rtf
Norton AntiVirus.pkg
Norton AutoProtect.pkg
Norton Disk Editor X.pkg
Norton Internet Security Log.rtf
Norton Personal Firewall 3.0 Log.rtf
Norton Scheduled Scans.pkg
Norton Scheduler.pkg
Norton SystemWorks 3.0 Log.rtf
Norton Utilities 8.0 Log.rtf
nortonanti-theftPostflight.pkg
nortonantitheftPostflight.pkg
NortonAutoProtect.pkg
# Remove all NortonAVDefs receipts
NortonAVDefs -a
NortonDefragger.pkg
NortonDiskDoctor.pkg
NortonFirewall -a
NortonInternetSecurity -a
NortonLauncher.pkg
NortonParentalControl.pkg
NortonPersonalFirewall.pkg
NortonPersonalFirewallMenu.pkg
NortonPrivacyControl.pkg
NortonQuickMenu -a
NPC Installer Log
NPC.pkg
NSMCore.pkg
NSMCore.Universal.pkg
NSWLaunch.pkg
NUMCompatibilityCheck.pkg
NumDocs.pkg
NUMLaunch.pkg
PredeleteTool.pkg
SavLog.pkg
# This line may need to be removed to avoid deleting third party files:
Scheduled Scans.pkg
# This line may need to be removed to avoid deleting third party files:
Scheduler.pkg
SDProfileEditor.pkg
SMC.pkg
SNAC.pkg
SpeedDisk.pkg
# NAV 9 installs the StuffIt engine if it needs to and creates the
# StuffIt.pkg receipt for it. The following line may need to be removed
# (but should not need to be) to avoid deleting third party files:
StuffIt.pkg
Symantec Alerts.pkg
Symantec AntiVirus.pkg
Symantec AutoProtect Prefs.pkg
Symantec AutoProtect.pkg
Symantec Decomposer.pkg
Symantec Endpoint Protection.pkg
Symantec Scheduled Scans.pkg
Symantec Scheduler.pkg
# Remove all SymantecAVDefs receipts
SymantecAVDefs -a
SymantecClientFirewall.pkg
SymantecDecomposer.pkg
SymantecDeepSightExtractor.pkg
SymantecParentalControl.pkg
SymantecQuickMenu.pkg
SymantecSAQuickMenu.pkg
SymantecSharedComponents -a
SymantecUninstaller -a
SymantecURLs.pkg
SymAV10StuffItInstall.pkg
SymAVScanServer.pkg
SymConfidential -a
SymConfidentialData.pkg
SymDaemon -a
SymDC.pkg
SymDiskMountNotify.pkg
SymErrorReporting.pkg
SymEvent.pkg
SymFileSecurity -a
SymFirewall -a
SymFS.pkg
SymHelper.pkg
SymHelpScripts.pkg
SymInstallExtras.pkg
SymInternetSecurity.pkg
SymIntrusionPrevention -a
SymIPS.pkg
SymLicensing -a
SymNCOApplication -a
SymOxygen.pkg
SymOSXKernelUtilities.pkg
SymPersonalFirewallCore -a
SymPersonalFirewallUI -a
SymProtector.pkg
SymPseudoLicensing -a
SymSetupAssistant -a
SymSharedFrameworks -a
SymSharedSettings -a
SymStuffit.pkg
SymSubmission.pkg
SymUIAgent -a
SymWebFraud -a
SymWebKitUtils.pkg
Unerase.pkg
# This line may need to be removed to avoid deleting third party files:
URL.pkg
VolumeAssist.pkg
VolumeRecover.pkg
WCIDEngine.pkg
Wipe Info.pkg
ZoneStandalone.pkg
'
# ----- ReceiptsTable END --------------------------------------------------
SavedFilesDir="/private/tmp/${AbbreviatedScriptName}SavedFiles"

# Function Declarations

AssignVolume()
{ # Usage: AssignVolume $1 # Argument: $1 = Volume name. The name can begin with "/Volumes/" # unless it is "/" (boot volume). # Summary: Assigns the name of the volume passed as $1 to VolumesToUse. # If volume is assigned, 0 is returned; else, 1 is returned. # # If nothing passed, skip assignment [ -z "$1" ] && return 1 VolumeToAssign=CheckIfValidVolume "$1" if [ -z "$VolumeToAssign" ] ; then VolumeToAssign=CheckIfValidVolume "/Volumes/$1" [ -z "$VolumeToAssign" ] && return 1 fi [ "$VolumeToAssign" = "/" ] && BootVolumeWillBeSearched=true VolumesToUse="$VolumesToUse
$VolumeToAssign" return 0
}

CheckIfValidVolume()
{ # Usage: CheckIfValidVolume $1 # Argument: $1 = Volume name to check. # Summary: If $1 is a valid volume name, it is echoed; # else, "" is echoed. # VVolume="" # If something passed if [ -n "$1" ] ; then # If it is a directory and not a link if [ -d "$1" -a ! -L "$1" ] ; then InitCurrentDir=pwd # Save initial directory location cd "$1" if [ "pwd" = "/" -o "pwd" = "//" ] ; then VVolume=/ else cd .. ParentDir=pwd # If there is an extra / at beginning of path, remove it [ "echo "z$ParentDir" | awk '{print substr($0,2,2)}'" = "//" ] && ParentDir=echo "z$ParentDir" | awk '{print substr($0,3)}' # If $1 is a volume, assign it to VVolume [ "$ParentDir" = "/Volumes" ] && VVolume="$ParentDir/basename "$1"" fi cd "$InitCurrentDir" # Return to initial directory fi fi echo "$VVolume"
}

DeleteCrontabEntries()
{ # Usage: DeleteCrontabEntries [$1] # Argument: $1 = Volume name. The name should begin with "/Volumes/" # unless it is "/" (boot volume). If NULL, then / is # used as volume name. # Authors: John Hansen, Corey Swertfager # Summary: Deletes from / or volume specified the crontab entries # created by Norton Scheduler and Symantec Scheduler. # Note: User must be root when calling this function. # if [ "z$1" = z/ ] ; then VolumeToDeleteCrontabsFrom="" else VolumeToDeleteCrontabsFrom="$1" fi CRONDIRNEW="$VolumeToDeleteCrontabsFrom/private/var/at/tabs" # OS 10.5 and later crontab directory CRONDIROLD="$VolumeToDeleteCrontabsFrom/private/var/cron/tabs" # OS 10.4 and earlier crontab directory if [ ! -d "$CRONDIRNEW" -a ! -d "$CRONDIROLD" ] ; then if $CreateFilesRemovedListOnly ; then if [ -z "$VolumeToDeleteCrontabsFrom" ] ; then echo "No crontab directory was found on on the current boot volume." >> "$FilesRemovedList" else echo "No crontab directory was found on on the volume "basename "$VolumeToDeleteCrontabsFrom""." >> "$FilesRemovedList" fi echo "" >> "$FilesRemovedList" else if [ -z "$VolumeToDeleteCrontabsFrom" ] ; then echo "No crontab directory was found on on the current boot volume." else echo "No crontab directory was found on on the volume "basename "$VolumeToDeleteCrontabsFrom""." fi fi return 1 fi TEMPFILETEMPLATE="/private/tmp/NortonTemp" GREP1="^#SqzS" GREP2="^#SYMANTEC SCHEDULER CRON ENTRIES" GREP3="^#PLEASE DO NOT EDIT.$" GREP4="EvType1=.EvType2=.Sched=" GREP5="Norton Solutions Support/Scheduler/schedLauncher" GREP6="Symantec/Scheduler/SymSecondaryLaunch.app/Contents/schedLauncher" SymantecCrontabEntryExists=false CurrentDir="pwd" # Save initial directory location # Set IFS to only newline to get all crontabs IFS='
' for CRONDIR in ls -d "$CRONDIRNEW" "$CRONDIROLD" 2>/dev/null ; do cd "$CRONDIR" # List each crontab, pipe through grep command and replace for user in ls * 2>/dev/null ; do # If not root and not a valid user, skip [ "z$user" != "zroot" -a ! -d "$VolumeToDeleteCrontabsFrom/Users/$user" ] && continue # If deleting from boot volume if [ -z "$VolumeToDeleteCrontabsFrom" ] ; then # Check to see if there is a Symantec crontab entry if [ "crontab -u "$user" -l | grep -c "$GREP1|$GREP2|$GREP3|$GREP4|$GREP5|$GREP6"" != 0 ] ; then SymantecCrontabEntryExists=true else continue # Nothing to remove, skip user fi $CreateFilesRemovedListOnly && break TEMPFILE="$TEMPFILETEMPLATEdate "%Y%m%d%H%M%S"" crontab -u "$user" -l | grep -v "$GREP1|$GREP2|$GREP3|$GREP4|$GREP5|$GREP6" > $TEMPFILE # Restore crontab file if it has more entries, else remove if [ -s "$TEMPFILE" ] ; then crontab -u "$user" $TEMPFILE else echo "y" | crontab -u "$user" -r fi else # Check to see if there is a Symantec crontab entry if [ "grep -c "$GREP1|$GREP2|$GREP3|$GREP4|$GREP5|$GREP6" "$user"" != 0 ] ; then SymantecCrontabEntryExists=true else continue # Nothing to remove, skip user fi $CreateFilesRemovedListOnly && break TEMPFILE="$TEMPFILETEMPLATEdate "%Y%m%d%H%M%S"" grep -v "$GREP1|$GREP2|$GREP3|$GREP4|$GREP5|$GREP6" "$user" > $TEMPFILE # Restore crontab file if it has more entries, else remove if [ -s "$TEMPFILE" ] ; then cat $TEMPFILE >"$user" else rm -f "$user" 2>/dev/null fi fi /bin/rm "$TEMPFILE" 2>/dev/null done [ $CreateFilesRemovedListOnly = true -a $SymantecCrontabEntryExists = true ] && break done cd "$CurrentDir" # Return to intial directory if $SymantecCrontabEntryExists ; then if $CreateFilesRemovedListOnly ; then if [ -z "$VolumeToDeleteCrontabsFrom" ] ; then echo "Symantec crontab entries would be deleted from the current boot volume." >> "$FilesRemovedList" else echo "Symantec crontab entries would be deleted from the volume" >> "$FilesRemovedList" echo ""basename "$VolumeToDeleteCrontabsFrom""." >> "$FilesRemovedList" fi echo "" >> "$FilesRemovedList" else if [ -z "$VolumeToDeleteCrontabsFrom" ] ; then echo "Symantec crontab entries were deleted from the current boot volume." else echo "Symantec crontab entries were deleted from the volume" echo ""basename "$VolumeToDeleteCrontabsFrom""." fi fi NoFilesToRemove=false else if $CreateFilesRemovedListOnly ; then if [ -z "$VolumeToDeleteCrontabsFrom" ] ; then echo "There are no Symantec crontab entries on the current boot volume;" >> "$FilesRemovedList" echo "no crontab entries would be removed from it." >> "$FilesRemovedList" else echo "There are no Symantec crontab entries on the volume "basename "$VolumeToDeleteCrontabsFrom"";" >> "$FilesRemovedList" echo "no crontabs would be adjusted on that volume." >> "$FilesRemovedList" fi echo "" >> "$FilesRemovedList" elif [ -z "$VolumeToDeleteCrontabsFrom" ] ; then echo "There are no Symantec crontab entries to delete from the current boot volume." else echo "There are no Symantec crontab entries to delete from the volume" echo ""basename "$VolumeToDeleteCrontabsFrom""." fi fi return 0
}

DeleteLaunchdPlists()
{ # Usage: DeleteLaunchdPlists [$1] # Argument: $1 = Volume name. The name should begin with "/Volumes/" # unless it is "/" (boot volume). If NULL, then / is # used as volume name. # Summary: Deletes from / or volume specified the launchd plists # created by Symantec Scheduler. # Note: User must be root when calling this function. # if [ "z$1" = z/ ] ; then VolumeToDeleteLaunchdPlistsFrom="" else VolumeToDeleteLaunchdPlistsFrom="$1" fi LaunchdPlists=ls -d "$VolumeToDeleteLaunchdPlistsFrom/Library/LaunchDaemons/com.symantec.Sched"*.plist 2>/dev/null if [ "$LaunchdPlists" ] ; then if $CreateFilesRemovedListOnly ; then if [ -z "$VolumeToDeleteLaunchdPlistsFrom" ] ; then echo "Symantec Scheduler launchd plists would be deleted from the current boot volume." >> "$FilesRemovedList" else echo "Symantec Scheduler launchd plists would be deleted from the volume" >> "$FilesRemovedList" echo ""basename "$VolumeToDeleteLaunchdPlistsFrom""." >> "$FilesRemovedList" fi echo "" >> "$FilesRemovedList" else IFS='
' for EachPlist in $LaunchdPlists ; do rm -f "$EachPlist" 2>/dev/null done if [ -z "$VolumeToDeleteLaunchdPlistsFrom" ] ; then echo "Symantec Scheduler launchd plists were deleted from the current boot volume." else echo "Symantec Scheduler launchd plists were deleted from the volume" echo ""basename "$VolumeToDeleteLaunchdPlistsFrom""." fi fi NoFilesToRemove=false else if $CreateFilesRemovedListOnly ; then if [ -z "$VolumeToDeleteLaunchdPlistsFrom" ] ; then echo "There are no Symantec Scheduler launchd plists on the current boot volume," >> "$FilesRemovedList" echo "so none would be removed from it." >> "$FilesRemovedList" else echo "There are no Symantec Scheduler launchd plists on the volume" >> "$FilesRemovedList" echo ""basename "$VolumeToDeleteLaunchdPlistsFrom"", so none would be removed from it." >> "$FilesRemovedList" fi echo "" >> "$FilesRemovedList" elif [ -z "$VolumeToDeleteLaunchdPlistsFrom" ] ; then echo "There are no Symantec Scheduler launchd plists to delete from the current boot" echo "volume." else echo "There are no Symantec Scheduler launchd plists to delete from the volume" echo ""basename "$VolumeToDeleteLaunchdPlistsFrom""." fi fi return 0
}

DeleteSymantecLoginItems()
{ # Usage: DeleteSymantecLoginItems [$1] # Argument: $1 = Name of volume from which to remove login items. # The name must begin with "/Volumes/" unless it is # "/" (boot volume). If nothing is passed, / is assumed. # Summary: Deletes Symantec items from all loginwindow.plist files on # volume specified. # Note: If this function is run while booted in OS 10.1.x, it will # not be able to adjust loginwindow.plist files on an OS 10.4.x # volume because plutil did not ship with basic OS 10.1.x. # Boolean CreateFilesRemovedListOnly must be defined before # running this function. # local Buffer local Line local TARGETVOLUME="$1" [ "z$1" = z/ ] && TARGETVOLUME="" TEMPFILETEMPLATE=/private/tmp/DeleteSymantecLoginItems OUTFILE=${TEMPFILETEMPLATE}date "%Y%m%d%H%M%S"-1 SOURCEFILE=${TEMPFILETEMPLATE}date "%Y%m%d%H%M%S"-2 GREPSTR="/Library/Application Support/Symantec|/Library/Application Support/Norton Solutions|/Library/Application Support/Symnatec/Scheduler/SymSecondaryLaunch.app|/Library/StartupItems/Norton|/Norton Zone.app" FileShouldBeAdjusted=false IFS='
' for EachUser in ls "$TARGETVOLUME/Users" 2>/dev/null "root" "/" ; do if [ "z$EachUser" = z/ ] ; then ORIGFILE="$TARGETVOLUME/Library/Preferences/loginwindow.plist" elif [ "z$EachUser" = zroot ] ; then ORIGFILE="$TARGETVOLUME/private/var/root/Library/Preferences/loginwindow.plist" else ORIGFILE="$TARGETVOLUME/Users/$EachUser/Library/Preferences/loginwindow.plist" fi [ ! -f "$ORIGFILE" ] && continue rm -rf $SOURCEFILE 2>/dev/null cp "$ORIGFILE" $SOURCEFILE CheckSyntax=true plutil -convert xml1 $SOURCEFILE 2>/dev/null # If plutil failed to convert the plist, don't check syntax later [ $? != 0 ] && CheckSyntax=false IsBinaryFormat=false # If original plist is different than converted plist, treat it as a binary file [ -n "diff "$ORIGFILE" $SOURCEFILE 2>/dev/null" ] && IsBinaryFormat=true # If some Symantec login item(s) found if [ "grep "$GREPSTR" $SOURCEFILE" ] ; then printf "" > $OUTFILE FileShouldBeAdjusted=true if $CreateFilesRemovedListOnly ; then echo "Symantec login items would be removed from:" >>"$FilesRemovedList" echo " "$ORIGFILE"" >>"$FilesRemovedList" else # Purge Symantec login item(s) Buffer="" DoWriteBuffer=true for Line in cat $SOURCEFILE ; do # If beginning of a dictionary key if [ "printf "%s" "$Line" | grep '<dict>$'" ] ; then [ "$Buffer" ] && echo "$Buffer" >> $OUTFILE Buffer="$Line" DoWriteBuffer=true else if [ "$Buffer" ] ; then Buffer="$Buffer
$Line" else Buffer="$Line" fi # If end of a dictionary key if [ "printf "%s" "$Line" | grep '</dict>$'" ] ; then $DoWriteBuffer && echo "$Buffer" >> $OUTFILE Buffer="" DoWriteBuffer=true # Else if Symantec path was found elif [ "printf "%s" "$Line" | grep "$GREPSTR"" ] ; then DoWriteBuffer=false fi fi done [ "$Buffer" ] && echo "$Buffer" >> $OUTFILE # If some login item information is missing if [ grep -c '<dict>$' $OUTFILE != grep -c '</dict>$' $OUTFILE ] ; then echo "ERROR: Could not remove Symantec login items from:" echo " $ORIGFILE" # Else if syntax is to be checked and plist contains bad syntax elif [ $CheckSyntax = true -a -n "plutil -s $OUTFILE 2>/dev/null" ] ; then echo "ERROR: Could not remove Symantec login items from:" echo " $ORIGFILE" else echo "Removing Symantec login items from:" echo " "$ORIGFILE"" cat $OUTFILE > "$ORIGFILE" $IsBinaryFormat && plutil -convert binary1 "$ORIGFILE" 2>/dev/null fi fi fi done rm -f $OUTFILE $SOURCEFILE 2>/dev/null $FileShouldBeAdjusted && echo "" >>"$FilesRemovedList"
}

DetermineAction()
{ # Usage: DetermineAction # Summary: Determines which action to take based on user input. # clear echo ShowVersion echo "
WARNING: This script will remove all files and folders created by Symantec OS X products (except Symantec Adminstration Console for Macintosh files) and any files within those folders. Therefore, you will lose ALL files that reside in those folders, including any that you have created.
" echo "1 - Remove all Symantec files/folders." echo echo "2 - Quit. Do not remove any files." echo printf "Enter choice (1 or 2): " read choice echo case "echo "z$choice" | awk '{print tolower(substr($0,2))}'" in 1) # Remove files CreateFilesRemovedListOnly=false ;; 2|q|quit) # Quit echo "Program cancelled. No files were removed." ExitScript 0 ;; *) # Show choices again DetermineAction ;; esac
}

ExitScript()
{ # Usage: ExitScript [-b] [-e] [exit_number [error_string]] # Summary: Checks to see if ShowQuitMessage and RunScriptAsStandAlone # variables are set to true. If so, a message is displayed; # otherwise, no message is displayed. The script is then # exited and passes exit_number to exit command. If no # exit_number is passed, then 0 is passed to exit command. If # a non-integer is passed as exit_number, 255 is passed to # exit command. If error_string is passed, it is printed to # to standard out before exiting and is padded by blank lines # if error_string is not "". Pass -b before exit_number to # suppress beginning padding line, -e to suppress ending # padding line, both to suppress both. Also removes temp # files and kills Terminal if need be. # local PadBeginning=true local PadEnd=true while [ "$1" ] ; do case "$1" in -b) PadBeginning=false ;; -e) PadEnd=false ;; *) break ;; esac shift done rm -f "$FilesRemovedList" "$FilesRemovedFilesOnlyList" "$LogFile" 2>/dev/null 1>&2 if $QuitTerminalForcefully ; then KillTerminal fi if [ $# -gt 1 ] ; then if [ -z "$2" ] ; then PadBeginning=false PadEnd=false fi $PadBeginning && echo printf "%s " "$2" $PadEnd && echo fi if [ "z$ShowQuitMessage" = ztrue -a "z$RunScriptAsStandAlone" = ztrue ] ; then [ $# -lt 2 -o ( $PadEnd = false -a -n "$2" ) ] && echo echo "NOTE: If you double-clicked this program, quit Terminal application now." [ $PadEnd = true -o -z "$2" ] && echo fi [ -z "$1" ] && exit 0 [ -z "expr "$1" / 1 2>/dev/null" ] && exit 255 || exit $1
}

FinishCleanup()
{ # Usage: FinishCleanup # Summary: Displays then deletes the file named by LogFile, a log # of files not removed by RemoveItem function, if ErrorOccurred # is true. If NoFilesToRemove is true, a message is shown # and the function is exited. If RemoveInvisibleFilesOnly # is true, a message is shown and the function is exited; # otherwise, a message is shown. Returns 2 if ErrorOccurred # is true, 0 otherwise. # if $CreateFilesRemovedListOnly ; then clear >&2 if $UseMore ; then ShowContents "$FilesRemovedList" else cat "$FilesRemovedList" fi echo "" >&2 echo "NOTE: No files have been removed." >&2 echo "" >&2 /bin/rm -rf "$FilesRemovedList" "$FilesRemovedFilesOnlyList" 2>/dev/null 1>&2 return 0 elif $ErrorOccurred ; then echo # Display LogFile ShowContents "$LogFile" # Remove LogFile /bin/rm -rf "$LogFile" 2>/dev/null 1>&2 echo if $RemoveInvisibleFilesOnly ; then echo "NOTE: Not all of the invisible Symantec files were removed." echo " Make sure each volume passed is unlocked and accessible." return 2 else echo "NOTE: Not all folders/files were removed." echo " Perhaps a file or folder listed above is in use or a folder" echo " listed above is not empty." if $RestartMayBeNeeded ; then echo echo "Some Symantec product files have been removed from the boot volume." return 2 else if $SomeFileWasRemoved ; then echo echo "Some folders or files have been removed." fi return 2 fi fi fi if $RemoveInvisibleFilesOnly ; then if $NoFilesToRemove ; then echo "There were no invisible Symantec files to be removed." else echo "AntiVirus QuickScan and/or Norton FS files have been removed." fi return 0 fi if $NoFilesToRemove ; then echo "There were no files that needed to be removed. No files were removed." return 0 fi $RemoveCrontabEntriesOnly && return 0 echo if $RestartMayBeNeeded ; then printf "Symantec product files have been removed from the boot volume" if $SomeFileWasRemovedFromNonBootVolume ; then echo echo "and from other volume(s) listed above." else echo "." fi else echo "Symantec product files have been removed from the above volume(s)." fi return 0
}

GetAdminPassword()
{ # Usage: GetAdminPassword [$1] # Argument: $1 - Prompt for password. If true is passed, a user that # is not root will always be asked for a password. If # something other than true is passed or if nothing is # passed, then a user that is not root will only be # prompted for a password if authentication has lapsed. # Summary: Gets an admin user password from the user so that # future sudo commands can be run without a password # prompt. The script is exited with a value of 1 if # the user enters an invalid password or if the user # is not an admin user. If the user is the root user, # then there is no prompt for a password (there is # no need for a password when user is root). # NOTE: Make sure ExitScript function is in the script. # # If root user, no need to prompt for password [ "whoami" = "root" ] && return 0 echo >&2 # If prompt for password if [ "$1" = "true" -o "$1" = "true" ] ; then ShowVersion >&2 echo >&2 sudo -k >&2 # Make sudo require a password the next time it is run echo "You must be an admin user to run this script." >&2 fi # A dummy sudo command to get password sudo -p "Please enter your admin password: " date 2>/dev/null 1>&2 if [ ! $? = 0 ] ; then # If failed to get password, alert user and exit script echo "You entered an invalid password or you are not an admin user. Script aborted." >&2 ExitScript 1 fi
}

KillNortonZone()
{ $CreateFilesRemovedListOnly && return ZoneProcesses=ps -axww | grep "Norton Zone.app/Contents/MacOS/Norton Zone" | grep -v grep | awk '{print $1}' for EachZoneAppPID in $ZoneProcesses ; do kill -9 "$EachZoneAppPID" done [ "$ZoneProcesses" ] && killall Finder
}

KillTerminal()
{ ProcessLines=ps -axww | grep -e "/Applications/Utilities/Terminal.app" | grep -v grep | sort -f if [ -z "$ProcessLines" ] ; then return elif [ echo "$ProcessLines" | grep . -c -gt 1 -a $QuitTerminalForcefullyForAll = false ] ; then echo "NOTE: Terminal was launched more than once so it could not be quit." echo " Use the -QQ option to force Terminal to be quit for all users." return else echo "WARNING: Quitting Terminal." fi IFS='
' for ProcessLine in $ProcessLines ; do ProcessID=printf "%s" "$ProcessLine" | awk '{print $1}' kill -9 "$ProcessID" done
}

ProcessArguments()
{ # Usage: ProcessArguments [ --OptionTakesUnparsedArgument=string ] [ --OptionIsOneArgument=string ] "$@" # # Version: 1.0.1 # # Summary: Processes arguments passed to script. Arguments beginning with a # single hyphen (-) are parsed into separate options except when an # argument is negative integer. Arguments beginning with two hypens # are treated as one argument; if the argument contains is an equals # sign (=), the string after the first "=" is treated as a separate # argument (i.e., the value assigned to the double-hyphen argument). # # For each --OptionTakesUnparsedArgument passed before "$@", the string # after "=" is used as an option that takes the next argument in full # without parsing it (see examples below); string must be a hyphen # followed by a single character. # # For each --OptionIsOneArgument passed before "$@", the string after # "=" is used as an option that should be treated as a single argument. # This is useful when processing an argument that begins with a single # hyphen to avoid having that argument parsed into separate options. # The referenced option cannot be embedded within other options (see # final example below). # # "$@" must be the last argument passed to ProcessArguments. Put all custom # option handling between "--- Customized argument handling begins here ---" # and "--- Customized argument handling ends here ---". # # Note: ProcessArgumentsNextArgument may be called to verify and obtain the # next argument after or before a given option; see that function's usage # for more details. OriginalArgumentNumber can be used to determine if # two arguments were originally passed within the same string of options. # # Examples: These examples have expanded the arguments passed as "$@". # # ProcessArguments -ab -c # Would process three arguments: -a, -b, and -c # ProcessArguments --ab -c # Would process two arguments: --ab and -c # ProcessArguments --equation=a=b+c # Would process two arguments: --equation and a=b+c # ProcessArguments -10 # Would process one argument: -10 # ProcessArguments -10a # Would process three arguments: -1, -0, -a # ProcessArguments --OptionTakesUnparsedArgument=-e -e -ger # Would process two arguments: -e and -ger # ProcessArguments --OptionTakesUnparsedArgument=-e -peer # Would process three arguments: -p, -e, and er # ProcessArguments --OptionTakesUnparsedArgument=-e --OptionTakesUnparsedArgument=-t -eter -ter # Would process four arguments: -e, ter, -t, and er # ProcessArguments --OptionIsOneArgument=-hi -hi # Would process one argument: -hi # ProcessArguments --OptionIsOneArgument=-hi -his # Would process three arguments: -h, -i, and -s # # History: 1.0.1 - 06/23/2013 - Corey Swertfager: # Added processing of options within a string that begins # with a single hyphen. # Added --OptionTakesUnparsedArgument option. # Added --OptionIsOneArgument option. # local ArgList="" local ArgsToAdd local ArgWasAdded=false local CurrentArgNumber=1 local CurrentArgument local CurrentCharacter local DoNotParseNextArgument=false local NextArgument="" local NumberOfArgumentsPassed local NumberOfArgumentsToUse=0 local OptionToAdd local OriginalArgumentNumber=0 local OriginalArgumentNumberList="" local RemainingOptionsInString local TableOfOptionsWithoutParsing=" Each option in this table will have its succeeding argument left unparsed. " local TableOfUndividedArguments=" Each item in this table should each be treated as single argument. " while [ "$1" ] ; do case "$1" in --OptionIsOneArgument) ExitScript 99 "WARNING: Bad use of --OptionIsOneArgument passed to ProcessArguments: "$1"" ;; --OptionIsOneArgument=) OptionToAdd=printf "%s" "$1" | awk '{match($0,"=") ; print substr($0,RSTART+1)}' [ -z "$OptionToAdd" ] && ExitScript 99 "WARNING: Bad use of --OptionIsOneArgument passed to ProcessArguments: "$1"" TableOfUndividedArguments="$TableOfUndividedArguments
$OptionToAdd" ;; --OptionTakesUnparsedArgument|--OptionTakesUnparsedArgument=) OptionToAdd=printf "%s" "$1" | awk '{match($0,"=") ; print substr($0,RSTART+1)}' [ -z "printf "%s" "$OptionToAdd" | grep -xe '-.'" ] && ExitScript 99 "WARNING: Bad use of --OptionTakesUnparsedArgument passed to ProcessArguments: "$1"" TableOfOptionsWithoutParsing="$TableOfOptionsWithoutParsing
$OptionToAdd" ;;
) break ;; esac shift done NumberOfArgumentsPassed=$# while [ $# != 0 ] ; do let OriginalArgumentNumber=$OriginalArgumentNumber+1 # If argument is in the list of arguments whose next argument should not be parsed if [ "printf "%s" "$1" | grep -xF "$TableOfOptionsWithoutParsing"" ] ; then ArgsToAdd="$1" OriginalArgumentNumberList="$OriginalArgumentNumberList
$OriginalArgumentNumber" DoNotParseNextArgument=true # Else if argument is in the list of arguments that should be treated as one argument elif [ "printf "%s" "$1" | grep -xF "$TableOfUndividedArguments"" ] ; then ArgsToAdd="$1" OriginalArgumentNumberList="$OriginalArgumentNumberList
$OriginalArgumentNumber" else case "$1" in -|-?) # If argument was a hyphen or a hyphen followed by a single character ArgsToAdd="$1" OriginalArgumentNumberList="$OriginalArgumentNumberList
$OriginalArgumentNumber" DoNotParseNextArgument=false ;; --) # If a value was passed to the option that begins with -- if [ "printf "%s" "$1" | grep =" ] ; then # Add the option and its value as separate arguments ArgsToAdd="printf "%s" "$1" | awk -F = '{print $1}'
printf "%s" "$1" | awk '{match($0,"=") ; print substr($0,RSTART+1)}'" OriginalArgumentNumberList="$OriginalArgumentNumberList
$OriginalArgumentNumber
$OriginalArgumentNumber" else ArgsToAdd="$1" OriginalArgumentNumberList="$OriginalArgumentNumberList
$OriginalArgumentNumber" fi DoNotParseNextArgument=false ;; -
) # If argument should not be parsed or is a negative integer if [ $DoNotParseNextArgument = true -o -z "printf "%s" "$1" | awk '{print substr($0,2)}' | tr -d '[:digit:]'" ] ; then # Treat argument as a single argument ArgsToAdd="$1" OriginalArgumentNumberList="$OriginalArgumentNumberList
$OriginalArgumentNumber" DoNotParseNextArgument=false else # Parse string into separate arguments ArgsToAdd="" RemainingOptionsInString=printf "%s" "$1" | awk '{print substr($0,2)}' while [ "$RemainingOptionsInString" ] ; do CurrentCharacter=printf "%s" "$RemainingOptionsInString" | awk '{print substr($0,1,1)}' # Prefix the character with a hyphen and add as an argument if [ "$ArgsToAdd" ] ; then ArgsToAdd="$ArgsToAdd
-$CurrentCharacter" else ArgsToAdd="-$CurrentCharacter" fi OriginalArgumentNumberList="$OriginalArgumentNumberList
$OriginalArgumentNumber" RemainingOptionsInString=printf "%s" "$RemainingOptionsInString" | awk '{print substr($0,2)}' # If this is an option whose next string should not be parsed if [ "printf "%s" "$TableOfOptionsWithoutParsing" | grep -xe "-$CurrentCharacter"" ] ; then # If string has characters remaining after that option if [ "$RemainingOptionsInString" ] ; then # Add remainder of string as the unparsed string argument ArgsToAdd="$ArgsToAdd
$RemainingOptionsInString" OriginalArgumentNumberList="$OriginalArgumentNumberList
$OriginalArgumentNumber" else # Use next argument passed as unparsed string argument DoNotParseNextArgument=true fi break fi done fi ;; ) ArgsToAdd="$1" OriginalArgumentNumberList="$OriginalArgumentNumberList
$OriginalArgumentNumber" DoNotParseNextArgument=false ;; esac fi if $ArgWasAdded ; then ArgList="$ArgList
$ArgsToAdd" else ArgList="$ArgsToAdd" fi ArgWasAdded=true shift done if [ $NumberOfArgumentsPassed -gt 0 ] ; then # Add a non-blank line to ArgList in case last argument passed was "" ArgList="$ArgList TheEnd" OriginalArgumentNumberList=echo "$OriginalArgumentNumberList" | grep . NumberOfArgumentsToUse=printf "%s" "$ArgList" | grep "" -c let NumberOfArgumentsToUse=$NumberOfArgumentsToUse-1 fi # --- Customized argument handling begins here --- BootVolumeWillBeSearched=false CreateFilesRemovedListOnly=false DoRunPredeleteScripts=true ListOnlyFilesThatExist=false NoFilesToRemove=true PauseBeforeRestarting=true QuitTerminalForcefully=false QuitTerminalForcefullyForAll=false QuitWithoutRestarting=false $AutoRunScript && QuitWithoutRestarting=true RemoveCrontabEntries=true RemoveCrontabEntriesOnly=false RemoveInvisibleFiles=true RemoveInvisibleFilesOnly=false RemoveFromAllVolumes=false RemoveFromOtherVolumes=false RestartAutomatically=false RestartMayBeNeeded=false ShowFilesAsRemoved=true ShowPredeleteErrors=false ShowQuitMessage=true SomeFileWasRemoved=false SomeFileWasRemovedFromNonBootVolume=false SomeFileWasRemovedFromBootVolume=false UseMore=false while [ $CurrentArgNumber -le $NumberOfArgumentsToUse ] ; do CurrentArgument=printf "%s" "$ArgList" | head -n $CurrentArgNumber | tail -n 1 OriginalArgumentNumber=echo "$OriginalArgumentNumberList" | head -n $CurrentArgNumber | tail -n 1 case "$CurrentArgument" in -A) RemoveFromAllVolumes=true BootVolumeWillBeSearched=true ;; -c) RemoveCrontabEntriesOnly=true RemoveCrontabEntries=true RemoveInvisibleFilesOnly=false RemoveInvisibleFiles=false ;; -C) RemoveCrontabEntriesOnly=false RemoveCrontabEntries=false ;; -d) DoRunPredeleteScripts=false ;; -e) ShowPredeleteErrors=true ;; -f) ShowFilesAsRemoved=false ;; -H) ShowUsage 0 ;; -h) ShowHelp 0 ;; -i) RemoveInvisibleFilesOnly=true RemoveInvisibleFiles=true RemoveCrontabEntries=false RemoveCrontabEntriesOnly=false ;; -I) RemoveInvisibleFilesOnly=false RemoveInvisibleFiles=false ;; -l|-R) CreateFilesRemovedListOnly=true ListOnlyFilesThatExist=true ;; -L) CreateFilesRemovedListOnly=true ListOnlyFilesThatExist=false ;; -m) UseMore=true ;; -p) PauseBeforeRestarting=false ;; -q) QuitWithoutRestarting=true RestartAutomatically=false ;; -Q) # If -Q was previously passed, treat as -QQ if $QuitTerminalForcefully ; then # Treat as if -QQ was passed QuitTerminalForcefullyForAll=true else QuitTerminalForcefullyForAll=false fi QuitTerminalForcefully=true QuitWithoutRestarting=true RestartAutomatically=false ;; -QQ) QuitTerminalForcefully=true QuitTerminalForcefullyForAll=true QuitWithoutRestarting=true RestartAutomatically=false ;; -r|-re) RestartAutomatically=true QuitWithoutRestarting=false ;; -V) echo $Version ExitScript 0 ;;
) AssignVolume "$CurrentArgument" # Assign it to a Volume variable # If not a valid volume if [ $? = 1 ] ; then ShowUsage 4 "ERROR: Invalid option or volume name: "$CurrentArgument"." fi RemoveFromOtherVolumes=true ;; esac let CurrentArgNumber=$CurrentArgNumber+1 done # --- Customized argument handling ends here ---
}

ProcessArgumentsNextArgument()
{ # Usage: ProcessArgumentsNextArgument [exit_code] [-F | -P] [-p | -r ] [operator] # # Version: 1.0.0 # # Arguments: exit_code Pass integer in range 0-255 to ShowUsage when next # argument is missing or invalid. If exit_code is not # specified, 0 is assumed. # # -F Assign the full logical path to NextArgumentFullPath. # This is the default. ShowFullFilePath function must # be included in script. If no operator was passed, -E # is the assumed operator. # # -P Assign the full physical path to NextArgumentFullPath. # ShowFullFilePath function must be included in script. # If no operator was passed, -e is the assumed operator. # # -p Get previous argument instead of next argument. If # there is no previous argument, sets NextArgument to "" # and returns 1. # # -r Return 1 instead of exiting script if there is no next # argument. Sets NextArgument to "". # # operator Operator used to test next argument: # -d Folder # -E File, folder, or link # -e File, folder, or link to an existing file/folder # -f File # -i [min [max]] # Integer in range min-max; pass "" to min and # an integer to max if there is no minimum but # a maximum is desired; pass "" to to both min # and max if passing another option after the -i # option. Also tests to see if the value of the # next argument is out of range for the currently # running version of Mac OS. # -L Link; does not check to see if link is broken # unless -P option was also passed # -l Link to an existing file/folder # -n Non-null string # # Summary: Called by ProcessArguments 1.0.1 or later to assign values to: # # CurrentArgNumber # NextArgument # NextArgumentFullPath # NextArgumentOriginalArgumentNumber # # using pre-existing values of: # # ArgList # CurrentArgNumber # CurrentArgument # OriginalArgumentNumberList # NumberOfArgumentsToUse # # Returns 0 if next or previous argument was assigned to NextArgument, # CurrentArgNumber was incremented (or decremented if -p was passed), # and NextArgumentOriginalArgumentNumber was assigned. # # Assigns "" to NextArgument and NextArgumentFullPath and returns 1 if # -p is passed and there is no previous argument, or if -r is passed # and there is no next argument; otherwise, calls ShowUsage to show # error message and exit script if operator test fails or if there is # no next or previous argument. # # Note: ShowFullFilePath function must be included in script in order to # assign a value to NextArgumentFullPath. # # Examples: ProcessArgumentsNextArgument # Returns 0 if there was a next argument; otherwise, passes 0 to # ShowUsage and displays error message about missing argument. # ProcessArgumentsNextArgument -r # Returns 0 if there was a next argument; otherwise, assigns "" to # NextArgument and NextArgumentFullPath, then returns 1. # ProcessArgumentsNextArgument 2 -d # Returns 0 if NextArgument was set to a folder; otherwise, passes # 2 to ShowUsage and displays error message if the next argument is # missing or is not a folder. # ProcessArgumentsNextArgument 3 -r -d # Returns 0 if NextArgument was set to a folder. If the next argument # is missing, assigns "" to NextArgument and NextArgumentFullPath, # then returns 1. If next argument is not a folder, passes 3 to # ShowUsage and displays error message. # ProcessArgumentsNextArgument 4 -i 1 # Returns 0 if NextArgument was set to an integer; otherwise, passes # 4 to ShowUsage and displays error message if the next argument is # missing, is not an integer, or is less than 1. # ProcessArgumentsNextArgument -i "" 100 5 # Returns 0 if NextArgument was set to an integer; otherwise, passes # 5 to ShowUsage and displays error message if the next argument is # missing, is not an integer, or is greater than 100. # ProcessArgumentsNextArgument -i "" "" 6 # Returns 0 if NextArgument was set to an integer; otherwise, passes # 6 to ShowUsage and displays error message if the next argument is # missing or is not an integer. # local DoShowMissingError=true local DirectionText=after local ExitCode=0 local ErrorText="" local GoToPreviousArgument=false local Max local Min local NextArgumentOriginal local PathOption="" local TestOperator="" NextArgumentFullPath="" while [ "$1" ] ; do case "$1" in -d) ErrorText="folder" TestOperator="$1" ;; -E) ErrorText="file, folder, or link" TestOperator="$1" ;; -e) ErrorText="file or folder" TestOperator="$1" ;; -F) PathOption="$1" if [ -z "$ErrorText" ] ; then ErrorText="file, folder, or link" TestOperator="-E" fi ;; -f) ErrorText="file" TestOperator="$1" ;; -i) ErrorText="integer" TestOperator="$1" Min="$2" Max="$3" shift 2 ;; -L) ErrorText="link" TestOperator="$1" [ "z$PathOption" = "z-P" ] && ErrorText="unbroken link" ;; -l) ErrorText="unbroken link" TestOperator="-L" ;; -n) ErrorText="non-null string" TestOperator="$1" ;; -P) PathOption="$1" if [ -z "$ErrorText" ] ; then ErrorText="file or folder" TestOperator="-e" elif [ "$ErrorText" = "link" ] ; then ErrorText="unbroken link" fi ;; -p) GoToPreviousArgument=true DirectionText=before ;; -r) DoShowMissingError=false ;; ) ExitCode=printf "%s" "$1" | tr -d -c "[:digit:]" [ -z "$ExitCode" ] && ExitCode=0 ;; esac shift done if $GoToPreviousArgument ; then if [ $CurrentArgNumber -gt 1 ] ; then let CurrentArgNumber=$CurrentArgNumber-1 NextArgument=printf "%s" "$ArgList" | head -n $CurrentArgNumber | tail -n 1 NextArgumentOriginalArgumentNumber=echo "$OriginalArgumentNumberList" | head -n $CurrentArgNumber | tail -n 1 else NextArgument="" NextArgumentFullPath="" return 1 fi # Else if there are no more arguments in ArgList elif [ $CurrentArgNumber = $NumberOfArgumentsToUse ] ; then if $DoShowMissingError ; then ShowUsage $ExitCode "ERROR: Nothing was passed after $CurrentArgument" >&2 else NextArgument="" NextArgumentFullPath="" return 1 fi else let CurrentArgNumber=$CurrentArgNumber+1 NextArgument=printf "%s" "$ArgList" | head -n $CurrentArgNumber | tail -n 1 NextArgumentOriginalArgumentNumber=echo "$OriginalArgumentNumberList" | head -n $CurrentArgNumber | tail -n 1 fi NextArgumentFullPath=ShowFullFilePath $PathOption "$NextArgument" if [ "z$ErrorText" = zinteger ] ; then NextArgumentOriginal="$NextArgument" if [ -z "$NextArgument" ] ; then ShowUsage $ExitCode "ERROR: Argument passed $DirectionText $CurrentArgument is not an integer: "$NextArgumentOriginal"" >&2 # Else if argument contains something other than a hyphen or digits elif [ "printf "%s" "$NextArgument" | tr -d "[:digit:]-"" ] ; then ShowUsage $ExitCode "ERROR: Argument passed $DirectionText $CurrentArgument is not an integer: "$NextArgumentOriginal"" >&2 # Else if argument contains a hyphen that is not at the beginning elif [ "printf "%s" "$NextArgument" | grep '..-'" ] ; then ShowUsage $ExitCode "ERROR: Argument passed $DirectionText $CurrentArgument is not an integer: "$NextArgumentOriginal"" >&2 fi NextArgument=expr "$NextArgument" / 1 2>/dev/null test "$NextArgumentOriginal" -eq "$NextArgument" 2>/dev/null if [ $? != 0 ] ; then ShowUsage $ExitCode "ERROR: Value passed $DirectionText $CurrentArgument is out of range for this OS: $NextArgumentOriginal" >&2 fi # If minimum value was specified if [ "$Min" ] ; then [ $NextArgument -lt $Min ] && ShowUsage $ExitCode "ERROR: Value passed $DirectionText $CurrentArgument ($NextArgumentOriginal) is less than minimum value ($Min)." >&2 fi # If maximum value was specified if [ "$Max" ] ; then [ $NextArgument -gt $Max ] && ShowUsage $ExitCode "ERROR: Value passed $DirectionText $CurrentArgument ($NextArgumentOriginal) is greater than maximum value ($Max)." >&2 fi elif [ "z$ErrorText" = "zfile, folder, or link" ] ; then [ ! -e "$NextArgument" -a ! -L "$NextArgument" ] && ShowUsage $ExitCode "ERROR: Argument passed $DirectionText $CurrentArgument is not a $ErrorText: "$NextArgument"" >&2 elif [ "z$ErrorText" = "zunbroken link" ] ; then if [ ! -L "$NextArgument" ] ; then ShowUsage $ExitCode "ERROR: Argument passed $DirectionText $CurrentArgument is not a link: "$NextArgument"" >&2 # Else if link is broken elif [ ! -e "$NextArgument" ] ; then ShowUsage $ExitCode "ERROR: The target of the link passed $DirectionText $CurrentArgument does not exist: "$NextArgument"" >&2 fi elif [ "$ErrorText" ] ; then [ ! $TestOperator "$NextArgument" ] && ShowUsage $ExitCode "ERROR: Argument passed $DirectionText $CurrentArgument is not a $ErrorText: "$NextArgument"" >&2 fi if [ "$PathOption" ] ; then if [ -z "$NextArgumentFullPath" ] ; then if [ -L "$NextArgument" ] ; then ShowUsage $ExitCode "ERROR: The target of the link passed $DirectionText $CurrentArgument does not exist: "$NextArgument"" >&2 else ExitScript $ExitCode "WARNING: ShowFullFilePath function could not resolve path for: "$NextArgument"" >&2 fi fi fi return 0
}

RemoveAllNortonFiles()
{ # Usage: RemoveAllNortonFiles $1 # Argument: $1 = Volume name. The name should begin with "/Volumes/" # unless it is "/" (boot volume). # Summary: Removes all OS X Norton products' files and folders # from volume named by $1 if RemoveInvisibleFilesOnly # equals false; otherwise, removes only the invisible Norton # files. Removes the invisible Norton files from other # volumes that are passed to the script. Symantec crontab # entries are removed if RemoveCrontabEntries = true. # # If not a valid volume, return 1 [ -z "CheckIfValidVolume "$1"" ] && return 1 CurrentVolumeBeingUsed="$1" if $CreateFilesRemovedListOnly ; then printf "" > "$FilesRemovedFilesOnlyList" echo "" >> "$FilesRemovedList" if [ echo "$ListOfVolumesToUse" | grep -c . -gt 1 ] ; then if [ "$1" = / ] ; then echo "------ Volume: / (current boot volume) ------" >> "$FilesRemovedList" else echo "------ Volume: "basename "$1"" ------" >> "$FilesRemovedList" fi echo "" >> "$FilesRemovedList" fi fi $RemoveCrontabEntries && DeleteCrontabEntries "$1" $RemoveCrontabEntries && DeleteLaunchdPlists "$1" $RemoveCrontabEntriesOnly && return 0 ! $RemoveInvisibleFilesOnly && DeleteSymantecLoginItems "$1" if $CreateFilesRemovedListOnly ; then if ! $RemoveInvisibleFilesOnly ; then RunPredeleteScripts "$1" echo "" >> "$FilesRemovedList" fi if $ListOnlyFilesThatExist ; then echo "The following files/folders currently exist and would be removed unless" >> "$FilesRemovedList" echo "otherwise noted:" >> "$FilesRemovedList" else echo "$FullScriptName would attempt to find and remove the following:" >> "$FilesRemovedList" fi echo "" >> "$FilesRemovedList" fi RemoveInvisibleFilesFromVolume "$1" $RemoveInvisibleFilesOnly && return 0 $CreateFilesRemovedListOnly || RunPredeleteScripts "$1" # If not an OS X volume, return 1 [ ! -d "$1/Library/Application Support" ] && return 1 if $CreateFilesRemovedListOnly ; then echo "Finding visible Symantec files on: $1" >&2 elif $ShowFilesAsRemoved ; then echo "Locating visible Symantec files in: $1" else echo "Removing visible Symantec files from: $1" fi cd "$1" if [ "pwd" = "/" ] ; then VolumePrefix="" else VolumePrefix="pwd" fi KillNortonZone RemoveItem "/.com_symantec_symfs_private" RemoveItem "/.symSchedScanLockxz" RemoveItem "/Applications/Firefox.app/Contents/MacOS/extensions/{0e10f3d7-07f6-4f12-97b9-9b27e07139a5}" RemoveItem "/Applications/Firefox.app/Contents/MacOS/extensions/{29dd9c80-9ea1-4aaf-9305-a0314aba24e3}" RemoveItem "/Applications/Firefox.app/Contents/MacOS/extensions/nortonsafetyminder@symantec.com" RemoveItem "/Applications/GatherSymantecInfo" RemoveItem "/Applications/Late Breaking News" RemoveItem "/Applications/LiveUpdate" RemoveItem "/Applications/LiveUpdate Folder" RemoveItem "/Applications/LiveUpdate Folder (OS X)"
# Remove navx incorrectly installed by NAV 800.007 installer: RemoveItem "/Applications/navx" RemoveItem "/Applications/Norton " "" RemoveItem "/Applications/Symantec AntiVirus" RemoveItem "/Applications/Symantec Solutions"
# The next 3 items are erroneously created by early builds of NAV 10 installer RemoveItem "/Applications/Symantec/LiveUpdate.app" RemoveItem "/Applications/Symantec/Read Me Files" RemoveItem "/Applications/Symantec" -e RemoveItem "/Applications/Trash Running Daemons" RemoveItem "/Applications/uDelete Preferences" RemoveItem "/Applications/Register Your Software"
# Folder erroneously created by NPF 300.001 - removed if empty: RemoveItem "/Firewall" -e -u RemoveItem "/Library/Application Support/NAVDiagnostic.log" RemoveItem "/Library/Application Support/NAV.history" RemoveItem "/Library/Application Support/nat
" "" -u RemoveItem "/Library/Application Support/nat" "" -u RemoveItem "/Library/Application Support/nav" "" -u RemoveItem "/Library/Application Support/nis" "" -u RemoveItem "/Library/Application Support/nsm" "" -u RemoveItem "/Library/Application Support/Norton Application Aliases" RemoveItem "/Library/Application Support/Norton Solutions Support" RemoveItem "/Library/Application Support/norton" "" -u RemoveItem "/Library/Application Support/o2spy.log" RemoveItem "/Library/Application Support/Symantec" RemoveItem "/Library/Application Support/symantec_uninstalldashboard" "" RemoveItem "/Library/Application Support/SymRun" RemoveItem "/Library/Authenticators/SymAuthenticator.bundle" RemoveItem "/Library/CFMSupport/Norton Shared Lib" RemoveItem "/Library/CFMSupport/Norton Shared Lib Carbon" RemoveItem "/Library/Contextual Menu Items/NAVCMPlugIn.plugin" RemoveItem "/Library/Contextual Menu Items/SAVCMPlugIn.plugin" RemoveItem "/Library/Contextual Menu Items/SymFileSecurityCM.plugin" RemoveItem "/Library/Documentation/Help/LiveUpdate Help" RemoveItem "/Library/Documentation/Help/LiveUpdate-Hilfe" RemoveItem "/Library/Documentation/Help/Norton AntiVirus Help" RemoveItem "/Library/Documentation/Help/Norton AntiVirus-Hilfe" RemoveItem "/Library/Documentation/Help/Norton Help" RemoveItem "/Library/Documentation/Help/Norton Help Scripts" RemoveItem "/Library/Documentation/Help/Norton Help Scripts Folder" RemoveItem "/Library/Documentation/Help/Norton Utilities Help" RemoveItem "/Library/Extensions/FileSecurity.kext" RemoveItem "/Library/Extensions/ndcengine.kext" RemoveItem "/Library/Extensions/NortonForMac.kext" RemoveItem "/Library/Extensions/SymAPComm.kext" RemoveItem "/Library/Extensions/SymFirewall.kext" RemoveItem "/Library/Extensions/SymInternetSecurity.kext" RemoveItem "/Library/Extensions/SymIPS.kext" RemoveItem "/Library/Extensions/SymPersonalFirewall.kext" RemoveItem "/Library/Frameworks/mach_inject_bundle.framework" RemoveItem "/Library/InputManagers/Norton Confidential for Safari" RemoveItem "/Library/InputManagers/Norton Safety Minder" RemoveItem "/Library/InputManagers/SymWebKitUtils" RemoveItem "/Library/Internet Plug-Ins/Norton Confidential for Safari.plugin" RemoveItem "/Library/Internet Plug-Ins/Norton Family Safety.plugin" RemoveItem "/Library/Internet Plug-Ins/Norton Safety Minder.plugin" RemoveItem "/Library/Internet Plug-Ins/NortonInternetSecurityBF.plugin" RemoveItem "/Library/Internet Plug-Ins/NortonSafetyMinderBF.plugin" RemoveItem "/Library/LaunchAgents/com.symantec" "" RemoveItem "/Library/LaunchDaemons/com.norton" "" RemoveItem "/Library/LaunchDaemons/com.symantec" "" RemoveItem "/Library/Logs/Norton" "" RemoveItem "/Library/Logs/o2spy.log" RemoveItem "/Library/Logs/Symantec" "" RemoveItem "/Library/Logs/SymAPErr.log" RemoveItem "/Library/Logs/SymAPOut.log" RemoveItem "/Library/Logs/SymDeepsight" "" RemoveItem "/Library/Logs/SymFWLog.log" RemoveItem "/Library/Logs/SymFWRules.log" "" RemoveItem "/Library/Logs/SymScanServerDaemon.log" RemoveItem "/Library/Plug-ins/DiskImages/NUMPlugin.bundle" RemoveItem "/Library/Plug-ins/DiskImages/VRPlugin.bundle" RemoveItem "/Library/Plug-ins/DiskImages" -e -u RemoveItem "/Library/Plug-ins" -e -u RemoveItem "/Library/PreferencePanes/APPrefPane.prefPane" RemoveItem "/Library/PreferencePanes/FileSaver.prefPane" RemoveItem "/Library/PreferencePanes/Norton Family Safety.prefPane" RemoveItem "/Library/PreferencePanes/Norton Safety Minder.prefPane" RemoveItem "/Library/PreferencePanes/Ribbon.Norton.prefPane" RemoveItem "/Library/PreferencePanes/SymantecQuickMenu.prefPane" RemoveItem "/Library/PreferencePanes/SymAutoProtect.prefPane" RemoveItem "/Library/PrivateFrameworks/NPF.framework" RemoveItem "/Library/PrivateFrameworks/NPFCoreServices.framework" RemoveItem "/Library/PrivateFrameworks/NPFDataSource.framework" RemoveItem "/Library/PrivateFrameworks/PlausibleDatabase.framework" RemoveItem "/Library/PrivateFrameworks/SymAppKitAdditions.framework" RemoveItem "/Library/PrivateFrameworks/SymAVScan.framework" RemoveItem "/Library/PrivateFrameworks/SymBase.framework" RemoveItem "/Library/PrivateFrameworks/SymConfidential.framework" RemoveItem "/Library/PrivateFrameworks/SymDaemon.framework" RemoveItem "/Library/PrivateFrameworks/SymFirewall.framework" RemoveItem "/Library/PrivateFrameworks/SymInternetSecurity.framework" RemoveItem "/Library/PrivateFrameworks/SymIPS.framework" RemoveItem "/Library/PrivateFrameworks/SymIR.framework" RemoveItem "/Library/PrivateFrameworks/SymLicensing.framework" RemoveItem "/Library/PrivateFrameworks/SymNetworking.framework" RemoveItem "/Library/PrivateFrameworks/SymOxygen.framework" RemoveItem "/Library/PrivateFrameworks/SymPersonalFirewall.framework" RemoveItem "/Library/PrivateFrameworks/SymScheduler.framework" RemoveItem "/Library/PrivateFrameworks/SymSEP.framework" RemoveItem "/Library/PrivateFrameworks/SymSharedSettings.framework" RemoveItem "/Library/PrivateFrameworks/SymSubmission.framework" RemoveItem "/Library/PrivateFrameworks/SymSystem.framework" RemoveItem "/Library/PrivateFrameworks/SymUIAgent.framework" RemoveItem "/Library/PrivateFrameworks/SymUIAgentUI.framework" if [ ! -e "$VolumePrefix/Library/PrivateFrameworks/SymWebKitUtils.framework/Versions/A/Resources/SymWKULoader.dylib" -o ( $CreateFilesRemovedListOnly = true -a $ListOnlyFilesThatExist = false ) ] ; then RemoveItem "/Library/PrivateFrameworks/SymWebKitUtils.framework" fi RemoveItem "/Library/PrivilegedHelperTools/com.symantec" "" RemoveItem "/Library/PrivilegedHelperTools/NATRemoteLock.app" IFS='
' for EachReceiptLine in echo "$ReceiptsTable" | grep . | grep -v '^#' ; do ReceiptName=echo "$EachReceiptLine" | awk -F " " '{print $1}' ReceiptArg=echo "$EachReceiptLine" | awk -F " " '{print $2}' if [ "z$ReceiptArg" = z-a ] ; then RemoveItem "/Library/Receipts/$ReceiptName" "" RemoveItem "/Library/Receipts/$ReceiptName"Dev "" else if [ "z$ReceiptName" = zSymWebKitUtils.pkg -o "z$ReceiptName" = zSymWebKitUtilsDev.pkg ] ; then # If SymWKULoader exists and CleanUpSymWebKitUtils does not, skip deletion of SymWebKitUtils receipt [ -e "$VolumePrefix/Library/PrivateFrameworks/SymWebKitUtils.framework/Versions/A/Resources/SymWKULoader.dylib" -a ! -e /Library/StartupItems/CleanUpSymWebKitUtils ] && continue fi RemoveItem "/Library/Receipts/$ReceiptName" if [ "echo "$ReceiptName" | grep '.pkg$'" ] ; then ReceiptName="basename "$ReceiptName" .pkgDev.pkg" RemoveItem "/Library/Receipts/$ReceiptName" fi fi done RemoveItem "/Library/ScriptingAdditions/SymWebKitUtils.osax" RemoveItem "/Library/ScriptingAdditions/SymWebKitUtilsSL.osax" RemoveItem "/Library/Services/ScanService.service" RemoveItem "/Library/Services/SymSafeWeb.service" RemoveItem "/Library/Services" -e -u RemoveItem "/Library/StartupItems/NortonAutoProtect" RemoveItem "/Library/StartupItems/NortonAutoProtect.kextcache" RemoveItem "/Library/StartupItems/NortonLastStart" RemoveItem "/Library/StartupItems/NortonMissedTasks" RemoveItem "/Library/StartupItems/NortonPersonalFirewall" RemoveItem "/Library/StartupItems/NortonPrivacyControl" RemoveItem "/Library/StartupItems/NUMCompatibilityCheck" RemoveItem "/Library/StartupItems/SMC" RemoveItem "/Library/StartupItems/SymAutoProtect" RemoveItem "/Library/StartupItems/SymAutoProtect.kextcache" RemoveItem "/Library/StartupItems/SymDCInit" RemoveItem "/Library/StartupItems/SymMissedTasks" RemoveItem "/Library/StartupItems/SymProtector" RemoveItem "/Library/StartupItems/SymQuickMenuOSFix" RemoveItem "/Library/StartupItems/SymWebKitUtilsOSFix" RemoveItem "/Library/StartupItems/TrackDelete" RemoveItem "/Library/StartupItems/VolumeAssist" RemoveItem "/Library/Symantec/tmp" RemoveItem "/Library/Symantec" -E -u RemoveItem "/Library/Widgets/NAV.wdgt" RemoveItem "/Library/Widgets/Symantec Alerts.wdgt" RemoveItem "/Library/Widgets" -E -u RemoveItem "/Norton AntiVirus Installer Log"
# Folder with files erroneously created by an early Corsair installer: RemoveItem "/opt/Symantec"
# Folder erroneously created by that Corsair installer - removed if empty: RemoveItem "/opt" -E -u
# Folder erroneously created by NPF 300.001 - removed if empty: RemoveItem "/Personal" -e -u RemoveItem "/private/etc/liveupdate.conf" RemoveItem "/private/etc/mach_init.d/SymSharedSettings.plist" RemoveItem "/private/etc/Symantec.conf" RemoveItem "/private/tmp/com.symantec.liveupdate.reboot" RemoveItem "/private/tmp/com.symantec.liveupdate.restart" RemoveItem "/private/tmp/jlulogtemp" RemoveItem "/private/tmp/LiveUpdate." "" RemoveItem "/private/tmp/liveupdate" RemoveItem "/private/tmp/lulogtemp" RemoveItem "/private/tmp/SymSharedFrameworks" "" RemoveItem "/private/tmp/symask" RemoveItem "/private/var/db/NATSqlDatabase.db" RemoveItem '/private/var/db/receipts/$(SYM_SKU_REVDOMAIN).install.bom' RemoveItem '/private/var/db/receipts/$(SYM_SKU_REVDOMAIN).install.plist' RemoveItem "/private/var/db/receipts/com.Symantec" "" RemoveItem "/private/var/db/receipts/com.symantec" "" RemoveItem "/private/var/tmp/com.Symantec" "" RemoveItem "/private/var/tmp/com.symantec" "" RemoveItem "/private/var/tmp/symantec_error_report" "" RemoveItem "/private/var/log/nortondns.log" RemoveItem "/private/var/log/Npfkernel.log.fifo" RemoveItem "/private/var/root/Library/Bundles/NAVIR.bundle" RemoveItem "/private/var/root/Library/Bundles" -E -u RemoveItem "/private/var/root/Library/Contextual Menu Items/NAVCMPlugIn.plugin" RemoveItem "/private/var/root/Library/Contextual Menu Items" -E -u RemoveItem "/var/root/Applications/Norton Internet Security.app"
# Folder erroneously created by NPF 300.001 - removed if empty: RemoveItem "/Solutions" -e -u
# Folder erroneously created by NPF 300.001 - removed if empty: RemoveItem "/Support/Norton" -e -u
# Folder erroneously created by NPF 300.001 - removed if empty: RemoveItem "/Support" -e -u RemoveItem "/symaperr.log" RemoveItem "/symapout.log"
# Four frameworks erroneously installed by early builds of NAV 9.0.1: RemoveItem "/SymAppKitAdditions.framework" RemoveItem "/SymBase.framework" RemoveItem "/SymNetworking.framework" RemoveItem "/SymSystem.framework" RemoveItem "/System/Library/Authenticators/SymAuthenticator.bundle" RemoveItem "/System/Library/CFMSupport/Norton Shared Lib Carbon" RemoveItem "/System/Library/CoreServices/NSWemergency" RemoveItem "/System/Library/CoreServices/NUMemergency" RemoveItem "/System/Library/Extensions/DeleteTrap.kext" RemoveItem "/System/Library/Extensions/KTUM.kext" RemoveItem "/System/Library/Extensions/ndcengine.kext" RemoveItem "/System/Library/Extensions/NortonForMac.kext" RemoveItem "/System/Library/Extensions/NPFKPI.kext" RemoveItem "/System/Library/Extensions/SymDC.kext" RemoveItem "/System/Library/Extensions/SymEvent.kext" RemoveItem "/System/Library/Extensions/symfs.kext" RemoveItem "/System/Library/Extensions/SymInternetSecurity.kext" RemoveItem "/System/Library/Extensions/SymIPS.kext" RemoveItem "/System/Library/Extensions/SymOSXKernelUtilities.kext" RemoveItem "/System/Library/Extensions/SymPersonalFirewall.kext" RemoveItem "/System/Library/StartupItems/NortonAutoProtect" RemoveItem "/System/Library/StartupItems/SymMissedTasks" RemoveItem "/System/Library/Symantec" RemoveItem "/System/Library/SymInternetSecurity.kext" RemoveItem "/SystemWorks Installer Log" RemoveItem "/Users/dev/bin/smellydecode" RemoveItem "/Users/dev/bin" -E -u RemoveItem "/Users/dev" -E -u RemoveItem "/Users/Shared/NAV Corporate" RemoveItem "/Users/Shared/NIS Corporate" RemoveItem "/Users/Shared/RemoveSymantecMacFilesRemovesThese.txt" RemoveItem "/Users/Shared/RemoveSymantecMacFilesLog.txt" RemoveItem "/Users/Shared/RemoveSymantecMacFilesRemovesThese.txt" RemoveItem "/Users/Shared/RemoveSymantecMacFilesLog.txt" RemoveItem "/Users/Shared/SymantecRemovalToolRemovesThese.txt" RemoveItem "/Users/Shared/SymantecRemovalToolLog.txt" RemoveItem "/usr/bin/nortonscanner" RemoveItem "/usr/bin/nortonsettings" RemoveItem "/usr/bin/MigrateQTF" RemoveItem "/usr/bin/navx" RemoveItem "/usr/bin/npfx" RemoveItem "/usr/bin/savx" RemoveItem "/usr/bin/scfx" RemoveItem "/usr/bin/symsched" RemoveItem "/usr/lib/libsymsea." "dylib" RemoveItem "/usr/lib/libwpsapi.dylib" RemoveItem "/usr/local/bin/CoreLocationProviderTest" RemoveItem "/usr/local/bin/KeyGenerator" RemoveItem "/usr/local/bin/LocationProviderInterfaceTest" RemoveItem "/usr/local/bin/LocationProviderTest" RemoveItem "/usr/local/bin/MigrateQTF" RemoveItem "/usr/local/bin/nortonsettings" RemoveItem "/usr/local/bin/SkyhookProviderTest" RemoveItem "/usr/local/bin" -E -u RemoveItem "/usr/local/lib/libcx_lib.so" RemoveItem "/usr/local/lib/libecomlodr.dylib" RemoveItem "/usr/local/lib/libgecko3parsers.dylib" RemoveItem "/usr/local/lib/liblux.so." "
" RemoveItem "/usr/local/lib/libnlucallback.dylib" RemoveItem "/usr/local/lib" -E -u RemoveItem "/usr/local" -E -u RemoveItem "/usr/share/man/man1/NAVScanIDs.h" RemoveItem "/var/db/receipts/com.symantec" "" RemoveItem "/var/log/du.log" "" RemoveItem "/var/log/dulux.log" "" RemoveItem "/var/log/lut.log" "" RemoveItem "/var/log/lux.log" "" RemoveItem "/var/log/luxtool.log" "" RemoveItem "/var/log/mexd.log" "" RemoveItem "/var/log/microdef.log" "" # Delete logs listed in logging conf files within /private/etc/symantec IFS='
' for LUXLogFile in cat "/Library/Application Support/Symantec/Silo/NFM/LiveUpdate/Conf/lux.logging.conf" /private/etc/symantec/dulux.logging.conf /private/etc/symantec/lux.logging.conf /private/etc/symantec/microdef.logging.conf 2>/dev/null | tr '�15' '�12' | grep logger.sink.file.filePath= | awk -F = '{print $2}' | sort -f | uniq ; do RemoveItem "$LUXLogFile" "" done if [ -f /private/etc/symantec/defutils.conf ] ; then DefUtilsLogContents=cat /private/etc/symantec/defutils.conf 2>/dev/null | tr '�15' '�12' DefUtilsLogDir=printf "%s" "$DefUtilsLogContents" | grep defutillog_dir= | awk -F = '{print $2}' if [ "$DefUtilsLogDir" ] ; then DefUtilsLogBaseName=printf "%s" "$DefUtilsLogContents" | grep defutillog_name= | awk -F = '{print $2}' [ "$DefUtilsLogBaseName" ] && RemoveItem "$DefUtilsLogDir/$DefUtilsLogBaseName".log "" fi fi RemoveItem "/private/etc/symantec" if [ -f "$VolumePrefix/etc/syslog.conf" -a $CreateFilesRemovedListOnly = false ] ; then # Remove Norton Personal Firewall entries from /etc/syslog.conf sed -e "/Norton Personal Firewall/d" -e "/Npfkernel.log.fifo/d" "$VolumePrefix/etc/syslog.conf" > /private/tmp/NPF.syslog.conf /bin/cp -f /private/tmp/NPF.syslog.conf "$VolumePrefix/etc/syslog.conf" /bin/rm -f /private/tmp/NPF.syslog.conf fi RemoveFilesFromLibraryAndUserDirectories "$1" RemoveItem /Library/Preferences/Network -E -u if [ -s "$FilesRemovedFilesOnlyList" ] ; then sort -f "$FilesRemovedFilesOnlyList" | uniq | grep . >> "$FilesRemovedList" fi RemoveLoginKeychainPasswords "$CurrentVolumeBeingUsed"
}

RemoveEmptyDirectory()
{ # Usage: RemoveEmptyDirectory $1 # Argument: $1 = Full path name of directory # Summary: Removes directory $1 if it is empty or if it contains # only .DS_Store and/or .localized (the next best thing # to being empty). # # If $1 is a directory and not a link if [ -d "$1" -a ! -L "$1" ] ; then # If folder contains only .DS_Store and/or .localized, or is empty if [ -z "ls "$1" 2>/dev/null | grep -v "^.DS_Store|^.localized"" ] ; then $ShowFilesAsRemoved && echo " Removing: "$1"" # Clear immutable bit to remove any Finder lock chflags -R nouchg "$1" 2>/dev/null 1>&2 /bin/rm -rf "$1" 2>/dev/null 1>&2 # Remove folder fi fi
}

RemoveFilesFromLibraryAndUserDirectories()
{ # Usage: RemoveFilesFromLibraryAndUserDirectories $1 # Argument: $1 = Name of volume from which to remove preferences. # The name must begin with "/Volumes/" # unless it is "/" (boot volume). # Summary: Removes all Symantec files & folders from each user's # preferences, /Library/Caches, and /Library/Preferences. # Removes help files from /Library/Documentation. Removes # folders incorrectly created by NAV 7.0.2 from each # user's home directory. # local UserHomeDir local UserLibraryDir CurrentVolumeBeingUsed="$1" if [ "$1" = "/" ] ; then VolumeToCheck="" else VolumeToCheck="$1" fi # set IFS to only newline to get all user names IFS='
' for UserName in ls "$VolumeToCheck/Users" 2>/dev/null "root" "/" ; do if [ "$UserName" = "root" ] ; then UserLibraryDir="/private/var/root/Library" UserHomeDir="/private/var/root" elif [ "$UserName" = "/" ] ; then UserLibraryDir="/Library" UserHomeDir="" else UserLibraryDir="/Users/$UserName/Library" UserHomeDir="/Users/$UserName" fi # If UserLibraryDir is not a directory, skip to the next name [ ! -d "$VolumeToCheck$UserLibraryDir" ] && continue cd "$VolumeToCheck/" # If a user, delete folders from user's home directory that were # incorrectly created by NAV 7.0.2 if [ "$UserName" != "/" ] ; then RemoveItem "$UserHomeDir/Applications/LiveUpdate Folder (OS X)" RemoveItem "$UserHomeDir/Applications/Norton AntiVirus (OS X)" RemoveItem "$UserHomeDir/Applications" -e -u fi RemoveItem "$UserLibraryDir/Application Support/Norton" "" # If a user directory if [ "$UserHomeDir" ] ; then RemoveItem "$UserLibraryDir/Application Support/Symantec" RemoveItem "$UserHomeDir/Application Support/Symantec" RemoveItem "$UserHomeDir/Application Support" -e else # Make second attempt to remove "/Application Support/Symantec/ErrorReporting" RemoveItem "$UserLibraryDir/Application Support/Symantec/ErrorReporting" RemoveItem "$UserLibraryDir/Application Support/Symantec" fi RemoveItem "$UserLibraryDir/Documentation/Help/Norton Privacy Control Help" RemoveItem "$UserLibraryDir/Documentation/Help/Norton Personal Firewall Help" RemoveItem "$UserLibraryDir/Caches/com.apple.Safari/Extensions/Norton" "" -u RemoveItem "$UserLibraryDir/Caches/com.apple.Safari/Extensions/Symantec" "" -u RemoveItem "$UserLibraryDir/Caches/com.norton" "" -u RemoveItem "$UserLibraryDir/Caches/com.symantec" "" -u RemoveItem "$UserLibraryDir/Caches/Norton" "" -u RemoveItem "$UserLibraryDir/Caches/Symantec" "" -u RemoveItem "$UserLibraryDir/Logs/Symantec" "" -u RemoveItem "$UserLibraryDir/Preferences/ByHost/com.symantec" "" RemoveItem "$UserLibraryDir/Preferences/com.norton" "" RemoveItem "$UserLibraryDir/Preferences/com.symantec" "" -x 'com.symantec.sacm.' -x 'com.symantec.smac.' RemoveItem "$UserLibraryDir/Preferences/LiveUpdate Preferences" RemoveItem "$UserLibraryDir/Preferences/LU Admin Preferences" RemoveItem "$UserLibraryDir/Preferences/LU Host Admin.plist" RemoveItem "$UserLibraryDir/Preferences/NAV8.0.003.plist" RemoveItem "$UserLibraryDir/Preferences/Network/com.symantec" "" RemoveItem "$UserLibraryDir/Preferences/Norton AntiVirus Prefs Folder" RemoveItem "$UserLibraryDir/Preferences/Norton Application Aliases" RemoveItem "$UserLibraryDir/Preferences/Norton Personal Firewall Log" RemoveItem "$UserLibraryDir/Preferences/Norton Scheduler OS X.plist" RemoveItem "$UserLibraryDir/Preferences/Norton Utilities Preferences" RemoveItem "$UserLibraryDir/Preferences/Norton Zone" RemoveItem "$UserLibraryDir/Preferences/wcid" RemoveItem "$UserLibraryDir/Safari/Extensions/Norton" "" RemoveItem "$UserLibraryDir/Saved Application State/com.symantec" "" done
}

RemoveInvisibleFilesFromVolume()
{ # Usage: RemoveInvisibleFilesFromVolume $1 # Argument: $1 = Volume name. The name should begin with "/Volumes/" # unless it is "/" (boot volume). # Summary: Removes the invisible Symantec for OS X files - Norton FS # and AntiVirus QuickScan files - from $1. # ! $RemoveInvisibleFiles && return CurrentVolumeBeingUsed="$1" cd "$1" if $CreateFilesRemovedListOnly ; then echo "Finding invisible Symantec files on: $1" >&2 elif $ShowFilesAsRemoved ; then echo "Locating invisible Symantec files in: $1" else echo "Removing invisible Symantec files from: $1" fi RemoveItem "/.SymAVQSFile" RemoveItem "/NAVMac800QSFile" RemoveItem "/Norton FS Data" RemoveItem "/Norton FS Index" RemoveItem "/Norton FS Volume" RemoveItem "/Norton FS Volume 2"
}

RemoveItem()
{ # Usage: RemoveItem FilePath [-e | -E] [-u] [-x <pattern>] [FileExtension] # # Summary: Deletes the file or folder passed, FilePath, from the # current directory. # # Options: # -e Delete FilePath only if it is a directory that is empty or # that contains only ".DS_Store" and/or ".localized" files. # If the folder could not be deleted, error message is shown. # -E Same as the -e option, except no error message is shown if # the folder could not be deleted. # -u Item is not removed by Symantec Uninstaller.app. # -x <Pattern> # Pattern to exclude from file list. Pattern will become # ^FilePath/Pattern$ so add wildcards as needed. Make sure # to prefix special characters you wish to match with # (example: to match a period, .). You may pass several # -x <pattern> groupings. # <FileExtension> # All files that match FilePathFileExtension are deleted. # To match any files that begin with FilePath, pass "" as # FileExtension (don't pass unquoted). Only the last # FileExtension passed will be used # # Note: Make sure to run the SetupCleanup function before the # first run of this function and run the FinishCleanup # function before exiting the script. # Make sure to change directory to root of the volume you # want the file or folder removed from before calling this # function. # FilePath must be the first argument. The other options # may appear after FilePath in any order. # local ExclusionPattern="" # If / or no file name passed, return [ "z$1" = z/ -o -z "$1" ] && return VolumeFromWhichToRemove="pwd" FilePath="$1" if [ "$VolumeFromWhichToRemove" = "/" ] ; then FullFilePath="$FilePath" else FullFilePath="$VolumeFromWhichToRemove$FilePath" fi PathDir=dirname "$FullFilePath" PathBasePattern=basename "$FullFilePath" | sed s/"."/"\."/g shift DeleteOnlyIfEmptyDir=false SkipErrorMessageIfEmptyDirNotFound=false ExtensionPassed="" ShouldNotBeRemovedBySymantecUninstaller=false while [ "$1" ] ; do if [ "z$1" = z-e ] ; then DeleteOnlyIfEmptyDir=true SkipErrorMessageIfEmptyDirNotFound=false elif [ "z$1" = z-E ] ; then DeleteOnlyIfEmptyDir=true SkipErrorMessageIfEmptyDirNotFound=true elif [ "z$1" = z-u ] ; then ShouldNotBeRemovedBySymantecUninstaller=true elif [ "z$1" = z-x ] ; then if [ "$2" ] ; then shift if [ "$ExclusionPattern" ] ; then ExclusionPattern="$ExclusionPattern|^$PathDir/$1$" else ExclusionPattern="^$PathDir/$1$" fi fi else ExtensionPassed="$1" fi shift done if [ "z$ExtensionPassed" = "z" ] ; then ListOfPaths=ls -d "$PathDir/" 2>/dev/null | grep -i "^$PathDir/$PathBasePattern" | sort -f PathToShow="$FullFilePath" elif [ "$ExtensionPassed" ] ; then ExtensionPassedPattern=printf "%s" "$ExtensionPassed" | sed s/"."/"\."/g ListOfPaths=ls -d "$PathDir/" 2>/dev/null | grep -i "^$PathDir/$PathBasePattern.$ExtensionPassedPattern$" | sort -f PathToShow="$FullFilePath*$ExtensionPassed" else ListOfPaths=ls -d "$FullFilePath" 2>/dev/null PathToShow="$FullFilePath" fi # If there are items to exclude from the list and there are matching items if [ "z$ExclusionPattern" != z -a -n "$ListOfPaths" ] ; then ListOfPaths=printf "%s" "$ListOfPaths" | grep -i -v -e "$ExclusionPattern" fi if $CreateFilesRemovedListOnly ; then # If -E passed, then don't list the item $SkipErrorMessageIfEmptyDirNotFound && return if ! $ListOnlyFilesThatExist ; then echo "$PathToShow$DeleteOnlyIfEmptyDir && echo " [folder deleted only if empty]"" >> "$FilesRemovedList" # Else if file exists elif [ "$ListOfPaths" ] ; then IFS='
' if $DeleteOnlyIfEmptyDir ; then ItemsToAddToList="$ListOfPaths" else ItemsToAddToList="" for EachItemListed in $ListOfPaths ; do if [ -L "$EachItemListed" -o -f "$EachItemListed" ] ; then ItemsToAddToList="$ItemsToAddToList
$EachItemListed" else ItemsToAddToList="$ItemsToAddToList
find "$EachItemListed" 2>/dev/null" fi done fi for EachItemFound in $ItemsToAddToList ; do if $ShouldNotBeRemovedBySymantecUninstaller ; then AddedText="$NotRemovedBySymantecUninstallerText" elif [ "echo "$EachItemFound" | grep -F "$NotRemovedBySymantecUninstaller"" ] ; then AddedText="$NotRemovedBySymantecUninstallerText" else AddedText="" fi echo "$EachItemFound$DeleteOnlyIfEmptyDir && echo " [folder deleted only if empty]"$AddedText" >> "$FilesRemovedFilesOnlyList" done NoFilesToRemove=false FilesFoundOnThisVolume=true fi return fi IFS='
' for EachFullPath in $ListOfPaths ; do # If -e or -E was passed if $DeleteOnlyIfEmptyDir ; then # remove directory only if empty RemoveEmptyDirectory "$EachFullPath" # If -E passed, then skip error reporting $SkipErrorMessageIfEmptyDirNotFound && continue else $ShowFilesAsRemoved && echo " Removing: "$EachFullPath"" # Clear immutable bit to remove any Finder lock chflags -R nouchg "$EachFullPath" 2>/dev/null 1>&2 /bin/rm -rf "$EachFullPath" 2>/dev/null 1>&2 # Remove file/folder fi # If file still exists if [ "ls -d "$EachFullPath" 2>/dev/null" ] ; then TheFileWasRemoved=false else TheFileWasRemoved=true SomeFileWasRemoved=true fi # If the file/folder was not removed if ! $TheFileWasRemoved ; then if ! $ErrorOccurred ; then # Create LogFile echo "Symantec files/folders not removed:" >"$LogFile" chmod a=rw "$LogFile" ErrorOccurred=true fi echo " $EachFullPath" >>"$LogFile" # Else if boot volume elif [ "$CurrentVolumeBeingUsed" = "/" ] ; then RestartMayBeNeeded=true SomeFileWasRemovedFromBootVolume=true else SomeFileWasRemovedFromNonBootVolume=true fi NoFilesToRemove=false FilesFoundOnThisVolume=true done
}

RemoveLoginKeychainPasswords()
{ # Usage: RemoveLoginKeychainPasswords volume # Summary: Removes items from login keychains. # If volume is not / (current boot volume), removal is skipped. # If volume is not specified, / is assumed. # local VolumeBeingPurged="$1" local EachLoginKeychain local HelpTextToShow local LoginKeychainPasswordToDelete local LoginKeychainPasswordToDeleteLine local UserOfKeychain # If volume not specified, assume it is boot volume [ -z "$VolumeBeingPurged" ] && VolumeBeingPurged=/ # If volume being cleaned up is not the boot volume, skip purge [ "z$VolumeBeingPurged" != z/ ] && return echo "Looking for Symantec login keychain items" IFS='
' for EachLoginKeychain in ls -d /Users/*/Library/Keychains/login.keychain 2>/dev/null ; do UserOfKeychain=echo "$EachLoginKeychain" | awk -F / '{print $3}' for LoginKeychainPasswordToDeleteLine in $LoginKeychainPasswordsToDelete ; do LoginKeychainPasswordToDelete=echo "$LoginKeychainPasswordToDeleteLine" | awk -F ' ' '{print $1}' HelpTextToShow=echo "$LoginKeychainPasswordToDeleteLine" | awk -F ' ' '{print $2}' /usr/bin/security find-generic-password -s "$LoginKeychainPasswordToDelete" "$EachLoginKeychain" 2>/dev/null 1>&2 if [ $? = 0 ] ; then if $CreateFilesRemovedListOnly ; then echo "$HelpTextToShow ($LoginKeychainPasswordToDelete) would be removed" >> "$FilesRemovedList" echo "from $UserOfKeychain's login keychain" >> "$FilesRemovedList" echo "" >> "$FilesRemovedList" else echo "Removing $HelpTextToShow ($LoginKeychainPasswordToDelete)" echo "from $UserOfKeychain's login keychain" /usr/bin/security delete-generic-password -s "$LoginKeychainPasswordToDelete" "$EachLoginKeychain" 2>/dev/null 1>&2 fi fi done done
}

RemoveNortonZoneDirectories()
{ # Usage: RemoveNortonZoneDirectories user_home_directory # Summary: Removes Norton Zone paths listed in zoneDirectoryManagerRegistryKey in # user_home_directory/Preference/com.symantec.nds.Norton-Zone.plist # local UserHomeDir="$1" local ZonePath local ZonePaths [ ! -d "$UserHomeDir" ] && return ZonePaths=defaults read "$UserHomeDir/Library/Preferences/"com.symantec.nds.Norton-Zone zoneDirectoryManagerRegistryKey 2>/dev/null | grep = | awk -F '"' '{print $2}' IFS='
' for ZonePath in $ZonePaths ; do RemoveItem "$ZonePath" done RemoveItem "$UserHomeDir/Norton Zone" "*"
}

RestartComputer()
{ # Usage: RestartComputer # Summary: Prompts to see if user would like to restart. Restarts # computer using 'reboot' command if 'yes' or 'y' is # entered; exits the script otherwise. # Note: User must be root or an admin for reboot to work, so this # function should only be used in scripts run as root or # admin user. # echo if $RunningFromWithinAppBundleOrSupportFolder ; then ExitScript $FinishedExitCode elif $QuitWithoutRestarting ; then echo "Exited the script without restarting the computer." ExitScript $FinishedExitCode elif ! $RestartAutomatically ; then echo "Do you wish to restart the computer now (WARNING: Unsaved changes" printf "in other open applications will be lost if you do!) (y/n)? " if YesEntered ; then RestartAutomatically=true fi echo fi if $RestartAutomatically ; then if $PauseBeforeRestarting ; then printf "Computer will restart in 3 seconds (ctrl-C to cancel restart)..." sleep 1 printf " 3" sleep 1 printf " 2" sleep 1 printf " 1" sleep 1 fi echo echo "Computer is restarting..." reboot else echo "Exited the script without restarting the computer." ExitScript $FinishedExitCode fi
}

RunPredeleteScripts()
{ # Usage: RunPredeleteScripts [$1] # Argument: $1 = Path of current volume. # Summary: If $1 is "" or /, predelete scripts in receipts listed in # ReceiptsTable are run. # local EachReceiptLine local EachReceiptMatchingAll local ReceiptList local ReceiptListMatchingAll="" local VolumePathPassed="$1" [ "z$VolumePathPassed" = z/ ] && VolumePathPassed="" if $CreateFilesRemovedListOnly ; then if [ "$VolumePathPassed" ] ; then echo "Receipt predelete scripts would not be run on that volume." >> "$FilesRemovedList" elif $DoRunPredeleteScripts ; then echo "Receipt predelete scripts would be run as they are found." >> "$FilesRemovedList" else echo "Receipt predelete scripts would not be run because the -d option was specified." >> "$FilesRemovedList" fi return elif [ "$VolumePathPassed" ] ; then echo "Receipt predelete scripts were not run on that volume." return elif ! $DoRunPredeleteScripts ; then echo "Receipt predelete scripts were not run because the -d option was specified." return fi SYMANTEC_SAVED_DATA_DIR="/private/tmp/$FullScriptName-SYMANTEC_SAVED_DATA_DIR-date +"%Y%m%d%H%M%S"" mkdir -p "$SYMANTEC_SAVED_DATA_DIR" 2>/dev/null IFS='
' echo "Looking for predelete scripts in Symantec Uninstaller's Receipts folder" for PredeleteScript in find "/Library/Application Support/Symantec/Uninstaller" 2>/dev/null | grep -E 'predelete$|pre_delete$' ; do if [ -x "$PredeleteScript" ] ; then echo "--- Running $PredeleteScript ---" export SYMANTEC_SAVED_DATA_DIR if $ShowPredeleteErrors ; then "$PredeleteScript" else "$PredeleteScript" 2>/dev/null 1>&2 fi fi done echo "Looking for predelete scripts in /Library/Receipts" ReceiptList=echo "$ReceiptsTable" | grep '.pkg' | grep -v '^#' for EachReceiptMatchingAll in echo "$ReceiptsTable" | grep ' -a' | grep -v '^#' | awk -F ' ' '{print $1}' ; do ReceiptListMatchingAll="$ReceiptListMatchingAll
ls -d "/Library/Receipts/$EachReceiptMatchingAll"* 2>/dev/null" done for EachReceiptMatchingAll in $ReceiptListMatchingAll ; do ReceiptList="$ReceiptList
basename "$EachReceiptMatchingAll"" done for EachReceiptLine in $ReceiptList ; do ReceiptArg=echo "$EachReceiptLine" | awk -F " " '{print $2}' [ "z$ReceiptArg" = z-s ] && continue ReceiptName=echo "$EachReceiptLine" | awk -F " " '{print $1}' [ -z "echo "$ReceiptName" | grep '.pkg$'" ] && continue if [ -d "/Library/Receipts/$ReceiptName" ] ; then for PredeleteScript in find "/Library/Receipts/$ReceiptName" 2>/dev/null | grep -E 'predelete$|pre_delete$' ; do if [ -x "$PredeleteScript" ] ; then echo "--- Running $PredeleteScript ---" export SYMANTEC_SAVED_DATA_DIR if $ShowPredeleteErrors ; then "$PredeleteScript" else "$PredeleteScript" 2>/dev/null 1>&2 fi fi done fi ReceiptName="basename "$ReceiptName" .pkgDev.pkg" if [ -d "/Library/Receipts/$ReceiptName" ] ; then for PredeleteScript in find "/Library/Receipts/$ReceiptName" 2>/dev/null | grep -E 'predelete$|pre_delete$' ; do if [ -x "$PredeleteScript" ] ; then echo "--- Running $PredeleteScript ---" export SYMANTEC_SAVED_DATA_DIR if $ShowPredeleteErrors ; then "$PredeleteScript" else "$PredeleteScript" 2>/dev/null 1>&2 fi fi done fi done rm -rf "$SYMANTEC_SAVED_DATA_DIR" 2>/dev/null
}

SetupCleanup()
{ # Usage: SetupCleanup # Summary: Initializes variables needed for the RemoveItem function. # ErrorOccurred=false NoFilesToRemove=true /bin/rm -rf "$FilesRemovedList" "$FilesRemovedFilesOnlyList" 2>/dev/null 1>&2 if $CreateFilesRemovedListOnly ; then if $ListOnlyFilesThatExist ; then echo "Summary of what $FullScriptName would do, based on files" > "$FilesRemovedList" echo "$RemoveCrontabEntries && echo "and crontab entries "that currently exist:" >> "$FilesRemovedList" else echo "Summary of what $FullScriptName would attempt to do:" > "$FilesRemovedList" fi fi
}

ShowContents()
{ # Usage1: ShowContents [-c] [-w] File [TextToShow] # Usage2: ShowContents [-c] [-w] -s String [TextToShow] # Summary: Displays contents of File or String. If there are more than # $LINES or 23 lines, more command is used, using TextToShow as # the name of the file; if TextToShow is not passed, "....." is # used. If -c is specified, screen is cleared beforehand. # If -w is specified, then width of strings will be factored # into the line count (this option makes output slower when # the number of lines is less than $LINES or 23). # local SCLineCount local SCCurrentDir local SCTempFolder local SCTempFile local SCColumns local SCColumnsMax local SCColumnsMaxDefault=80 local SCColumnsRemainder local CSDoAdjustForWidth=false local CSDoUseString=false local SCEachLine local SCGrepPattern='.' local SCLineFactor local SCLines local SCLinesMax local SCLinesMaxDefault=23 local SCText while [ "$1" ] ; do if [ "z$1" = z-c ] ; then clear elif [ "z$1" = z-s ] ; then CSDoUseString=true elif [ "z$1" = z-w ] ; then CSDoAdjustForWidth=true else break fi shift done [ "$COLUMNS" ] && SCColumnsMax=expr "$COLUMNS" - 0 2>/dev/null [ -z "$SCColumnsMax" ] && SCColumnsMax=$SCColumnsMaxDefault [ "$LINES" ] && SCLinesMax=expr "$LINES" - 1 2>/dev/null [ -z "$SCLinesMax" ] && SCLinesMax=$SCLinesMaxDefault [ $SCColumnsMax -ge $SCColumnsMaxDefault ] && SCGrepPattern='.................................................................................' if $CSDoUseString ; then SCLineCount=printf "%s " "$1" | grep -c "" $CSDoAdjustForWidth && SCText=printf "%s " "$1" | grep "$SCGrepPattern" elif [ -f "$1" ] ; then SCLineCount=grep -c "" "$1" $CSDoAdjustForWidth && SCText=grep "$SCGrepPattern" "$1" else return 1 fi if $CSDoAdjustForWidth ; then if [ $SCLineCount -le $SCLinesMax ] ; then IFS='
' for SCColumns in printf "%s" "$SCText" | awk '{print length($0)}' ; do [ $SCLineCount -gt $SCLinesMax ] && break SCLineFactor=expr $SCColumns / $SCColumnsMax [ expr $SCColumns % $SCColumnsMax -gt 0 ] && let SCLineFactor=$SCLineFactor+1 [ $SCLineFactor -gt 1 ] && let SCLineCount=$SCLineCount+$SCLineFactor-1 done fi fi if $CSDoUseString ; then if [ $SCLineCount -gt $SCLinesMax ] ; then SCCurrentDir=pwd SCTempFolder="/private/tmp/$FullScriptName-SC-date "%Y%m%d%H%M%S"" mkdir "$SCTempFolder" 2>/dev/null [ ! -d "$SCTempFolder" ] && return 1 cd "$SCTempFolder" 2>/dev/null [ "$2" ] && SCTempFile="$2" || SCTempFile="....." printf "%s " "$1" >"$SCTempFile" more -E "$SCTempFile" cd "$SCCurrentDir" 2>/dev/null rm -rf "$SCTempFolder" 2>/dev/null else printf "%s " "$1" fi elif [ -f "$1" ] ; then if [ $SCLineCount -gt $SCLinesMax ] ; then SCCurrentDir=pwd SCTempFolder="/private/tmp/$FullScriptName-SC-date "%Y%m%d%H%M%S"" mkdir "$SCTempFolder" 2>/dev/null [ ! -d "$SCTempFolder" ] && return 1 [ "$2" ] && SCTempFile="$2" || SCTempFile="....." cat "$1" >"$SCTempFolder/$SCTempFile" cd "$SCTempFolder" 2>/dev/null more -E "$SCTempFile" cd "$SCCurrentDir" 2>/dev/null rm -rf "$SCTempFolder" 2>/dev/null else cat "$1" fi fi return 0
}

ShowFullFilePath()
{ # Usage: ShowFullFilePath [-a] [-P | -L] [-e] Path [[-e] Path] # Version: 1.0.2 # Summary: Prints the full path starting at / of Path if Path exists # and Path is accessible by the user calling this function. # Run this function as root to ensure full path displaying. # If there is more than one existing file that matches the # name, then only the first path that the shell matches is # printed unless -a or more than one path is specified. # You can specify wild card characters ? and and other # argument operators in the Path (e.g., "../", "a?.txt", # "[ab]"). # Options: -a Show all matching paths, sorted alphanumerically. If # -P is not passed, the same file may be shown multiple # times if there is more than one matching link that # points to it. # -e <Path> # Treat argument after -e as a path. Use -e to treat # -a, -e, -L, or -P as a path. # -L Show logical path, even if a file pointed to by a link # doesn't exist. This is the default. # -P Show physical path. If a link points to a file that # does not exist, the path won't be shown. # History: 1.0.1 - Added -e option and ability to pass multiple paths. # Arguments can now be passed in any order. # Fixed error that could occur when resolving links # with long paths. # 1.0.2 - Modified for case-sensitive volume compatibility. # Made temporary file names more distinctive. # local SFFPArgCount=$# local SFFPCurrentDir local SFFPCurrentDirTranslated local SFFPEachLine local SFFPEachPath local SFFPFile local SFFPLDir local SFFPLLinkLS local SFFPLLinkPath local SFFPLPath local SFFPPathOption=-L local SFFPSaveIFS="$IFS" local SFFPShowAll=false local SFFPTempBase=/private/tmp/ShowFullFilePath-/usr/bin/basename "$0"-/bin/date +"%Y%m%d%H%M%S" local SFFPTempFile="$SFFPTempBase.tmp" local SFFPTempFile2="$SFFPTempBase-2.tmp" /bin/rm -f "$SFFPTempFile" 2>/dev/null while [ $SFFPArgCount != 0 ] ; do case "$1" in -a) SFFPShowAll=true ;; -L|-P) SFFPPathOption="$1" ;; ) [ "z$1" = z-e ] && shift if [ "$1" ] ; then [ -s "$SFFPTempFile" ] && SFFPShowAll=true /usr/bin/printf "%s " "$1" >>"$SFFPTempFile" fi ;; esac shift let SFFPArgCount=$SFFPArgCount-1 done [ ! -s "$SFFPTempFile" ] && return SFFPCurrentDir=/bin/pwd SFFPCurrentDirTranslated=/bin/pwd $SFFPPathOption 2>/dev/null if [ ! -d "$SFFPCurrentDirTranslated" ] ; then /bin/rm -f "$SFFPTempFile" 2>/dev/null return fi cd "$SFFPCurrentDirTranslated" 2>/dev/null if [ $? != 0 ] ; then /bin/rm -f "$SFFPTempFile" 2>/dev/null return fi /usr/bin/printf "" >"$SFFPTempFile2" IFS='
' for SFFPEachLine in /bin/cat "$SFFPTempFile" 2>/dev/null ; do cd "$SFFPCurrentDirTranslated" 2>/dev/null [ $? != 0 ] && break if [ "z$SFFPPathOption" = z-P ] ; then SFFPLPath="$SFFPEachLine" while [ -L "$SFFPLPath" ] ; do [ ! -e "$SFFPLPath" ] && break cd "/usr/bin/dirname "$SFFPLPath" 2>/dev/null" 2>/dev/null [ $? != 0 ] && break SFFPLDir=/bin/pwd -P 2>/dev/null [ ! -d "$SFFPLDir" ] && break SFFPLLinkLS=/bin/ls -ld "$SFFPLPath" 2>/dev/null [ -z "$SFFPLLinkLS" ] && break # If link or link target contains " -> " in its name if [ "echo "z$SFFPLLinkLS" | grep ' -> .* -> '" ] ; then SFFPLLinkPath=/usr/bin/printf "%s" "$SFFPLLinkLS" | /usr/bin/awk -v THESTR="$SFFPLPath -> " '{ match($0,THESTR) ; print substr($0,RSTART+RLENGTH)}' else SFFPLLinkPath=echo "$SFFPLLinkLS" | awk -F " -> " '{print $2}' fi # If link target begins with / if [ "/usr/bin/printf "%s" "$SFFPLLinkPath" | grep '^/'" ] ; then SFFPLPath="$SFFPLLinkPath" else SFFPLPath="$SFFPLDir/$SFFPLLinkPath" fi [ "/usr/bin/printf "%s" "$SFFPLPath" | grep '^//'" ] && SFFPLPath=echo "$SFFPLPath" | /usr/bin/awk '{print substr($0,2)}' done cd "$SFFPCurrentDirTranslated" 2>/dev/null [ $? != 0 ] && break if [ ! -e "$SFFPLPath" ] ; then $SFFPShowAll && continue || break fi SFFPEachPath="$SFFPLPath" else SFFPEachPath="$SFFPEachLine" fi if [ -d "$SFFPEachPath" ] ; then cd "$SFFPEachPath" 2>/dev/null if [ $? != 0 ] ; then $SFFPShowAll && continue || break fi SFFPFile="" elif [ -d "/usr/bin/dirname "$SFFPEachPath" 2>/dev/null" ] ; then cd "/usr/bin/dirname "$SFFPEachPath" 2>/dev/null" 2>/dev/null if [ $? != 0 ] ; then $SFFPShowAll && continue || break fi SFFPFile=basename "$SFFPEachPath" 2>/dev/null [ "z$SFFPFile" = z/ -o "z$SFFPFile" = z. -o "z$SFFPFile" = z.. ] && SFFPFile="" elif $SFFPShowAll ; then continue else break fi SFFPDir=/bin/pwd $SFFPPathOption 2>/dev/null if [ ! -d "$SFFPDir" ] ; then $SFFPShowAll && continue || break fi SFFPPath="$SFFPDir[ "z$SFFPFile" != z -a "z$SFFPDir" != z/ -a "z$SFFPDir" != z// ] && echo /$SFFPFile" if [ ! -e "$SFFPPath" -a ! -L "$SFFPPath" ] ; then $SFFPShowAll && continue || break fi [ "echo "$SFFPPath" | grep '^//'" ] && SFFPPath=echo "$SFFPPath" | /usr/bin/awk '{print substr($0,2)}' echo "$SFFPPath" >>"$SFFPTempFile2" # If neither option -a nor more than one path was passed, don't show any more names ! $SFFPShowAll && break done IFS=$SFFPSaveIFS [ -s "$SFFPTempFile2" ] && /usr/bin/sort -f "$SFFPTempFile2" | /usr/bin/uniq /bin/rm -f "$SFFPTempFile" "$SFFPTempFile2" 2>/dev/null cd "$SFFPCurrentDir" 2>/dev/null
}

ShowHelp()
{ # Usage: ShowHelp [$1] # Argument: $1 = Exit code. # Summary: Displays script usage and help then exits script. # If a number is passed to $1, then script exits with # that number; else, script is not exited. # TEMPFILETEMPLATE="/private/tmp/SymantecTemp" TEMPFILE="$TEMPFILETEMPLATEdate +"%Y%m%d%H%M%S"-1" ShowVersion >>"$TEMPFILE" $AutoRunScript && echo "
Note: This script requires no user interaction if run as root. You can run this script on several machines at once by using Symantec Endpoint Protection to push this script to client Macs." >>"$TEMPFILE" echo "
WARNING: This script will remove all files and folders created by Symantec Mac OS X products (LiveUpdate Administration Utility files) and any files within those folders. Therefore, you will lose ALL files that reside in those folders, including any that you have created.

Usage: $FullScriptName [-CcdefhIiLlmpQqRrV] [-QQ] [-re] [volume ...]

Summary: If no option or volume is specified, then all Symantec files are removed from the current boot volume, including the invisible Symantec files (i.e., AntiVirus QuickScan and Norton FS files), and Symantec crontab entries are removed from all users' crontabs; otherwise, for each volume specified, all Symantec files and Symantec crontab entries will be removed from that volume if no options are specified. If files are removed from the current boot volume, receipt predelete scripts are run unless -d is specified.

If a volume does not have OS X installed on it, then only the invisible Symantec files are removed from that volume.

Each volume name may begin with "/Volumes/", unless it is "/". The easiest way to specify a volume is to drag the volume onto the Terminal window.

Note: The Terminal application does not support high ASCII or double-byte character entry via keyboard or via drag-and-drop. If you want to have files removed from a volume that is not the current boot volume and that has a name containing high ASCII or double-byte characters, use the -A option.

Options: -A Remove all Symantec files from all mounted volumes. Crontab entries are also removed from the current boot volume, but not from other volumes. If a volume does not have OS X installed on it, then only the invisible Symantec files are removed from that volume. -c Only remove crontab entries from all users' crontabs. Nothing is removed from any volume. -C Do not remove crontab entries. -d Bypass the running of receipt predelete scripts. It is best to have predelete scripts run for more thorough uninstalls. -e Show errors when run predelete scripts are run. Predelete scripts are run only when removing files from the current boot volume. -f Do not show files as they are removed. If -f is not specified, file names are shown as files are removed. -h Display help. -i Only remove invisible Symantec files. -I Does not remove invisible Symantec files. -l List only files that are currently installed and that would be deleted. As of version 6.0.0, contents of folders are also shown. Nothing is deleted by this option. -L List all files that $FullScriptName will attempt to find and delete. Nothing is deleted by this option. -m Show output from -l, -L, or -R options using more program. This is no longer the default action as of version 5.52 of $FullScriptName. -p Eliminate pause before restarting computer. If option -p is not specified, then there is a three second delay before the restart occurs. -q Quit script without restarting. This also suppresses the prompt to restart. -Q Quits Terminal application when script is done. If Terminal is being run by more than one user at once, Terminal is not quit. If passed a second time, it is the same as -QQ option. -QQ Quits Terminal application for all users when script is done. -R This option is equivalent to the -l option. -r Automatically restart computer when script is done if there are Symantec processes and/or kexts in memory and there were non-invisible files removed from /. -re Same as -r option. Though -re is deprecated, it remains for backwards compatibility. -V Show version only.

Examples: $FullScriptName Deletes all Symantec files and Symantec crontab entries from the boot volume.

$FullScriptName /Volumes/OS 10.2 Deletes all Symantec files and Symantec crontab entries from the volume named "OS 10.2". Nothing is deleted from the boot volume.

$FullScriptName Runner / Deletes all Symantec files and Symantec crontab entries from the volume named "Runner" and from the boot volume.

$FullScriptName -i "Test Disk" Deletes only invisible Symantec files from the volume named "Test Disk".

$FullScriptName -A -r Deletes all Symantec files and Symantec crontab entries from all mounted volumes that have OS X installed on them. Deletes only invisible Symantec files from volumes that do not have OS X installed on them. Computer is restarted automatically if necessary.

$FullScriptName -iA Deletes only invisible Symantec files from all volumes.

$FullScriptName -I Deletes all but the invisible Symantec files from the boot volume. Crontab entries are removed from the boot volume.

$FullScriptName -C Deletes all Symantec files from the boot volume. No crontab entries are removed.

$FullScriptName -L -A Lists all the files that $FullScriptName looks for on all volumes. The files may or may not be currently installed. Nothing is deleted.

$FullScriptName -R -A Lists only the Symantec files that are currently installed on all volumes. Files within existing folders will also be shown. Nothing is deleted.

$FullScriptName -l -i Lists the invisible Symantec files that are currently installed on the boot volume. Nothing is deleted.

Note: You must be root or an admin user to run this script. You can simply double-click on $FullScriptName to remove all Symantec files and crontab entries from the boot volume.
" >>"$TEMPFILE" ShowContents "$TEMPFILE" /bin/rm "$TEMPFILE" 2>/dev/null [ "$1" ] && exit $1
}

ShowUsage()
{ # Usage: ShowUsage [$1 [$2]] # Arguments: $1 = Exit code. # $2 = Error message to display before showing usage. # Summary: Displays script usage. If an exit code is passed, # script is exited with that value. # if [ "$2" ] ; then echo echo "$2" echo fi ShowHelp | grep "^Usage.*:" [ "$2" ] && echo [ -n "$1" ] && exit "$1"
}

ShowVersion()
{ # Usage: ShowVersion # Summary: Displays the name and version of script. # echo " $FullScriptName $Version **"
}

SymantecIsInMemory()
{ # Usage: SymantecIsInMemory # Summary: If a Symantec process or kext is in memory, true is shown # and 0 is returned; otherwise, false is shown and 1 is # returned. Sample call: # if SymantecIsInMemory # local SymantecIsInMemoryResult=false if [ "ps -wwax | grep -i "/Application Support/Norton|/Application Support/Symantec|/Applications/Norton|/Applications/Symantec|PrivateFrameworks/Sym|/StartupItems/.*Norton|/StartupItems/NUMCompatibilityCheck|/StartupItems/SMac Client|/StartupItems/Sym|/StartupItems/TrackDelete|/StartupItems/VolumeAssist" | grep -v " grep -|/LiveUpdateAdminUtility/"" ] ; then SymantecIsInMemoryResult=true else kextstat 2>/dev/null 1>&2 if [ $? -gt 0 ] ; then if [ "kmodstat | grep -i Symantec | grep -v " grep -"" ] ; then SymantecIsInMemoryResult=true fi elif [ "kextstat | grep -i Symantec | grep -v " grep -"" ] ; then SymantecIsInMemoryResult=true fi fi echo $SymantecIsInMemoryResult ! $SymantecIsInMemoryResult && return 1 return 0
}

YesEntered()
{ # Usage: YesEntered # Summary: Reads a line from standard input. If "y" or "yes" # was entered, true is shown and 0 is returned; otherwise, # false is shown and 1 is returned. The case of letters is # ignored. Sample call: # if YesEntered # read YesEnteredString YesEnteredString=echo "z$YesEnteredString" | awk '{print tolower(substr($0,2))}' if [ "'$YesEnteredString" = "'y" -o "'$YesEnteredString" = "'yes" ] ; then echo true return 0 fi echo false return 1
}

# Beginning of Commands to Execute

ScriptPath=ShowFullFilePath "$0" -P
ScriptDir=dirname "$ScriptPath"
if [ $# -eq 0 ] ; then # If no arguments were passed to script # Run script as if it was double-clicked in Finder so that # screen will be cleared and quit message will be displayed. RunScriptAsStandAlone=true
else # Run script in command line mode so that # screen won't be cleared and quit message won't be displayed. RunScriptAsStandAlone=false
fi
# If script was run from support folder or from within an app bundle
if [ "echo "$ScriptDir" | grep -e "$LaunchLocationGrepPattern"" ] ; then RunScriptAsStandAlone=false RunningFromWithinAppBundleOrSupportFolder=true
else RunningFromWithinAppBundleOrSupportFolder=false
fi
if $RunScriptAsStandAlone ; then clear >&2
fi
ProcessArguments --OptionIsOneArgument="-QQ" --OptionIsOneArgument="-re" "$@"
if [ "whoami" != "root" ] ; then # If not root user, if $PublicVersion ; then GetAdminPassword true # Prompt user for admin password else ShowVersion >&2 echo >&2 fi # Run this script again as root sudo -p "Please enter your admin password: " "$0" "$@" ErrorFromSudoCommand=$? # If unable to authenticate if [ $ErrorFromSudoCommand -eq 1 ] ; then echo "You entered an invalid password or you are not an admin user. Script aborted." >&2 ExitScript 1 fi if $PublicVersion ; then sudo -k # Make sudo require a password the next time it is run fi exit $ErrorFromSudoCommand # Exit so script doesn't run again
fi
# If no volumes were passed to script, the boot volume will be searched
if [ -z "$VolumesToUse" ] ; then BootVolumeWillBeSearched=true
fi
if [ $PublicVersion = true -a $CreateFilesRemovedListOnly = false -a $RemoveCrontabEntriesOnly = false -a $RemoveInvisibleFilesOnly = false -a $AutoRunScript = false -a $RunningFromWithinAppBundleOrSupportFolder = false ] ; then DetermineAction
fi
if [ $RemoveFromAllVolumes = true -a $CreateFilesRemovedListOnly = false -a $RemoveCrontabEntriesOnly = false -a $RemoveInvisibleFilesOnly = false -a $AutoRunScript = false -a $RunningFromWithinAppBundleOrSupportFolder = false ] ; then echo printf "Are you sure you want to remove Symantec files from ALL mounted volumes (y/n)? " if YesEntered ; then echo else echo echo "Script aborted. No files were removed." ExitScript 0 fi
fi
SetupCleanup
WillTense=will
if $CreateFilesRemovedListOnly ; then echo "Generating a list of files that would be removed by" >&2 echo " $FullScriptName (no files will be removed at this time)..." >&2 WillTense=would
elif $RemoveInvisibleFilesOnly ; then echo "Removing AntiVirus QuickScan files and Norton FS files..."
else if $BootVolumeWillBeSearched ; then if [ $RestartAutomatically = true -a $RemoveCrontabEntriesOnly = false ] ; then echo echo "Note: Computer will be restarted automatically if necessary." echo elif $QuitWithoutRestarting ; then echo echo "Note: This script will automatically quit when finished." echo fi fi echo "Removing Symantec files..." ! $RemoveInvisibleFiles && echo "Invisible Symantec files will not be deleted."
fi
if $RemoveCrontabEntriesOnly ; then echo "Only crontab entries $WillTense be removed."
fi
! $RemoveCrontabEntries && echo "Symantec crontab entries $WillTense not be removed."
! $RemoveInvisibleFiles && echo "AntiVirus QuickScan and Norton FS files $WillTense not be removed."
if $RemoveFromAllVolumes ; then VolumesToUse="/
"ls -d /Volumes/*
elif ! $RemoveFromOtherVolumes ; then VolumesToUse=/
fi
ListOfVolumesToUse=echo "$VolumesToUse" | sort -f | uniq
IFS='
'
for EachVolume in $ListOfVolumesToUse ; do [ -L "$EachVolume" ] && continue FilesFoundOnThisVolume=false RemoveAllNortonFiles "$EachVolume" if [ $CreateFilesRemovedListOnly = true -a $FilesFoundOnThisVolume = false -a $ListOnlyFilesThatExist = true ] ; then echo "No matching files were found on "basename "$EachVolume""." >> "$FilesRemovedList" fi
done
FinishCleanup
FinishedExitCode=$?
if [ $BootVolumeWillBeSearched = true -a $CreateFilesRemovedListOnly = false ] ; then if SymantecIsInMemory ; then echo echo "NOTE: You should now restart the computer to get Symantec processes" echo " and kexts out of memory." RestartComputer elif [ -e /Library/StartupItems/CleanUpSymWebKitUtils ] ; then echo echo "NOTE: You should now restart the computer to have CleanUpSymWebKitUtils" echo " finish removing SymWebKitUtils.framework." RestartComputer fi
fi
ExitScript $FinishedExitCode

# End of Commands to Execute

View solution in original post

42 REPLIES 42

scottb
Honored Contributor

Actually, we added this to our SEP install policies too. We run it as a script, so I don't know why you saw errors with that? No need for use to make a .pkg as it runs as a script in JSS fine.

Ours runs before the SEP install as we also offer it in Self Service and sometimes there's remnants of old SEP on Macs. It works great and makes sure there are no "can't upgrade" errors.

Here's the top of the script I have:

#!/bin/sh
# File Name: SymantecRemovalTool.command Version=5.53
# Author: Corey Swertfager, Symantec Corporation
# Created: 10/04/2001
# Modified: 11/02/2009

mojo21221
Contributor II

@boettchs

Can you post the full script or link to it? As we are looking into this as well without pushing a .pkg.

scottb
Honored Contributor

Sure. Here 'tis.

#!/bin/sh
# File Name:    SymantecRemovalTool.command
  Version=5.53
# Author:       Corey Swertfager, Symantec Corporation
# Created:      10/04/2001
# Modified:     11/02/2009
#
# WARNING: This script will remove all files and folders created by
#          Symantec OS X products (except Symantec Adminstration Console
#          for Macintosh files) and any files within those folders.
#          Therefore, you will lose ALL files that reside in those folders,
#          including any that you have created.
#
# Usage:   SymantecRemovalTool.command [options] [volume ...]
#
# Summary: See ShowUsage() function.
#
# History: 5.00 - Ported code from version 4.27.
#                 Now removes crontab entries from any OS X boot volume.
#                 Now removes Symantec items from loginwindow.plist files.
#                 Now removes receipts from any volume.
#                 Now checks for Symantec kexts/processes in memory when
#                 determining when a restart is necessary.
#                 Added -f option to suppress output of removed files.
#                 Now shows names of files as they are removed, unless the
#                 -f option is specified.
#          5.01 - Now removes:
#                    /Library/Contextual Menu Items/SAVCMPlugIn.plugin
#          5.02 - Adjusted output when a folder/file cannot be removed.
#                 Removed warning when /Library/StartupItems remains.
#                 Now removes:
#                    /Library/Application Support/Symantec/Daemon/SymDaemon.bundle
#                    /Library/Application Support/Symantec/Daemon
#                    /Library/Application Support/Symantec/SymUIAgent
#                    /Library/Application Support/Symantec/WebFraud
#                    /Library/Contextual Menu Items/SymFileSecurityCM.plugin
#                    /Library/PrivateFrameworks/SymAppKitAdditions.framework
#                    /Library/PrivateFrameworks/SymBase.framework
#                    /Library/PrivateFrameworks/SymConfidential.framework
#                    /Library/PrivateFrameworks/SymSharedSettings.framework
#                    /Library/Receipts/SymConfidential.pkg
#                    /Library/Receipts/SymFileSecurity.pkg
#                    /Library/Receipts/SymSharedFrameworks.pkg
#                    /Library/Receipts/SymSharedSettings.pkg
#                    /private/etc/mach_init.d/SymSharedSettings.plist
#          5.03 - Now removes:
#                    /Applications/Norton Confidential.app
#                    /Library/Application Support/Symantec/IntrusionPrevention
#                    /Library/LaunchDaemons/com.symantec.symdaemon.plist
#                    /Library/LaunchDaemons/com.symantec.uiagent.bundle
#                    /Library/PrivateFrameworks/SymDaemon.framework
#                    /Library/PrivateFrameworks/SymInternetSecurity.framework
#                    /Library/PrivateFrameworks/SymUIAgent.framework
#                    /Library/PrivateFrameworks/SymUIAgentUI.framework
#                    /Library/Receipts/SymConfidentialData.pkg
#                    /Library/Receipts/SymDaemon.pkg
#                    /Library/Receipts/SymFileSecurity.pkg
#                    /Library/Receipts/SymInternetSecurity.pkg
#                    /Library/Receipts/SymIntrusionPrevention.pkg
#                    /Library/Receipts/SymNCOApplication.pkg
#                    /Library/Receipts/SymUIAgent.pkg
#                    /Library/Receipts/SymWebFraud.pkg
#                    /Library/Receipts/WCIDEngine.pkg
#                    /System/Library/Extensions/SymInternetSecurity.kext
#                    /System/Library/Extensions/SymIPS.kext
#                    /System/Library/SymInternetSecurity.kext
#          5.04 - Now removes:
#                    /Applications/Firefox.app/Contents/MacOS/extensions/{0e10f3d7-07f6-4f12-97b9-9b27e07139a5}
#                    /Library/Application Support/Symantec/Assistants/Norton Confidential
#                    /Library/Application Support/Symantec/Assistants/Symantec Setup Assistant.app
#                    /Library/Application Support/Symantec/Assistants/Symantec Setup Assistant.bundle
#                    /Library/Application Support/Symantec/Assistants
#                    /Library/Receipts/SymSetupAssistant.pkg
#          5.05 - Now removes:
#                    /Library/Preferences/com.symantec.sharedsettings
#          5.06 - Now removes:
#                    /Library/Application Support/Symantec/Settings
#          5.07 - Now removes:
#                    /Library/LaunchDaemons/com.symantec.uiagent.plist
#          5.08 - Now removes:
#                    */Library/Preferences/com.symantec.uninstaller.plist
#          5.09 - Now only removes when empty:
#                    /Library/Application Support/Symantec/Assistants
#                    /Library/Application Support/Symantec/Daemon
#          5.10 - Now removes:
#                    /Library/Application Support/Symantec/Daemon/error.log
#                 Added volume name to paths in progress.
#          5.11 - Now removes:
#                    /Applications/Firefox.app/Contents/MacOS/extensions/{29dd9c80-9ea1-4aaf-9305-a0314aba24e3}
#          5.12 - Now removes:
#                    /private/var/tmp/com.symantec.liveupdate.*
#          5.13 - OSXvnc StartupItems are now filtered out during Symantec
#                 process checking.
#          5.14 - Modified for OS 10.5 compatibility.
#                 No longer removes empty /Library/StartupItems.
#                 Now removes:
#                    /Library/InputManagers/Norton Confidential for Safari
#                 Now removes files installed by NAV 11 build 1.
#          5.15 - Now removes:
#                    /.symSchedScanLockxz
#                 RemoveInvisibleFilesFromVolume functions now removes:
#                    /.SymAVQSFile
#                 Added DeleteLaunchdPlists function to remove Symantec
#                 Scheduler launchd plists.
#                 Added messaging when there are no Symantec crontab
#                 entries to delete.
#                 Renamed Remove function to RemoveItem.
#                 RemoveItem function can now match several files.
#                 Now removes additional files installed by NAV 11.
#                 A list of files deleted by this program is now appended
#                 to ReadMe.txt.
#                 All com.symantec.* preferences are now shown when using
#                 the -L option to show all files that would be deleted.
#          5.16 - Now removes:
#                    */Library/Preferences/com.symantec.nortonantivirus.*
#                    */Library/Preferences/com.symantec.nortonconfidential.*
#                    */Library/Preferences/com.symantec.schedScanResults*
#                    */Library/Preferences/com.symantec.symsched*
#          5.17 - Adjusted grep filters in SymantecIsInMemory function.
#                 Now removes:
#                    /Applications/Norton AntiVirus.app
#          5.18 - Changed how ShowVersion is called for OS 10.5 compatibility.
#          5.19 - Now removes:
#                    /Library/Internet Plug-Ins/Norton Confidential for Safari.plugin
#          5.20 - Now removes:
#                    /Library/Receipts/SymantecAVDefs*
#                    /private/tmp/com.symantec.liveupdate.restart
#          5.21 - Added output to DeleteSymantecLoginItems function.
#                 Revised output of -l and -L options.
#                 Now removes:
#                    /Library/Receipts/SymStuffit.pkg
#          5.22 - Now removes:
#                    /Library/Application Support/Symantec/Protector
#                    /Library/Receipts/SymProtector.pkg
#                    /Library/StartupItems/SymProtector
#          5.23 - Now removes:
#                    /Library/Receipts/SavLog.pkg
#          5.24 - Changed the assignment order of CRONDIR to account for
#                 cases where OS 10.5 was installed over OS 10.4.
#          5.25 - Now removes:
#                    */Library/Preferences/com.Symantec.SAVX.*
#          5.26 - Now removes:
#                    /Library/Application Support/Symantec/Assistants/Client Firewall
#                    /Library/Application Support/Symantec/Assistants/SCF Assistant Startup.app
#                    /Library/Application Support/Symantec/DeepSight
#                    /Library/Application Support/Symantec/Firewall
#                    /Library/LaunchDaemons/com.symantec.deepsight-extractor.plist
#                    /Library/LaunchDaemons/com.symantec.npfbootstrap.plist
#                    /Library/PrivateFrameworks/SymFirewall.framework
#                    /Library/PrivateFrameworks/SymPersonalFirewall.framework
#                    /System/Library/Extensions/SymPersonalFirewall.kext
#                    /usr/bin/scfx
#          5.27 - Now removes:
#                    /Library/Application Support/Symantec/Daemon/debug.log
#                    /Library/Receipts/SymantecClientFirewall.pkg
#                    /Library/Receipts/SymFirewall.pkg
#                    /Library/Receipts/SymPersonalFirewallCore.pkg
#          5.28 - Now removes:
#                    /Library/Application Support/Symantec/Assistants/Norton Firewall
#                    /Library/Application Support/Symantec/Assistants/NPF Assistant Startup.app
#                    /Library/Receipts/NortonFirewall.pkg
#                    /Library/Receipts/SymPersonalFirewallUI.pkg
#                    /usr/bin/npfx
#          5.29 - Added ReceiptsTable variable and RunPredeleteScripts
#                 function to incorporate the running of predelete scripts.
#                 Added -e option to show predelete errors.
#          5.30 - Now removes:
#                    /Library/Application Support/Symantec/Assistants/NIS Assistant Startup.app
#                    /Library/Application Support/Symantec/Assistants/Norton Internet Security
#                    /Library/Receipts/NortonInternetSecurity.pkg
#          5.31 - Now removes temporary files used by this program.
#                 Added running of pre_delete scripts to RunPredeleteScripts functions.
#          5.32 - Adjusted DeleteSymantecLoginItems diff filtering.
#          5.33 - Now removes:
#                    /private/tmp/symask
#          5.34 - Now removes:
#                    /Library/LaunchDaemons/com.symantec*
#                    /Library/Preferences/com.symantec*
#                       [except com.symantec.sacm* and com.symantec.smac*]
#                    {each user's home directory}/Library/Preferences/com.symantec*
#                       [except com.symantec.sacm* and com.symantec.smac*]
#                    {each user's home directory}/Library/Preferences/Network/com.symantec*
#                    /Library/Preferences/Network/com.symantec*
#                 Added -x option to RemoveItem function.
#                 RemoveItem function now ignores letter case when a
#                 pattern or an exclusion is passed.
#                 Links in /Volumes are now ignored.
#          5.35 - Removed return statement that caused premature script end.
#          5.36 - Now removes items installed by NFS 100.001:
#                    /Library/Application Support/Symantec/Norton Family Safety
#                    /Library/Internet Plug-Ins/Norton Family Safety.plugin
#                    /Library/PreferencePanes/Norton Family Safety.prefPane
#                    /Library/Receipts/NFSCore.pkg
#          5.37 - Revised pattern to find Symantec processes.
#                 Now removes all Dev.pkg receipts.
#          5.38 - Now removes items installed by NSM 100.008:
#                    /Library/Application Support/Symantec/Norton Safety Minder
#                    /Library/Internet Plug-Ins/Norton Safety Minder.plugin
#                    /Library/PreferencePanes/Norton Safety Minder.prefPane
#                    /Library/PreferencePanes/Ribbon.Norton.prefPane
#                    /Library/Receipts/NSMCore.pkg
#          5.39 - Now removes:
#                    /Library/Caches/com.symantec*
#                    /Library/Caches/Norton*
#                    /Library/Caches/Symantec*
#                    /Library/Logs/Norton*
#                    /Library/Logs/Symantec*
#                    /Library/Logs/SymDeepsight*
#                    /Library/Logs/SymFWLog.log
#                    /Library/Logs/SymFWRules.log*
#                    /Library/Preferences/wcid
#                    /private/var/tmp/com.symantec*
#                    {each user's home directory}/Library/Caches/com.symantec*
#                    {each user's home directory}/Library/Caches/Norton*
#                    {each user's home directory}/Library/Caches/Symantec*
#                    {each user's home directory}/Library/Preferences/wcid
#          5.40 - Fixed an erroneous "invalid password" error message.
#                 Non-removal of /opt is no longer considered an error
#                 (some third party programs install files into there).
#          5.41 - Updated Usage(s) comments.
#          5.42 - Now removes:
#                    /Library/PrivateFrameworks/SymWebKitUtils.framework
#          5.43 - Now removes:
#                    /Library/InputManagers/Norton Safety Minder
#          5.44 - Now removes:
#                    /var/db/receipts/com.symantec*
#          5.45 - Now removes if empty folder:
#                    /Library/Preferences/Network
#                 Now removes:
#                    /Applications/Firefox.app/Contents/MacOS/extensions/nortonsafetyminder@symantec.com
#          5.46 - Added -d option.
#                 Updated help.
#          5.47 - Added running of predelete scripts stored in new Symantec
#                 Uninstaller's Receipt folder.
#                 Now removes:
#                    /Library/Application Support/Symantec/Uninstaller
#                 Added -Q and -QQ options.
#                 Added KillTerminal function.
#          5.48 - Restart prompt is now shown any time boot volume is checked
#                 and there are Symantec processes and/or kexts in memory,
#                 except when -l or -L is passed.
#                 Now removes:
#                    /Library/Application Support/Symantec/Registry
#                    /Library/Application Support/Symantec/Submissions
#                    /Library/Application Support/Symantec/SymWebKitUtils
#                    /Library/PrivateFrameworks/SymSubmission.framework
#                    /Library/Receipts/SymSubmission.pkg
#                    /Library/Receipts/SymWebKitUtils.pkg
#                 Now removes /Library/PrivateFrameworks/SymWebKitUtils.framework
#                 only if the framework does not contain SymWKULoader.dylib; its
#                 receipt is removed if SymWKULoader.dylib does not exist or if
#                 /Library/StartupItems/CleanUpSymWebKitUtils exists.
#          5.49 - Excluded /LiveUpdateAdminUtility/ from processes to find in
#                 SymantecIsInMemory function.
#          5.50 - Fixed RunPredeleteScripts function so that it runs more than
#                 just the first predelete script in Symantec Uninstaller's
#                 Receipts folder and allows for multiple predelete scripts in
#                 /Library/Receipts receipts.
#                 Now removes:
#                    /Library/InputManagers/SymWebKitUtils
#                    /Library/StartupItems/SymQuickMenuOSFix
#                    /Library/StartupItems/SymWebKitUtilsOSFix
#                 Restart prompt is now shown if CleanUpSymWebKitUtils exists in
#                 /Library/StartupItems.
#                 Running ofLiveUpdate.pkg predelete script is no longer skipped.
#          5.51 - Now removes:
#                    /Library/Application Support/Symantec/SEP
#                    /Library/Application Support/Symantec/SMC
#                    /Library/Application Support/Symantec/SNAC
#                    /Library/LaunchAgents/com.symantec*
#                    /Library/Receipts/SMC.pkg
#                    /Library/Receipts/SNAC.pkg
#                    /Library/Receipts/Symantec Endpoint Protection.pkg
#                    /Library/Receipts/SymantecSAQuickMenu.pkg
#                    /Library/Services/ScanService.service
#                    /Library/Services [deleted if empty]
#                    /Library/StartupItems/SMC
#                    /usr/lib/libsymsea.1.0.0.dylib
#                    /usr/lib/libsymsea.dylib
#                 Adjusted RunPredeleteScripts function to limit predelete script
#                 names to those ending with predelete or pre_delete; doing so
#                 prevents a bus error by no longer running "predeletetool".
#          5.52 - Added -m option to use more program when -l, -L, or -R
#                 options are used.
#                 Removed -r option, which deleted only receipts.
#                 Added -R option to include folder contents when showing
#                 installed files.
#                 Progress shown when using the -l, -L, or -R options is
#                 now sent to standard error to facilitate piping the
#                 generated report to a file without piping progress.
#          5.53 - Now removes:
#                    /Library/ScriptingAdditions/SymWebKitUtils.osax
#                    /Library/ScriptingAdditions/SymWebKitUtilsSL.osax
#                    /usr/local/lib/libgecko3parsers.dylib
#                    /usr/local/lib [deleted if empty]
#                    /usr/local [deleted if empty]

# *** Variable Initializations ***

PATH=/bin:/sbin:/usr/bin:/usr/sbin
AbbreviatedScriptName=`basename "$0" .command`
AutoRunScript=TRUE
BootVolumeWillBeSearched=FALSE
CreateFilesRemovedListOnly=FALSE
DoRunPredeleteScripts=TRUE
CurrentVolumeBeingUsed="/"
FilesRemovedList="/private/tmp/${AbbreviatedScriptName}RemovesThese.txt"
FilesRemovedFilesOnlyList="/private/tmp/${AbbreviatedScriptName}RemovesThese-FilesOnly.txt"
FilesRemovedListOfOld="/Users/Shared/${AbbreviatedScriptName}RemovesThese.txt"
FilesWereSaved=FALSE
FinishedExitCode=0
FullScriptName=`basename "$0"`
LANG=""
ListOnlyFilesThatExist=FALSE
LogFile="/private/tmp/${AbbreviatedScriptName}Log.txt"
LogFileOfOld="/Users/Shared/${AbbreviatedScriptName}Log.txt"
NoFilesToRemove=TRUE
NumberOfArgumentsPassedToScript=$#
PauseBeforeRestarting=TRUE
PublicVersion=TRUE
QuitTerminalForcefully=FALSE
QuitTerminalForcefullyForAll=FALSE
QuitWithoutRestarting=FALSE
$AutoRunScript && QuitWithoutRestarting=TRUE
# ----- ReceiptsTable BEGIN ------------------------------------------------
#       (2 fields, tab delimited):
#          Receipt name / Receipt option (-a = delete receipt*, -s = skip run of predelete script)
ReceiptsTable='
# Check to make sure there are no vague receipts that may be used by
#    third party software before releasing to the public.
# This line may need to be removed to avoid deleting third party files:
CompatibilityCheck.pkg
# This line may need to be removed to avoid deleting third party files:
Decomposer.pkg
# This line may need to be removed to avoid deleting third party files:
DeletionTracking.pkg
FileSaver.pkg
LiveUpdate.pkg
NAVcorporate.pkg
NAVEngine.pkg
NAVContextualMenu.pkg
NAVWidget.pkg
NAVDefs.pkg
navx.pkg
NFSCore.pkg
NISLaunch.pkg
Norton AntiVirus Application.pkg
Norton AntiVirus Product Log.rtf
Norton AntiVirus.pkg
Norton AutoProtect.pkg
Norton Disk Editor X.pkg
Norton Internet Security Log.rtf
Norton Personal Firewall 3.0 Log.rtf
Norton Scheduled Scans.pkg
Norton Scheduler.pkg
Norton SystemWorks 3.0 Log.rtf
Norton Utilities 8.0 Log.rtf
NortonAutoProtect.pkg
# Remove all NortonAVDefs receipts
NortonAVDefs    -a
NortonDefragger.pkg
NortonDiskDoctor.pkg
NortonFirewall.pkg
NortonInternetSecurity.pkg
NortonLauncher.pkg
NortonParentalControl.pkg
NortonPersonalFirewall.pkg
NortonPersonalFirewallMenu.pkg
NortonPrivacyControl.pkg
NortonQuickMenu.pkg
NPC Installer Log
NPC.pkg
NSMCore.pkg
NSWLaunch.pkg
NUMCompatibilityCheck.pkg
NumDocs.pkg
NUMLaunch.pkg
SavLog.pkg
# This line may need to be removed to avoid deleting third party files:
Scheduled Scans.pkg
# This line may need to be removed to avoid deleting third party files:
Scheduler.pkg
# NAV 9 installs the StuffIt engine if it needs to and creates the
# StuffIt.pkg receipt for it. The following line may need to be removed
# (but should not need to be) to avoid deleting third party files:
StuffIt.pkg
SDProfileEditor.pkg
SMC.pkg
SNAC.pkg
SpeedDisk.pkg
Symantec Alerts.pkg
Symantec AntiVirus.pkg
Symantec AutoProtect.pkg
Symantec AutoProtect Prefs.pkg
Symantec Decomposer.pkg
Symantec Endpoint Protection.pkg
Symantec Scheduled Scans.pkg
Symantec Scheduler.pkg
# Remove all SymantecAVDefs receipts
SymantecAVDefs  -a
SymantecClientFirewall.pkg
SymantecDecomposer.pkg
SymantecDeepSightExtractor.pkg
SymantecParentalControl.pkg
SymantecQuickMenu.pkg
SymantecSAQuickMenu.pkg
SymantecUninstaller.pkg
SymantecURLs.pkg
SymAV10StuffItInstall.pkg
SymAVScanServer.pkg
SymConfidential.pkg
SymConfidentialData.pkg
SymDaemon.pkg
SymDC.pkg
SymDiskMountNotify.pkg
SymEvent.pkg
SymFileSecurity.pkg
SymFirewall.pkg
SymFS.pkg
SymHelper.pkg
SymHelpScripts.pkg
SymInstallExtras.pkg
SymInternetSecurity.pkg
SymIntrusionPrevention.pkg
SymIPS.pkg
SymNCOApplication.pkg
SymOSXKernelUtilities.pkg
SymPersonalFirewallCore.pkg
SymPersonalFirewallUI.pkg
SymProtector.pkg
SymSetupAssistant.pkg
SymSharedFrameworks.pkg
SymSharedSettings.pkg
SymStuffit.pkg
SymSubmission.pkg
SymUIAgent.pkg
SymWebFraud.pkg
SymWebKitUtils.pkg
Unerase.pkg
# This line may need to be removed to avoid deleting third party files:
URL.pkg
VolumeAssist.pkg
VolumeRecover.pkg
WCIDEngine.pkg
Wipe Info.pkg
'
# ----- ReceiptsTable END --------------------------------------------------
RecurseFolders=FALSE
RemoveCrontabEntries=TRUE
RemoveCrontabEntriesOnly=FALSE
RemoveInvisibleFiles=TRUE
RemoveInvisibleFilesOnly=FALSE
RemoveFromAllVolumes=FALSE
RemoveFromOtherVolumes=FALSE
RestartAutomatically=FALSE
RestartMayBeNeeded=FALSE
SavedFilesDir="/private/tmp/${AbbreviatedScriptName}SavedFiles"
ShowFilesAsRemoved=TRUE
ShowPredeleteErrors=FALSE
ShowQuitMessage=TRUE
SomeFileWasRemoved=FALSE
SomeFileWasRemovedFromNonBootVolume=FALSE
SomeFileWasRemovedFromBootVolume=FALSE
UseMore=FALSE

# *** Function Declarations ***

AssignOptions()
{
   # Usage:     AssignOptions $1
   # Argument:  $1 = Option to check.
   # Summary:   Assigns options for script. If $1 is a valid option,
   #            it changes script options accordingly.
   #
   case "$1" in
      -A)
         RemoveFromAllVolumes=TRUE
         BootVolumeWillBeSearched=TRUE
         ;;
      -c)
         RemoveCrontabEntriesOnly=TRUE
         RemoveCrontabEntries=TRUE
         RemoveInvisibleFilesOnly=FALSE
         RemoveInvisibleFiles=FALSE
         ;;
      -C)
         RemoveCrontabEntriesOnly=FALSE
         RemoveCrontabEntries=FALSE
         ;;
      -d)
         DoRunPredeleteScripts=FALSE
         ;;
      -e)
         ShowPredeleteErrors=TRUE
         ;;
      -f)
         ShowFilesAsRemoved=FALSE
         ;;
      -h)
         ShowUsage
         ;;
      -i)
         RemoveInvisibleFilesOnly=TRUE
         RemoveInvisibleFiles=TRUE
         RemoveCrontabEntries=FALSE
         RemoveCrontabEntriesOnly=FALSE
         ;;
      -I)
         RemoveInvisibleFilesOnly=FALSE
         RemoveInvisibleFiles=FALSE
         ;;
      -l)
         CreateFilesRemovedListOnly=TRUE
         ListOnlyFilesThatExist=TRUE
         ;;
      -L)
         CreateFilesRemovedListOnly=TRUE
         ListOnlyFilesThatExist=FALSE
         RecurseFolders=FALSE
         ;;
      -m)
         UseMore=TRUE
         ;;
      -p)
         PauseBeforeRestarting=FALSE
         ;;
      -q)
         QuitWithoutRestarting=TRUE
         RestartAutomatically=FALSE
         ;;
      -Q)
         QuitTerminalForcefully=TRUE
         QuitTerminalForcefullyForAll=FALSE
         QuitWithoutRestarting=TRUE
         RestartAutomatically=FALSE
         ;;
      -QQ)
         QuitTerminalForcefully=TRUE
         QuitTerminalForcefullyForAll=TRUE
         QuitWithoutRestarting=TRUE
         RestartAutomatically=FALSE
         ;;
      -R)
         CreateFilesRemovedListOnly=TRUE
         ListOnlyFilesThatExist=TRUE
         RecurseFolders=TRUE
         ;;
      -re)
         RestartAutomatically=TRUE
         QuitWithoutRestarting=FALSE
         ;;
      -V)
         echo $Version
         ExitScript 0
         ;;
      *)
         AssignVolume "$1"   # Assign it to a Volume variable
         # If not a valid volume
         if [ $? = 1 ] ; then
            echo
            echo "ERROR: Invalid option or volume name: "$1"."
            ShowUsageHelp 4
         fi
         RemoveFromOtherVolumes=TRUE
         ;;
   esac
}

AssignVolume()
{
   # Usage:     AssignVolume $1
   # Argument:  $1 = Volume name. The name can begin with "/Volumes/"
   #                 unless it is "/" (boot volume).
   # Summary:   Assigns the name of the volume passed as $1 to VolumesToUse.
   #            If volume is assigned, 0 is returned; else, 1 is returned.
   #
   # If nothing passed, skip assignment
   [ -z "$1" ] && return 1
   VolumeToAssign=`CheckIfValidVolume "$1"`
   if [ -z "$VolumeToAssign" ] ; then
      VolumeToAssign=`CheckIfValidVolume "/Volumes/$1"`
      [ -z "$VolumeToAssign" ] && return 1
   fi
   [ "$VolumeToAssign" = "/" ] && BootVolumeWillBeSearched=TRUE
   VolumesToUse="$VolumesToUse
$VolumeToAssign"
   return 0
}

CheckIfValidVolume()
{
   # Usage:     CheckIfValidVolume $1
   # Argument:  $1 = Volume name to check.
   # Summary:   If $1 is a valid volume name, it is echoed;
   #            else, "" is echoed.
   #
   VVolume=""
   # If something passed
   if [ -n "$1" ] ; then
      # If it is a directory and not a link
      if [ -d "$1" -a ! -L "$1" ] ; then
         InitCurrentDir=`pwd` # Save initial directory location
         cd "$1"
         if [ "`pwd`" = "/" -o "`pwd`" = "//" ] ; then
            VVolume=/
         else
            cd ..
            ParentDir=`pwd`
            # If there is an extra / at beginning of path, remove it
            [ "`echo "z$ParentDir" | awk '{print substr($0,2,2)}'`" = "//" ] && ParentDir=`echo "z$ParentDir" | awk '{print substr($0,3)}'`
            # If $1 is a volume, assign it to VVolume
            [ "$ParentDir" = "/Volumes" ] && VVolume="$ParentDir/`basename "$1"`"
         fi
         cd "$InitCurrentDir"  # Return to initial directory
      fi
   fi
   echo "$VVolume"
}

DeleteCrontabEntries()
{
   # Usage:     DeleteCrontabEntries [$1]
   # Argument:  $1 = Volume name. The name should begin with "/Volumes/"
   #                 unless it is "/" (boot volume). If NULL, then / is
   #                 used as volume name.
   # Authors:   John Hansen, Corey Swertfager
   # Summary:   Deletes from / or volume specified the crontab entries
   #            created by Norton Scheduler and Symantec Scheduler.
   # Note:      User must be root when calling this function.
   #
   if [ "z$1" = z/ ] ; then
      VolumeToDeleteCrontabsFrom=""
   else
      VolumeToDeleteCrontabsFrom="$1"
   fi
   CRONDIR="$VolumeToDeleteCrontabsFrom/private/var/at/tabs"
   # IF OS 10.5 crontab directory does not exist, try the one from OS 10.4.x and earlier
   [ ! -d "$CRONDIR" ] && CRONDIR="$VolumeToDeleteCrontabsFrom/private/var/cron/tabs"
   if [ ! -d "$CRONDIR" ] ; then
      if $CreateFilesRemovedListOnly ; then
         if [ -z "$VolumeToDeleteCrontabsFrom" ] ; then
            echo "No crontab directory was found on on the current boot volume." >> "$FilesRemovedList"
         else
            echo "No crontab directory was found on on the volume "`basename "$VolumeToDeleteCrontabsFrom"`"." >> "$FilesRemovedList"
         fi
         echo "" >> "$FilesRemovedList"
      else
         if [ -z "$VolumeToDeleteCrontabsFrom" ] ; then
            echo "No crontab directory was found on on the current boot volume."
         else
            echo "No crontab directory was found on on the volume "`basename "$VolumeToDeleteCrontabsFrom"`"."
         fi
      fi
      return 1
   fi
   TEMPFILETEMPLATE="/private/tmp/NortonTemp"
   GREP1="^#SqzS"
   GREP2="^#SYMANTEC SCHEDULER CRON ENTRIES"
   GREP3="^#PLEASE DO NOT EDIT.$"
   GREP4="EvType1=.*EvType2=.*Sched="
   GREP5="Norton Solutions Support/Scheduler/schedLauncher"
   GREP6="Symantec/Scheduler/SymSecondaryLaunch.app/Contents/schedLauncher"
   SymantecCrontabEntryExists=FALSE
   CurrentDir="`pwd`" # Save initial directory location
   cd "$CRONDIR"
   # Set IFS to only newline to get all crontabs
   IFS='
'
   # List each crontab, pipe through grep command and replace
   for user in `ls` ; do
      # If not root and not a valid user, skip
      [ "z$user" != "zroot" -a ! -d "$VolumeToDeleteCrontabsFrom/Users/$user" ] && continue
      # If deleting from boot volume
      if [ -z "$VolumeToDeleteCrontabsFrom" ] ; then
         # Check to see if there is a Symantec crontab entry
         if [ "`crontab -u "$user" -l | grep -c "$GREP1|$GREP2|$GREP3|$GREP4|$GREP5|$GREP6"`" != 0 ] ; then
            SymantecCrontabEntryExists=TRUE
         else
            continue   # Nothing to remove, skip user
         fi
         $CreateFilesRemovedListOnly && break
         TEMPFILE="$TEMPFILETEMPLATE`date +"%Y%m%d%H%M%S"`"
         crontab -u "$user" -l | grep -v "$GREP1|$GREP2|$GREP3|$GREP4|$GREP5|$GREP6" > $TEMPFILE
         # Restore crontab file if it has more entries, else remove
         if [ -s "$TEMPFILE" ] ; then
            crontab -u "$user" $TEMPFILE
         else
            echo "y" | crontab -u "$user" -r
         fi
      else
         # Check to see if there is a Symantec crontab entry
         if [ "`grep -c "$GREP1|$GREP2|$GREP3|$GREP4|$GREP5|$GREP6" "$user"`" != 0 ] ; then
            SymantecCrontabEntryExists=TRUE
         else
            continue   # Nothing to remove, skip user
         fi
         $CreateFilesRemovedListOnly && break
         TEMPFILE="$TEMPFILETEMPLATE`date +"%Y%m%d%H%M%S"`"
         grep -v "$GREP1|$GREP2|$GREP3|$GREP4|$GREP5|$GREP6" "$user" > $TEMPFILE
         # Restore crontab file if it has more entries, else remove
         if [ -s "$TEMPFILE" ] ; then
            cat $TEMPFILE >"$user"
         else
            rm -f "$user" 2>/dev/null
         fi
      fi
      /bin/rm "$TEMPFILE" 2>/dev/null
   done
   cd "$CurrentDir"   # Return to intial directory
   if $SymantecCrontabEntryExists ; then
      if $CreateFilesRemovedListOnly ; then
         if [ -z "$VolumeToDeleteCrontabsFrom" ] ; then
            echo "Symantec crontab entries would be deleted from the current boot volume." >> "$FilesRemovedList"
         else
            echo "Symantec crontab entries would be deleted from the volume" >> "$FilesRemovedList"
            echo ""`basename "$VolumeToDeleteCrontabsFrom"`"." >> "$FilesRemovedList"
         fi
         echo "" >> "$FilesRemovedList"
      else
         if [ -z "$VolumeToDeleteCrontabsFrom" ] ; then
            echo "Symantec crontab entries were deleted from the current boot volume."
         else
            echo "Symantec crontab entries were deleted from the volume"
            echo ""`basename "$VolumeToDeleteCrontabsFrom"`"."
         fi
      fi
      NoFilesToRemove=FALSE
   else
      if $CreateFilesRemovedListOnly ; then
         if [ -z "$VolumeToDeleteCrontabsFrom" ] ; then
            echo "There are no Symantec crontab entries on the current boot volume;" >> "$FilesRemovedList"
            echo "no crontab entries would be removed from it." >> "$FilesRemovedList"
         else
            echo "There are no Symantec crontab entries on the volume "`basename "$VolumeToDeleteCrontabsFrom"`";" >> "$FilesRemovedList"
            echo "no crontabs would be adjusted on that volume." >> "$FilesRemovedList"
         fi
         echo "" >> "$FilesRemovedList"
      elif [ -z "$VolumeToDeleteCrontabsFrom" ] ; then
         echo "There are no Symantec crontab entries to delete from the current boot volume."
      else
         echo "There are no Symantec crontab entries to delete from the volume"
         echo ""`basename "$VolumeToDeleteCrontabsFrom"`"."
      fi
   fi
   return 0
}

DeleteLaunchdPlists()
{
   # Usage:     DeleteLaunchdPlists [$1]
   # Argument:  $1 = Volume name. The name should begin with "/Volumes/"
   #                 unless it is "/" (boot volume). If NULL, then / is
   #                 used as volume name.
   # Summary:   Deletes from / or volume specified the launchd plists
   #            created by Symantec Scheduler.
   # Note:      User must be root when calling this function.
   #
   if [ "z$1" = z/ ] ; then
      VolumeToDeleteLaunchdPlistsFrom=""
   else
      VolumeToDeleteLaunchdPlistsFrom="$1"
   fi
   LaunchdPlists=`ls -d "$VolumeToDeleteLaunchdPlistsFrom/Library/LaunchDaemons/com.symantec.Sched"*.plist 2>/dev/null`
   if [ "$LaunchdPlists" ] ; then
      if $CreateFilesRemovedListOnly ; then
         if [ -z "$VolumeToDeleteLaunchdPlistsFrom" ] ; then
            echo "Symantec Scheduler launchd plists would be deleted from the current boot volume." >> "$FilesRemovedList"
         else
            echo "Symantec Scheduler launchd plists would be deleted from the volume" >> "$FilesRemovedList"
            echo ""`basename "$VolumeToDeleteLaunchdPlistsFrom"`"." >> "$FilesRemovedList"
         fi
         echo "" >> "$FilesRemovedList"
      else
         IFS='
'
         for EachPlist in $LaunchdPlists ; do
            rm -f "$EachPlist" 2>/dev/null
         done
         if [ -z "$VolumeToDeleteLaunchdPlistsFrom" ] ; then
            echo "Symantec Scheduler launchd plists were deleted from the current boot volume."
         else
            echo "Symantec Scheduler launchd plists were deleted from the volume"
            echo ""`basename "$VolumeToDeleteLaunchdPlistsFrom"`"."
         fi
      fi
      NoFilesToRemove=FALSE
   else
      if $CreateFilesRemovedListOnly ; then
         if [ -z "$VolumeToDeleteLaunchdPlistsFrom" ] ; then
            echo "There are no Symantec Scheduler launchd plists on the current boot volume," >> "$FilesRemovedList"
            echo "so none would be removed from it." >> "$FilesRemovedList"
         else
            echo "There are no Symantec Scheduler launchd plists on the volume" >> "$FilesRemovedList"
            echo ""`basename "$VolumeToDeleteLaunchdPlistsFrom"`", so none would be removed from it." >> "$FilesRemovedList"
         fi
         echo "" >> "$FilesRemovedList"
      elif [ -z "$VolumeToDeleteLaunchdPlistsFrom" ] ; then
         echo "There are no Symantec Scheduler launchd plists to delete from the current boot"
         echo "volume."
      else
         echo "There are no Symantec Scheduler launchd plists to delete from the volume"
         echo ""`basename "$VolumeToDeleteLaunchdPlistsFrom"`"."
      fi
   fi
   return 0
}

DeleteSymantecLoginItems()
{
   # Usage:     DeleteSymantecLoginItems [$1]
   # Argument:  $1 = Name of volume from which to remove login items.
   #                 The name must begin with "/Volumes/" unless it is
   #                 "/" (boot volume). If nothing is passed, / is assumed.
   # Authors:   John Hansen, Corey Swertfager
   # Summary:   Deletes Symantec items from all loginwindow.plist files on
   #            volume specified. Returns the number of files adjusted or
   #            that would be deleted.
   # Note:      If this function is run while booted in OS 10.1.x, it will
   #            not be able to adjust loginwindow.plist files on an OS 10.4.x
   #            volume because plutil did not ship with basic OS 10.1.x.
   #            Boolean CreateFilesRemovedListOnly must be defined before
   #            running this function.
   #
   TARGETVOLUME="$1"
   [ "z$1" = z/ ] && TARGETVOLUME=""
   TEMPFILETEMPLATE=/private/tmp/DeleteSymantecLoginItems
   OUTFILE=${TEMPFILETEMPLATE}`date +"%Y%m%d%H%M%S"`-1
   OUTFILE2=${TEMPFILETEMPLATE}`date +"%Y%m%d%H%M%S"`-2
   SOURCEFILE=${TEMPFILETEMPLATE}`date +"%Y%m%d%H%M%S"`-3
   GREPSTR="/Library/Application Support/Symantec|/Library/Application Support/Norton Solutions|/Library/Application Support/Symnatec/Scheduler/SymSecondaryLaunch.app|/Library/StartupItems/Norton"
   FILESADJUSTED=0
   IFS='
'
   for EachUser in `ls "$TARGETVOLUME/Users" 2>/dev/null` "root" "/" ; do
      if [ "z$EachUser" = z/ ] ; then
         ORIGFILE="$TARGETVOLUME/Library/Preferences/loginwindow.plist"
      elif [ "z$EachUser" = zroot ] ; then
         ORIGFILE="$TARGETVOLUME/private/var/root/Library/Preferences/loginwindow.plist"
      else
         ORIGFILE="$TARGETVOLUME/Users/$EachUser/Library/Preferences/loginwindow.plist"
      fi
      [ ! -f "$ORIGFILE" ] && continue
      rm -rf $SOURCEFILE 2>/dev/null
      cp "$ORIGFILE" $SOURCEFILE
      CheckSyntax=TRUE
      plutil -convert xml1 $SOURCEFILE 2>/dev/null
      # If plutil failed to convert the plist, don't check syntax later
      [ $? != 0 ] && CheckSyntax=FALSE
      IsBinaryFormat=FALSE
      # If original plist is different than converted plist, treat it as a binary file
      [ -n "`diff "$ORIGFILE" $SOURCEFILE 2>/dev/null`" ] && IsBinaryFormat=TRUE
      grep -B 4 -A 1 "$GREPSTR" $SOURCEFILE > $OUTFILE
      # If some Symantec login item(s) found
      if [ -s $OUTFILE ] ; then
         if $CreateFilesRemovedListOnly ; then
            [ $FILESADJUSTED = 0 ] && echo "Symantec login items would be removed from:" >>"$FilesRemovedList"
            echo "   "$ORIGFILE"" >>"$FilesRemovedList"
            FILESADJUSTED=`expr $FILESADJUSTED + 1`
         else
#            diff $SOURCEFILE $OUTFILE | sed -e 's/< //' | grep -v "[0-9],[0-9]" > $OUTFILE2
            diff $SOURCEFILE $OUTFILE | grep '^< ' | sed -e 's/< //' > $OUTFILE2
            # If the some login item information is missing
            if [ `grep -c '<dict>$' $OUTFILE` != `grep -c '</dict>$' $OUTFILE` ] ; then
               echo "ERROR: Could not remove Symantec login items from:"
               echo "       $ORIGFILE"
            # Else if syntax is to be checked and plist contains bad syntax
            elif [ $CheckSyntax = TRUE -a -n "`plutil -s $OUTFILE 2>/dev/null`" ] ; then
               echo "ERROR: Could not remove Symantec login items from:"
               echo "       $ORIGFILE"
            elif [ -n "`grep "^Binary files .* differ" $OUTFILE2`" ] ; then
               echo "ERROR: Plist is in binary format. Could not remove Symantec login items from:"
               echo "       $ORIGFILE"
            else
               [ $FILESADJUSTED = 0 ] && echo "Removing Symantec login items from:"
               echo "   "$ORIGFILE""
               cat $OUTFILE2 > "$ORIGFILE"
               $IsBinaryFormat && plutil -convert binary1 "$ORIGFILE" 2>/dev/null
               FILESADJUSTED=`expr $FILESADJUSTED + 1`
            fi
         fi
      fi
   done
   rm -f $OUTFILE 2>/dev/null
   rm -f $OUTFILE2 2>/dev/null
   rm -f $SOURCEFILE 2>/dev/null
   [ $FILESADJUSTED -gt 0 ] && echo "" >>"$FilesRemovedList"
   return $FILESADJUSTED
}

DetermineAction()
{
   # Usage:     DetermineAction
   # Summary:   Determines which action to take based on user input.
   #
   clear
   echo
   ShowVersion
   echo "
WARNING: This script will remove all files and folders created by Symantec
         OS X products (except Symantec Adminstration Console for Macintosh
         files) and any files within those folders. Therefore, you will
         lose ALL files that reside in those folders, including any that
         you have created.
"
   echo "1 - Remove all Symantec files/folders."
   echo
   echo "2 - Quit. Do not remove any files."
   echo
   printf "Enter choice (1 or 2): "
   read choice
   echo
   case "`echo "z$choice" | awk '{print tolower(substr($0,2))}'`" in
      1)   # Remove files
         CreateFilesRemovedListOnly=FALSE
         ;;
      2|q|quit)   # Quit
         echo "Program cancelled. No files were removed."
         ExitScript 0
         ;;
      *)   # Show choices again
         DetermineAction
         ;;
   esac
}

ExitScript()
{
   # Usage:     ExitScript [$1]
   # Argument:  $1 = The value to pass when calling the exit command.
   # Summary:   Checks to see if ShowQuitMessage and RunScriptAsStandAlone
   #            variables are set to TRUE. If so, a message is displayed;
   #            otherwise, no message is displayed. The script is then
   #            exited and passes $1 to exit command. If nothing is passed
   #            to $1, then 0 is passed to exit command. If a non-integer
   #            is passed to $1, then 255 is passed to exit command.
   #
   rm -f "$FilesRemovedList" "$FilesRemovedFilesOnlyList" "$LogFile" 2>/dev/null 1>&2
   if $QuitTerminalForcefully ; then
      KillTerminal
   elif [ $ShowQuitMessage = TRUE -a $RunScriptAsStandAlone = TRUE ] ; then
      echo
      echo "NOTE: If you double-clicked this script, quit Terminal application now."
      echo
   fi
   [ -z "$1" ] && exit 0
   [ -z "`expr "$1" / 1 2>/dev/null`" ] && exit 255
   exit $1
}

FinishCleanup()
{
   # Usage:     FinishCleanup
   # Summary:   Displays then deletes the file named by LogFile, a log
   #            of files not removed by RemoveItem function, if ErrorOccurred
   #            is TRUE. If NoFilesToRemove is TRUE, a message is shown
   #            and the function is exited. If RemoveInvisibleFilesOnly
   #            is TRUE, a message is shown and the function is exited;
   #            otherwise, a message is shown. Returns 2 if ErrorOccurred
   #            is TRUE, 0 otherwise.
   #
   if $CreateFilesRemovedListOnly ; then
      clear >&2
      if $UseMore ; then
         ShowContents "$FilesRemovedList"
      else
         cat "$FilesRemovedList"
      fi
      echo ""  >&2
      echo "NOTE: No files have been removed."  >&2
      echo ""  >&2
      /bin/rm -rf "$FilesRemovedList" "$FilesRemovedFilesOnlyList" 2>/dev/null 1>&2
      return 0
   elif $ErrorOccurred ; then
      echo
      # Display LogFile
      ShowContents "$LogFile"
      # Remove LogFile
      /bin/rm -rf "$LogFile" 2>/dev/null 1>&2
      echo
      if $RemoveInvisibleFilesOnly ; then
         echo "NOTE: Not all of the invisible Symantec files were removed."
         echo "      Make sure each volume passed is unlocked and accessible."
         return 2
      else
         echo "NOTE: Not all folders/files were removed."
         echo "      Perhaps a file or folder listed above is in use or a folder"
         echo "      listed above is not empty."
         if $RestartMayBeNeeded ; then
            echo
            echo "Some Symantec product files have been removed from the boot volume."
            return 2
         else
            if $SomeFileWasRemoved ; then
               echo
               echo "Some folders or files have been removed."
            fi
            return 2
         fi
      fi
   fi
   if $RemoveInvisibleFilesOnly ; then
      if $NoFilesToRemove ; then
         echo "There were no invisible Symantec files to be removed."
      else
         echo "AntiVirus QuickScan and/or Norton FS files have been removed."
      fi
      return 0
   fi
   if $NoFilesToRemove ; then
      echo "There were no files that needed to be removed. No files were removed."
      return 0
   fi
   $RemoveCrontabEntriesOnly && return 0
   echo
   if $RestartMayBeNeeded ; then
      printf "Symantec product files have been removed from the boot volume"
      if $SomeFileWasRemovedFromNonBootVolume ; then
         echo
         echo "and from other volume(s) listed above."
      else
         echo "."
      fi
   else
      echo "Symantec product files have been removed from the above volume(s)."
   fi
   return 0
}

GetAdminPassword()
{
   # Usage:     GetAdminPassword [$1]
   # Argument:  $1 - Prompt for password. If TRUE is passed, a user that
   #                 is not root will always be asked for a password. If
   #                 something other than TRUE is passed or if nothing is
   #                 passed, then a user that is not root will only be
   #                 prompted for a password if authentication has lapsed.
   # Summary:   Gets an admin user password from the user so that
   #            future sudo commands can be run without a password
   #            prompt. The script is exited with a value of 1 if
   #            the user enters an invalid password or if the user
   #            is not an admin user. If the user is the root user,
   #            then there is no prompt for a password (there is
   #            no need for a password when user is root).
   #            NOTE: Make sure ExitScript function is in the script.
   #
   # If root user, no need to prompt for password
   [ "`whoami`" = "root" ] && return 0
   echo >&2
   # If prompt for password
   if [ "$1" = "TRUE" -o "$1" = "true" ] ; then
      ShowVersion >&2
      echo >&2
      sudo -k >&2   # Make sudo require a password the next time it is run
      echo "You must be an admin user to run this script." >&2
   fi
   # A dummy sudo command to get password
   sudo -p "Please enter your admin password: " date 2>/dev/null 1>&2
   if [ ! $? = 0 ] ; then       # If failed to get password, alert user and exit script
      echo "You entered an invalid password or you are not an admin user. Script aborted." >&2
      ExitScript 1
   fi
}

KillTerminal()
{
   ProcessLines=`ps -axww | grep -e "/Applications/Utilities/Terminal.app" | grep -v grep | sort -f`
   if [ -z "$ProcessLines" ] ; then
      return
   elif [ `echo "$ProcessLines" | grep . -c` -gt 1 -a $QuitTerminalForcefullyForAll = FALSE ] ; then
      echo "NOTE: Terminal was launched more than once so it could not be quit."
      echo "      Use the -QQ option to force Terminal to be quit for all users."
      return
   else
      echo "WARNING: Quitting Terminal."
   fi
   IFS='
'
   for ProcessLine in $ProcessLines ; do
      ProcessID=`printf "%s" "$ProcessLine" | awk '{print $1}'`
      kill -9 "$ProcessID"
   done
}

RemoveAllNortonFiles()
{
   # Usage:     RemoveAllNortonFiles $1
   # Argument:  $1 = Volume name. The name should begin with "/Volumes/"
   #                 unless it is "/" (boot volume).
   # Summary:   Removes all OS X Norton products' files and folders
   #            from volume named by $1 if RemoveInvisibleFilesOnly
   #            equals FALSE; otherwise, removes only the invisible Norton
   #            files. Removes the invisible Norton files from other
   #            volumes that are passed to the script. Symantec crontab
   #            entries are removed if RemoveCrontabEntries = TRUE.
   #
   # If not a valid volume, return 1
   [ -z "`CheckIfValidVolume "$1"`" ] && return 1
   CurrentVolumeBeingUsed="$1"
   if $CreateFilesRemovedListOnly ; then
      printf "" > "$FilesRemovedFilesOnlyList"
      echo "" >> "$FilesRemovedList"
      if [ `echo "$ListOfVolumesToUse" | grep -c .` -gt 1 ] ; then
         if [ "$1" = / ] ; then
            echo "------ Volume: / (current boot volume) ------" >> "$FilesRemovedList"
         else
            echo "------ Volume: "`basename "$1"`" ------" >> "$FilesRemovedList"
         fi
         echo "" >> "$FilesRemovedList"
      fi
   fi
   $RemoveCrontabEntries && DeleteCrontabEntries "$1"
   $RemoveCrontabEntries && DeleteLaunchdPlists "$1"
   $RemoveCrontabEntriesOnly && return 0
   ! $RemoveInvisibleFilesOnly && DeleteSymantecLoginItems "$1"
   if $CreateFilesRemovedListOnly ; then
      if ! $RemoveInvisibleFilesOnly ; then
         RunPredeleteScripts "$1"
         echo "" >> "$FilesRemovedList"
      fi
      if $ListOnlyFilesThatExist ; then
         echo "The following files/folders currently exist and would be removed unless" >> "$FilesRemovedList"
         echo "otherwise noted:" >> "$FilesRemovedList"
      else
         echo "$FullScriptName would attempt to find and remove the following:" >> "$FilesRemovedList"
      fi
      echo "" >> "$FilesRemovedList"
   fi
   RemoveInvisibleFilesFromVolume "$1"
   $RemoveInvisibleFilesOnly && return 0
   $CreateFilesRemovedListOnly || RunPredeleteScripts "$1"
   # If not an OS X volume, return 1
   [ ! -d "$1/Library/Application Support" ] && return 1
   if $CreateFilesRemovedListOnly ; then
      echo "Finding visible Symantec files on:   $1" >&2
   elif $ShowFilesAsRemoved ; then
      echo "Locating visible Symantec files in:   $1"
   else
      echo "Removing visible Symantec files from:   $1"
   fi
   cd "$1"
   if [ "`pwd`" = "/" ] ; then
      VolumePrefix=""
   else
      VolumePrefix="`pwd`"
   fi
   RemoveItem "/.com_symantec_symfs_private"
   RemoveItem "/.symSchedScanLockxz"
   RemoveItem "/Applications/Firefox.app/Contents/MacOS/extensions/{0e10f3d7-07f6-4f12-97b9-9b27e07139a5}"
   RemoveItem "/Applications/Firefox.app/Contents/MacOS/extensions/{29dd9c80-9ea1-4aaf-9305-a0314aba24e3}"
   RemoveItem "/Applications/Firefox.app/Contents/MacOS/extensions/nortonsafetyminder@symantec.com"
   RemoveItem "/Applications/Late Breaking News"
   RemoveItem "/Applications/LiveUpdate"
   RemoveItem "/Applications/LiveUpdate Folder"
   RemoveItem "/Applications/LiveUpdate Folder (OS X)"
#  Remove navx incorrectly installed by NAV 800.007 installer:
   RemoveItem "/Applications/navx"
   RemoveItem "/Applications/Norton AntiVirus"
   RemoveItem "/Applications/Norton AntiVirus.app"
   RemoveItem "/Applications/Norton Confidential.app"
   RemoveItem "/Applications/Norton AntiVirus (OS X)"
   RemoveItem "/Applications/Norton Internet Security"
   RemoveItem "/Applications/Norton Internet Security.app"
   RemoveItem "/Applications/Norton Internet Security.NisX"
   RemoveItem "/Applications/Norton Internet Security (OS X)"
   RemoveItem "/Applications/Norton Parental Control"
   RemoveItem "/Applications/Norton Parental Control.app"
   RemoveItem "/Applications/Norton Personal Firewall"
   RemoveItem "/Applications/Norton Personal Firewall.app"
   RemoveItem "/Applications/Norton Personal Firewall (OS X)"
   RemoveItem "/Applications/Norton Scheduler (OS X)"
   RemoveItem "/Applications/Norton Solutions"
   RemoveItem "/Applications/Norton System Works"
   RemoveItem "/Applications/Norton SystemWorks"
   RemoveItem "/Applications/Norton SystemWorks.NswX"
   RemoveItem "/Applications/Norton Utilities"
   RemoveItem "/Applications/Norton Utilities Folder (OS X)"
   RemoveItem "/Applications/Norton Utilities.NnuX"
   RemoveItem "/Applications/Symantec AntiVirus"
   RemoveItem "/Applications/Symantec Solutions"
#  The next 3 items are erroneously created by early builds of NAV 10 installer
   RemoveItem "/Applications/Symantec/LiveUpdate.app"
   RemoveItem "/Applications/Symantec/Read Me Files"
   RemoveItem "/Applications/Symantec" -e
   RemoveItem "/Applications/Trash Running Daemons"
   RemoveItem "/Applications/uDelete Preferences"
   RemoveItem "/Applications/Register Your Software"
#  Folder erroneously created by NPF 300.001 - removed if empty:
   RemoveItem "/Firewall" -e
   RemoveItem "/Library/Application Support/NAVDiagnostic.log"
   RemoveItem "/Library/Application Support/NAV.history"
   RemoveItem "/Library/Application Support/Norton Application Aliases"
#  Remove "/Library/Application Support/Norton Solutions Support" if necessary
   if [ -e "$VolumePrefix/Library/Application Support/Norton Solutions Support" ] ; then
      # if Norton Solutions Support contains something other than "LiveUpdate/Registry/LUsm "*
      #    or it does not contain "LiveUpdate/Registry/LUsm "*
      if [ "`ls -d "$VolumePrefix/Library/Application Support/Norton Solutions Support/"* 2>/dev/null | grep -v "^.DS_Store|^.localized"`" != 
                   "$VolumePrefix/Library/Application Support/Norton Solutions Support/LiveUpdate" -o 
           "`ls -d "$VolumePrefix/Library/Application Support/Norton Solutions Support/LiveUpdate/"* 2>/dev/null | grep -v "^.DS_Store|^.localized"`" != 
                   "$VolumePrefix/Library/Application Support/Norton Solutions Support/LiveUpdate/Registry" -o 
           "z`ls -d "$VolumePrefix/Library/Application Support/Norton Solutions Support/LiveUpdate/Registry/"* 2>/dev/null | grep -v "^.DS_Store|^.localized" | grep -v "LUsm "`" != z -o 
           -z "`ls -d "$VolumePrefix/Library/Application Support/Norton Solutions Support/LiveUpdate/Registry/LUsm "* 2>/dev/null`" ] ; then
         SaveFiles
         RemoveItem "/Library/Application Support/Norton Solutions Support"
         RestoreSaved
      fi
   fi
   RemoveItem "/Library/Application Support/Symantec/AntiVirus"
   RemoveItem "/Library/Application Support/Symantec/Application Aliases"
   RemoveItem "/Library/Application Support/Symantec/Assistants/Client Firewall"
   RemoveItem "/Library/Application Support/Symantec/Assistants/NIS Assistant Startup.app"
   RemoveItem "/Library/Application Support/Symantec/Assistants/Norton Confidential"
   RemoveItem "/Library/Application Support/Symantec/Assistants/Norton Confidential Startup.app"
   RemoveItem "/Library/Application Support/Symantec/Assistants/Norton Firewall"
   RemoveItem "/Library/Application Support/Symantec/Assistants/Norton Internet Security"
   RemoveItem "/Library/Application Support/Symantec/Assistants/NPF Assistant Startup.app"
   RemoveItem "/Library/Application Support/Symantec/Assistants/SCF Assistant Startup.app"
   RemoveItem "/Library/Application Support/Symantec/Assistants/Symantec Setup Assistant.app"
   RemoveItem "/Library/Application Support/Symantec/Assistants/Symantec Setup Assistant.bundle"
   RemoveItem "/Library/Application Support/Symantec/Assistants" -e
   RemoveItem "/Library/Application Support/Symantec/Daemon/debug.log"
   RemoveItem "/Library/Application Support/Symantec/Daemon/error.log"
   RemoveItem "/Library/Application Support/Symantec/Daemon/SymDaemon.bundle"
   RemoveItem "/Library/Application Support/Symantec/Daemon" -e
   RemoveItem "/Library/Application Support/Symantec/DeepSight"
   RemoveItem "/Library/Application Support/Symantec/Firewall"
   RemoveItem "/Library/Application Support/Symantec/IntrusionPrevention"
   RemoveItem "/Library/Application Support/Symantec/LiveUpdate"
   RemoveItem "/Library/Application Support/Symantec/Norton AntiVirus"
   RemoveItem "/Library/Application Support/Symantec/Norton Application Aliases"
   RemoveItem "/Library/Application Support/Symantec/Norton Family Safety"
   RemoveItem "/Library/Application Support/Symantec/Norton Personal Firewall"
   RemoveItem "/Library/Application Support/Symantec/Norton Privacy Control.bundle"
   RemoveItem "/Library/Application Support/Symantec/Norton Safety Minder"
   RemoveItem "/Library/Application Support/Symantec/Norton Utilities"
   RemoveItem "/Library/Application Support/Symantec/Protector"
   RemoveItem "/Library/Application Support/Symantec/Registry"
   RemoveItem "/Library/Application Support/Symantec/Scheduler"
   RemoveItem "/Library/Application Support/Symantec/SEP"
   RemoveItem "/Library/Application Support/Symantec/Settings"
   RemoveItem "/Library/Application Support/Symantec/SMC"
   RemoveItem "/Library/Application Support/Symantec/SNAC"
   RemoveItem "/Library/Application Support/Symantec/Submissions"
   RemoveItem "/Library/Application Support/Symantec/Symantec AntiVirus"
   RemoveItem "/Library/Application Support/Symantec/SymQuickMenu"
   RemoveItem "/Library/Application Support/Symantec/SymUIAgent"
   RemoveItem "/Library/Application Support/Symantec/SymWebKitUtils"
   RemoveItem "/Library/Application Support/Symantec/Uninstaller"
   RemoveItem "/Library/Application Support/Symantec/WebFraud"
   RemoveItem "/Library/Application Support/Symantec" -e
   RemoveItem "/Library/Application Support/SymRun"
   RemoveItem "/Library/Authenticators/SymAuthenticator.bundle"
   RemoveItem "/Library/CFMSupport/Norton Shared Lib"
   RemoveItem "/Library/CFMSupport/Norton Shared Lib Carbon"
   RemoveItem "/Library/Contextual Menu Items/NAVCMPlugIn.plugin"
   RemoveItem "/Library/Contextual Menu Items/SAVCMPlugIn.plugin"
   RemoveItem "/Library/Contextual Menu Items/SymFileSecurityCM.plugin"
   RemoveItem "/Library/Documentation/Help/LiveUpdate Help"
   RemoveItem "/Library/Documentation/Help/LiveUpdate-Hilfe"
   RemoveItem "/Library/Documentation/Help/Norton AntiVirus Help"
   RemoveItem "/Library/Documentation/Help/Norton AntiVirus-Hilfe"
   RemoveItem "/Library/Documentation/Help/Norton Help"
   RemoveItem "/Library/Documentation/Help/Norton Help Scripts"
   RemoveItem "/Library/Documentation/Help/Norton Help Scripts Folder"
   RemoveItem "/Library/Documentation/Help/Norton Utilities Help"
   RemoveItem "/Library/InputManagers/Norton Confidential for Safari"
   RemoveItem "/Library/InputManagers/Norton Safety Minder"
   RemoveItem "/Library/InputManagers/SymWebKitUtils"
   RemoveItem "/Library/Internet Plug-Ins/Norton Confidential for Safari.plugin"
   RemoveItem "/Library/Internet Plug-Ins/Norton Family Safety.plugin"
   RemoveItem "/Library/Internet Plug-Ins/Norton Safety Minder.plugin"
   RemoveItem "/Library/LaunchAgents/com.symantec" "*"
   RemoveItem "/Library/LaunchDaemons/com.symantec" "*"
   RemoveItem "/Library/Logs/Norton" "*"
   RemoveItem "/Library/Logs/Symantec" "*"
   RemoveItem "/Library/Logs/SymAPErr.log"
   RemoveItem "/Library/Logs/SymAPOut.log"
   RemoveItem "/Library/Logs/SymDeepsight" "*"
   RemoveItem "/Library/Logs/SymFWLog.log"
   RemoveItem "/Library/Logs/SymFWRules.log" "*"
   RemoveItem "/Library/Logs/SymScanServerDaemon.log"
   RemoveItem "/Library/Plug-ins/DiskImages/NUMPlugin.bundle"
   RemoveItem "/Library/Plug-ins/DiskImages/VRPlugin.bundle"
   RemoveItem "/Library/Plug-ins/DiskImages" -e
   RemoveItem "/Library/Plug-ins" -e
   RemoveItem "/Library/PreferencePanes/APPrefPane.prefPane"
   RemoveItem "/Library/PreferencePanes/FileSaver.prefPane"
   RemoveItem "/Library/PreferencePanes/Norton Family Safety.prefPane"
   RemoveItem "/Library/PreferencePanes/Norton Safety Minder.prefPane"
   RemoveItem "/Library/PreferencePanes/Ribbon.Norton.prefPane"
   RemoveItem "/Library/PreferencePanes/SymantecQuickMenu.prefPane"
   RemoveItem "/Library/PreferencePanes/SymAutoProtect.prefPane"
   RemoveItem "/Library/PrivateFrameworks/NPF.framework"
   RemoveItem "/Library/PrivateFrameworks/NPFCoreServices.framework"
   RemoveItem "/Library/PrivateFrameworks/NPFDataSource.framework"
   RemoveItem "/Library/PrivateFrameworks/SymAppKitAdditions.framework"
   RemoveItem "/Library/PrivateFrameworks/SymAVScan.framework"
   RemoveItem "/Library/PrivateFrameworks/SymBase.framework"
   RemoveItem "/Library/PrivateFrameworks/SymConfidential.framework"
   RemoveItem "/Library/PrivateFrameworks/SymDaemon.framework"
   RemoveItem "/Library/PrivateFrameworks/SymFirewall.framework"
   RemoveItem "/Library/PrivateFrameworks/SymInternetSecurity.framework"
   RemoveItem "/Library/PrivateFrameworks/SymIPS.framework"
   RemoveItem "/Library/PrivateFrameworks/SymIR.framework"
   RemoveItem "/Library/PrivateFrameworks/SymNetworking.framework"
   RemoveItem "/Library/PrivateFrameworks/SymPersonalFirewall.framework"
   RemoveItem "/Library/PrivateFrameworks/SymScheduler.framework"
   RemoveItem "/Library/PrivateFrameworks/SymSharedSettings.framework"
   RemoveItem "/Library/PrivateFrameworks/SymSubmission.framework"
   RemoveItem "/Library/PrivateFrameworks/SymSystem.framework"
   RemoveItem "/Library/PrivateFrameworks/SymUIAgent.framework"
   RemoveItem "/Library/PrivateFrameworks/SymUIAgentUI.framework"
   if [ ! -e "$VolumePrefix/Library/PrivateFrameworks/SymWebKitUtils.framework/Versions/A/Resources/SymWKULoader.dylib" 
        -o ( $CreateFilesRemovedListOnly = TRUE -a $ListOnlyFilesThatExist = FALSE ) ] ; then
      RemoveItem "/Library/PrivateFrameworks/SymWebKitUtils.framework"
   fi
   IFS='
'
   for EachReceiptLine in `echo "$ReceiptsTable" | grep . | grep -v '^#'` ; do
      ReceiptName=`echo "$EachReceiptLine" | awk -F "    " '{print $1}'`
      ReceiptArg=`echo "$EachReceiptLine" | awk -F " " '{print $2}'`
      if [ "z$ReceiptArg" = z-a ] ; then
         RemoveItem "/Library/Receipts/$ReceiptName" "*"
         RemoveItem "/Library/Receipts/$ReceiptName"Dev "*"
      else
         if [ "z$ReceiptName" = zSymWebKitUtils.pkg -o "z$ReceiptName" = zSymWebKitUtilsDev.pkg ] ; then
            # If SymWKULoader exists and CleanUpSymWebKitUtils does not, skip deletion of SymWebKitUtils receipt
            [ -e "$VolumePrefix/Library/PrivateFrameworks/SymWebKitUtils.framework/Versions/A/Resources/SymWKULoader.dylib" -a ! -e /Library/StartupItems/CleanUpSymWebKitUtils ] && continue
         fi
         RemoveItem "/Library/Receipts/$ReceiptName"
         if [ "`echo "$ReceiptName" | grep '.pkg$'`" ] ; then
            ReceiptName="`basename "$ReceiptName" .pkg`Dev.pkg"
            RemoveItem "/Library/Receipts/$ReceiptName"
         fi
      fi
   done
   RemoveItem "/Library/ScriptingAdditions/SymWebKitUtils.osax"
   RemoveItem "/Library/ScriptingAdditions/SymWebKitUtilsSL.osax"
   RemoveItem "/Library/Services/ScanService.service"
   RemoveItem "/Library/Services" -e
   RemoveItem "/Library/StartupItems/NortonAutoProtect"
   RemoveItem "/Library/StartupItems/NortonAutoProtect.kextcache"
   RemoveItem "/Library/StartupItems/NortonLastStart"
   RemoveItem "/Library/StartupItems/NortonMissedTasks"
   RemoveItem "/Library/StartupItems/NortonPersonalFirewall"
   RemoveItem "/Library/StartupItems/NortonPrivacyControl"
   RemoveItem "/Library/StartupItems/NUMCompatibilityCheck"
   RemoveItem "/Library/StartupItems/SMC"
   RemoveItem "/Library/StartupItems/SymAutoProtect"
   RemoveItem "/Library/StartupItems/SymAutoProtect.kextcache"
   RemoveItem "/Library/StartupItems/SymDCInit"
   RemoveItem "/Library/StartupItems/SymMissedTasks"
   RemoveItem "/Library/StartupItems/SymProtector"
   RemoveItem "/Library/StartupItems/SymQuickMenuOSFix"
   RemoveItem "/Library/StartupItems/SymWebKitUtilsOSFix"
   RemoveItem "/Library/StartupItems/TrackDelete"
   RemoveItem "/Library/StartupItems/VolumeAssist"
   RemoveItem "/Library/Symantec/tmp"
   RemoveItem "/Library/Symantec" -E
   RemoveItem "/Library/Widgets/NAV.wdgt"
   RemoveItem "/Library/Widgets/Symantec Alerts.wdgt"
   RemoveItem "/Library/Widgets" -E
   RemoveItem "/Norton AntiVirus Installer Log"
#  Folder with files erroneously created by an early Corsair installer:
   RemoveItem "/opt/Symantec"
#  Folder erroneously created by that Corsair installer - removed if empty:
   RemoveItem "/opt" -E
#  Folder erroneously created by NPF 300.001 - removed if empty:
   RemoveItem "/Personal" -e
   RemoveItem "/private/etc/liveupdate.conf"
   RemoveItem "/private/etc/mach_init.d/SymSharedSettings.plist"
   RemoveItem "/private/etc/Symantec.conf"
   RemoveItem "/private/tmp/com.symantec.liveupdate.restart"
   RemoveItem "/private/tmp/symask"
   RemoveItem "/private/var/tmp/com.symantec" "*"
   RemoveItem "/private/var/log/Npfkernel.log.fifo"
   RemoveItem "/private/var/root/Library/Bundles/NAVIR.bundle"
   RemoveItem "/private/var/root/Library/Bundles" -E
   RemoveItem "/private/var/root/Library/Contextual Menu Items/NAVCMPlugIn.plugin"
   RemoveItem "/private/var/root/Library/Contextual Menu Items" -E
#  Folder erroneously created by NPF 300.001 - removed if empty:
   RemoveItem "/Solutions" -e
#  Folder erroneously created by NPF 300.001 - removed if empty:
   RemoveItem "/Support/Norton" -e
#  Folder erroneously created by NPF 300.001 - removed if empty:
   RemoveItem "/Support" -e
   RemoveItem "/symaperr.log"
   RemoveItem "/symapout.log"
#  Four frameworks erroneously installed by early builds of NAV 9.0.1:
   RemoveItem "/SymAppKitAdditions.framework"
   RemoveItem "/SymBase.framework"
   RemoveItem "/SymNetworking.framework"
   RemoveItem "/SymSystem.framework"
   RemoveItem "/System/Library/Authenticators/SymAuthenticator.bundle"
   RemoveItem "/System/Library/CFMSupport/Norton Shared Lib Carbon"
   RemoveItem "/System/Library/CoreServices/NSWemergency"
   RemoveItem "/System/Library/CoreServices/NUMemergency"
   RemoveItem "/System/Library/Extensions/DeleteTrap.kext"
   RemoveItem "/System/Library/Extensions/KTUM.kext"
   RemoveItem "/System/Library/Extensions/NPFKPI.kext"
   RemoveItem "/System/Library/Extensions/SymDC.kext"
   RemoveItem "/System/Library/Extensions/SymEvent.kext"
   RemoveItem "/System/Library/Extensions/symfs.kext"
   RemoveItem "/System/Library/Extensions/SymInternetSecurity.kext"
   RemoveItem "/System/Library/Extensions/SymIPS.kext"
   RemoveItem "/System/Library/Extensions/SymOSXKernelUtilities.kext"
   RemoveItem "/System/Library/Extensions/SymPersonalFirewall.kext"
   RemoveItem "/System/Library/StartupItems/NortonAutoProtect"
   RemoveItem "/System/Library/StartupItems/SymMissedTasks"
   RemoveItem "/System/Library/Symantec"
   RemoveItem "/System/Library/SymInternetSecurity.kext"
   RemoveItem "/SystemWorks Installer Log"
   RemoveItem "/Users/dev/bin/smellydecode"
   RemoveItem "/Users/dev/bin" -E
   RemoveItem "/Users/dev" -E
   RemoveItem "/Users/Shared/NAV Corporate"
   RemoveItem "/Users/Shared/NIS Corporate"
   RemoveItem "/Users/Shared/SymantecRemovalToolRemovesThese.txt"
   RemoveItem "/Users/Shared/SymantecRemovalToolLog.txt"
   RemoveItem "/Users/Shared/RemoveSymantecMacFilesRemovesThese.txt"
   RemoveItem "/Users/Shared/RemoveSymantecMacFilesLog.txt"
   RemoveItem "/Users/Shared/SymantecRemovalToolRemovesThese.txt"
   RemoveItem "/Users/Shared/SymantecRemovalToolLog.txt"
   RemoveItem "/usr/bin/navx"
   RemoveItem "/usr/bin/npfx"
   RemoveItem "/usr/bin/savx"
   RemoveItem "/usr/bin/scfx"
   RemoveItem "/usr/bin/symsched"
   RemoveItem "/usr/lib/libsymsea.1.0.0.dylib"
   RemoveItem "/usr/lib/libsymsea.dylib"
   RemoveItem "/usr/local/lib/libgecko3parsers.dylib"
   RemoveItem "/usr/local/lib" -E
   RemoveItem "/usr/local" -E
   RemoveItem "/usr/share/man/man1/NAVScanIDs.h"
   RemoveItem "/var/db/receipts/com.symantec" "*"
   if [ -f "$VolumePrefix/etc/syslog.conf" -a $CreateFilesRemovedListOnly = FALSE ] ; then
      # Remove Norton Personal Firewall entries from /etc/syslog.conf
      sed -e "/Norton Personal Firewall/d" -e "/Npfkernel.log.fifo/d" "$VolumePrefix/etc/syslog.conf" > /private/tmp/NPF.syslog.conf
      /bin/cp -f /private/tmp/NPF.syslog.conf "$VolumePrefix/etc/syslog.conf"
      /bin/rm -f /private/tmp/NPF.syslog.conf
   fi
   RemoveFilesFromLibraryAndUserDirectories "$1"
   RemoveItem /Library/Preferences/Network -E
   if [ $RecurseFolders = TRUE -a -s "$FilesRemovedFilesOnlyList" ] ; then
      sort -f "$FilesRemovedFilesOnlyList" | uniq | grep . >> "$FilesRemovedList"
   fi
}

RemoveEmptyDirectory()
{
   # Usage:     RemoveEmptyDirectory $1
   # Argument:  $1 = Full path name of directory
   # Summary:   Removes directory $1 if it is empty or if it contains
   #            only .DS_Store and/or .localized (the next best thing
   #            to being empty).
   #
   # If $1 is a directory and not a link
   if [ -d "$1" -a ! -L "$1" ] ; then
      # If folder contains only .DS_Store and/or .localized, or is empty
      if [ -z "`ls "$1" 2>/dev/null | grep -v "^.DS_Store|^.localized"`" ] ; then
         $ShowFilesAsRemoved && echo "   Removing: "$1""
         # Clear immutable bit to remove any Finder lock
         chflags -R nouchg "$1" 2>/dev/null 1>&2
         /bin/rm -rf "$1" 2>/dev/null 1>&2   # Remove folder
      fi
   fi
}

RemoveFilesFromLibraryAndUserDirectories()
{
   # Usage:     RemoveFilesFromLibraryAndUserDirectories $1
   # Argument:  $1 = Name of volume from which to remove preferences.
   #                 The name must begin with "/Volumes/"
   #                 unless it is "/" (boot volume).
   # Summary:   Removes all Symantec files & folders from each user's
   #            preferences, /Library/Caches, and /Library/Preferences.
   #            Removes help files from /Library/Documentation. Removes
   #            folders incorrectly created by NAV 7.0.2 from each
   #            user's home directory.
   #
   CurrentVolumeBeingUsed="$1"
   if [ "$1" = "/" ] ; then
      VolumeToCheck=""
   else
      VolumeToCheck="$1"
   fi
   # set IFS to only newline to get all user names
   IFS='
'
   for UserName in `ls "$VolumeToCheck/Users" 2>/dev/null` "root" "/" ; do
      if [ "$UserName" = "root" ] ; then
         dir="/private/var/root/Library"
         dir2="/private/var/root"
      elif [ "$UserName" = "/" ] ; then
         dir="/Library"
         dir2=""
      else
         dir="/Users/$UserName/Library"
         dir2="/Users/$UserName"
      fi
      # If dir is not a directory, skip to the next name
      [ ! -d "$VolumeToCheck$dir" ] && continue
      cd "$VolumeToCheck/"
      # If a user, delete folders from user's home directory that were
      # incorrectly created by NAV 7.0.2
      if [ "$UserName" != "/" ] ; then
         RemoveItem "$dir2/Applications/LiveUpdate Folder (OS X)"
         RemoveItem "$dir2/Applications/Norton AntiVirus (OS X)"
         RemoveItem "$dir2/Applications" -e
      fi
      RemoveItem "$dir/Documentation/Help/Norton Privacy Control Help"
      RemoveItem "$dir/Documentation/Help/Norton Personal Firewall Help"
      RemoveItem "$dir/Caches/com.symantec" "*"
      RemoveItem "$dir/Caches/Norton" "*"
      RemoveItem "$dir/Caches/Symantec" "*"
      RemoveItem "$dir/Preferences/com.symantec" "*" -x 'com.symantec.sacm.*' -x 'com.symantec.smac.*'
      RemoveItem "$dir/Preferences/LiveUpdate Preferences"
      RemoveItem "$dir/Preferences/LU Admin Preferences"
      RemoveItem "$dir/Preferences/LU Host Admin.plist"
      RemoveItem "$dir/Preferences/NAV8.0.003.plist"
      RemoveItem "$dir/Preferences/Network/com.symantec" "*"
      RemoveItem "$dir/Preferences/Norton AntiVirus Prefs Folder"
      RemoveItem "$dir/Preferences/Norton Application Aliases"
      RemoveItem "$dir/Preferences/Norton Personal Firewall Log"
      RemoveItem "$dir/Preferences/Norton Scheduler OS X.plist"
      RemoveItem "$dir/Preferences/Norton Utilities Preferences"
      RemoveItem "$dir/Preferences/wcid"
   done
}

RemoveInvisibleFilesFromVolume()
{
   # Usage:     RemoveInvisibleFilesFromVolume $1
   # Argument:  $1 = Volume name. The name should begin with "/Volumes/"
   #                 unless it is "/" (boot volume).
   # Summary:   Removes the invisible Symantec for OS X files - Norton FS
   #            and AntiVirus QuickScan files - from $1.
   #
   ! $RemoveInvisibleFiles && return
   CurrentVolumeBeingUsed="$1"
   cd "$1"
   if $CreateFilesRemovedListOnly ; then
      echo "Finding invisible Symantec files on: $1" >&2
   elif $ShowFilesAsRemoved ; then
      echo "Locating invisible Symantec files in: $1"
   else
      echo "Removing invisible Symantec files from: $1"
   fi
   RemoveItem "/.SymAVQSFile"
   RemoveItem "/NAVMac800QSFile"
   RemoveItem "/Norton FS Data"
   RemoveItem "/Norton FS Index"
   RemoveItem "/Norton FS Volume"
   RemoveItem "/Norton FS Volume 2"
}

RemoveItem()
{
   # Usage:     RemoveItem FilePath [-e | -E] [-x <pattern>] [FileExtension]
   #
   # Summary:   Deletes the file or folder passed, FilePath, from the
   #            current directory.
   #
   # Options:
   #    -e      Delete FilePath only if it is a directory that is empty or
   #            that contains only ".DS_Store" and/or ".localized" files.
   #            If the folder could not be deleted, error message is shown.
   #    -E      Same as the -e option, except no error message is shown if
   #            the folder could not be deleted.
   #    -x <Pattern>
   #            Pattern to exclude from file list. Pattern will become
   #            ^FilePath/Pattern$ so add wildcards as needed. Make sure
   #            to prefix special characters you wish to match with 
   #            (example: to match a period, .). You may pass several
   #            -x <pattern> groupings.
   #    <FileExtension>
   #            All files that match FilePath*FileExtension are deleted.
   #            To match any files that begin with FilePath, pass "*" as
   #            FileExtension (don't pass * unquoted). Only the last
   #            FileExtension passed will be used
   #
   # Note:      Make sure to run the SetupCleanup function before the
   #            first run of this function and run the FinishCleanup
   #            function before exiting the script.
   #            Make sure to change directory to root of the volume you
   #            want the file or folder removed from before calling this
   #            function.
   #            FilePath must be the first argument. The other options
   #            may appear after FilePath in any order.
   #
   local ExclusionPattern=""
   # If / or no file name passed, return
   [ "z$1" = z/ -o -z "$1" ] && return 
   VolumeFromWhichToRemove="`pwd`"
   FilePath="$1"
   if [ "$VolumeFromWhichToRemove" = "/" ] ; then
      FullFilePath="$FilePath"
   else
      FullFilePath="$VolumeFromWhichToRemove$FilePath"
   fi
   PathDir=`dirname "$FullFilePath"`
   PathBasePattern=`basename "$FullFilePath" | sed s/"."/"\\."/g`
   shift
   DeleteOnlyIfEmptyDir=FALSE
   SkipErrorMessageIfEmptyDirNotFound=FALSE
   ExtensionPassed=""
   while [ "$1" ] ; do
      if [ "z$1" = z-e ] ; then
         DeleteOnlyIfEmptyDir=TRUE
         SkipErrorMessageIfEmptyDirNotFound=FALSE
      elif [ "z$1" = z-E ] ; then
         DeleteOnlyIfEmptyDir=TRUE
         SkipErrorMessageIfEmptyDirNotFound=TRUE
      elif [ "z$1" = z-x ] ; then
         if [ "$2" ] ; then
            shift
            if [ "$ExclusionPattern" ] ; then
               ExclusionPattern="$ExclusionPattern|^$PathDir/$1$"
            else
               ExclusionPattern="^$PathDir/$1$"
            fi
         fi
      else
         ExtensionPassed="$1"
      fi
      shift
   done
   if [ "z$ExtensionPassed" = "z*" ] ; then
      ListOfPaths=`ls -d "$PathDir/"* 2>/dev/null | grep -i "^$PathDir/$PathBasePattern" | sort -f`
      PathToShow="$FullFilePath*"
   elif [ "$ExtensionPassed" ] ; then
      ExtensionPassedPattern=`printf "%s" "$ExtensionPassed" | sed s/"."/"\\."/g`
      ListOfPaths=`ls -d "$PathDir/"* 2>/dev/null | grep -i "^$PathDir/$PathBasePattern.*$ExtensionPassedPattern$" | sort -f`
      PathToShow="$FullFilePath*$ExtensionPassed"
   else
      ListOfPaths=`ls -d "$FullFilePath" 2>/dev/null`
      PathToShow="$FullFilePath"
   fi
   # If there are items to exclude from the list and there are matching items
   if [ "z$ExclusionPattern" != z -a -n "$ListOfPaths" ] ; then
      ListOfPaths=`printf "%s" "$ListOfPaths" | grep -i -v -e "$ExclusionPattern"`
   fi
   if $CreateFilesRemovedListOnly ; then
      # If -E passed, then don't list the item
      $SkipErrorMessageIfEmptyDirNotFound && return
      if ! $ListOnlyFilesThatExist ; then
         echo "$PathToShow`$DeleteOnlyIfEmptyDir && echo " [folder deleted only if empty]"`" >> "$FilesRemovedList"
      # Else if file exists
      elif [ "$ListOfPaths" ] ; then
         if $RecurseFolders ; then
            IFS='
'
            for EachItemListed in $ListOfPaths ; do
               if [ -L "$EachItemListed" ] ; then
                  echo "$EachItemListed" >>"$FilesRemovedFilesOnlyList"
               else
                  find "$EachItemListed" 2>/dev/null 1>>"$FilesRemovedFilesOnlyList"
               fi
            done
         else
            echo "$ListOfPaths`$DeleteOnlyIfEmptyDir && echo " [folder deleted only if empty]"`" >> "$FilesRemovedList"
         fi
         NoFilesToRemove=FALSE
         FilesFoundOnThisVolume=TRUE
      fi
      return
   fi
   IFS='
'
   for EachFullPath in $ListOfPaths ; do
      # If -e or -E was passed
      if $DeleteOnlyIfEmptyDir ; then
         #   remove directory only if empty
         RemoveEmptyDirectory "$EachFullPath"
         # If -E passed, then skip error reporting
         $SkipErrorMessageIfEmptyDirNotFound && continue
      else
         $ShowFilesAsRemoved && echo "   Removing: "$EachFullPath""
         # Clear immutable bit to remove any Finder lock
         chflags -R nouchg "$EachFullPath" 2>/dev/null 1>&2
         /bin/rm -rf "$EachFullPath" 2>/dev/null 1>&2   # Remove file/folder
      fi
      # If file still exists
      if [ "`ls -d "$EachFullPath" 2>/dev/null`" ] ; then
         TheFileWasRemoved=FALSE
      else
         TheFileWasRemoved=TRUE
         SomeFileWasRemoved=TRUE
      fi
      # If the file/folder was not removed
      if ! $TheFileWasRemoved ; then
         if ! $ErrorOccurred ; then
            # Create LogFile
            echo "Symantec files/folders not removed:" >"$LogFile"
            chmod a=rw "$LogFile"
            ErrorOccurred=TRUE
         fi
         echo "   $EachFullPath" >>"$LogFile"
      # Else if boot volume
      elif [ "$CurrentVolumeBeingUsed" = "/" ] ; then
         RestartMayBeNeeded=TRUE
         SomeFileWasRemovedFromBootVolume=TRUE
      else
         SomeFileWasRemovedFromNonBootVolume=TRUE
      fi
      NoFilesToRemove=FALSE
      FilesFoundOnThisVolume=TRUE
   done
}

RestartComputer()
{
   # Usage:     RestartComputer
   # Summary:   Prompts to see if user would like to restart. Restarts
   #            computer using 'reboot' command if 'yes' or 'y' is
   #            entered; exits the script otherwise.
   # Note:      User must be root or an admin for reboot to work, so this
   #            function should only be used in scripts run as root or
   #            admin user.
   #
   echo
   if $QuitWithoutRestarting ; then
      echo "Exited the script without restarting the computer."
      ExitScript $FinishedExitCode
   elif ! $RestartAutomatically ; then
      echo "Do you wish to restart the computer now (WARNING: Unsaved changes"
      printf "in other open applications will be lost if you do!) (y/n)? "
      if `YesEntered` ; then
         RestartAutomatically=TRUE
      fi
      echo
   fi
   if $RestartAutomatically ; then
      if $PauseBeforeRestarting ; then
         printf "Computer will restart in 3 seconds (ctrl-C to cancel restart)..."
         sleep 1
         printf " 3"
         sleep 1
         printf " 2"
         sleep 1
         printf " 1"
         sleep 1
      fi
      echo
      echo "Computer is restarting..."
      reboot
   else
      echo "Exited the script without restarting the computer."
      ExitScript $FinishedExitCode
   fi
}

RestoreSaved()
{
   # Usage:     RestoreSaved
   # Summary:   Restores the files saved by the Save function.
   # Note:      Make sure to change directory to the root of the
   #            volume to which files will be restored before
   #            calling this function.
   #
   ! $FilesWereSaved && return
   mkdir -p "Library/Application Support/Norton Solutions Support/LiveUpdate/Registry" 2>/dev/null
   /bin/cp -Rpf "$SavedFilesDir/LUsm "* "Library/Application Support/Norton Solutions Support/LiveUpdate/Registry" 2>/dev/null
   /usr/sbin/chown root:admin "`pwd`/"
   /usr/sbin/chown root:admin "Applications"
   /usr/sbin/chown root:admin "Library"
   /usr/sbin/chown root:admin "Library/Application Support"
   /usr/sbin/chown root:admin "Library/Application Support/Norton Solutions Support"
   /usr/sbin/chown root:admin "Library/Application Support/Norton Solutions Support/LiveUpdate"
   /usr/sbin/chown root:admin "Library/Application Support/Norton Solutions Support/LiveUpdate/Registry"
   /usr/sbin/chown root:admin "Library/Application Support/Norton Solutions Support/LiveUpdate/Registry/LUsm "*
   /bin/chmod 1775 "`pwd`/".
   /bin/chmod 775 "Applications"
   /bin/chmod 775 "Library"
   /bin/chmod 775 "Library/Application Support"
   /bin/chmod 755 "Library/Application Support/Norton Solutions Support"
   /bin/chmod 755 "Library/Application Support/Norton Solutions Support/LiveUpdate"
   /bin/chmod 755 "Library/Application Support/Norton Solutions Support/LiveUpdate/Registry"
   /bin/chmod 644 "Library/Application Support/Norton Solutions Support/LiveUpdate/Registry/LUsm "*
   /bin/rm -rf "$SavedFilesDir" 2>/dev/null
}

RunPredeleteScripts()
{
   # Usage:     RunPredeleteScripts [$1]
   # Argument:  $1 = Path of current volume.
   # Summary:   If $1 is "" or /, predelete scripts in receipts listed in
   #            ReceiptsTable are run.
   #
   local VolumePathPassed="$1"
   [ "z$VolumePathPassed" = z/ ] && VolumePathPassed=""
   if $CreateFilesRemovedListOnly ; then
      if [ "$VolumePathPassed" ] ; then
         echo "Receipt predelete scripts would not be run on that volume." >> "$FilesRemovedList"
      elif $DoRunPredeleteScripts ; then
         echo "Receipt predelete scripts would be run as they are found." >> "$FilesRemovedList"
      else
         echo "Receipt predelete scripts would not be run because the -d option was specified." >> "$FilesRemovedList"
      fi
      return
   elif [ "$VolumePathPassed" ] ; then
      echo "Receipt predelete scripts were not run on that volume."
      return
   elif ! $DoRunPredeleteScripts ; then
      echo "Receipt predelete scripts were not run because the -d option was specified."
      return
   fi
   SYMANTEC_SAVED_DATA_DIR="/private/tmp/$FullScriptName-SYMANTEC_SAVED_DATA_DIR-`date +"%Y%m%d%H%M%S"`"
   mkdir -p "$SYMANTEC_SAVED_DATA_DIR" 2>/dev/null
   IFS='
'
   echo "Looking for predelete scripts in Symantec Uninstaller's Receipts folder"
   for PredeleteScript in `find "/Library/Application Support/Symantec/Uninstaller" 2>/dev/null | grep 'predelete$|pre_delete$'` ; do
      if [ -x "$PredeleteScript" ] ; then
         echo "--- Running $PredeleteScript ---"
         export SYMANTEC_SAVED_DATA_DIR
         if $ShowPredeleteErrors ; then
            "$PredeleteScript"
         else
            "$PredeleteScript" 2>/dev/null 1>&2
         fi
      fi
   done
   echo "Looking for predelete scripts in /Library/Receipts"
   for EachReceiptLine in `echo "$ReceiptsTable" | grep '.pkg' | grep -v '^#'` ; do
      ReceiptArg=`echo "$EachReceiptLine" | awk -F " " '{print $2}'`
      [ "z$ReceiptArg" = z-s ] && continue
      ReceiptName=`echo "$EachReceiptLine" | awk -F "    " '{print $1}'`
      [ -z "`echo "$ReceiptName" | grep '.pkg$'`" ] && continue
      if [ -d "/Library/Receipts/$ReceiptName" ] ; then
         for PredeleteScript in `find "/Library/Receipts/$ReceiptName" 2>/dev/null | grep 'predelete$|pre_delete$'` ; do
            if [ -x "$PredeleteScript" ] ; then
               echo "--- Running $PredeleteScript ---"
               export SYMANTEC_SAVED_DATA_DIR
               if $ShowPredeleteErrors ; then
                  "$PredeleteScript"
               else
                  "$PredeleteScript" 2>/dev/null 1>&2
               fi
            fi
         done
      fi
      ReceiptName="`basename "$ReceiptName" .pkg`Dev.pkg"
      if [ -d "/Library/Receipts/$ReceiptName" ] ; then
         for PredeleteScript in `find "/Library/Receipts/$ReceiptName" 2>/dev/null | grep 'predelete$|pre_delete$'` ; do
            if [ -x "$PredeleteScript" ] ; then
               echo "--- Running $PredeleteScript ---"
               export SYMANTEC_SAVED_DATA_DIR
               if $ShowPredeleteErrors ; then
                  "$PredeleteScript"
               else
                  "$PredeleteScript" 2>/dev/null 1>&2
               fi
            fi
         done
      fi
   done
   rm -rf "$SYMANTEC_SAVED_DATA_DIR" 2>/dev/null
}

SaveFiles()
{
   # Usage:     SaveFiles
   # Summary:   Saves file(s) in /private/tmp. Use the RestoreSaved
   #            function to restore it.
   # Note:      Make sure to change directory to root of the volume you
   #            want the file or folder removed from before calling this
   #            function.
   #
   FilesWereSaved=FALSE
   $CreateFilesRemovedListOnly && return
   [ -z "`ls -d "Library/Application Support/Norton Solutions Support/LiveUpdate/Registry/LUsm "* 2>/dev/null`" ] && return
   /bin/rm -rf "$SavedFilesDir" 2>/dev/null
   mkdir "$SavedFilesDir" 2>/dev/null
   /bin/cp -Rp "Library/Application Support/Norton Solutions Support/LiveUpdate/Registry/LUsm "* "$SavedFilesDir"
   FilesWereSaved=TRUE
}

SetupCleanup()
{
   # Usage:     SetupCleanup
   # Summary:   Initializes variables needed for the RemoveItem function.
   #
   ErrorOccurred=FALSE
   NoFilesToRemove=TRUE
   /bin/rm -rf "$FilesRemovedList" "$FilesRemovedFilesOnlyList" 2>/dev/null 1>&2
   if $CreateFilesRemovedListOnly ; then
      if $ListOnlyFilesThatExist ; then
         echo "Summary of what $FullScriptName would do, based on files" > "$FilesRemovedList"
         echo "`$RemoveCrontabEntries && echo "and crontab entries "`that currently exist:" >> "$FilesRemovedList"
      else
         echo "Summary of what $FullScriptName would attempt to do:" > "$FilesRemovedList"
      fi
   fi
}

ShowContents()
{
   # Usage1:    ShowContents [-c] File [TextToShow]
   # Usage2:    ShowContents [-c] -s String [TextToShow]
   # Summary:   Displays contents of File or String. If there are more than
   #            23 lines, more command is used, using TextToShow as the
   #            name of the file; if TextToShow is not passed, "....." is
   #            used. If -c is specified, screen is cleared beforehand. 
   #
   if [ "z$1" = z-c ] ; then
      shift
      clear >&2
   fi  
   if [ "z$1" = z-s ] ; then
      shift
      if [ `printf "%s
" "$1" | grep -c ""` -gt 23 ] ; then
         ShowContentsCurrentDir=`pwd`
         ShowContentsTempFolder="/private/tmp/$FullScriptName-ShowContents-`date +"%Y%m%d%H%M%S"`"
         mkdir "$ShowContentsTempFolder" 2>/dev/null
         [ ! -d "$ShowContentsTempFolder" ] && return 1
         cd "$ShowContentsTempFolder" 2>/dev/null
         [ "$2" ] && ShowContentsTempFile="$2" || ShowContentsTempFile="....."
         printf "%s
" "$1" >"$ShowContentsTempFile"
         more -E "$ShowContentsTempFile"
         echo
         cd "$ShowContentsCurrentDir" 2>/dev/null
         rm -rf "$ShowContentsTempFolder" 2>/dev/null
      else
         printf "%s
" "$1"
      fi
   elif [ -f "$1" ] ; then
      if [ `grep -c "" "$1"` -gt 23 ] ; then
         ShowContentsCurrentDir=`pwd`
         ShowContentsTempFolder="/private/tmp/$FullScriptName-ShowContents-`date +"%Y%m%d%H%M%S"`"
         mkdir "$ShowContentsTempFolder" 2>/dev/null
         [ ! -d "$ShowContentsTempFolder" ] && return 1
         [ "$2" ] && ShowContentsTempFile="$2" || ShowContentsTempFile="....."
         cat "$1" >"$ShowContentsTempFolder/$ShowContentsTempFile"
         cd "$ShowContentsTempFolder" 2>/dev/null
         more -E "$ShowContentsTempFile"
         echo
         cd "$ShowContentsCurrentDir" 2>/dev/null
         rm -rf "$ShowContentsTempFolder" 2>/dev/null
      else
         cat "$1"
      fi
   else
      return 1
   fi
   return 0
}

ShowUsage()
{
   # Usage:     ShowUsage
   # Summary:   Displays script usage message and exits script.
   #
   TEMPFILETEMPLATE="/private/tmp/SymantecTemp"
   TEMPFILE="$TEMPFILETEMPLATE`date +"%Y%m%d%H%M%S"`-1"
   ShowVersion >>"$TEMPFILE"
   $AutoRunScript && echo "
Note:    This script requires no user interaction if run as root. You can
         run this script on several machines at once by using Symantec
         Administration Console for Macintosh to send this script." >>"$TEMPFILE"
   echo "
WARNING: This script will remove all files and folders created by Symantec
         Mac OS X products (except Symantec Administration Console and
         LiveUpdate Administration Utility files) and any files within
         those folders. Therefore, you will lose ALL files that reside in
         those folders, including any that you have created.

Usage:   $FullScriptName [options] [volume ...]

Summary: If no option or volume is specified, then all Symantec files are
         removed from the current boot volume, including the invisible
         Symantec files (i.e., AntiVirus QuickScan and Norton FS files),
         and Symantec crontab entries are removed from all users' crontabs;
         otherwise, for each volume specified, all Symantec files and
         Symantec crontab entries will be removed from that volume if no
         options are specified. If files are removed from the current boot
         volume, receipt predelete scripts are run unless -d is specified.

         If a volume does not have OS X installed on it, then only the
         invisible Symantec files are removed from that volume.

         Each volume name may begin with "/Volumes/", unless it is "/".
         The easiest way to specify a volume is to drag the volume onto the
         Terminal window.

Note:    The Terminal application does not support high ASCII or
         double-byte character entry via keyboard or via drag-and-drop.
         If you want to have files removed from a volume that is not
         the current boot volume and that has a name containing high
         ASCII or double-byte characters, use the -A option.

Options: -A     Remove all Symantec files from all mounted volumes.
                Crontab entries are also removed from the current boot
                volume, but not from other volumes. If a volume does not
                have OS X installed on it, then only the invisible Symantec
                files are removed from that volume.
         -c     Only remove crontab entries from all users' crontabs.
                Nothing is removed from any volume.
         -C     Do not remove crontab entries.
         -d     Bypass the running of receipt predelete scripts. It is best
                to have predelete scripts run for more thorough uninstalls.
         -e     Show errors when run predelete scripts are run. Predelete
                scripts are run only when removing files from the current
                boot volume.
         -f     Do not show files as they are removed. If -f is not
                specified, file names are shown as files are removed.
         -h     Display help.
         -i     Only remove invisible Symantec files.
         -I     Does not remove invisible Symantec files.
         -l     List only files that are currently installed and that
                would be deleted. Nothing is deleted by this option.
         -L     List all files that $FullScriptName will attempt
                to find and delete. Nothing is deleted by this option.
         -m     Show output from -l, -L, or -R options using more program.
                This is no longer the default action as of version 5.52
                of $FullScriptName.
         -p     Eliminate pause before restarting computer. If option -p
                is not specified, then there is a three second delay
                before the restart occurs.
         -q     Quit script without restarting. This also suppresses
                the prompt to restart.
         -Q     Quits Terminal application when script is done. If
                Terminal is being run by more than one user at once,
                Terminal is not quit.
         -QQ    Quits Terminal application for all users when script is
                done.
         -R     This is the same as the -l option, except contents of
                folders will be also be shown. This is useful when doing
                uninstall tests. Nothing is deleted by this option.
         -re    Automatically restart computer when script is done if
                there are Symantec processes and/or kexts in memory and
                there were non-invisible files removed from /.
         -V     Show version only.

Examples:
         $FullScriptName
                Deletes all Symantec files and Symantec crontab entries
                from the boot volume.

         $FullScriptName /Volumes/OS 10.2
                Deletes all Symantec files and Symantec crontab entries
                from the volume named "OS 10.2".
                Nothing is deleted from the boot volume.

         $FullScriptName Runner /
                Deletes all Symantec files and Symantec crontab entries
                from the volume named "Runner" and from the boot volume.

         $FullScriptName -i "Test Disk"
                Deletes only invisible Symantec files from the volume named
                "Test Disk".

         $FullScriptName -A -re
                Deletes all Symantec files and Symantec crontab entries
                from all mounted volumes that have OS X installed on them.
                Deletes only invisible Symantec files from volumes that do
                not have OS X installed on them.
                Computer is restarted automatically if necessary.

         $FullScriptName -i -A
                Deletes only invisible Symantec files from all volumes.

         $FullScriptName -I
                Deletes all but the invisible Symantec files from the boot
                volume. Crontab entries are removed from the boot volume.

         $FullScriptName -C
                Deletes all Symantec files from the boot volume. No crontab
                entries are removed.

         $FullScriptName -L -A
                Lists all the files that $FullScriptName looks
                for on all volumes. The files may or may not be currently
                installed. Nothing is deleted.

         $FullScriptName -R -A
                Lists only the Symantec files that are currently installed
                on all volumes. Files within existing folders will also be
                shown. Nothing is deleted.

         $FullScriptName -l -i
                Lists the invisible Symantec files that are currently
                installed on the boot volume. Nothing is deleted.

         $FullScriptName -r -A
                Removes only the receipts from /Library/Receipts
                from all mounted volumes.

Note:    You must be root or an admin user to run this script. You can
         simply double-click on $FullScriptName to remove all
         Symantec files and crontab entries from the boot volume.

         The -r option to remove only receipts is no longer available as
         of $FullScriptName version 5.52." >>"$TEMPFILE"
   ShowContents "$TEMPFILE"
   /bin/rm "$TEMPFILE" 2>/dev/null
   ExitScript 0
}

ShowUsageHelp()
{
   # Usage:     ShowUsageHelp [$1]
   # Argument:  $1 = Value with which to exit script (2-255).
   # Summary:   Displays script usage help message and exits script with
   #            value passed to $1 or with 0 if nothing is passed to $1.
   #
   echo
   echo "For help, type:"
   echo
   echo "   $FullScriptName -h"
   echo
   [ -n "$1" ] && exit "$1"
   exit 0
}

ShowVersion()
{
   # Usage:     ShowVersion
   # Summary:   Displays the name and version of script.
   #
   echo "********* $FullScriptName $Version *********"
}

SymantecIsInMemory()
{
   # Usage:     SymantecIsInMemory
   # Summary:   If a Symantec process or kext is in memory, TRUE is shown
   #            and 0 is returned; otherwise, FALSE is shown and 1 is
   #            returned. Sample call:
   #               if `SymantecIsInMemory`
   #
   local SymantecIsInMemoryResult=FALSE
   if [ "`ps -wwax | grep -i "/Application Support/Norton|/Application Support/Symantec|/Applications/Norton|/Applications/Symantec|PrivateFrameworks/Sym|/StartupItems/.*Norton|/StartupItems/NUMCompatibilityCheck|/StartupItems/SMac Client|/StartupItems/Sym|/StartupItems/TrackDelete|/StartupItems/VolumeAssist" | grep -v " grep -|/LiveUpdateAdminUtility/"`" ] ; then
      SymantecIsInMemoryResult=TRUE
   else
      kextstat 2>/dev/null 1>&2
      if [ $? -gt 0 ] ; then
         if [ "`kmodstat | grep -i Symantec | grep -v " grep -"`" ] ; then
            SymantecIsInMemoryResult=TRUE
         fi
      elif [ "`kextstat | grep -i Symantec | grep -v " grep -"`" ] ; then
         SymantecIsInMemoryResult=TRUE
      fi
   fi
   echo $SymantecIsInMemoryResult
   ! $SymantecIsInMemoryResult && return 1
   return 0
}

YesEntered()
{
   # Usage:     YesEntered
   # Summary:   Reads a line from standard input. If "y" or "yes"
   #            was entered, TRUE is shown and 0 is returned; otherwise,
   #            FALSE is shown and 1 is returned. The case of letters is
   #            ignored. Sample call:
   #               if `YesEntered`
   #
   read YesEnteredString
   YesEnteredString=`echo "z$YesEnteredString" | awk '{print tolower(substr($0,2))}'`
   if [ "'$YesEnteredString" = "'y" -o "'$YesEnteredString" = "'yes" ] ; then
      echo TRUE
      return 0
   fi
   echo FALSE
   return 1
}

# *** Beginning of Commands to Execute ***

if [ $# -eq 0 ] ; then   # If no arguments were passed to script
   # Run script as if it was double-clicked in Finder so that
   # screen will be cleared and quit message will be displayed.
   RunScriptAsStandAlone=TRUE
else
   # Run script in command line mode so that
   # screen won't be cleared and quit message won't be displayed.
   RunScriptAsStandAlone=FALSE
fi
if $RunScriptAsStandAlone ; then
   clear >&2
fi
if [ "z$1" = z-h ] ; then
   ShowUsage
elif [ "z$1" = z-V ] ; then
   echo $Version
   ExitScript 0
fi
if [ "`whoami`" != "root" ] ; then   # If not root user,
   if $PublicVersion ; then
      GetAdminPassword TRUE   #    Prompt user for admin password
   else
      ShowVersion >&2
      echo >&2
   fi
   # Run this script again as root
   sudo -p "Please enter your admin password: " "$0" "$@"
   ErrorFromSudoCommand=$?
   # If unable to authenticate
   if [ $ErrorFromSudoCommand -eq 1 ] ; then
      echo "You entered an invalid password or you are not an admin user. Script aborted." >&2
      ExitScript 1
   fi
   if $PublicVersion ; then
      sudo -k   # Make sudo require a password the next time it is run
   fi
   exit $ErrorFromSudoCommand #    Exit so script doesn't run again
fi
NumberOfArgumentsLeft=$#
while [ $NumberOfArgumentsLeft != 0 ] ; do
   AssignOptions "$1"
   shift
   NumberOfArgumentsLeft=`expr $NumberOfArgumentsLeft - 1`
done
# If no volumes were passed to script, the boot volume will be searched
if [ -z "$VolumesToUse" ] ; then
   BootVolumeWillBeSearched=TRUE
fi
if [ $PublicVersion = TRUE -a $CreateFilesRemovedListOnly = FALSE -a $RemoveCrontabEntriesOnly = FALSE -a $RemoveInvisibleFilesOnly = FALSE -a $AutoRunScript = FALSE ] ; then
   DetermineAction
fi
if [ $RemoveFromAllVolumes = TRUE -a $CreateFilesRemovedListOnly = FALSE -a $RemoveCrontabEntriesOnly = FALSE -a $RemoveInvisibleFilesOnly = FALSE -a $AutoRunScript = FALSE ] ; then
   echo
   printf "Are you sure you want to remove Symantec files from ALL mounted volumes (y/n)? "
   if `YesEntered` ; then
      echo
   else
      echo
      echo "Script aborted. No files were removed."
      ExitScript 0
   fi
fi
SetupCleanup
WillTense=will
if $CreateFilesRemovedListOnly ; then
   echo "Generating a list of files that would be removed by" >&2
   echo "   $FullScriptName (no files will be removed at this time)..." >&2
   WillTense=would
elif $RemoveInvisibleFilesOnly ; then
   echo "Removing AntiVirus QuickScan files and Norton FS files..."
else
   if $BootVolumeWillBeSearched ; then
      if [ $RestartAutomatically = TRUE -a $RemoveCrontabEntriesOnly = FALSE ] ; then
         echo
         echo "Note: Computer will be restarted automatically if necessary."
         echo
      elif $QuitWithoutRestarting ; then
         echo
         echo "Note: This script will automatically quit when finished."
         echo
      fi
   fi
   echo "Removing Symantec files..."
   ! $RemoveInvisibleFiles && echo "Invisible Symantec files will not be deleted."
fi
if $RemoveCrontabEntriesOnly ; then
   echo "Only crontab entries $WillTense be removed."
fi
! $RemoveCrontabEntries && echo "Symantec crontab entries $WillTense not be removed."
! $RemoveInvisibleFiles && echo "AntiVirus QuickScan and Norton FS files $WillTense not be removed."
if $RemoveFromAllVolumes ; then
   VolumesToUse="/
"`ls -d /Volumes/*`
elif ! $RemoveFromOtherVolumes ; then
   VolumesToUse=/
fi
ListOfVolumesToUse=`echo "$VolumesToUse" | sort -f | uniq`
IFS='
'
for EachVolume in $ListOfVolumesToUse ; do
   [ -L "$EachVolume" ] && continue
   FilesFoundOnThisVolume=FALSE
   RemoveAllNortonFiles "$EachVolume"
   if [ $CreateFilesRemovedListOnly = TRUE -a $FilesFoundOnThisVolume = FALSE -a $ListOnlyFilesThatExist = TRUE ] ; then
      echo "No matching files were found on "`basename "$EachVolume"`"." >> "$FilesRemovedList"
   fi
done
FinishCleanup
FinishedExitCode=$?
if [ $BootVolumeWillBeSearched = TRUE -a $CreateFilesRemovedListOnly = FALSE ] ; then
   if `SymantecIsInMemory` ; then
      echo
      echo "NOTE: You should now restart the computer to get Symantec processes"
      echo "      and kexts out of memory."
      RestartComputer
   elif [ -e /Library/StartupItems/CleanUpSymWebKitUtils ] ; then
      echo
      echo "NOTE: You should now restart the computer to have CleanUpSymWebKitUtils"
      echo "      finish removing SymWebKitUtils.framework."
      RestartComputer
   fi
fi
ExitScript $FinishedExitCode

# *** End of Commands to Execute ***

zmbarker
Contributor

@mojo21221][/url - The script is already linked in the original posting. Just go to ftp://ftp.symantec.com/misc/tools/mactools/RemoveSymantecMacFiles.zip and download the script.

@boettchs][/url - The script you posted is from 2009. The link ftp://ftp.symantec.com/misc/tools/mactools/RemoveSymantecMacFiles.zip is the most current script from Dec 10, 2013

[ftp://ftp.symantec.com/misc/tools/mactools/RemoveSymantecMacFiles.zip](ftp://ftp.symantec.com/misc/tools/mactools/RemoveSymantecMacFiles.zip)

scottb
Honored Contributor

@zmbarker][/url - my first post showed that header. I was asked to post it, so I did.
The script I'm using is working great with SEP 11.x. I'll have a look at the other.
Thanks!

*Edit: I'm unable to grab that file on the Symantec ftp site...

zmbarker
Contributor

#!/bin/sh
# File Name: RemoveSymantecMacFiles.command Version=7.0.8
# Author: Corey Swertfager, Symantec Corporation
# Watermark ID: CB70-6840-3597-44-15-4
# Created: 10/04/2001
# Modified: 12/10/2013
#
# WARNING: This script will remove all files and folders created by
# Symantec OS X products (except Symantec Adminstration Console
# for Macintosh files) and any files within those folders.
# Therefore, you will lose ALL files that reside in those folders,
# including any that you have created.
#
# Usage: RemoveSymantecMacFiles.command [options] [volume ...]
#
# Summary: See ShowHelp() function.
#
# History: 5.00 - Ported code from version 4.27.
# Now removes crontab entries from any OS X boot volume.
# Now removes Symantec items from loginwindow.plist files.
# Now removes receipts from any volume.
# Now checks for Symantec kexts/processes in memory when
# determining when a restart is necessary.
# Added -f option to suppress output of removed files.
# Now shows names of files as they are removed, unless the
# -f option is specified.
# 5.01 - Now removes:
# /Library/Contextual Menu Items/SAVCMPlugIn.plugin
# 5.02 - Adjusted output when a folder/file cannot be removed.
# Removed warning when /Library/StartupItems remains.
# Now removes:
# /Library/Application Support/Symantec/Daemon/SymDaemon.bundle
# /Library/Application Support/Symantec/Daemon
# /Library/Application Support/Symantec/SymUIAgent
# /Library/Application Support/Symantec/WebFraud
# /Library/Contextual Menu Items/SymFileSecurityCM.plugin
# /Library/PrivateFrameworks/SymAppKitAdditions.framework
# /Library/PrivateFrameworks/SymBase.framework
# /Library/PrivateFrameworks/SymConfidential.framework
# /Library/PrivateFrameworks/SymSharedSettings.framework
# /Library/Receipts/SymConfidential.pkg
# /Library/Receipts/SymFileSecurity.pkg
# /Library/Receipts/SymSharedFrameworks.pkg
# /Library/Receipts/SymSharedSettings.pkg
# /private/etc/mach_init.d/SymSharedSettings.plist
# 5.03 - Now removes:
# /Applications/Norton Confidential.app
# /Library/Application Support/Symantec/IntrusionPrevention
# /Library/LaunchDaemons/com.symantec.symdaemon.plist
# /Library/LaunchDaemons/com.symantec.uiagent.bundle
# /Library/PrivateFrameworks/SymDaemon.framework
# /Library/PrivateFrameworks/SymInternetSecurity.framework
# /Library/PrivateFrameworks/SymUIAgent.framework
# /Library/PrivateFrameworks/SymUIAgentUI.framework
# /Library/Receipts/SymConfidentialData.pkg
# /Library/Receipts/SymDaemon.pkg
# /Library/Receipts/SymFileSecurity.pkg
# /Library/Receipts/SymInternetSecurity.pkg
# /Library/Receipts/SymIntrusionPrevention.pkg
# /Library/Receipts/SymNCOApplication.pkg
# /Library/Receipts/SymUIAgent.pkg
# /Library/Receipts/SymWebFraud.pkg
# /Library/Receipts/WCIDEngine.pkg
# /System/Library/Extensions/SymInternetSecurity.kext
# /System/Library/Extensions/SymIPS.kext
# /System/Library/SymInternetSecurity.kext
# 5.04 - Now removes:
# /Applications/Firefox.app/Contents/MacOS/extensions/{0e10f3d7-07f6-4f12-97b9-9b27e07139a5}
# /Library/Application Support/Symantec/Assistants/Norton Confidential
# /Library/Application Support/Symantec/Assistants/Symantec Setup Assistant.app
# /Library/Application Support/Symantec/Assistants/Symantec Setup Assistant.bundle
# /Library/Application Support/Symantec/Assistants
# /Library/Receipts/SymSetupAssistant.pkg
# 5.05 - Now removes:
# /Library/Preferences/com.symantec.sharedsettings
# 5.06 - Now removes:
# /Library/Application Support/Symantec/Settings
# 5.07 - Now removes:
# /Library/LaunchDaemons/com.symantec.uiagent.plist
# 5.08 - Now removes:
# /Library/Preferences/com.symantec.uninstaller.plist
# 5.09 - Now only removes when empty:
# /Library/Application Support/Symantec/Assistants
# /Library/Application Support/Symantec/Daemon
# 5.10 - Now removes:
# /Library/Application Support/Symantec/Daemon/error.log
# Added volume name to paths in progress.
# 5.11 - Now removes:
# /Applications/Firefox.app/Contents/MacOS/extensions/{29dd9c80-9ea1-4aaf-9305-a0314aba24e3}
# 5.12 - Now removes:
# /private/var/tmp/com.symantec.liveupdate.

# 5.13 - OSXvnc StartupItems are now filtered out during Symantec
# process checking.
# 5.14 - Modified for OS 10.5 compatibility.
# No longer removes empty /Library/StartupItems.
# Now removes:
# /Library/InputManagers/Norton Confidential for Safari
# Now removes files installed by NAV 11 build 1.
# 5.15 - Now removes:
# /.symSchedScanLockxz
# RemoveInvisibleFilesFromVolume functions now removes:
# /.SymAVQSFile
# Added DeleteLaunchdPlists function to remove Symantec
# Scheduler launchd plists.
# Added messaging when there are no Symantec crontab
# entries to delete.
# Renamed Remove function to RemoveItem.
# RemoveItem function can now match several files.
# Now removes additional files installed by NAV 11.
# A list of files deleted by this program is now appended
# to ReadMe.txt.
# All com.symantec. preferences are now shown when using
# the -L option to show all files that would be deleted.
# 5.16 - Now removes:
#
/Library/Preferences/com.symantec.nortonantivirus.
#
/Library/Preferences/com.symantec.nortonconfidential.
#
/Library/Preferences/com.symantec.schedScanResults
#
/Library/Preferences/com.symantec.symsched
# 5.17 - Adjusted grep filters in SymantecIsInMemory function.
# Now removes:
# /Applications/Norton AntiVirus.app
# 5.18 - Changed how ShowVersion is called for OS 10.5 compatibility.
# 5.19 - Now removes:
# /Library/Internet Plug-Ins/Norton Confidential for Safari.plugin
# 5.20 - Now removes:
# /Library/Receipts/SymantecAVDefs

# /private/tmp/com.symantec.liveupdate.restart
# 5.21 - Added output to DeleteSymantecLoginItems function.
# Revised output of -l and -L options.
# Now removes:
# /Library/Receipts/SymStuffit.pkg
# 5.22 - Now removes:
# /Library/Application Support/Symantec/Protector
# /Library/Receipts/SymProtector.pkg
# /Library/StartupItems/SymProtector
# 5.23 - Now removes:
# /Library/Receipts/SavLog.pkg
# 5.24 - Changed the assignment order of CRONDIR to account for
# cases where OS 10.5 was installed over OS 10.4.
# 5.25 - Now removes:
# /Library/Preferences/com.Symantec.SAVX.
# 5.26 - Now removes:
# /Library/Application Support/Symantec/Assistants/Client Firewall
# /Library/Application Support/Symantec/Assistants/SCF Assistant Startup.app
# /Library/Application Support/Symantec/DeepSight
# /Library/Application Support/Symantec/Firewall
# /Library/LaunchDaemons/com.symantec.deepsight-extractor.plist
# /Library/LaunchDaemons/com.symantec.npfbootstrap.plist
# /Library/PrivateFrameworks/SymFirewall.framework
# /Library/PrivateFrameworks/SymPersonalFirewall.framework
# /System/Library/Extensions/SymPersonalFirewall.kext
# /usr/bin/scfx
# 5.27 - Now removes:
# /Library/Application Support/Symantec/Daemon/debug.log
# /Library/Receipts/SymantecClientFirewall.pkg
# /Library/Receipts/SymFirewall.pkg
# /Library/Receipts/SymPersonalFirewallCore.pkg
# 5.28 - Now removes:
# /Library/Application Support/Symantec/Assistants/Norton Firewall
# /Library/Application Support/Symantec/Assistants/NPF Assistant Startup.app
# /Library/Receipts/NortonFirewall.pkg
# /Library/Receipts/SymPersonalFirewallUI.pkg
# /usr/bin/npfx
# 5.29 - Added ReceiptsTable variable and RunPredeleteScripts
# function to incorporate the running of predelete scripts.
# Added -e option to show predelete errors.
# 5.30 - Now removes:
# /Library/Application Support/Symantec/Assistants/NIS Assistant Startup.app
# /Library/Application Support/Symantec/Assistants/Norton Internet Security
# /Library/Receipts/NortonInternetSecurity.pkg
# 5.31 - Now removes temporary files used by this program.
# Added running of pre_delete scripts to RunPredeleteScripts functions.
# 5.32 - Adjusted DeleteSymantecLoginItems diff filtering.
# 5.33 - Now removes:
# /private/tmp/symask
# 5.34 - Now removes:
# /Library/LaunchDaemons/com.symantec
# /Library/Preferences/com.symantec

# [except com.symantec.sacm and com.symantec.smac]
# {each user's home directory}/Library/Preferences/com.symantec
# [except com.symantec.sacm
and com.symantec.smac]
# {each user's home directory}/Library/Preferences/Network/com.symantec

# /Library/Preferences/Network/com.symantec
# Added -x option to RemoveItem function.
# RemoveItem function now ignores letter case when a
# pattern or an exclusion is passed.
# Links in /Volumes are now ignored.
# 5.35 - Removed return statement that caused premature script end.
# 5.36 - Now removes items installed by NFS 100.001:
# /Library/Application Support/Symantec/Norton Family Safety
# /Library/Internet Plug-Ins/Norton Family Safety.plugin
# /Library/PreferencePanes/Norton Family Safety.prefPane
# /Library/Receipts/NFSCore.pkg
# 5.37 - Revised pattern to find Symantec processes.
# Now removes all Dev.pkg receipts.
# 5.38 - Now removes items installed by NSM 100.008:
# /Library/Application Support/Symantec/Norton Safety Minder
# /Library/Internet Plug-Ins/Norton Safety Minder.plugin
# /Library/PreferencePanes/Norton Safety Minder.prefPane
# /Library/PreferencePanes/Ribbon.Norton.prefPane
# /Library/Receipts/NSMCore.pkg
# 5.39 - Now removes:
# /Library/Caches/com.symantec

# /Library/Caches/Norton
# /Library/Caches/Symantec

# /Library/Logs/Norton
# /Library/Logs/Symantec

# /Library/Logs/SymDeepsight
# /Library/Logs/SymFWLog.log
# /Library/Logs/SymFWRules.log

# /Library/Preferences/wcid
# /private/var/tmp/com.symantec
# {each user's home directory}/Library/Caches/com.symantec

# {each user's home directory}/Library/Caches/Norton
# {each user's home directory}/Library/Caches/Symantec

# {each user's home directory}/Library/Preferences/wcid
# 5.40 - Fixed an erroneous "invalid password" error message.
# Non-removal of /opt is no longer considered an error
# (some third party programs install files into there).
# 5.41 - Updated Usage(s) comments.
# 5.42 - Now removes:
# /Library/PrivateFrameworks/SymWebKitUtils.framework
# 5.43 - Now removes:
# /Library/InputManagers/Norton Safety Minder
# 5.44 - Now removes:
# /var/db/receipts/com.symantec
# 5.45 - Now removes if empty folder:
# /Library/Preferences/Network
# Now removes:
# /Applications/Firefox.app/Contents/MacOS/extensions/nortonsafetyminder@symantec.com
# 5.46 - Added -d option.
# Updated help.
# 5.47 - Added running of predelete scripts stored in new Symantec
# Uninstaller's Receipt folder.
# Now removes:
# /Library/Application Support/Symantec/Uninstaller
# Added -Q and -QQ options.
# Added KillTerminal function.
# 5.48 - Restart prompt is now shown any time boot volume is checked
# and there are Symantec processes and/or kexts in memory,
# except when -l or -L is passed.
# Now removes:
# /Library/Application Support/Symantec/Registry
# /Library/Application Support/Symantec/Submissions
# /Library/Application Support/Symantec/SymWebKitUtils
# /Library/PrivateFrameworks/SymSubmission.framework
# /Library/Receipts/SymSubmission.pkg
# /Library/Receipts/SymWebKitUtils.pkg
# Now removes /Library/PrivateFrameworks/SymWebKitUtils.framework
# only if the framework does not contain SymWKULoader.dylib; its
# receipt is removed if SymWKULoader.dylib does not exist or if
# /Library/StartupItems/CleanUpSymWebKitUtils exists.
# 5.49 - Excluded /LiveUpdateAdminUtility/ from processes to find in
# SymantecIsInMemory function.
# 5.50 - Fixed RunPredeleteScripts function so that it runs more than
# just the first predelete script in Symantec Uninstaller's
# Receipts folder and allows for multiple predelete scripts in
# /Library/Receipts receipts.
# Now removes:
# /Library/InputManagers/SymWebKitUtils
# /Library/StartupItems/SymQuickMenuOSFix
# /Library/StartupItems/SymWebKitUtilsOSFix
# Restart prompt is now shown if CleanUpSymWebKitUtils exists in
# /Library/StartupItems.
# Running ofLiveUpdate.pkg predelete script is no longer skipped.
# 5.51 - Now removes:
# /Library/Application Support/Symantec/SEP
# /Library/Application Support/Symantec/SMC
# /Library/Application Support/Symantec/SNAC
# /Library/LaunchAgents/com.symantec

# /Library/Receipts/SMC.pkg
# /Library/Receipts/SNAC.pkg
# /Library/Receipts/Symantec Endpoint Protection.pkg
# /Library/Receipts/SymantecSAQuickMenu.pkg
# /Library/Services/ScanService.service
# /Library/Services [deleted if empty]
# /Library/StartupItems/SMC
# /usr/lib/libsymsea.1.0.0.dylib
# /usr/lib/libsymsea.dylib
# Adjusted RunPredeleteScripts function to limit predelete script
# names to those ending with predelete or pre_delete; doing so
# prevents a bus error by no longer running "predeletetool".
# 5.52 - Added -m option to use more program when -l, -L, or -R
# options are used.
# Removed -r option, which deleted only receipts.
# Added -R option to include folder contents when showing
# installed files.
# Progress shown when using the -l, -L, or -R options is
# now sent to standard error to facilitate piping the
# generated report to a file without piping progress.
# 5.53 - Now removes:
# /Library/ScriptingAdditions/SymWebKitUtils.osax
# /Library/ScriptingAdditions/SymWebKitUtilsSL.osax
# /usr/local/lib/libgecko3parsers.dylib
# /usr/local/lib [deleted if empty]
# /usr/local [deleted if empty]
# 5.54 - Now removes:
# /private/var/db/receipts/com.symantec
# 5.55 - Now removes:
# /Library/Receipts/LiveUpdate

# /Library/Application Support/Symantec/AntiVirus.kextcache
# RunPredeleteScripts function now also runs predelete scripts for
# receipts in ReceiptsTable that pass option -a.
# 5.56 - Now removes:
# /private/tmp/jlulogtemp
# /private/tmp/LiveUpdate.
# /private/tmp/liveupdate
# /private/tmp/lulogtemp
# /private/tmp/SymSharedFrameworks

# /private/var/db/receipts/$(SYM_SKU_REVDOMAIN).install.bom
# /private/var/db/receipts/$(SYM_SKU_REVDOMAIN).install.plist
# /private/var/tmp/com.Symantec
# 5.57 - Now removes:
# /Library/Application Support/nis_postuninstall.rb
# /Library/Application Support/nis_postuninstall.sh
# 5.58 - Now removes:
# /Library/Receipts/NSMCore.Universal.pkg
# 5.59 - Now removes:
# /Applications/Norton DNS Beta.app
# /Applications/Norton DNS.app
# /Library/Application Support/Symantec/Norton DNS
# /Library/LaunchDaemons/com.norton
# /private/var/log/nortondns.log
# {each user's home directory}/Library/Caches/com.norton
# {each user's home directory}/Library/Preferences/com.norton
# 5.60 - Now removes:
# /Library/Preferences/com.norton

# {each user's home directory}/Library/Preferences/com.norton
# The following removals were added in version 5.59, but the version
# history erroneously left off the trailing
:
# /Library/LaunchDaemons/com.norton
# {each user's home directory}/Library/Caches/com.norton

# The following removal were added in version 5.59, but the version
# history erroneously omitted its addition:
# /Library/Caches/com.norton
# 5.61 - Removed CurrentUserTempFile/ProcessArgumentsCalled.
# 5.62 - Modified for case-sensitive volume compatibility.
# Now removes (based on NIS 5.0 builds 8-12 boms):
# /Library/Application Support/Symantec/ErrorReporting
# /Library/PrivateFrameworks/SymLicensing.framework
# /Library/Receipts/NAV_App

# /Library/Receipts/NAV_AutoProtect
# /Library/Receipts/NortonFirewall

# /Library/Receipts/NortonInternetSecurity
# /Library/Receipts/NortonQuickMenu

# /Library/Receipts/SymantecSharedComponents
# /Library/Receipts/SymantecUninstaller

# /Library/Receipts/SymConfidential
# /Library/Receipts/SymDaemon

# /Library/Receipts/SymErrorReporting.pkg
# /Library/Receipts/SymFileSecurity
# /Library/Receipts/SymFirewall

# /Library/Receipts/SymIntrusionPrevention
# /Library/Receipts/SymNCOApplication

# /Library/Receipts/SymPersonalFirewallCore
# /Library/Receipts/SymPersonalFirewallUI

# /Library/Receipts/SymPseudoLicensing
# /Library/Receipts/SymSetupAssistant

# /Library/Receipts/SymSharedFrameworks
# /Library/Receipts/SymSharedSettings

# /Library/Receipts/SymUIAgent
# /Library/Receipts/SymWebFraud

# /Library/Services/SymSafeWeb.service
# /usr/bin/MigrateQTF
# 5.63 - Now removes:
# /usr/local/lib/libecomlodr.dylib
# 5.64 - Updated DeleteCrontabEntries to delete entries from both
# OS 10.4 and OS 10.5 crontab directories.
# 5.65 - Updated for NAV 12/NIS 5.
# 5.66 - Added check for launch location to suppress screen clearing, prompts,
# and quit message ("NOTE: If you double-clicked this script, quit Terminal
# application now.") when running from within app bundle or in support folder.
# Now removes:
# /Library/Receipts/SymLicensing
# 5.67 - Fixed "[: too many arguments" error.
# 5.68 - Now removes in all versions:
# /Library/Application Support/Symantec/Daemon/timer
# /Library/Application Support/Symantec/Licensing
# 5.69 - Now removes:
# /Preferences/ByHost/com.symantec

# {each user's home directory}/Preferences/ByHost/com.symantec
# 5.70 - Now removes:
# /Library/Application Support/Symantec/Daemon/timer.log
# 6.0.0 - 09/01/2011:
# Now designates when Symantec Uninstaller.app should not
# remove an item when using the -l or -R options.
# The -l and -R options are now equivalent.
# 6.0.1 - 09/11/2011:
# Updated file list.
# 6.0.2 - 09/16/2011:
# Updated file list.
# 6.0.3 - 10/07/2011:
# Now removes:
# /Library/Application Support/nav_postuninstall.rb
# /Library/Application Support/nsm_postuninstall.rb
# /Library/Application Support/o2spy.log
# /Library/Application Support/Symantec/NortonM
# /Library/PrivateFrameworks/PlausibleDatabase.framework
# /Library/PrivateFrameworks/SymOxygen.framework
# 6.0.4 - 11/08/2011:
# Now removes:
# /Library/Application Support/nav_uninstalldashboard

# /Library/Application Support/symantec_uninstalldashboard
# 6.0.5 - 11/17/2011:
# Now removes:
# /Library/Application Support/Symantec/SymSAQuickMenu
# 6.0.6 - 12/06/2011:
# Now removes:
# /Library/PrivilegedHelperTools/NATRemoteLock.app
# /Library/Receipts/NATRemoteLock.pkg
# /Library/Receipts/NATSDPlugin.pkg
# /Library/Receipts/nortonantitheftPostflight.pkg
# /Library/Receipts/PredeleteTool.pkg
# /Library/Receipts/SymOxygen.pkg
# /usr/lib/libwpsapi.dylib
# 6.0.7 - 12/14/2011:
# Now removes:
# /Library/Receipts/nortonanti-theftPostflight.pkg
# /private/var/db/NATSqlDatabase.db
# 6.0.8 - 02/28/2012:
# Now removes:
# /private/tmp/com.symantec.liveupdate.reboot
# 6.0.9 - 03/30/2012:
# Now removes:
# /private/var/db/receipts/com.Symantec

# 6.0.10 - 06/19/2012 - Corey Swertfager:
# Now removes:
# /Applications/Norton Zone
# /Library/Application Support/nav_uninstalldashboard

# /Library/Application Support/symantec_uninstalldashboard
# /Library/Caches/com.apple.Safari/Extensions/Norton

# /Library/Caches/com.apple.Safari/Extensions/Symantec
# /Library/Internet Plug-Ins/NortonSafetyMinderBF.plugin
# /Library/Preferences/Norton Zone
# /Library/Receipts/ZoneStandalone.pkg
# {each user's home directory}/Library/Caches/com.apple.Safari/Extensions/Norton

# {each user's home directory}/Library/Caches/com.apple.Safari/Extensions/Symantec
# {each user's home directory}/Library/Preferences/Norton Zone
# Now actually removes (added missing quotes to RemoveItem calls):
# /Library/Application Support/nav_uninstalldashboard

# /Library/Application Support/symantec_uninstalldashboard
# 6.0.11 - 06/19/2012 - Corey Swertfager:
# Now removes:
# /Library/Application Support/NortonZone
# {each user's home directory}/Library/Application Support/NortonZone
# 6.0.12 - 07/06/2012 - Corey Swertfager:
#
Modified grep calls with regular expressions that contain pattern "$|"
# to instead use extended regular expression "$|" for OS 10.8 compatibility,
# fixing the problem of predelete scripts not being run on OS 10.8.
# Now removes:
# /usr/local/bin/KeyGenerator
# 6.0.13 - 08/03/2012 - Corey Swertfager:
#
Now removes:
# /Library/Application Support/Symantec/Mexico
# /Library/Frameworks/mach_inject_bundle.framework
# 6.0.14 - 08/27/2012 - Corey Swertfager:
# Now removes Norton Zone saved sessions.
# 6.0.15 - 08/31/2012 - Corey Swertfager:
#
Removed logic that attempted to remove:
# {each user's home directory}/Library/Norton Zone
# 6.0.16 - 10/08/2012 - Corey Swertfager:
# Now removes:
# {each user's home directory}/Library/Application Support/Symantec
# /Library/Internet Plug-Ins/NortonInternetSecurityBF.plugin
#
Now makes a second attempt to remove:
# /Library/Application Support/Symantec/ErrorReporting
# /Library/Application Support/Symantec [deleted if empty]
# 6.0.17 - 10/11/2012 - Corey Swertfager:
# Now removes:
# /Library/Application Support/Symantec/NisLaunch
# 6.0.18 - 10/19/2012 - Corey Swertfager:
# Now removes:
# {each user's home directory}/Library/Safari/Extensions/NortonSafetyMinderBF
# 6.0.19 - 03/12/2013 - Corey Swertfager:
#
Now removes:
# /Library/Application Support/Symantec/Daemon [deleted whether empty or not]
# /Library/PrivilegedHelperTools/com.symantec
#
Added KillNortonZone function.
# Added watermark ID.
# 6.0.20 - 03/15/2013 - Corey Swertfager:
#
Now removes Norton Zone from loginwindow.plist files.
# Revamped DeleteSymantecLoginItems function to account
# for varying key values.
#
KillNortonZone function now only runs killall Finder
# if Norton Zone process was killed.
# 6.0.21 - 04/26/2013 - Corey Swertfager:
# Now removes:
# /Library/Application Support/Symantec/Silo
# /usr/local/bin/MigrateQTF
# /usr/local/bin [deleted if empty]
# 6.0.22 - 05/10/2013 - Corey Swertfager:
#
Now removes:
# /var/log/luxtool.log
# 6.0.23 - 05/14/2013 - Corey Swertfager:
#
Now removes:
# /var/log/mexd.log
# 6.0.24 - 05/28/2013 - Corey Swertfager:
# Now removes:
# /Library/Application Support/nat

# /Library/Application Support/nav

# /Library/Application Support/nis

# /Library/Application Support/nsm

# /Library/Application Support/norton

# /Library/Application Support/Symantec/Norton Anti-Theft
# /usr/local/bin/CoreLocationProviderTest
# /usr/local/bin/LocationProviderInterfaceTest
# /usr/local/bin/LocationProviderTest
# /usr/local/bin/SkyhookProviderTest
# 6.0.25 - 05/28/2013 - Corey Swertfager:
#
Now removes:
# /Applications/Norton
# /predelete (installed by Norton Anti-Theft)
# {each user's home directory}/Application Support/Symantec
# {each user's home directory}/Application Support [deleted if empty]
# 6.1.0 - 06/28/2013 - Corey Swertfager:
#
ProcessArguments 1.0.1 is now used to process arguments to allow
# options to be combined in one argument that begins with a single
# hyphen (e.g., passing -ab to script would be equivalent to passing
# -a and -b separately; --ab would be treated as a single option).
# The -QQ and -re remain separate arguments for backwards compatibility.
# Added -r option to restart automatically (equivalent to deprecated
# -re option).
#
Now removes, even when not empty:
# /Library/Application Support/Symantec
# Now removes:
# /Applications/GatherSymantecInfo
# /Library/Application Support/Norton

# /private/var/tmp/symantec_error_report
# /usr/local/lib/libcx_lib.so
# /usr/local/lib/liblux.so.1
# /usr/local/lib/libnlucallback.dylib
# {each user's home directory}/Library/Application Support/Norton

# {each user's home directory}/Library/Saved Application State/com.symantec
#
Now removes Symantec Administration Console for Macintosh files.
# Updated help: changed "Administration Console for Macintosh" to
# "Endpoint Protection".
# 6.1.1 - 07/10/2013 - Corey Swertfager:
#
Now removes:
# {each user's home directory}/Library/Logs/Symantec
# 6.1.2 - 07/11/2013 - Corey Swertfager:
#
Now removes:
# /usr/local/lib/liblux.so.
# 6.1.3 - 07/14/2013 - Corey Swertfager:
#
Updated ReadMe.txt.
# Now removes:
# {each user's home directory}/Library/Safari/Extensions/Norton

# 7.0.0 - 07/19/2013 - Corey Swertfager:
# Now removes:
# /private/etc/symantec
# /var/log/lux.log

# Updated version to make sure tools updater finds this program.
# 7.0.1 - 08/19/2013 - Corey Swertfager:
#
Now removes:
# /var/log/du.log
# /var/log/dulux.log

# /var/log/lut.log
# /var/log/mexd.log

# /var/log/microdef.log
#
Now removes logs listed in:
# /Library/Application Support/Symantec/Silo/NFM/LiveUpdate/Conf
# /private/etc/symantec/defutils.conf
# /private/etc/symantec/dulux.logging.conf
# /private/etc/symantec/lux.logging.conf
# /private/etc/symantec/microdef.logging.conf
# 7.0.2 - 09/05/2013 - Corey Swertfager:
# Now removes:
# /Library/Extensions/FileSecurity.kext
# /Library/Extensions/SymAPComm.kext
# /Library/Extensions/SymFirewall.kext
# /Library/Extensions/SymInternetSecurity.kext
# /Library/Extensions/SymIPS.kext
# /Library/Extensions/SymPersonalFirewall.kext
# 7.0.3 - 09/05/2013 - Corey Swertfager:
#
Updated for NIS 6.
# 7.0.4 - 10/15/2013 - Corey Swertfager:
# Now removes for all versions:
# /Library/Extensions/ndcengine.kext
# /Library/Extensions/NortonForMac.kext
# /Library/PrivateFrameworks/SymSEP.framework
# /System/Library/Extensions/ndcengine.kext
# /System/Library/Extensions/NortonForMac.kext
# /usr/bin/nortonscanner
# /usr/bin/nortonsettings
# /usr/lib/libsymsea.
dylib
# /usr/local/bin/nortonsettings
# /var/root/Applications/Norton Internet Security.app
# 7.0.5 - 10/28/2013 - Corey Swertfager:
# Updated read me.
# 7.0.6 - 11/05/2013 - Corey Swertfager:
#
Updated read me.
# 7.0.7 - 12/03/2013 - Corey Swertfager:
# Now removes:
# /Library/Logs/o2spy.log
# 7.0.8 - 12/10/2013 - Corey Swertfager:
#
Now removes com.norton.NFM.auth from login keychains.
# * Renamed RemoveNortonZoneSavedSessions function to
# RemoveLoginKeychainPasswords.

# Variable Initializations

PATH=/bin:/sbin:/usr/bin:/usr/sbin
AbbreviatedScriptName=basename "$0" .command
AutoRunScript=true
AutoRunScript=false
CurrentVolumeBeingUsed="/"
FilesRemovedList="/private/tmp/${AbbreviatedScriptName}RemovesThese.txt"
FilesRemovedFilesOnlyList="/private/tmp/${AbbreviatedScriptName}RemovesThese-FilesOnly.txt"
FilesRemovedListOfOld="/Users/Shared/${AbbreviatedScriptName}RemovesThese.txt"
FilesWereSaved=false
FinishedExitCode=0
FullScriptName=basename "$0"
LANG=""
LaunchLocationGrepPattern='/Library/Application Support/Symantec/Uninstaller|.app/Contents/Resources'
LogFile="/private/tmp/${AbbreviatedScriptName}Log.txt"
LogFileOfOld="/Users/Shared/${AbbreviatedScriptName}Log.txt"
# ----- LoginKeychainPasswordsToDelete BEGIN ------------------------------------------------
# (2 fields, tab delimited):
# Item to delete / help text to show
LoginKeychainPasswordsToDelete="com.norton.NFM.auth Norton Internet Security account info
com.norton.mexico.auth Norton Zone saved sessions"
# ----- LoginKeychainPasswordsToDelete END --------------------------------------------------
# ----- NotRemovedBySymantecUninstaller BEGIN ------------------------------------------------
# A list of paths or partial paths that aren't removed by Symantec Uninstaller.app.
# Add only items that cannot be isolated by the -u option.
NotRemovedBySymantecUninstaller='/Library/LaunchDaemons/com.symantec.nis.uninstall.plist
/Library/Logs/SymantecTestPatchers.log'
# ----- NotRemovedBySymantecUninstaller END --------------------------------------------------
NotRemovedBySymantecUninstallerText=" [should not be removed by Symantec Uninstaller.app]"
PublicVersion=true
# ----- ReceiptsTable BEGIN ------------------------------------------------
# (2 fields, tab delimited):
# Receipt name / Receipt option (-a = delete receipt*, -s = skip run of predelete script)
ReceiptsTable='
# Check to make sure there are no vague receipts that may be used by
# third party software before releasing to the public.
# This line may need to be removed to avoid deleting third party files:
CompatibilityCheck.pkg
# This line may need to be removed to avoid deleting third party files:
Decomposer.pkg
# This line may need to be removed to avoid deleting third party files:
DeletionTracking.pkg
FileSaver.pkg
LiveUpdate -a
NATRemoteLock.pkg
NATSDPlugin.pkg
NAVContextualMenu.pkg
NAVcorporate.pkg
NAVDefs.pkg
NAVEngine.pkg
NAVWidget.pkg
navx.pkg
NAV_App -a
NAV_AutoProtect -a
NFSCore.pkg
NISLaunch.pkg
Norton AntiVirus Application.pkg
Norton AntiVirus Product Log.rtf
Norton AntiVirus.pkg
Norton AutoProtect.pkg
Norton Disk Editor X.pkg
Norton Internet Security Log.rtf
Norton Personal Firewall 3.0 Log.rtf
Norton Scheduled Scans.pkg
Norton Scheduler.pkg
Norton SystemWorks 3.0 Log.rtf
Norton Utilities 8.0 Log.rtf
nortonanti-theftPostflight.pkg
nortonantitheftPostflight.pkg
NortonAutoProtect.pkg
# Remove all NortonAVDefs receipts
NortonAVDefs -a
NortonDefragger.pkg
NortonDiskDoctor.pkg
NortonFirewall -a
NortonInternetSecurity -a
NortonLauncher.pkg
NortonParentalControl.pkg
NortonPersonalFirewall.pkg
NortonPersonalFirewallMenu.pkg
NortonPrivacyControl.pkg
NortonQuickMenu -a
NPC Installer Log
NPC.pkg
NSMCore.pkg
NSMCore.Universal.pkg
NSWLaunch.pkg
NUMCompatibilityCheck.pkg
NumDocs.pkg
NUMLaunch.pkg
PredeleteTool.pkg
SavLog.pkg
# This line may need to be removed to avoid deleting third party files:
Scheduled Scans.pkg
# This line may need to be removed to avoid deleting third party files:
Scheduler.pkg
SDProfileEditor.pkg
SMC.pkg
SNAC.pkg
SpeedDisk.pkg
# NAV 9 installs the StuffIt engine if it needs to and creates the
# StuffIt.pkg receipt for it. The following line may need to be removed
# (but should not need to be) to avoid deleting third party files:
StuffIt.pkg
Symantec Alerts.pkg
Symantec AntiVirus.pkg
Symantec AutoProtect Prefs.pkg
Symantec AutoProtect.pkg
Symantec Decomposer.pkg
Symantec Endpoint Protection.pkg
Symantec Scheduled Scans.pkg
Symantec Scheduler.pkg
# Remove all SymantecAVDefs receipts
SymantecAVDefs -a
SymantecClientFirewall.pkg
SymantecDecomposer.pkg
SymantecDeepSightExtractor.pkg
SymantecParentalControl.pkg
SymantecQuickMenu.pkg
SymantecSAQuickMenu.pkg
SymantecSharedComponents -a
SymantecUninstaller -a
SymantecURLs.pkg
SymAV10StuffItInstall.pkg
SymAVScanServer.pkg
SymConfidential -a
SymConfidentialData.pkg
SymDaemon -a
SymDC.pkg
SymDiskMountNotify.pkg
SymErrorReporting.pkg
SymEvent.pkg
SymFileSecurity -a
SymFirewall -a
SymFS.pkg
SymHelper.pkg
SymHelpScripts.pkg
SymInstallExtras.pkg
SymInternetSecurity.pkg
SymIntrusionPrevention -a
SymIPS.pkg
SymLicensing -a
SymNCOApplication -a
SymOxygen.pkg
SymOSXKernelUtilities.pkg
SymPersonalFirewallCore -a
SymPersonalFirewallUI -a
SymProtector.pkg
SymPseudoLicensing -a
SymSetupAssistant -a
SymSharedFrameworks -a
SymSharedSettings -a
SymStuffit.pkg
SymSubmission.pkg
SymUIAgent -a
SymWebFraud -a
SymWebKitUtils.pkg
Unerase.pkg
# This line may need to be removed to avoid deleting third party files:
URL.pkg
VolumeAssist.pkg
VolumeRecover.pkg
WCIDEngine.pkg
Wipe Info.pkg
ZoneStandalone.pkg
'
# ----- ReceiptsTable END --------------------------------------------------
SavedFilesDir="/private/tmp/${AbbreviatedScriptName}SavedFiles"

# Function Declarations

AssignVolume()
{ # Usage: AssignVolume $1 # Argument: $1 = Volume name. The name can begin with "/Volumes/" # unless it is "/" (boot volume). # Summary: Assigns the name of the volume passed as $1 to VolumesToUse. # If volume is assigned, 0 is returned; else, 1 is returned. # # If nothing passed, skip assignment [ -z "$1" ] && return 1 VolumeToAssign=CheckIfValidVolume "$1" if [ -z "$VolumeToAssign" ] ; then VolumeToAssign=CheckIfValidVolume "/Volumes/$1" [ -z "$VolumeToAssign" ] && return 1 fi [ "$VolumeToAssign" = "/" ] && BootVolumeWillBeSearched=true VolumesToUse="$VolumesToUse
$VolumeToAssign" return 0
}

CheckIfValidVolume()
{ # Usage: CheckIfValidVolume $1 # Argument: $1 = Volume name to check. # Summary: If $1 is a valid volume name, it is echoed; # else, "" is echoed. # VVolume="" # If something passed if [ -n "$1" ] ; then # If it is a directory and not a link if [ -d "$1" -a ! -L "$1" ] ; then InitCurrentDir=pwd # Save initial directory location cd "$1" if [ "pwd" = "/" -o "pwd" = "//" ] ; then VVolume=/ else cd .. ParentDir=pwd # If there is an extra / at beginning of path, remove it [ "echo "z$ParentDir" | awk '{print substr($0,2,2)}'" = "//" ] && ParentDir=echo "z$ParentDir" | awk '{print substr($0,3)}' # If $1 is a volume, assign it to VVolume [ "$ParentDir" = "/Volumes" ] && VVolume="$ParentDir/basename "$1"" fi cd "$InitCurrentDir" # Return to initial directory fi fi echo "$VVolume"
}

DeleteCrontabEntries()
{ # Usage: DeleteCrontabEntries [$1] # Argument: $1 = Volume name. The name should begin with "/Volumes/" # unless it is "/" (boot volume). If NULL, then / is # used as volume name. # Authors: John Hansen, Corey Swertfager # Summary: Deletes from / or volume specified the crontab entries # created by Norton Scheduler and Symantec Scheduler. # Note: User must be root when calling this function. # if [ "z$1" = z/ ] ; then VolumeToDeleteCrontabsFrom="" else VolumeToDeleteCrontabsFrom="$1" fi CRONDIRNEW="$VolumeToDeleteCrontabsFrom/private/var/at/tabs" # OS 10.5 and later crontab directory CRONDIROLD="$VolumeToDeleteCrontabsFrom/private/var/cron/tabs" # OS 10.4 and earlier crontab directory if [ ! -d "$CRONDIRNEW" -a ! -d "$CRONDIROLD" ] ; then if $CreateFilesRemovedListOnly ; then if [ -z "$VolumeToDeleteCrontabsFrom" ] ; then echo "No crontab directory was found on on the current boot volume." >> "$FilesRemovedList" else echo "No crontab directory was found on on the volume "basename "$VolumeToDeleteCrontabsFrom""." >> "$FilesRemovedList" fi echo "" >> "$FilesRemovedList" else if [ -z "$VolumeToDeleteCrontabsFrom" ] ; then echo "No crontab directory was found on on the current boot volume." else echo "No crontab directory was found on on the volume "basename "$VolumeToDeleteCrontabsFrom""." fi fi return 1 fi TEMPFILETEMPLATE="/private/tmp/NortonTemp" GREP1="^#SqzS" GREP2="^#SYMANTEC SCHEDULER CRON ENTRIES" GREP3="^#PLEASE DO NOT EDIT.$" GREP4="EvType1=.EvType2=.Sched=" GREP5="Norton Solutions Support/Scheduler/schedLauncher" GREP6="Symantec/Scheduler/SymSecondaryLaunch.app/Contents/schedLauncher" SymantecCrontabEntryExists=false CurrentDir="pwd" # Save initial directory location # Set IFS to only newline to get all crontabs IFS='
' for CRONDIR in ls -d "$CRONDIRNEW" "$CRONDIROLD" 2>/dev/null ; do cd "$CRONDIR" # List each crontab, pipe through grep command and replace for user in ls * 2>/dev/null ; do # If not root and not a valid user, skip [ "z$user" != "zroot" -a ! -d "$VolumeToDeleteCrontabsFrom/Users/$user" ] && continue # If deleting from boot volume if [ -z "$VolumeToDeleteCrontabsFrom" ] ; then # Check to see if there is a Symantec crontab entry if [ "crontab -u "$user" -l | grep -c "$GREP1|$GREP2|$GREP3|$GREP4|$GREP5|$GREP6"" != 0 ] ; then SymantecCrontabEntryExists=true else continue # Nothing to remove, skip user fi $CreateFilesRemovedListOnly && break TEMPFILE="$TEMPFILETEMPLATEdate "%Y%m%d%H%M%S"" crontab -u "$user" -l | grep -v "$GREP1|$GREP2|$GREP3|$GREP4|$GREP5|$GREP6" > $TEMPFILE # Restore crontab file if it has more entries, else remove if [ -s "$TEMPFILE" ] ; then crontab -u "$user" $TEMPFILE else echo "y" | crontab -u "$user" -r fi else # Check to see if there is a Symantec crontab entry if [ "grep -c "$GREP1|$GREP2|$GREP3|$GREP4|$GREP5|$GREP6" "$user"" != 0 ] ; then SymantecCrontabEntryExists=true else continue # Nothing to remove, skip user fi $CreateFilesRemovedListOnly && break TEMPFILE="$TEMPFILETEMPLATEdate "%Y%m%d%H%M%S"" grep -v "$GREP1|$GREP2|$GREP3|$GREP4|$GREP5|$GREP6" "$user" > $TEMPFILE # Restore crontab file if it has more entries, else remove if [ -s "$TEMPFILE" ] ; then cat $TEMPFILE >"$user" else rm -f "$user" 2>/dev/null fi fi /bin/rm "$TEMPFILE" 2>/dev/null done [ $CreateFilesRemovedListOnly = true -a $SymantecCrontabEntryExists = true ] && break done cd "$CurrentDir" # Return to intial directory if $SymantecCrontabEntryExists ; then if $CreateFilesRemovedListOnly ; then if [ -z "$VolumeToDeleteCrontabsFrom" ] ; then echo "Symantec crontab entries would be deleted from the current boot volume." >> "$FilesRemovedList" else echo "Symantec crontab entries would be deleted from the volume" >> "$FilesRemovedList" echo ""basename "$VolumeToDeleteCrontabsFrom""." >> "$FilesRemovedList" fi echo "" >> "$FilesRemovedList" else if [ -z "$VolumeToDeleteCrontabsFrom" ] ; then echo "Symantec crontab entries were deleted from the current boot volume." else echo "Symantec crontab entries were deleted from the volume" echo ""basename "$VolumeToDeleteCrontabsFrom""." fi fi NoFilesToRemove=false else if $CreateFilesRemovedListOnly ; then if [ -z "$VolumeToDeleteCrontabsFrom" ] ; then echo "There are no Symantec crontab entries on the current boot volume;" >> "$FilesRemovedList" echo "no crontab entries would be removed from it." >> "$FilesRemovedList" else echo "There are no Symantec crontab entries on the volume "basename "$VolumeToDeleteCrontabsFrom"";" >> "$FilesRemovedList" echo "no crontabs would be adjusted on that volume." >> "$FilesRemovedList" fi echo "" >> "$FilesRemovedList" elif [ -z "$VolumeToDeleteCrontabsFrom" ] ; then echo "There are no Symantec crontab entries to delete from the current boot volume." else echo "There are no Symantec crontab entries to delete from the volume" echo ""basename "$VolumeToDeleteCrontabsFrom""." fi fi return 0
}

DeleteLaunchdPlists()
{ # Usage: DeleteLaunchdPlists [$1] # Argument: $1 = Volume name. The name should begin with "/Volumes/" # unless it is "/" (boot volume). If NULL, then / is # used as volume name. # Summary: Deletes from / or volume specified the launchd plists # created by Symantec Scheduler. # Note: User must be root when calling this function. # if [ "z$1" = z/ ] ; then VolumeToDeleteLaunchdPlistsFrom="" else VolumeToDeleteLaunchdPlistsFrom="$1" fi LaunchdPlists=ls -d "$VolumeToDeleteLaunchdPlistsFrom/Library/LaunchDaemons/com.symantec.Sched"*.plist 2>/dev/null if [ "$LaunchdPlists" ] ; then if $CreateFilesRemovedListOnly ; then if [ -z "$VolumeToDeleteLaunchdPlistsFrom" ] ; then echo "Symantec Scheduler launchd plists would be deleted from the current boot volume." >> "$FilesRemovedList" else echo "Symantec Scheduler launchd plists would be deleted from the volume" >> "$FilesRemovedList" echo ""basename "$VolumeToDeleteLaunchdPlistsFrom""." >> "$FilesRemovedList" fi echo "" >> "$FilesRemovedList" else IFS='
' for EachPlist in $LaunchdPlists ; do rm -f "$EachPlist" 2>/dev/null done if [ -z "$VolumeToDeleteLaunchdPlistsFrom" ] ; then echo "Symantec Scheduler launchd plists were deleted from the current boot volume." else echo "Symantec Scheduler launchd plists were deleted from the volume" echo ""basename "$VolumeToDeleteLaunchdPlistsFrom""." fi fi NoFilesToRemove=false else if $CreateFilesRemovedListOnly ; then if [ -z "$VolumeToDeleteLaunchdPlistsFrom" ] ; then echo "There are no Symantec Scheduler launchd plists on the current boot volume," >> "$FilesRemovedList" echo "so none would be removed from it." >> "$FilesRemovedList" else echo "There are no Symantec Scheduler launchd plists on the volume" >> "$FilesRemovedList" echo ""basename "$VolumeToDeleteLaunchdPlistsFrom"", so none would be removed from it." >> "$FilesRemovedList" fi echo "" >> "$FilesRemovedList" elif [ -z "$VolumeToDeleteLaunchdPlistsFrom" ] ; then echo "There are no Symantec Scheduler launchd plists to delete from the current boot" echo "volume." else echo "There are no Symantec Scheduler launchd plists to delete from the volume" echo ""basename "$VolumeToDeleteLaunchdPlistsFrom""." fi fi return 0
}

DeleteSymantecLoginItems()
{ # Usage: DeleteSymantecLoginItems [$1] # Argument: $1 = Name of volume from which to remove login items. # The name must begin with "/Volumes/" unless it is # "/" (boot volume). If nothing is passed, / is assumed. # Summary: Deletes Symantec items from all loginwindow.plist files on # volume specified. # Note: If this function is run while booted in OS 10.1.x, it will # not be able to adjust loginwindow.plist files on an OS 10.4.x # volume because plutil did not ship with basic OS 10.1.x. # Boolean CreateFilesRemovedListOnly must be defined before # running this function. # local Buffer local Line local TARGETVOLUME="$1" [ "z$1" = z/ ] && TARGETVOLUME="" TEMPFILETEMPLATE=/private/tmp/DeleteSymantecLoginItems OUTFILE=${TEMPFILETEMPLATE}date "%Y%m%d%H%M%S"-1 SOURCEFILE=${TEMPFILETEMPLATE}date "%Y%m%d%H%M%S"-2 GREPSTR="/Library/Application Support/Symantec|/Library/Application Support/Norton Solutions|/Library/Application Support/Symnatec/Scheduler/SymSecondaryLaunch.app|/Library/StartupItems/Norton|/Norton Zone.app" FileShouldBeAdjusted=false IFS='
' for EachUser in ls "$TARGETVOLUME/Users" 2>/dev/null "root" "/" ; do if [ "z$EachUser" = z/ ] ; then ORIGFILE="$TARGETVOLUME/Library/Preferences/loginwindow.plist" elif [ "z$EachUser" = zroot ] ; then ORIGFILE="$TARGETVOLUME/private/var/root/Library/Preferences/loginwindow.plist" else ORIGFILE="$TARGETVOLUME/Users/$EachUser/Library/Preferences/loginwindow.plist" fi [ ! -f "$ORIGFILE" ] && continue rm -rf $SOURCEFILE 2>/dev/null cp "$ORIGFILE" $SOURCEFILE CheckSyntax=true plutil -convert xml1 $SOURCEFILE 2>/dev/null # If plutil failed to convert the plist, don't check syntax later [ $? != 0 ] && CheckSyntax=false IsBinaryFormat=false # If original plist is different than converted plist, treat it as a binary file [ -n "diff "$ORIGFILE" $SOURCEFILE 2>/dev/null" ] && IsBinaryFormat=true # If some Symantec login item(s) found if [ "grep "$GREPSTR" $SOURCEFILE" ] ; then printf "" > $OUTFILE FileShouldBeAdjusted=true if $CreateFilesRemovedListOnly ; then echo "Symantec login items would be removed from:" >>"$FilesRemovedList" echo " "$ORIGFILE"" >>"$FilesRemovedList" else # Purge Symantec login item(s) Buffer="" DoWriteBuffer=true for Line in cat $SOURCEFILE ; do # If beginning of a dictionary key if [ "printf "%s" "$Line" | grep '<dict>$'" ] ; then [ "$Buffer" ] && echo "$Buffer" >> $OUTFILE Buffer="$Line" DoWriteBuffer=true else if [ "$Buffer" ] ; then Buffer="$Buffer
$Line" else Buffer="$Line" fi # If end of a dictionary key if [ "printf "%s" "$Line" | grep '</dict>$'" ] ; then $DoWriteBuffer && echo "$Buffer" >> $OUTFILE Buffer="" DoWriteBuffer=true # Else if Symantec path was found elif [ "printf "%s" "$Line" | grep "$GREPSTR"" ] ; then DoWriteBuffer=false fi fi done [ "$Buffer" ] && echo "$Buffer" >> $OUTFILE # If some login item information is missing if [ grep -c '<dict>$' $OUTFILE != grep -c '</dict>$' $OUTFILE ] ; then echo "ERROR: Could not remove Symantec login items from:" echo " $ORIGFILE" # Else if syntax is to be checked and plist contains bad syntax elif [ $CheckSyntax = true -a -n "plutil -s $OUTFILE 2>/dev/null" ] ; then echo "ERROR: Could not remove Symantec login items from:" echo " $ORIGFILE" else echo "Removing Symantec login items from:" echo " "$ORIGFILE"" cat $OUTFILE > "$ORIGFILE" $IsBinaryFormat && plutil -convert binary1 "$ORIGFILE" 2>/dev/null fi fi fi done rm -f $OUTFILE $SOURCEFILE 2>/dev/null $FileShouldBeAdjusted && echo "" >>"$FilesRemovedList"
}

DetermineAction()
{ # Usage: DetermineAction # Summary: Determines which action to take based on user input. # clear echo ShowVersion echo "
WARNING: This script will remove all files and folders created by Symantec OS X products (except Symantec Adminstration Console for Macintosh files) and any files within those folders. Therefore, you will lose ALL files that reside in those folders, including any that you have created.
" echo "1 - Remove all Symantec files/folders." echo echo "2 - Quit. Do not remove any files." echo printf "Enter choice (1 or 2): " read choice echo case "echo "z$choice" | awk '{print tolower(substr($0,2))}'" in 1) # Remove files CreateFilesRemovedListOnly=false ;; 2|q|quit) # Quit echo "Program cancelled. No files were removed." ExitScript 0 ;; *) # Show choices again DetermineAction ;; esac
}

ExitScript()
{ # Usage: ExitScript [-b] [-e] [exit_number [error_string]] # Summary: Checks to see if ShowQuitMessage and RunScriptAsStandAlone # variables are set to true. If so, a message is displayed; # otherwise, no message is displayed. The script is then # exited and passes exit_number to exit command. If no # exit_number is passed, then 0 is passed to exit command. If # a non-integer is passed as exit_number, 255 is passed to # exit command. If error_string is passed, it is printed to # to standard out before exiting and is padded by blank lines # if error_string is not "". Pass -b before exit_number to # suppress beginning padding line, -e to suppress ending # padding line, both to suppress both. Also removes temp # files and kills Terminal if need be. # local PadBeginning=true local PadEnd=true while [ "$1" ] ; do case "$1" in -b) PadBeginning=false ;; -e) PadEnd=false ;; *) break ;; esac shift done rm -f "$FilesRemovedList" "$FilesRemovedFilesOnlyList" "$LogFile" 2>/dev/null 1>&2 if $QuitTerminalForcefully ; then KillTerminal fi if [ $# -gt 1 ] ; then if [ -z "$2" ] ; then PadBeginning=false PadEnd=false fi $PadBeginning && echo printf "%s " "$2" $PadEnd && echo fi if [ "z$ShowQuitMessage" = ztrue -a "z$RunScriptAsStandAlone" = ztrue ] ; then [ $# -lt 2 -o ( $PadEnd = false -a -n "$2" ) ] && echo echo "NOTE: If you double-clicked this program, quit Terminal application now." [ $PadEnd = true -o -z "$2" ] && echo fi [ -z "$1" ] && exit 0 [ -z "expr "$1" / 1 2>/dev/null" ] && exit 255 || exit $1
}

FinishCleanup()
{ # Usage: FinishCleanup # Summary: Displays then deletes the file named by LogFile, a log # of files not removed by RemoveItem function, if ErrorOccurred # is true. If NoFilesToRemove is true, a message is shown # and the function is exited. If RemoveInvisibleFilesOnly # is true, a message is shown and the function is exited; # otherwise, a message is shown. Returns 2 if ErrorOccurred # is true, 0 otherwise. # if $CreateFilesRemovedListOnly ; then clear >&2 if $UseMore ; then ShowContents "$FilesRemovedList" else cat "$FilesRemovedList" fi echo "" >&2 echo "NOTE: No files have been removed." >&2 echo "" >&2 /bin/rm -rf "$FilesRemovedList" "$FilesRemovedFilesOnlyList" 2>/dev/null 1>&2 return 0 elif $ErrorOccurred ; then echo # Display LogFile ShowContents "$LogFile" # Remove LogFile /bin/rm -rf "$LogFile" 2>/dev/null 1>&2 echo if $RemoveInvisibleFilesOnly ; then echo "NOTE: Not all of the invisible Symantec files were removed." echo " Make sure each volume passed is unlocked and accessible." return 2 else echo "NOTE: Not all folders/files were removed." echo " Perhaps a file or folder listed above is in use or a folder" echo " listed above is not empty." if $RestartMayBeNeeded ; then echo echo "Some Symantec product files have been removed from the boot volume." return 2 else if $SomeFileWasRemoved ; then echo echo "Some folders or files have been removed." fi return 2 fi fi fi if $RemoveInvisibleFilesOnly ; then if $NoFilesToRemove ; then echo "There were no invisible Symantec files to be removed." else echo "AntiVirus QuickScan and/or Norton FS files have been removed." fi return 0 fi if $NoFilesToRemove ; then echo "There were no files that needed to be removed. No files were removed." return 0 fi $RemoveCrontabEntriesOnly && return 0 echo if $RestartMayBeNeeded ; then printf "Symantec product files have been removed from the boot volume" if $SomeFileWasRemovedFromNonBootVolume ; then echo echo "and from other volume(s) listed above." else echo "." fi else echo "Symantec product files have been removed from the above volume(s)." fi return 0
}

GetAdminPassword()
{ # Usage: GetAdminPassword [$1] # Argument: $1 - Prompt for password. If true is passed, a user that # is not root will always be asked for a password. If # something other than true is passed or if nothing is # passed, then a user that is not root will only be # prompted for a password if authentication has lapsed. # Summary: Gets an admin user password from the user so that # future sudo commands can be run without a password # prompt. The script is exited with a value of 1 if # the user enters an invalid password or if the user # is not an admin user. If the user is the root user, # then there is no prompt for a password (there is # no need for a password when user is root). # NOTE: Make sure ExitScript function is in the script. # # If root user, no need to prompt for password [ "whoami" = "root" ] && return 0 echo >&2 # If prompt for password if [ "$1" = "true" -o "$1" = "true" ] ; then ShowVersion >&2 echo >&2 sudo -k >&2 # Make sudo require a password the next time it is run echo "You must be an admin user to run this script." >&2 fi # A dummy sudo command to get password sudo -p "Please enter your admin password: " date 2>/dev/null 1>&2 if [ ! $? = 0 ] ; then # If failed to get password, alert user and exit script echo "You entered an invalid password or you are not an admin user. Script aborted." >&2 ExitScript 1 fi
}

KillNortonZone()
{ $CreateFilesRemovedListOnly && return ZoneProcesses=ps -axww | grep "Norton Zone.app/Contents/MacOS/Norton Zone" | grep -v grep | awk '{print $1}' for EachZoneAppPID in $ZoneProcesses ; do kill -9 "$EachZoneAppPID" done [ "$ZoneProcesses" ] && killall Finder
}

KillTerminal()
{ ProcessLines=ps -axww | grep -e "/Applications/Utilities/Terminal.app" | grep -v grep | sort -f if [ -z "$ProcessLines" ] ; then return elif [ echo "$ProcessLines" | grep . -c -gt 1 -a $QuitTerminalForcefullyForAll = false ] ; then echo "NOTE: Terminal was launched more than once so it could not be quit." echo " Use the -QQ option to force Terminal to be quit for all users." return else echo "WARNING: Quitting Terminal." fi IFS='
' for ProcessLine in $ProcessLines ; do ProcessID=printf "%s" "$ProcessLine" | awk '{print $1}' kill -9 "$ProcessID" done
}

ProcessArguments()
{ # Usage: ProcessArguments [ --OptionTakesUnparsedArgument=string ] [ --OptionIsOneArgument=string ] "$@" # # Version: 1.0.1 # # Summary: Processes arguments passed to script. Arguments beginning with a # single hyphen (-) are parsed into separate options except when an # argument is negative integer. Arguments beginning with two hypens # are treated as one argument; if the argument contains is an equals # sign (=), the string after the first "=" is treated as a separate # argument (i.e., the value assigned to the double-hyphen argument). # # For each --OptionTakesUnparsedArgument passed before "$@", the string # after "=" is used as an option that takes the next argument in full # without parsing it (see examples below); string must be a hyphen # followed by a single character. # # For each --OptionIsOneArgument passed before "$@", the string after # "=" is used as an option that should be treated as a single argument. # This is useful when processing an argument that begins with a single # hyphen to avoid having that argument parsed into separate options. # The referenced option cannot be embedded within other options (see # final example below). # # "$@" must be the last argument passed to ProcessArguments. Put all custom # option handling between "--- Customized argument handling begins here ---" # and "--- Customized argument handling ends here ---". # # Note: ProcessArgumentsNextArgument may be called to verify and obtain the # next argument after or before a given option; see that function's usage # for more details. OriginalArgumentNumber can be used to determine if # two arguments were originally passed within the same string of options. # # Examples: These examples have expanded the arguments passed as "$@". # # ProcessArguments -ab -c # Would process three arguments: -a, -b, and -c # ProcessArguments --ab -c # Would process two arguments: --ab and -c # ProcessArguments --equation=a=b+c # Would process two arguments: --equation and a=b+c # ProcessArguments -10 # Would process one argument: -10 # ProcessArguments -10a # Would process three arguments: -1, -0, -a # ProcessArguments --OptionTakesUnparsedArgument=-e -e -ger # Would process two arguments: -e and -ger # ProcessArguments --OptionTakesUnparsedArgument=-e -peer # Would process three arguments: -p, -e, and er # ProcessArguments --OptionTakesUnparsedArgument=-e --OptionTakesUnparsedArgument=-t -eter -ter # Would process four arguments: -e, ter, -t, and er # ProcessArguments --OptionIsOneArgument=-hi -hi # Would process one argument: -hi # ProcessArguments --OptionIsOneArgument=-hi -his # Would process three arguments: -h, -i, and -s # # History: 1.0.1 - 06/23/2013 - Corey Swertfager: # Added processing of options within a string that begins # with a single hyphen. # Added --OptionTakesUnparsedArgument option. # Added --OptionIsOneArgument option. # local ArgList="" local ArgsToAdd local ArgWasAdded=false local CurrentArgNumber=1 local CurrentArgument local CurrentCharacter local DoNotParseNextArgument=false local NextArgument="" local NumberOfArgumentsPassed local NumberOfArgumentsToUse=0 local OptionToAdd local OriginalArgumentNumber=0 local OriginalArgumentNumberList="" local RemainingOptionsInString local TableOfOptionsWithoutParsing=" Each option in this table will have its succeeding argument left unparsed. " local TableOfUndividedArguments=" Each item in this table should each be treated as single argument. " while [ "$1" ] ; do case "$1" in --OptionIsOneArgument) ExitScript 99 "WARNING: Bad use of --OptionIsOneArgument passed to ProcessArguments: "$1"" ;; --OptionIsOneArgument=) OptionToAdd=printf "%s" "$1" | awk '{match($0,"=") ; print substr($0,RSTART+1)}' [ -z "$OptionToAdd" ] && ExitScript 99 "WARNING: Bad use of --OptionIsOneArgument passed to ProcessArguments: "$1"" TableOfUndividedArguments="$TableOfUndividedArguments
$OptionToAdd" ;; --OptionTakesUnparsedArgument|--OptionTakesUnparsedArgument=) OptionToAdd=printf "%s" "$1" | awk '{match($0,"=") ; print substr($0,RSTART+1)}' [ -z "printf "%s" "$OptionToAdd" | grep -xe '-.'" ] && ExitScript 99 "WARNING: Bad use of --OptionTakesUnparsedArgument passed to ProcessArguments: "$1"" TableOfOptionsWithoutParsing="$TableOfOptionsWithoutParsing
$OptionToAdd" ;;
) break ;; esac shift done NumberOfArgumentsPassed=$# while [ $# != 0 ] ; do let OriginalArgumentNumber=$OriginalArgumentNumber+1 # If argument is in the list of arguments whose next argument should not be parsed if [ "printf "%s" "$1" | grep -xF "$TableOfOptionsWithoutParsing"" ] ; then ArgsToAdd="$1" OriginalArgumentNumberList="$OriginalArgumentNumberList
$OriginalArgumentNumber" DoNotParseNextArgument=true # Else if argument is in the list of arguments that should be treated as one argument elif [ "printf "%s" "$1" | grep -xF "$TableOfUndividedArguments"" ] ; then ArgsToAdd="$1" OriginalArgumentNumberList="$OriginalArgumentNumberList
$OriginalArgumentNumber" else case "$1" in -|-?) # If argument was a hyphen or a hyphen followed by a single character ArgsToAdd="$1" OriginalArgumentNumberList="$OriginalArgumentNumberList
$OriginalArgumentNumber" DoNotParseNextArgument=false ;; --) # If a value was passed to the option that begins with -- if [ "printf "%s" "$1" | grep =" ] ; then # Add the option and its value as separate arguments ArgsToAdd="printf "%s" "$1" | awk -F = '{print $1}'
printf "%s" "$1" | awk '{match($0,"=") ; print substr($0,RSTART+1)}'" OriginalArgumentNumberList="$OriginalArgumentNumberList
$OriginalArgumentNumber
$OriginalArgumentNumber" else ArgsToAdd="$1" OriginalArgumentNumberList="$OriginalArgumentNumberList
$OriginalArgumentNumber" fi DoNotParseNextArgument=false ;; -
) # If argument should not be parsed or is a negative integer if [ $DoNotParseNextArgument = true -o -z "printf "%s" "$1" | awk '{print substr($0,2)}' | tr -d '[:digit:]'" ] ; then # Treat argument as a single argument ArgsToAdd="$1" OriginalArgumentNumberList="$OriginalArgumentNumberList
$OriginalArgumentNumber" DoNotParseNextArgument=false else # Parse string into separate arguments ArgsToAdd="" RemainingOptionsInString=printf "%s" "$1" | awk '{print substr($0,2)}' while [ "$RemainingOptionsInString" ] ; do CurrentCharacter=printf "%s" "$RemainingOptionsInString" | awk '{print substr($0,1,1)}' # Prefix the character with a hyphen and add as an argument if [ "$ArgsToAdd" ] ; then ArgsToAdd="$ArgsToAdd
-$CurrentCharacter" else ArgsToAdd="-$CurrentCharacter" fi OriginalArgumentNumberList="$OriginalArgumentNumberList
$OriginalArgumentNumber" RemainingOptionsInString=printf "%s" "$RemainingOptionsInString" | awk '{print substr($0,2)}' # If this is an option whose next string should not be parsed if [ "printf "%s" "$TableOfOptionsWithoutParsing" | grep -xe "-$CurrentCharacter"" ] ; then # If string has characters remaining after that option if [ "$RemainingOptionsInString" ] ; then # Add remainder of string as the unparsed string argument ArgsToAdd="$ArgsToAdd
$RemainingOptionsInString" OriginalArgumentNumberList="$OriginalArgumentNumberList
$OriginalArgumentNumber" else # Use next argument passed as unparsed string argument DoNotParseNextArgument=true fi break fi done fi ;; ) ArgsToAdd="$1" OriginalArgumentNumberList="$OriginalArgumentNumberList
$OriginalArgumentNumber" DoNotParseNextArgument=false ;; esac fi if $ArgWasAdded ; then ArgList="$ArgList
$ArgsToAdd" else ArgList="$ArgsToAdd" fi ArgWasAdded=true shift done if [ $NumberOfArgumentsPassed -gt 0 ] ; then # Add a non-blank line to ArgList in case last argument passed was "" ArgList="$ArgList TheEnd" OriginalArgumentNumberList=echo "$OriginalArgumentNumberList" | grep . NumberOfArgumentsToUse=printf "%s" "$ArgList" | grep "" -c let NumberOfArgumentsToUse=$NumberOfArgumentsToUse-1 fi # --- Customized argument handling begins here --- BootVolumeWillBeSearched=false CreateFilesRemovedListOnly=false DoRunPredeleteScripts=true ListOnlyFilesThatExist=false NoFilesToRemove=true PauseBeforeRestarting=true QuitTerminalForcefully=false QuitTerminalForcefullyForAll=false QuitWithoutRestarting=false $AutoRunScript && QuitWithoutRestarting=true RemoveCrontabEntries=true RemoveCrontabEntriesOnly=false RemoveInvisibleFiles=true RemoveInvisibleFilesOnly=false RemoveFromAllVolumes=false RemoveFromOtherVolumes=false RestartAutomatically=false RestartMayBeNeeded=false ShowFilesAsRemoved=true ShowPredeleteErrors=false ShowQuitMessage=true SomeFileWasRemoved=false SomeFileWasRemovedFromNonBootVolume=false SomeFileWasRemovedFromBootVolume=false UseMore=false while [ $CurrentArgNumber -le $NumberOfArgumentsToUse ] ; do CurrentArgument=printf "%s" "$ArgList" | head -n $CurrentArgNumber | tail -n 1 OriginalArgumentNumber=echo "$OriginalArgumentNumberList" | head -n $CurrentArgNumber | tail -n 1 case "$CurrentArgument" in -A) RemoveFromAllVolumes=true BootVolumeWillBeSearched=true ;; -c) RemoveCrontabEntriesOnly=true RemoveCrontabEntries=true RemoveInvisibleFilesOnly=false RemoveInvisibleFiles=false ;; -C) RemoveCrontabEntriesOnly=false RemoveCrontabEntries=false ;; -d) DoRunPredeleteScripts=false ;; -e) ShowPredeleteErrors=true ;; -f) ShowFilesAsRemoved=false ;; -H) ShowUsage 0 ;; -h) ShowHelp 0 ;; -i) RemoveInvisibleFilesOnly=true RemoveInvisibleFiles=true RemoveCrontabEntries=false RemoveCrontabEntriesOnly=false ;; -I) RemoveInvisibleFilesOnly=false RemoveInvisibleFiles=false ;; -l|-R) CreateFilesRemovedListOnly=true ListOnlyFilesThatExist=true ;; -L) CreateFilesRemovedListOnly=true ListOnlyFilesThatExist=false ;; -m) UseMore=true ;; -p) PauseBeforeRestarting=false ;; -q) QuitWithoutRestarting=true RestartAutomatically=false ;; -Q) # If -Q was previously passed, treat as -QQ if $QuitTerminalForcefully ; then # Treat as if -QQ was passed QuitTerminalForcefullyForAll=true else QuitTerminalForcefullyForAll=false fi QuitTerminalForcefully=true QuitWithoutRestarting=true RestartAutomatically=false ;; -QQ) QuitTerminalForcefully=true QuitTerminalForcefullyForAll=true QuitWithoutRestarting=true RestartAutomatically=false ;; -r|-re) RestartAutomatically=true QuitWithoutRestarting=false ;; -V) echo $Version ExitScript 0 ;;
) AssignVolume "$CurrentArgument" # Assign it to a Volume variable # If not a valid volume if [ $? = 1 ] ; then ShowUsage 4 "ERROR: Invalid option or volume name: "$CurrentArgument"." fi RemoveFromOtherVolumes=true ;; esac let CurrentArgNumber=$CurrentArgNumber+1 done # --- Customized argument handling ends here ---
}

ProcessArgumentsNextArgument()
{ # Usage: ProcessArgumentsNextArgument [exit_code] [-F | -P] [-p | -r ] [operator] # # Version: 1.0.0 # # Arguments: exit_code Pass integer in range 0-255 to ShowUsage when next # argument is missing or invalid. If exit_code is not # specified, 0 is assumed. # # -F Assign the full logical path to NextArgumentFullPath. # This is the default. ShowFullFilePath function must # be included in script. If no operator was passed, -E # is the assumed operator. # # -P Assign the full physical path to NextArgumentFullPath. # ShowFullFilePath function must be included in script. # If no operator was passed, -e is the assumed operator. # # -p Get previous argument instead of next argument. If # there is no previous argument, sets NextArgument to "" # and returns 1. # # -r Return 1 instead of exiting script if there is no next # argument. Sets NextArgument to "". # # operator Operator used to test next argument: # -d Folder # -E File, folder, or link # -e File, folder, or link to an existing file/folder # -f File # -i [min [max]] # Integer in range min-max; pass "" to min and # an integer to max if there is no minimum but # a maximum is desired; pass "" to to both min # and max if passing another option after the -i # option. Also tests to see if the value of the # next argument is out of range for the currently # running version of Mac OS. # -L Link; does not check to see if link is broken # unless -P option was also passed # -l Link to an existing file/folder # -n Non-null string # # Summary: Called by ProcessArguments 1.0.1 or later to assign values to: # # CurrentArgNumber # NextArgument # NextArgumentFullPath # NextArgumentOriginalArgumentNumber # # using pre-existing values of: # # ArgList # CurrentArgNumber # CurrentArgument # OriginalArgumentNumberList # NumberOfArgumentsToUse # # Returns 0 if next or previous argument was assigned to NextArgument, # CurrentArgNumber was incremented (or decremented if -p was passed), # and NextArgumentOriginalArgumentNumber was assigned. # # Assigns "" to NextArgument and NextArgumentFullPath and returns 1 if # -p is passed and there is no previous argument, or if -r is passed # and there is no next argument; otherwise, calls ShowUsage to show # error message and exit script if operator test fails or if there is # no next or previous argument. # # Note: ShowFullFilePath function must be included in script in order to # assign a value to NextArgumentFullPath. # # Examples: ProcessArgumentsNextArgument # Returns 0 if there was a next argument; otherwise, passes 0 to # ShowUsage and displays error message about missing argument. # ProcessArgumentsNextArgument -r # Returns 0 if there was a next argument; otherwise, assigns "" to # NextArgument and NextArgumentFullPath, then returns 1. # ProcessArgumentsNextArgument 2 -d # Returns 0 if NextArgument was set to a folder; otherwise, passes # 2 to ShowUsage and displays error message if the next argument is # missing or is not a folder. # ProcessArgumentsNextArgument 3 -r -d # Returns 0 if NextArgument was set to a folder. If the next argument # is missing, assigns "" to NextArgument and NextArgumentFullPath, # then returns 1. If next argument is not a folder, passes 3 to # ShowUsage and displays error message. # ProcessArgumentsNextArgument 4 -i 1 # Returns 0 if NextArgument was set to an integer; otherwise, passes # 4 to ShowUsage and displays error message if the next argument is # missing, is not an integer, or is less than 1. # ProcessArgumentsNextArgument -i "" 100 5 # Returns 0 if NextArgument was set to an integer; otherwise, passes # 5 to ShowUsage and displays error message if the next argument is # missing, is not an integer, or is greater than 100. # ProcessArgumentsNextArgument -i "" "" 6 # Returns 0 if NextArgument was set to an integer; otherwise, passes # 6 to ShowUsage and displays error message if the next argument is # missing or is not an integer. # local DoShowMissingError=true local DirectionText=after local ExitCode=0 local ErrorText="" local GoToPreviousArgument=false local Max local Min local NextArgumentOriginal local PathOption="" local TestOperator="" NextArgumentFullPath="" while [ "$1" ] ; do case "$1" in -d) ErrorText="folder" TestOperator="$1" ;; -E) ErrorText="file, folder, or link" TestOperator="$1" ;; -e) ErrorText="file or folder" TestOperator="$1" ;; -F) PathOption="$1" if [ -z "$ErrorText" ] ; then ErrorText="file, folder, or link" TestOperator="-E" fi ;; -f) ErrorText="file" TestOperator="$1" ;; -i) ErrorText="integer" TestOperator="$1" Min="$2" Max="$3" shift 2 ;; -L) ErrorText="link" TestOperator="$1" [ "z$PathOption" = "z-P" ] && ErrorText="unbroken link" ;; -l) ErrorText="unbroken link" TestOperator="-L" ;; -n) ErrorText="non-null string" TestOperator="$1" ;; -P) PathOption="$1" if [ -z "$ErrorText" ] ; then ErrorText="file or folder" TestOperator="-e" elif [ "$ErrorText" = "link" ] ; then ErrorText="unbroken link" fi ;; -p) GoToPreviousArgument=true DirectionText=before ;; -r) DoShowMissingError=false ;; ) ExitCode=printf "%s" "$1" | tr -d -c "[:digit:]" [ -z "$ExitCode" ] && ExitCode=0 ;; esac shift done if $GoToPreviousArgument ; then if [ $CurrentArgNumber -gt 1 ] ; then let CurrentArgNumber=$CurrentArgNumber-1 NextArgument=printf "%s" "$ArgList" | head -n $CurrentArgNumber | tail -n 1 NextArgumentOriginalArgumentNumber=echo "$OriginalArgumentNumberList" | head -n $CurrentArgNumber | tail -n 1 else NextArgument="" NextArgumentFullPath="" return 1 fi # Else if there are no more arguments in ArgList elif [ $CurrentArgNumber = $NumberOfArgumentsToUse ] ; then if $DoShowMissingError ; then ShowUsage $ExitCode "ERROR: Nothing was passed after $CurrentArgument" >&2 else NextArgument="" NextArgumentFullPath="" return 1 fi else let CurrentArgNumber=$CurrentArgNumber+1 NextArgument=printf "%s" "$ArgList" | head -n $CurrentArgNumber | tail -n 1 NextArgumentOriginalArgumentNumber=echo "$OriginalArgumentNumberList" | head -n $CurrentArgNumber | tail -n 1 fi NextArgumentFullPath=ShowFullFilePath $PathOption "$NextArgument" if [ "z$ErrorText" = zinteger ] ; then NextArgumentOriginal="$NextArgument" if [ -z "$NextArgument" ] ; then ShowUsage $ExitCode "ERROR: Argument passed $DirectionText $CurrentArgument is not an integer: "$NextArgumentOriginal"" >&2 # Else if argument contains something other than a hyphen or digits elif [ "printf "%s" "$NextArgument" | tr -d "[:digit:]-"" ] ; then ShowUsage $ExitCode "ERROR: Argument passed $DirectionText $CurrentArgument is not an integer: "$NextArgumentOriginal"" >&2 # Else if argument contains a hyphen that is not at the beginning elif [ "printf "%s" "$NextArgument" | grep '..-'" ] ; then ShowUsage $ExitCode "ERROR: Argument passed $DirectionText $CurrentArgument is not an integer: "$NextArgumentOriginal"" >&2 fi NextArgument=expr "$NextArgument" / 1 2>/dev/null test "$NextArgumentOriginal" -eq "$NextArgument" 2>/dev/null if [ $? != 0 ] ; then ShowUsage $ExitCode "ERROR: Value passed $DirectionText $CurrentArgument is out of range for this OS: $NextArgumentOriginal" >&2 fi # If minimum value was specified if [ "$Min" ] ; then [ $NextArgument -lt $Min ] && ShowUsage $ExitCode "ERROR: Value passed $DirectionText $CurrentArgument ($NextArgumentOriginal) is less than minimum value ($Min)." >&2 fi # If maximum value was specified if [ "$Max" ] ; then [ $NextArgument -gt $Max ] && ShowUsage $ExitCode "ERROR: Value passed $DirectionText $CurrentArgument ($NextArgumentOriginal) is greater than maximum value ($Max)." >&2 fi elif [ "z$ErrorText" = "zfile, folder, or link" ] ; then [ ! -e "$NextArgument" -a ! -L "$NextArgument" ] && ShowUsage $ExitCode "ERROR: Argument passed $DirectionText $CurrentArgument is not a $ErrorText: "$NextArgument"" >&2 elif [ "z$ErrorText" = "zunbroken link" ] ; then if [ ! -L "$NextArgument" ] ; then ShowUsage $ExitCode "ERROR: Argument passed $DirectionText $CurrentArgument is not a link: "$NextArgument"" >&2 # Else if link is broken elif [ ! -e "$NextArgument" ] ; then ShowUsage $ExitCode "ERROR: The target of the link passed $DirectionText $CurrentArgument does not exist: "$NextArgument"" >&2 fi elif [ "$ErrorText" ] ; then [ ! $TestOperator "$NextArgument" ] && ShowUsage $ExitCode "ERROR: Argument passed $DirectionText $CurrentArgument is not a $ErrorText: "$NextArgument"" >&2 fi if [ "$PathOption" ] ; then if [ -z "$NextArgumentFullPath" ] ; then if [ -L "$NextArgument" ] ; then ShowUsage $ExitCode "ERROR: The target of the link passed $DirectionText $CurrentArgument does not exist: "$NextArgument"" >&2 else ExitScript $ExitCode "WARNING: ShowFullFilePath function could not resolve path for: "$NextArgument"" >&2 fi fi fi return 0
}

RemoveAllNortonFiles()
{ # Usage: RemoveAllNortonFiles $1 # Argument: $1 = Volume name. The name should begin with "/Volumes/" # unless it is "/" (boot volume). # Summary: Removes all OS X Norton products' files and folders # from volume named by $1 if RemoveInvisibleFilesOnly # equals false; otherwise, removes only the invisible Norton # files. Removes the invisible Norton files from other # volumes that are passed to the script. Symantec crontab # entries are removed if RemoveCrontabEntries = true. # # If not a valid volume, return 1 [ -z "CheckIfValidVolume "$1"" ] && return 1 CurrentVolumeBeingUsed="$1" if $CreateFilesRemovedListOnly ; then printf "" > "$FilesRemovedFilesOnlyList" echo "" >> "$FilesRemovedList" if [ echo "$ListOfVolumesToUse" | grep -c . -gt 1 ] ; then if [ "$1" = / ] ; then echo "------ Volume: / (current boot volume) ------" >> "$FilesRemovedList" else echo "------ Volume: "basename "$1"" ------" >> "$FilesRemovedList" fi echo "" >> "$FilesRemovedList" fi fi $RemoveCrontabEntries && DeleteCrontabEntries "$1" $RemoveCrontabEntries && DeleteLaunchdPlists "$1" $RemoveCrontabEntriesOnly && return 0 ! $RemoveInvisibleFilesOnly && DeleteSymantecLoginItems "$1" if $CreateFilesRemovedListOnly ; then if ! $RemoveInvisibleFilesOnly ; then RunPredeleteScripts "$1" echo "" >> "$FilesRemovedList" fi if $ListOnlyFilesThatExist ; then echo "The following files/folders currently exist and would be removed unless" >> "$FilesRemovedList" echo "otherwise noted:" >> "$FilesRemovedList" else echo "$FullScriptName would attempt to find and remove the following:" >> "$FilesRemovedList" fi echo "" >> "$FilesRemovedList" fi RemoveInvisibleFilesFromVolume "$1" $RemoveInvisibleFilesOnly && return 0 $CreateFilesRemovedListOnly || RunPredeleteScripts "$1" # If not an OS X volume, return 1 [ ! -d "$1/Library/Application Support" ] && return 1 if $CreateFilesRemovedListOnly ; then echo "Finding visible Symantec files on: $1" >&2 elif $ShowFilesAsRemoved ; then echo "Locating visible Symantec files in: $1" else echo "Removing visible Symantec files from: $1" fi cd "$1" if [ "pwd" = "/" ] ; then VolumePrefix="" else VolumePrefix="pwd" fi KillNortonZone RemoveItem "/.com_symantec_symfs_private" RemoveItem "/.symSchedScanLockxz" RemoveItem "/Applications/Firefox.app/Contents/MacOS/extensions/{0e10f3d7-07f6-4f12-97b9-9b27e07139a5}" RemoveItem "/Applications/Firefox.app/Contents/MacOS/extensions/{29dd9c80-9ea1-4aaf-9305-a0314aba24e3}" RemoveItem "/Applications/Firefox.app/Contents/MacOS/extensions/nortonsafetyminder@symantec.com" RemoveItem "/Applications/GatherSymantecInfo" RemoveItem "/Applications/Late Breaking News" RemoveItem "/Applications/LiveUpdate" RemoveItem "/Applications/LiveUpdate Folder" RemoveItem "/Applications/LiveUpdate Folder (OS X)"
# Remove navx incorrectly installed by NAV 800.007 installer: RemoveItem "/Applications/navx" RemoveItem "/Applications/Norton " "" RemoveItem "/Applications/Symantec AntiVirus" RemoveItem "/Applications/Symantec Solutions"
# The next 3 items are erroneously created by early builds of NAV 10 installer RemoveItem "/Applications/Symantec/LiveUpdate.app" RemoveItem "/Applications/Symantec/Read Me Files" RemoveItem "/Applications/Symantec" -e RemoveItem "/Applications/Trash Running Daemons" RemoveItem "/Applications/uDelete Preferences" RemoveItem "/Applications/Register Your Software"
# Folder erroneously created by NPF 300.001 - removed if empty: RemoveItem "/Firewall" -e -u RemoveItem "/Library/Application Support/NAVDiagnostic.log" RemoveItem "/Library/Application Support/NAV.history" RemoveItem "/Library/Application Support/nat
" "" -u RemoveItem "/Library/Application Support/nat" "" -u RemoveItem "/Library/Application Support/nav" "" -u RemoveItem "/Library/Application Support/nis" "" -u RemoveItem "/Library/Application Support/nsm" "" -u RemoveItem "/Library/Application Support/Norton Application Aliases" RemoveItem "/Library/Application Support/Norton Solutions Support" RemoveItem "/Library/Application Support/norton" "" -u RemoveItem "/Library/Application Support/o2spy.log" RemoveItem "/Library/Application Support/Symantec" RemoveItem "/Library/Application Support/symantec_uninstalldashboard" "" RemoveItem "/Library/Application Support/SymRun" RemoveItem "/Library/Authenticators/SymAuthenticator.bundle" RemoveItem "/Library/CFMSupport/Norton Shared Lib" RemoveItem "/Library/CFMSupport/Norton Shared Lib Carbon" RemoveItem "/Library/Contextual Menu Items/NAVCMPlugIn.plugin" RemoveItem "/Library/Contextual Menu Items/SAVCMPlugIn.plugin" RemoveItem "/Library/Contextual Menu Items/SymFileSecurityCM.plugin" RemoveItem "/Library/Documentation/Help/LiveUpdate Help" RemoveItem "/Library/Documentation/Help/LiveUpdate-Hilfe" RemoveItem "/Library/Documentation/Help/Norton AntiVirus Help" RemoveItem "/Library/Documentation/Help/Norton AntiVirus-Hilfe" RemoveItem "/Library/Documentation/Help/Norton Help" RemoveItem "/Library/Documentation/Help/Norton Help Scripts" RemoveItem "/Library/Documentation/Help/Norton Help Scripts Folder" RemoveItem "/Library/Documentation/Help/Norton Utilities Help" RemoveItem "/Library/Extensions/FileSecurity.kext" RemoveItem "/Library/Extensions/ndcengine.kext" RemoveItem "/Library/Extensions/NortonForMac.kext" RemoveItem "/Library/Extensions/SymAPComm.kext" RemoveItem "/Library/Extensions/SymFirewall.kext" RemoveItem "/Library/Extensions/SymInternetSecurity.kext" RemoveItem "/Library/Extensions/SymIPS.kext" RemoveItem "/Library/Extensions/SymPersonalFirewall.kext" RemoveItem "/Library/Frameworks/mach_inject_bundle.framework" RemoveItem "/Library/InputManagers/Norton Confidential for Safari" RemoveItem "/Library/InputManagers/Norton Safety Minder" RemoveItem "/Library/InputManagers/SymWebKitUtils" RemoveItem "/Library/Internet Plug-Ins/Norton Confidential for Safari.plugin" RemoveItem "/Library/Internet Plug-Ins/Norton Family Safety.plugin" RemoveItem "/Library/Internet Plug-Ins/Norton Safety Minder.plugin" RemoveItem "/Library/Internet Plug-Ins/NortonInternetSecurityBF.plugin" RemoveItem "/Library/Internet Plug-Ins/NortonSafetyMinderBF.plugin" RemoveItem "/Library/LaunchAgents/com.symantec" "" RemoveItem "/Library/LaunchDaemons/com.norton" "" RemoveItem "/Library/LaunchDaemons/com.symantec" "" RemoveItem "/Library/Logs/Norton" "" RemoveItem "/Library/Logs/o2spy.log" RemoveItem "/Library/Logs/Symantec" "" RemoveItem "/Library/Logs/SymAPErr.log" RemoveItem "/Library/Logs/SymAPOut.log" RemoveItem "/Library/Logs/SymDeepsight" "" RemoveItem "/Library/Logs/SymFWLog.log" RemoveItem "/Library/Logs/SymFWRules.log" "" RemoveItem "/Library/Logs/SymScanServerDaemon.log" RemoveItem "/Library/Plug-ins/DiskImages/NUMPlugin.bundle" RemoveItem "/Library/Plug-ins/DiskImages/VRPlugin.bundle" RemoveItem "/Library/Plug-ins/DiskImages" -e -u RemoveItem "/Library/Plug-ins" -e -u RemoveItem "/Library/PreferencePanes/APPrefPane.prefPane" RemoveItem "/Library/PreferencePanes/FileSaver.prefPane" RemoveItem "/Library/PreferencePanes/Norton Family Safety.prefPane" RemoveItem "/Library/PreferencePanes/Norton Safety Minder.prefPane" RemoveItem "/Library/PreferencePanes/Ribbon.Norton.prefPane" RemoveItem "/Library/PreferencePanes/SymantecQuickMenu.prefPane" RemoveItem "/Library/PreferencePanes/SymAutoProtect.prefPane" RemoveItem "/Library/PrivateFrameworks/NPF.framework" RemoveItem "/Library/PrivateFrameworks/NPFCoreServices.framework" RemoveItem "/Library/PrivateFrameworks/NPFDataSource.framework" RemoveItem "/Library/PrivateFrameworks/PlausibleDatabase.framework" RemoveItem "/Library/PrivateFrameworks/SymAppKitAdditions.framework" RemoveItem "/Library/PrivateFrameworks/SymAVScan.framework" RemoveItem "/Library/PrivateFrameworks/SymBase.framework" RemoveItem "/Library/PrivateFrameworks/SymConfidential.framework" RemoveItem "/Library/PrivateFrameworks/SymDaemon.framework" RemoveItem "/Library/PrivateFrameworks/SymFirewall.framework" RemoveItem "/Library/PrivateFrameworks/SymInternetSecurity.framework" RemoveItem "/Library/PrivateFrameworks/SymIPS.framework" RemoveItem "/Library/PrivateFrameworks/SymIR.framework" RemoveItem "/Library/PrivateFrameworks/SymLicensing.framework" RemoveItem "/Library/PrivateFrameworks/SymNetworking.framework" RemoveItem "/Library/PrivateFrameworks/SymOxygen.framework" RemoveItem "/Library/PrivateFrameworks/SymPersonalFirewall.framework" RemoveItem "/Library/PrivateFrameworks/SymScheduler.framework" RemoveItem "/Library/PrivateFrameworks/SymSEP.framework" RemoveItem "/Library/PrivateFrameworks/SymSharedSettings.framework" RemoveItem "/Library/PrivateFrameworks/SymSubmission.framework" RemoveItem "/Library/PrivateFrameworks/SymSystem.framework" RemoveItem "/Library/PrivateFrameworks/SymUIAgent.framework" RemoveItem "/Library/PrivateFrameworks/SymUIAgentUI.framework" if [ ! -e "$VolumePrefix/Library/PrivateFrameworks/SymWebKitUtils.framework/Versions/A/Resources/SymWKULoader.dylib" -o ( $CreateFilesRemovedListOnly = true -a $ListOnlyFilesThatExist = false ) ] ; then RemoveItem "/Library/PrivateFrameworks/SymWebKitUtils.framework" fi RemoveItem "/Library/PrivilegedHelperTools/com.symantec" "" RemoveItem "/Library/PrivilegedHelperTools/NATRemoteLock.app" IFS='
' for EachReceiptLine in echo "$ReceiptsTable" | grep . | grep -v '^#' ; do ReceiptName=echo "$EachReceiptLine" | awk -F " " '{print $1}' ReceiptArg=echo "$EachReceiptLine" | awk -F " " '{print $2}' if [ "z$ReceiptArg" = z-a ] ; then RemoveItem "/Library/Receipts/$ReceiptName" "" RemoveItem "/Library/Receipts/$ReceiptName"Dev "" else if [ "z$ReceiptName" = zSymWebKitUtils.pkg -o "z$ReceiptName" = zSymWebKitUtilsDev.pkg ] ; then # If SymWKULoader exists and CleanUpSymWebKitUtils does not, skip deletion of SymWebKitUtils receipt [ -e "$VolumePrefix/Library/PrivateFrameworks/SymWebKitUtils.framework/Versions/A/Resources/SymWKULoader.dylib" -a ! -e /Library/StartupItems/CleanUpSymWebKitUtils ] && continue fi RemoveItem "/Library/Receipts/$ReceiptName" if [ "echo "$ReceiptName" | grep '.pkg$'" ] ; then ReceiptName="basename "$ReceiptName" .pkgDev.pkg" RemoveItem "/Library/Receipts/$ReceiptName" fi fi done RemoveItem "/Library/ScriptingAdditions/SymWebKitUtils.osax" RemoveItem "/Library/ScriptingAdditions/SymWebKitUtilsSL.osax" RemoveItem "/Library/Services/ScanService.service" RemoveItem "/Library/Services/SymSafeWeb.service" RemoveItem "/Library/Services" -e -u RemoveItem "/Library/StartupItems/NortonAutoProtect" RemoveItem "/Library/StartupItems/NortonAutoProtect.kextcache" RemoveItem "/Library/StartupItems/NortonLastStart" RemoveItem "/Library/StartupItems/NortonMissedTasks" RemoveItem "/Library/StartupItems/NortonPersonalFirewall" RemoveItem "/Library/StartupItems/NortonPrivacyControl" RemoveItem "/Library/StartupItems/NUMCompatibilityCheck" RemoveItem "/Library/StartupItems/SMC" RemoveItem "/Library/StartupItems/SymAutoProtect" RemoveItem "/Library/StartupItems/SymAutoProtect.kextcache" RemoveItem "/Library/StartupItems/SymDCInit" RemoveItem "/Library/StartupItems/SymMissedTasks" RemoveItem "/Library/StartupItems/SymProtector" RemoveItem "/Library/StartupItems/SymQuickMenuOSFix" RemoveItem "/Library/StartupItems/SymWebKitUtilsOSFix" RemoveItem "/Library/StartupItems/TrackDelete" RemoveItem "/Library/StartupItems/VolumeAssist" RemoveItem "/Library/Symantec/tmp" RemoveItem "/Library/Symantec" -E -u RemoveItem "/Library/Widgets/NAV.wdgt" RemoveItem "/Library/Widgets/Symantec Alerts.wdgt" RemoveItem "/Library/Widgets" -E -u RemoveItem "/Norton AntiVirus Installer Log"
# Folder with files erroneously created by an early Corsair installer: RemoveItem "/opt/Symantec"
# Folder erroneously created by that Corsair installer - removed if empty: RemoveItem "/opt" -E -u
# Folder erroneously created by NPF 300.001 - removed if empty: RemoveItem "/Personal" -e -u RemoveItem "/private/etc/liveupdate.conf" RemoveItem "/private/etc/mach_init.d/SymSharedSettings.plist" RemoveItem "/private/etc/Symantec.conf" RemoveItem "/private/tmp/com.symantec.liveupdate.reboot" RemoveItem "/private/tmp/com.symantec.liveupdate.restart" RemoveItem "/private/tmp/jlulogtemp" RemoveItem "/private/tmp/LiveUpdate." "" RemoveItem "/private/tmp/liveupdate" RemoveItem "/private/tmp/lulogtemp" RemoveItem "/private/tmp/SymSharedFrameworks" "" RemoveItem "/private/tmp/symask" RemoveItem "/private/var/db/NATSqlDatabase.db" RemoveItem '/private/var/db/receipts/$(SYM_SKU_REVDOMAIN).install.bom' RemoveItem '/private/var/db/receipts/$(SYM_SKU_REVDOMAIN).install.plist' RemoveItem "/private/var/db/receipts/com.Symantec" "" RemoveItem "/private/var/db/receipts/com.symantec" "" RemoveItem "/private/var/tmp/com.Symantec" "" RemoveItem "/private/var/tmp/com.symantec" "" RemoveItem "/private/var/tmp/symantec_error_report" "" RemoveItem "/private/var/log/nortondns.log" RemoveItem "/private/var/log/Npfkernel.log.fifo" RemoveItem "/private/var/root/Library/Bundles/NAVIR.bundle" RemoveItem "/private/var/root/Library/Bundles" -E -u RemoveItem "/private/var/root/Library/Contextual Menu Items/NAVCMPlugIn.plugin" RemoveItem "/private/var/root/Library/Contextual Menu Items" -E -u RemoveItem "/var/root/Applications/Norton Internet Security.app"
# Folder erroneously created by NPF 300.001 - removed if empty: RemoveItem "/Solutions" -e -u
# Folder erroneously created by NPF 300.001 - removed if empty: RemoveItem "/Support/Norton" -e -u
# Folder erroneously created by NPF 300.001 - removed if empty: RemoveItem "/Support" -e -u RemoveItem "/symaperr.log" RemoveItem "/symapout.log"
# Four frameworks erroneously installed by early builds of NAV 9.0.1: RemoveItem "/SymAppKitAdditions.framework" RemoveItem "/SymBase.framework" RemoveItem "/SymNetworking.framework" RemoveItem "/SymSystem.framework" RemoveItem "/System/Library/Authenticators/SymAuthenticator.bundle" RemoveItem "/System/Library/CFMSupport/Norton Shared Lib Carbon" RemoveItem "/System/Library/CoreServices/NSWemergency" RemoveItem "/System/Library/CoreServices/NUMemergency" RemoveItem "/System/Library/Extensions/DeleteTrap.kext" RemoveItem "/System/Library/Extensions/KTUM.kext" RemoveItem "/System/Library/Extensions/ndcengine.kext" RemoveItem "/System/Library/Extensions/NortonForMac.kext" RemoveItem "/System/Library/Extensions/NPFKPI.kext" RemoveItem "/System/Library/Extensions/SymDC.kext" RemoveItem "/System/Library/Extensions/SymEvent.kext" RemoveItem "/System/Library/Extensions/symfs.kext" RemoveItem "/System/Library/Extensions/SymInternetSecurity.kext" RemoveItem "/System/Library/Extensions/SymIPS.kext" RemoveItem "/System/Library/Extensions/SymOSXKernelUtilities.kext" RemoveItem "/System/Library/Extensions/SymPersonalFirewall.kext" RemoveItem "/System/Library/StartupItems/NortonAutoProtect" RemoveItem "/System/Library/StartupItems/SymMissedTasks" RemoveItem "/System/Library/Symantec" RemoveItem "/System/Library/SymInternetSecurity.kext" RemoveItem "/SystemWorks Installer Log" RemoveItem "/Users/dev/bin/smellydecode" RemoveItem "/Users/dev/bin" -E -u RemoveItem "/Users/dev" -E -u RemoveItem "/Users/Shared/NAV Corporate" RemoveItem "/Users/Shared/NIS Corporate" RemoveItem "/Users/Shared/RemoveSymantecMacFilesRemovesThese.txt" RemoveItem "/Users/Shared/RemoveSymantecMacFilesLog.txt" RemoveItem "/Users/Shared/RemoveSymantecMacFilesRemovesThese.txt" RemoveItem "/Users/Shared/RemoveSymantecMacFilesLog.txt" RemoveItem "/Users/Shared/SymantecRemovalToolRemovesThese.txt" RemoveItem "/Users/Shared/SymantecRemovalToolLog.txt" RemoveItem "/usr/bin/nortonscanner" RemoveItem "/usr/bin/nortonsettings" RemoveItem "/usr/bin/MigrateQTF" RemoveItem "/usr/bin/navx" RemoveItem "/usr/bin/npfx" RemoveItem "/usr/bin/savx" RemoveItem "/usr/bin/scfx" RemoveItem "/usr/bin/symsched" RemoveItem "/usr/lib/libsymsea." "dylib" RemoveItem "/usr/lib/libwpsapi.dylib" RemoveItem "/usr/local/bin/CoreLocationProviderTest" RemoveItem "/usr/local/bin/KeyGenerator" RemoveItem "/usr/local/bin/LocationProviderInterfaceTest" RemoveItem "/usr/local/bin/LocationProviderTest" RemoveItem "/usr/local/bin/MigrateQTF" RemoveItem "/usr/local/bin/nortonsettings" RemoveItem "/usr/local/bin/SkyhookProviderTest" RemoveItem "/usr/local/bin" -E -u RemoveItem "/usr/local/lib/libcx_lib.so" RemoveItem "/usr/local/lib/libecomlodr.dylib" RemoveItem "/usr/local/lib/libgecko3parsers.dylib" RemoveItem "/usr/local/lib/liblux.so." "
" RemoveItem "/usr/local/lib/libnlucallback.dylib" RemoveItem "/usr/local/lib" -E -u RemoveItem "/usr/local" -E -u RemoveItem "/usr/share/man/man1/NAVScanIDs.h" RemoveItem "/var/db/receipts/com.symantec" "" RemoveItem "/var/log/du.log" "" RemoveItem "/var/log/dulux.log" "" RemoveItem "/var/log/lut.log" "" RemoveItem "/var/log/lux.log" "" RemoveItem "/var/log/luxtool.log" "" RemoveItem "/var/log/mexd.log" "" RemoveItem "/var/log/microdef.log" "" # Delete logs listed in logging conf files within /private/etc/symantec IFS='
' for LUXLogFile in cat "/Library/Application Support/Symantec/Silo/NFM/LiveUpdate/Conf/lux.logging.conf" /private/etc/symantec/dulux.logging.conf /private/etc/symantec/lux.logging.conf /private/etc/symantec/microdef.logging.conf 2>/dev/null | tr '�15' '�12' | grep logger.sink.file.filePath= | awk -F = '{print $2}' | sort -f | uniq ; do RemoveItem "$LUXLogFile" "" done if [ -f /private/etc/symantec/defutils.conf ] ; then DefUtilsLogContents=cat /private/etc/symantec/defutils.conf 2>/dev/null | tr '�15' '�12' DefUtilsLogDir=printf "%s" "$DefUtilsLogContents" | grep defutillog_dir= | awk -F = '{print $2}' if [ "$DefUtilsLogDir" ] ; then DefUtilsLogBaseName=printf "%s" "$DefUtilsLogContents" | grep defutillog_name= | awk -F = '{print $2}' [ "$DefUtilsLogBaseName" ] && RemoveItem "$DefUtilsLogDir/$DefUtilsLogBaseName".log "" fi fi RemoveItem "/private/etc/symantec" if [ -f "$VolumePrefix/etc/syslog.conf" -a $CreateFilesRemovedListOnly = false ] ; then # Remove Norton Personal Firewall entries from /etc/syslog.conf sed -e "/Norton Personal Firewall/d" -e "/Npfkernel.log.fifo/d" "$VolumePrefix/etc/syslog.conf" > /private/tmp/NPF.syslog.conf /bin/cp -f /private/tmp/NPF.syslog.conf "$VolumePrefix/etc/syslog.conf" /bin/rm -f /private/tmp/NPF.syslog.conf fi RemoveFilesFromLibraryAndUserDirectories "$1" RemoveItem /Library/Preferences/Network -E -u if [ -s "$FilesRemovedFilesOnlyList" ] ; then sort -f "$FilesRemovedFilesOnlyList" | uniq | grep . >> "$FilesRemovedList" fi RemoveLoginKeychainPasswords "$CurrentVolumeBeingUsed"
}

RemoveEmptyDirectory()
{ # Usage: RemoveEmptyDirectory $1 # Argument: $1 = Full path name of directory # Summary: Removes directory $1 if it is empty or if it contains # only .DS_Store and/or .localized (the next best thing # to being empty). # # If $1 is a directory and not a link if [ -d "$1" -a ! -L "$1" ] ; then # If folder contains only .DS_Store and/or .localized, or is empty if [ -z "ls "$1" 2>/dev/null | grep -v "^.DS_Store|^.localized"" ] ; then $ShowFilesAsRemoved && echo " Removing: "$1"" # Clear immutable bit to remove any Finder lock chflags -R nouchg "$1" 2>/dev/null 1>&2 /bin/rm -rf "$1" 2>/dev/null 1>&2 # Remove folder fi fi
}

RemoveFilesFromLibraryAndUserDirectories()
{ # Usage: RemoveFilesFromLibraryAndUserDirectories $1 # Argument: $1 = Name of volume from which to remove preferences. # The name must begin with "/Volumes/" # unless it is "/" (boot volume). # Summary: Removes all Symantec files & folders from each user's # preferences, /Library/Caches, and /Library/Preferences. # Removes help files from /Library/Documentation. Removes # folders incorrectly created by NAV 7.0.2 from each # user's home directory. # local UserHomeDir local UserLibraryDir CurrentVolumeBeingUsed="$1" if [ "$1" = "/" ] ; then VolumeToCheck="" else VolumeToCheck="$1" fi # set IFS to only newline to get all user names IFS='
' for UserName in ls "$VolumeToCheck/Users" 2>/dev/null "root" "/" ; do if [ "$UserName" = "root" ] ; then UserLibraryDir="/private/var/root/Library" UserHomeDir="/private/var/root" elif [ "$UserName" = "/" ] ; then UserLibraryDir="/Library" UserHomeDir="" else UserLibraryDir="/Users/$UserName/Library" UserHomeDir="/Users/$UserName" fi # If UserLibraryDir is not a directory, skip to the next name [ ! -d "$VolumeToCheck$UserLibraryDir" ] && continue cd "$VolumeToCheck/" # If a user, delete folders from user's home directory that were # incorrectly created by NAV 7.0.2 if [ "$UserName" != "/" ] ; then RemoveItem "$UserHomeDir/Applications/LiveUpdate Folder (OS X)" RemoveItem "$UserHomeDir/Applications/Norton AntiVirus (OS X)" RemoveItem "$UserHomeDir/Applications" -e -u fi RemoveItem "$UserLibraryDir/Application Support/Norton" "" # If a user directory if [ "$UserHomeDir" ] ; then RemoveItem "$UserLibraryDir/Application Support/Symantec" RemoveItem "$UserHomeDir/Application Support/Symantec" RemoveItem "$UserHomeDir/Application Support" -e else # Make second attempt to remove "/Application Support/Symantec/ErrorReporting" RemoveItem "$UserLibraryDir/Application Support/Symantec/ErrorReporting" RemoveItem "$UserLibraryDir/Application Support/Symantec" fi RemoveItem "$UserLibraryDir/Documentation/Help/Norton Privacy Control Help" RemoveItem "$UserLibraryDir/Documentation/Help/Norton Personal Firewall Help" RemoveItem "$UserLibraryDir/Caches/com.apple.Safari/Extensions/Norton" "" -u RemoveItem "$UserLibraryDir/Caches/com.apple.Safari/Extensions/Symantec" "" -u RemoveItem "$UserLibraryDir/Caches/com.norton" "" -u RemoveItem "$UserLibraryDir/Caches/com.symantec" "" -u RemoveItem "$UserLibraryDir/Caches/Norton" "" -u RemoveItem "$UserLibraryDir/Caches/Symantec" "" -u RemoveItem "$UserLibraryDir/Logs/Symantec" "" -u RemoveItem "$UserLibraryDir/Preferences/ByHost/com.symantec" "" RemoveItem "$UserLibraryDir/Preferences/com.norton" "" RemoveItem "$UserLibraryDir/Preferences/com.symantec" "" -x 'com.symantec.sacm.' -x 'com.symantec.smac.' RemoveItem "$UserLibraryDir/Preferences/LiveUpdate Preferences" RemoveItem "$UserLibraryDir/Preferences/LU Admin Preferences" RemoveItem "$UserLibraryDir/Preferences/LU Host Admin.plist" RemoveItem "$UserLibraryDir/Preferences/NAV8.0.003.plist" RemoveItem "$UserLibraryDir/Preferences/Network/com.symantec" "" RemoveItem "$UserLibraryDir/Preferences/Norton AntiVirus Prefs Folder" RemoveItem "$UserLibraryDir/Preferences/Norton Application Aliases" RemoveItem "$UserLibraryDir/Preferences/Norton Personal Firewall Log" RemoveItem "$UserLibraryDir/Preferences/Norton Scheduler OS X.plist" RemoveItem "$UserLibraryDir/Preferences/Norton Utilities Preferences" RemoveItem "$UserLibraryDir/Preferences/Norton Zone" RemoveItem "$UserLibraryDir/Preferences/wcid" RemoveItem "$UserLibraryDir/Safari/Extensions/Norton" "" RemoveItem "$UserLibraryDir/Saved Application State/com.symantec" "" done
}

RemoveInvisibleFilesFromVolume()
{ # Usage: RemoveInvisibleFilesFromVolume $1 # Argument: $1 = Volume name. The name should begin with "/Volumes/" # unless it is "/" (boot volume). # Summary: Removes the invisible Symantec for OS X files - Norton FS # and AntiVirus QuickScan files - from $1. # ! $RemoveInvisibleFiles && return CurrentVolumeBeingUsed="$1" cd "$1" if $CreateFilesRemovedListOnly ; then echo "Finding invisible Symantec files on: $1" >&2 elif $ShowFilesAsRemoved ; then echo "Locating invisible Symantec files in: $1" else echo "Removing invisible Symantec files from: $1" fi RemoveItem "/.SymAVQSFile" RemoveItem "/NAVMac800QSFile" RemoveItem "/Norton FS Data" RemoveItem "/Norton FS Index" RemoveItem "/Norton FS Volume" RemoveItem "/Norton FS Volume 2"
}

RemoveItem()
{ # Usage: RemoveItem FilePath [-e | -E] [-u] [-x <pattern>] [FileExtension] # # Summary: Deletes the file or folder passed, FilePath, from the # current directory. # # Options: # -e Delete FilePath only if it is a directory that is empty or # that contains only ".DS_Store" and/or ".localized" files. # If the folder could not be deleted, error message is shown. # -E Same as the -e option, except no error message is shown if # the folder could not be deleted. # -u Item is not removed by Symantec Uninstaller.app. # -x <Pattern> # Pattern to exclude from file list. Pattern will become # ^FilePath/Pattern$ so add wildcards as needed. Make sure # to prefix special characters you wish to match with # (example: to match a period, .). You may pass several # -x <pattern> groupings. # <FileExtension> # All files that match FilePathFileExtension are deleted. # To match any files that begin with FilePath, pass "" as # FileExtension (don't pass unquoted). Only the last # FileExtension passed will be used # # Note: Make sure to run the SetupCleanup function before the # first run of this function and run the FinishCleanup # function before exiting the script. # Make sure to change directory to root of the volume you # want the file or folder removed from before calling this # function. # FilePath must be the first argument. The other options # may appear after FilePath in any order. # local ExclusionPattern="" # If / or no file name passed, return [ "z$1" = z/ -o -z "$1" ] && return VolumeFromWhichToRemove="pwd" FilePath="$1" if [ "$VolumeFromWhichToRemove" = "/" ] ; then FullFilePath="$FilePath" else FullFilePath="$VolumeFromWhichToRemove$FilePath" fi PathDir=dirname "$FullFilePath" PathBasePattern=basename "$FullFilePath" | sed s/"."/"\."/g shift DeleteOnlyIfEmptyDir=false SkipErrorMessageIfEmptyDirNotFound=false ExtensionPassed="" ShouldNotBeRemovedBySymantecUninstaller=false while [ "$1" ] ; do if [ "z$1" = z-e ] ; then DeleteOnlyIfEmptyDir=true SkipErrorMessageIfEmptyDirNotFound=false elif [ "z$1" = z-E ] ; then DeleteOnlyIfEmptyDir=true SkipErrorMessageIfEmptyDirNotFound=true elif [ "z$1" = z-u ] ; then ShouldNotBeRemovedBySymantecUninstaller=true elif [ "z$1" = z-x ] ; then if [ "$2" ] ; then shift if [ "$ExclusionPattern" ] ; then ExclusionPattern="$ExclusionPattern|^$PathDir/$1$" else ExclusionPattern="^$PathDir/$1$" fi fi else ExtensionPassed="$1" fi shift done if [ "z$ExtensionPassed" = "z" ] ; then ListOfPaths=ls -d "$PathDir/" 2>/dev/null | grep -i "^$PathDir/$PathBasePattern" | sort -f PathToShow="$FullFilePath" elif [ "$ExtensionPassed" ] ; then ExtensionPassedPattern=printf "%s" "$ExtensionPassed" | sed s/"."/"\."/g ListOfPaths=ls -d "$PathDir/" 2>/dev/null | grep -i "^$PathDir/$PathBasePattern.$ExtensionPassedPattern$" | sort -f PathToShow="$FullFilePath*$ExtensionPassed" else ListOfPaths=ls -d "$FullFilePath" 2>/dev/null PathToShow="$FullFilePath" fi # If there are items to exclude from the list and there are matching items if [ "z$ExclusionPattern" != z -a -n "$ListOfPaths" ] ; then ListOfPaths=printf "%s" "$ListOfPaths" | grep -i -v -e "$ExclusionPattern" fi if $CreateFilesRemovedListOnly ; then # If -E passed, then don't list the item $SkipErrorMessageIfEmptyDirNotFound && return if ! $ListOnlyFilesThatExist ; then echo "$PathToShow$DeleteOnlyIfEmptyDir && echo " [folder deleted only if empty]"" >> "$FilesRemovedList" # Else if file exists elif [ "$ListOfPaths" ] ; then IFS='
' if $DeleteOnlyIfEmptyDir ; then ItemsToAddToList="$ListOfPaths" else ItemsToAddToList="" for EachItemListed in $ListOfPaths ; do if [ -L "$EachItemListed" -o -f "$EachItemListed" ] ; then ItemsToAddToList="$ItemsToAddToList
$EachItemListed" else ItemsToAddToList="$ItemsToAddToList
find "$EachItemListed" 2>/dev/null" fi done fi for EachItemFound in $ItemsToAddToList ; do if $ShouldNotBeRemovedBySymantecUninstaller ; then AddedText="$NotRemovedBySymantecUninstallerText" elif [ "echo "$EachItemFound" | grep -F "$NotRemovedBySymantecUninstaller"" ] ; then AddedText="$NotRemovedBySymantecUninstallerText" else AddedText="" fi echo "$EachItemFound$DeleteOnlyIfEmptyDir && echo " [folder deleted only if empty]"$AddedText" >> "$FilesRemovedFilesOnlyList" done NoFilesToRemove=false FilesFoundOnThisVolume=true fi return fi IFS='
' for EachFullPath in $ListOfPaths ; do # If -e or -E was passed if $DeleteOnlyIfEmptyDir ; then # remove directory only if empty RemoveEmptyDirectory "$EachFullPath" # If -E passed, then skip error reporting $SkipErrorMessageIfEmptyDirNotFound && continue else $ShowFilesAsRemoved && echo " Removing: "$EachFullPath"" # Clear immutable bit to remove any Finder lock chflags -R nouchg "$EachFullPath" 2>/dev/null 1>&2 /bin/rm -rf "$EachFullPath" 2>/dev/null 1>&2 # Remove file/folder fi # If file still exists if [ "ls -d "$EachFullPath" 2>/dev/null" ] ; then TheFileWasRemoved=false else TheFileWasRemoved=true SomeFileWasRemoved=true fi # If the file/folder was not removed if ! $TheFileWasRemoved ; then if ! $ErrorOccurred ; then # Create LogFile echo "Symantec files/folders not removed:" >"$LogFile" chmod a=rw "$LogFile" ErrorOccurred=true fi echo " $EachFullPath" >>"$LogFile" # Else if boot volume elif [ "$CurrentVolumeBeingUsed" = "/" ] ; then RestartMayBeNeeded=true SomeFileWasRemovedFromBootVolume=true else SomeFileWasRemovedFromNonBootVolume=true fi NoFilesToRemove=false FilesFoundOnThisVolume=true done
}

RemoveLoginKeychainPasswords()
{ # Usage: RemoveLoginKeychainPasswords volume # Summary: Removes items from login keychains. # If volume is not / (current boot volume), removal is skipped. # If volume is not specified, / is assumed. # local VolumeBeingPurged="$1" local EachLoginKeychain local HelpTextToShow local LoginKeychainPasswordToDelete local LoginKeychainPasswordToDeleteLine local UserOfKeychain # If volume not specified, assume it is boot volume [ -z "$VolumeBeingPurged" ] && VolumeBeingPurged=/ # If volume being cleaned up is not the boot volume, skip purge [ "z$VolumeBeingPurged" != z/ ] && return echo "Looking for Symantec login keychain items" IFS='
' for EachLoginKeychain in ls -d /Users/*/Library/Keychains/login.keychain 2>/dev/null ; do UserOfKeychain=echo "$EachLoginKeychain" | awk -F / '{print $3}' for LoginKeychainPasswordToDeleteLine in $LoginKeychainPasswordsToDelete ; do LoginKeychainPasswordToDelete=echo "$LoginKeychainPasswordToDeleteLine" | awk -F ' ' '{print $1}' HelpTextToShow=echo "$LoginKeychainPasswordToDeleteLine" | awk -F ' ' '{print $2}' /usr/bin/security find-generic-password -s "$LoginKeychainPasswordToDelete" "$EachLoginKeychain" 2>/dev/null 1>&2 if [ $? = 0 ] ; then if $CreateFilesRemovedListOnly ; then echo "$HelpTextToShow ($LoginKeychainPasswordToDelete) would be removed" >> "$FilesRemovedList" echo "from $UserOfKeychain's login keychain" >> "$FilesRemovedList" echo "" >> "$FilesRemovedList" else echo "Removing $HelpTextToShow ($LoginKeychainPasswordToDelete)" echo "from $UserOfKeychain's login keychain" /usr/bin/security delete-generic-password -s "$LoginKeychainPasswordToDelete" "$EachLoginKeychain" 2>/dev/null 1>&2 fi fi done done
}

RemoveNortonZoneDirectories()
{ # Usage: RemoveNortonZoneDirectories user_home_directory # Summary: Removes Norton Zone paths listed in zoneDirectoryManagerRegistryKey in # user_home_directory/Preference/com.symantec.nds.Norton-Zone.plist # local UserHomeDir="$1" local ZonePath local ZonePaths [ ! -d "$UserHomeDir" ] && return ZonePaths=defaults read "$UserHomeDir/Library/Preferences/"com.symantec.nds.Norton-Zone zoneDirectoryManagerRegistryKey 2>/dev/null | grep = | awk -F '"' '{print $2}' IFS='
' for ZonePath in $ZonePaths ; do RemoveItem "$ZonePath" done RemoveItem "$UserHomeDir/Norton Zone" "*"
}

RestartComputer()
{ # Usage: RestartComputer # Summary: Prompts to see if user would like to restart. Restarts # computer using 'reboot' command if 'yes' or 'y' is # entered; exits the script otherwise. # Note: User must be root or an admin for reboot to work, so this # function should only be used in scripts run as root or # admin user. # echo if $RunningFromWithinAppBundleOrSupportFolder ; then ExitScript $FinishedExitCode elif $QuitWithoutRestarting ; then echo "Exited the script without restarting the computer." ExitScript $FinishedExitCode elif ! $RestartAutomatically ; then echo "Do you wish to restart the computer now (WARNING: Unsaved changes" printf "in other open applications will be lost if you do!) (y/n)? " if YesEntered ; then RestartAutomatically=true fi echo fi if $RestartAutomatically ; then if $PauseBeforeRestarting ; then printf "Computer will restart in 3 seconds (ctrl-C to cancel restart)..." sleep 1 printf " 3" sleep 1 printf " 2" sleep 1 printf " 1" sleep 1 fi echo echo "Computer is restarting..." reboot else echo "Exited the script without restarting the computer." ExitScript $FinishedExitCode fi
}

RunPredeleteScripts()
{ # Usage: RunPredeleteScripts [$1] # Argument: $1 = Path of current volume. # Summary: If $1 is "" or /, predelete scripts in receipts listed in # ReceiptsTable are run. # local EachReceiptLine local EachReceiptMatchingAll local ReceiptList local ReceiptListMatchingAll="" local VolumePathPassed="$1" [ "z$VolumePathPassed" = z/ ] && VolumePathPassed="" if $CreateFilesRemovedListOnly ; then if [ "$VolumePathPassed" ] ; then echo "Receipt predelete scripts would not be run on that volume." >> "$FilesRemovedList" elif $DoRunPredeleteScripts ; then echo "Receipt predelete scripts would be run as they are found." >> "$FilesRemovedList" else echo "Receipt predelete scripts would not be run because the -d option was specified." >> "$FilesRemovedList" fi return elif [ "$VolumePathPassed" ] ; then echo "Receipt predelete scripts were not run on that volume." return elif ! $DoRunPredeleteScripts ; then echo "Receipt predelete scripts were not run because the -d option was specified." return fi SYMANTEC_SAVED_DATA_DIR="/private/tmp/$FullScriptName-SYMANTEC_SAVED_DATA_DIR-date +"%Y%m%d%H%M%S"" mkdir -p "$SYMANTEC_SAVED_DATA_DIR" 2>/dev/null IFS='
' echo "Looking for predelete scripts in Symantec Uninstaller's Receipts folder" for PredeleteScript in find "/Library/Application Support/Symantec/Uninstaller" 2>/dev/null | grep -E 'predelete$|pre_delete$' ; do if [ -x "$PredeleteScript" ] ; then echo "--- Running $PredeleteScript ---" export SYMANTEC_SAVED_DATA_DIR if $ShowPredeleteErrors ; then "$PredeleteScript" else "$PredeleteScript" 2>/dev/null 1>&2 fi fi done echo "Looking for predelete scripts in /Library/Receipts" ReceiptList=echo "$ReceiptsTable" | grep '.pkg' | grep -v '^#' for EachReceiptMatchingAll in echo "$ReceiptsTable" | grep ' -a' | grep -v '^#' | awk -F ' ' '{print $1}' ; do ReceiptListMatchingAll="$ReceiptListMatchingAll
ls -d "/Library/Receipts/$EachReceiptMatchingAll"* 2>/dev/null" done for EachReceiptMatchingAll in $ReceiptListMatchingAll ; do ReceiptList="$ReceiptList
basename "$EachReceiptMatchingAll"" done for EachReceiptLine in $ReceiptList ; do ReceiptArg=echo "$EachReceiptLine" | awk -F " " '{print $2}' [ "z$ReceiptArg" = z-s ] && continue ReceiptName=echo "$EachReceiptLine" | awk -F " " '{print $1}' [ -z "echo "$ReceiptName" | grep '.pkg$'" ] && continue if [ -d "/Library/Receipts/$ReceiptName" ] ; then for PredeleteScript in find "/Library/Receipts/$ReceiptName" 2>/dev/null | grep -E 'predelete$|pre_delete$' ; do if [ -x "$PredeleteScript" ] ; then echo "--- Running $PredeleteScript ---" export SYMANTEC_SAVED_DATA_DIR if $ShowPredeleteErrors ; then "$PredeleteScript" else "$PredeleteScript" 2>/dev/null 1>&2 fi fi done fi ReceiptName="basename "$ReceiptName" .pkgDev.pkg" if [ -d "/Library/Receipts/$ReceiptName" ] ; then for PredeleteScript in find "/Library/Receipts/$ReceiptName" 2>/dev/null | grep -E 'predelete$|pre_delete$' ; do if [ -x "$PredeleteScript" ] ; then echo "--- Running $PredeleteScript ---" export SYMANTEC_SAVED_DATA_DIR if $ShowPredeleteErrors ; then "$PredeleteScript" else "$PredeleteScript" 2>/dev/null 1>&2 fi fi done fi done rm -rf "$SYMANTEC_SAVED_DATA_DIR" 2>/dev/null
}

SetupCleanup()
{ # Usage: SetupCleanup # Summary: Initializes variables needed for the RemoveItem function. # ErrorOccurred=false NoFilesToRemove=true /bin/rm -rf "$FilesRemovedList" "$FilesRemovedFilesOnlyList" 2>/dev/null 1>&2 if $CreateFilesRemovedListOnly ; then if $ListOnlyFilesThatExist ; then echo "Summary of what $FullScriptName would do, based on files" > "$FilesRemovedList" echo "$RemoveCrontabEntries && echo "and crontab entries "that currently exist:" >> "$FilesRemovedList" else echo "Summary of what $FullScriptName would attempt to do:" > "$FilesRemovedList" fi fi
}

ShowContents()
{ # Usage1: ShowContents [-c] [-w] File [TextToShow] # Usage2: ShowContents [-c] [-w] -s String [TextToShow] # Summary: Displays contents of File or String. If there are more than # $LINES or 23 lines, more command is used, using TextToShow as # the name of the file; if TextToShow is not passed, "....." is # used. If -c is specified, screen is cleared beforehand. # If -w is specified, then width of strings will be factored # into the line count (this option makes output slower when # the number of lines is less than $LINES or 23). # local SCLineCount local SCCurrentDir local SCTempFolder local SCTempFile local SCColumns local SCColumnsMax local SCColumnsMaxDefault=80 local SCColumnsRemainder local CSDoAdjustForWidth=false local CSDoUseString=false local SCEachLine local SCGrepPattern='.' local SCLineFactor local SCLines local SCLinesMax local SCLinesMaxDefault=23 local SCText while [ "$1" ] ; do if [ "z$1" = z-c ] ; then clear elif [ "z$1" = z-s ] ; then CSDoUseString=true elif [ "z$1" = z-w ] ; then CSDoAdjustForWidth=true else break fi shift done [ "$COLUMNS" ] && SCColumnsMax=expr "$COLUMNS" - 0 2>/dev/null [ -z "$SCColumnsMax" ] && SCColumnsMax=$SCColumnsMaxDefault [ "$LINES" ] && SCLinesMax=expr "$LINES" - 1 2>/dev/null [ -z "$SCLinesMax" ] && SCLinesMax=$SCLinesMaxDefault [ $SCColumnsMax -ge $SCColumnsMaxDefault ] && SCGrepPattern='.................................................................................' if $CSDoUseString ; then SCLineCount=printf "%s " "$1" | grep -c "" $CSDoAdjustForWidth && SCText=printf "%s " "$1" | grep "$SCGrepPattern" elif [ -f "$1" ] ; then SCLineCount=grep -c "" "$1" $CSDoAdjustForWidth && SCText=grep "$SCGrepPattern" "$1" else return 1 fi if $CSDoAdjustForWidth ; then if [ $SCLineCount -le $SCLinesMax ] ; then IFS='
' for SCColumns in printf "%s" "$SCText" | awk '{print length($0)}' ; do [ $SCLineCount -gt $SCLinesMax ] && break SCLineFactor=expr $SCColumns / $SCColumnsMax [ expr $SCColumns % $SCColumnsMax -gt 0 ] && let SCLineFactor=$SCLineFactor+1 [ $SCLineFactor -gt 1 ] && let SCLineCount=$SCLineCount+$SCLineFactor-1 done fi fi if $CSDoUseString ; then if [ $SCLineCount -gt $SCLinesMax ] ; then SCCurrentDir=pwd SCTempFolder="/private/tmp/$FullScriptName-SC-date "%Y%m%d%H%M%S"" mkdir "$SCTempFolder" 2>/dev/null [ ! -d "$SCTempFolder" ] && return 1 cd "$SCTempFolder" 2>/dev/null [ "$2" ] && SCTempFile="$2" || SCTempFile="....." printf "%s " "$1" >"$SCTempFile" more -E "$SCTempFile" cd "$SCCurrentDir" 2>/dev/null rm -rf "$SCTempFolder" 2>/dev/null else printf "%s " "$1" fi elif [ -f "$1" ] ; then if [ $SCLineCount -gt $SCLinesMax ] ; then SCCurrentDir=pwd SCTempFolder="/private/tmp/$FullScriptName-SC-date "%Y%m%d%H%M%S"" mkdir "$SCTempFolder" 2>/dev/null [ ! -d "$SCTempFolder" ] && return 1 [ "$2" ] && SCTempFile="$2" || SCTempFile="....." cat "$1" >"$SCTempFolder/$SCTempFile" cd "$SCTempFolder" 2>/dev/null more -E "$SCTempFile" cd "$SCCurrentDir" 2>/dev/null rm -rf "$SCTempFolder" 2>/dev/null else cat "$1" fi fi return 0
}

ShowFullFilePath()
{ # Usage: ShowFullFilePath [-a] [-P | -L] [-e] Path [[-e] Path] # Version: 1.0.2 # Summary: Prints the full path starting at / of Path if Path exists # and Path is accessible by the user calling this function. # Run this function as root to ensure full path displaying. # If there is more than one existing file that matches the # name, then only the first path that the shell matches is # printed unless -a or more than one path is specified. # You can specify wild card characters ? and and other # argument operators in the Path (e.g., "../", "a?.txt", # "[ab]"). # Options: -a Show all matching paths, sorted alphanumerically. If # -P is not passed, the same file may be shown multiple # times if there is more than one matching link that # points to it. # -e <Path> # Treat argument after -e as a path. Use -e to treat # -a, -e, -L, or -P as a path. # -L Show logical path, even if a file pointed to by a link # doesn't exist. This is the default. # -P Show physical path. If a link points to a file that # does not exist, the path won't be shown. # History: 1.0.1 - Added -e option and ability to pass multiple paths. # Arguments can now be passed in any order. # Fixed error that could occur when resolving links # with long paths. # 1.0.2 - Modified for case-sensitive volume compatibility. # Made temporary file names more distinctive. # local SFFPArgCount=$# local SFFPCurrentDir local SFFPCurrentDirTranslated local SFFPEachLine local SFFPEachPath local SFFPFile local SFFPLDir local SFFPLLinkLS local SFFPLLinkPath local SFFPLPath local SFFPPathOption=-L local SFFPSaveIFS="$IFS" local SFFPShowAll=false local SFFPTempBase=/private/tmp/ShowFullFilePath-/usr/bin/basename "$0"-/bin/date +"%Y%m%d%H%M%S" local SFFPTempFile="$SFFPTempBase.tmp" local SFFPTempFile2="$SFFPTempBase-2.tmp" /bin/rm -f "$SFFPTempFile" 2>/dev/null while [ $SFFPArgCount != 0 ] ; do case "$1" in -a) SFFPShowAll=true ;; -L|-P) SFFPPathOption="$1" ;; ) [ "z$1" = z-e ] && shift if [ "$1" ] ; then [ -s "$SFFPTempFile" ] && SFFPShowAll=true /usr/bin/printf "%s " "$1" >>"$SFFPTempFile" fi ;; esac shift let SFFPArgCount=$SFFPArgCount-1 done [ ! -s "$SFFPTempFile" ] && return SFFPCurrentDir=/bin/pwd SFFPCurrentDirTranslated=/bin/pwd $SFFPPathOption 2>/dev/null if [ ! -d "$SFFPCurrentDirTranslated" ] ; then /bin/rm -f "$SFFPTempFile" 2>/dev/null return fi cd "$SFFPCurrentDirTranslated" 2>/dev/null if [ $? != 0 ] ; then /bin/rm -f "$SFFPTempFile" 2>/dev/null return fi /usr/bin/printf "" >"$SFFPTempFile2" IFS='
' for SFFPEachLine in /bin/cat "$SFFPTempFile" 2>/dev/null ; do cd "$SFFPCurrentDirTranslated" 2>/dev/null [ $? != 0 ] && break if [ "z$SFFPPathOption" = z-P ] ; then SFFPLPath="$SFFPEachLine" while [ -L "$SFFPLPath" ] ; do [ ! -e "$SFFPLPath" ] && break cd "/usr/bin/dirname "$SFFPLPath" 2>/dev/null" 2>/dev/null [ $? != 0 ] && break SFFPLDir=/bin/pwd -P 2>/dev/null [ ! -d "$SFFPLDir" ] && break SFFPLLinkLS=/bin/ls -ld "$SFFPLPath" 2>/dev/null [ -z "$SFFPLLinkLS" ] && break # If link or link target contains " -> " in its name if [ "echo "z$SFFPLLinkLS" | grep ' -> .* -> '" ] ; then SFFPLLinkPath=/usr/bin/printf "%s" "$SFFPLLinkLS" | /usr/bin/awk -v THESTR="$SFFPLPath -> " '{ match($0,THESTR) ; print substr($0,RSTART+RLENGTH)}' else SFFPLLinkPath=echo "$SFFPLLinkLS" | awk -F " -> " '{print $2}' fi # If link target begins with / if [ "/usr/bin/printf "%s" "$SFFPLLinkPath" | grep '^/'" ] ; then SFFPLPath="$SFFPLLinkPath" else SFFPLPath="$SFFPLDir/$SFFPLLinkPath" fi [ "/usr/bin/printf "%s" "$SFFPLPath" | grep '^//'" ] && SFFPLPath=echo "$SFFPLPath" | /usr/bin/awk '{print substr($0,2)}' done cd "$SFFPCurrentDirTranslated" 2>/dev/null [ $? != 0 ] && break if [ ! -e "$SFFPLPath" ] ; then $SFFPShowAll && continue || break fi SFFPEachPath="$SFFPLPath" else SFFPEachPath="$SFFPEachLine" fi if [ -d "$SFFPEachPath" ] ; then cd "$SFFPEachPath" 2>/dev/null if [ $? != 0 ] ; then $SFFPShowAll && continue || break fi SFFPFile="" elif [ -d "/usr/bin/dirname "$SFFPEachPath" 2>/dev/null" ] ; then cd "/usr/bin/dirname "$SFFPEachPath" 2>/dev/null" 2>/dev/null if [ $? != 0 ] ; then $SFFPShowAll && continue || break fi SFFPFile=basename "$SFFPEachPath" 2>/dev/null [ "z$SFFPFile" = z/ -o "z$SFFPFile" = z. -o "z$SFFPFile" = z.. ] && SFFPFile="" elif $SFFPShowAll ; then continue else break fi SFFPDir=/bin/pwd $SFFPPathOption 2>/dev/null if [ ! -d "$SFFPDir" ] ; then $SFFPShowAll && continue || break fi SFFPPath="$SFFPDir[ "z$SFFPFile" != z -a "z$SFFPDir" != z/ -a "z$SFFPDir" != z// ] && echo /$SFFPFile" if [ ! -e "$SFFPPath" -a ! -L "$SFFPPath" ] ; then $SFFPShowAll && continue || break fi [ "echo "$SFFPPath" | grep '^//'" ] && SFFPPath=echo "$SFFPPath" | /usr/bin/awk '{print substr($0,2)}' echo "$SFFPPath" >>"$SFFPTempFile2" # If neither option -a nor more than one path was passed, don't show any more names ! $SFFPShowAll && break done IFS=$SFFPSaveIFS [ -s "$SFFPTempFile2" ] && /usr/bin/sort -f "$SFFPTempFile2" | /usr/bin/uniq /bin/rm -f "$SFFPTempFile" "$SFFPTempFile2" 2>/dev/null cd "$SFFPCurrentDir" 2>/dev/null
}

ShowHelp()
{ # Usage: ShowHelp [$1] # Argument: $1 = Exit code. # Summary: Displays script usage and help then exits script. # If a number is passed to $1, then script exits with # that number; else, script is not exited. # TEMPFILETEMPLATE="/private/tmp/SymantecTemp" TEMPFILE="$TEMPFILETEMPLATEdate +"%Y%m%d%H%M%S"-1" ShowVersion >>"$TEMPFILE" $AutoRunScript && echo "
Note: This script requires no user interaction if run as root. You can run this script on several machines at once by using Symantec Endpoint Protection to push this script to client Macs." >>"$TEMPFILE" echo "
WARNING: This script will remove all files and folders created by Symantec Mac OS X products (LiveUpdate Administration Utility files) and any files within those folders. Therefore, you will lose ALL files that reside in those folders, including any that you have created.

Usage: $FullScriptName [-CcdefhIiLlmpQqRrV] [-QQ] [-re] [volume ...]

Summary: If no option or volume is specified, then all Symantec files are removed from the current boot volume, including the invisible Symantec files (i.e., AntiVirus QuickScan and Norton FS files), and Symantec crontab entries are removed from all users' crontabs; otherwise, for each volume specified, all Symantec files and Symantec crontab entries will be removed from that volume if no options are specified. If files are removed from the current boot volume, receipt predelete scripts are run unless -d is specified.

If a volume does not have OS X installed on it, then only the invisible Symantec files are removed from that volume.

Each volume name may begin with "/Volumes/", unless it is "/". The easiest way to specify a volume is to drag the volume onto the Terminal window.

Note: The Terminal application does not support high ASCII or double-byte character entry via keyboard or via drag-and-drop. If you want to have files removed from a volume that is not the current boot volume and that has a name containing high ASCII or double-byte characters, use the -A option.

Options: -A Remove all Symantec files from all mounted volumes. Crontab entries are also removed from the current boot volume, but not from other volumes. If a volume does not have OS X installed on it, then only the invisible Symantec files are removed from that volume. -c Only remove crontab entries from all users' crontabs. Nothing is removed from any volume. -C Do not remove crontab entries. -d Bypass the running of receipt predelete scripts. It is best to have predelete scripts run for more thorough uninstalls. -e Show errors when run predelete scripts are run. Predelete scripts are run only when removing files from the current boot volume. -f Do not show files as they are removed. If -f is not specified, file names are shown as files are removed. -h Display help. -i Only remove invisible Symantec files. -I Does not remove invisible Symantec files. -l List only files that are currently installed and that would be deleted. As of version 6.0.0, contents of folders are also shown. Nothing is deleted by this option. -L List all files that $FullScriptName will attempt to find and delete. Nothing is deleted by this option. -m Show output from -l, -L, or -R options using more program. This is no longer the default action as of version 5.52 of $FullScriptName. -p Eliminate pause before restarting computer. If option -p is not specified, then there is a three second delay before the restart occurs. -q Quit script without restarting. This also suppresses the prompt to restart. -Q Quits Terminal application when script is done. If Terminal is being run by more than one user at once, Terminal is not quit. If passed a second time, it is the same as -QQ option. -QQ Quits Terminal application for all users when script is done. -R This option is equivalent to the -l option. -r Automatically restart computer when script is done if there are Symantec processes and/or kexts in memory and there were non-invisible files removed from /. -re Same as -r option. Though -re is deprecated, it remains for backwards compatibility. -V Show version only.

Examples: $FullScriptName Deletes all Symantec files and Symantec crontab entries from the boot volume.

$FullScriptName /Volumes/OS 10.2 Deletes all Symantec files and Symantec crontab entries from the volume named "OS 10.2". Nothing is deleted from the boot volume.

$FullScriptName Runner / Deletes all Symantec files and Symantec crontab entries from the volume named "Runner" and from the boot volume.

$FullScriptName -i "Test Disk" Deletes only invisible Symantec files from the volume named "Test Disk".

$FullScriptName -A -r Deletes all Symantec files and Symantec crontab entries from all mounted volumes that have OS X installed on them. Deletes only invisible Symantec files from volumes that do not have OS X installed on them. Computer is restarted automatically if necessary.

$FullScriptName -iA Deletes only invisible Symantec files from all volumes.

$FullScriptName -I Deletes all but the invisible Symantec files from the boot volume. Crontab entries are removed from the boot volume.

$FullScriptName -C Deletes all Symantec files from the boot volume. No crontab entries are removed.

$FullScriptName -L -A Lists all the files that $FullScriptName looks for on all volumes. The files may or may not be currently installed. Nothing is deleted.

$FullScriptName -R -A Lists only the Symantec files that are currently installed on all volumes. Files within existing folders will also be shown. Nothing is deleted.

$FullScriptName -l -i Lists the invisible Symantec files that are currently installed on the boot volume. Nothing is deleted.

Note: You must be root or an admin user to run this script. You can simply double-click on $FullScriptName to remove all Symantec files and crontab entries from the boot volume.
" >>"$TEMPFILE" ShowContents "$TEMPFILE" /bin/rm "$TEMPFILE" 2>/dev/null [ "$1" ] && exit $1
}

ShowUsage()
{ # Usage: ShowUsage [$1 [$2]] # Arguments: $1 = Exit code. # $2 = Error message to display before showing usage. # Summary: Displays script usage. If an exit code is passed, # script is exited with that value. # if [ "$2" ] ; then echo echo "$2" echo fi ShowHelp | grep "^Usage.*:" [ "$2" ] && echo [ -n "$1" ] && exit "$1"
}

ShowVersion()
{ # Usage: ShowVersion # Summary: Displays the name and version of script. # echo " $FullScriptName $Version **"
}

SymantecIsInMemory()
{ # Usage: SymantecIsInMemory # Summary: If a Symantec process or kext is in memory, true is shown # and 0 is returned; otherwise, false is shown and 1 is # returned. Sample call: # if SymantecIsInMemory # local SymantecIsInMemoryResult=false if [ "ps -wwax | grep -i "/Application Support/Norton|/Application Support/Symantec|/Applications/Norton|/Applications/Symantec|PrivateFrameworks/Sym|/StartupItems/.*Norton|/StartupItems/NUMCompatibilityCheck|/StartupItems/SMac Client|/StartupItems/Sym|/StartupItems/TrackDelete|/StartupItems/VolumeAssist" | grep -v " grep -|/LiveUpdateAdminUtility/"" ] ; then SymantecIsInMemoryResult=true else kextstat 2>/dev/null 1>&2 if [ $? -gt 0 ] ; then if [ "kmodstat | grep -i Symantec | grep -v " grep -"" ] ; then SymantecIsInMemoryResult=true fi elif [ "kextstat | grep -i Symantec | grep -v " grep -"" ] ; then SymantecIsInMemoryResult=true fi fi echo $SymantecIsInMemoryResult ! $SymantecIsInMemoryResult && return 1 return 0
}

YesEntered()
{ # Usage: YesEntered # Summary: Reads a line from standard input. If "y" or "yes" # was entered, true is shown and 0 is returned; otherwise, # false is shown and 1 is returned. The case of letters is # ignored. Sample call: # if YesEntered # read YesEnteredString YesEnteredString=echo "z$YesEnteredString" | awk '{print tolower(substr($0,2))}' if [ "'$YesEnteredString" = "'y" -o "'$YesEnteredString" = "'yes" ] ; then echo true return 0 fi echo false return 1
}

# Beginning of Commands to Execute

ScriptPath=ShowFullFilePath "$0" -P
ScriptDir=dirname "$ScriptPath"
if [ $# -eq 0 ] ; then # If no arguments were passed to script # Run script as if it was double-clicked in Finder so that # screen will be cleared and quit message will be displayed. RunScriptAsStandAlone=true
else # Run script in command line mode so that # screen won't be cleared and quit message won't be displayed. RunScriptAsStandAlone=false
fi
# If script was run from support folder or from within an app bundle
if [ "echo "$ScriptDir" | grep -e "$LaunchLocationGrepPattern"" ] ; then RunScriptAsStandAlone=false RunningFromWithinAppBundleOrSupportFolder=true
else RunningFromWithinAppBundleOrSupportFolder=false
fi
if $RunScriptAsStandAlone ; then clear >&2
fi
ProcessArguments --OptionIsOneArgument="-QQ" --OptionIsOneArgument="-re" "$@"
if [ "whoami" != "root" ] ; then # If not root user, if $PublicVersion ; then GetAdminPassword true # Prompt user for admin password else ShowVersion >&2 echo >&2 fi # Run this script again as root sudo -p "Please enter your admin password: " "$0" "$@" ErrorFromSudoCommand=$? # If unable to authenticate if [ $ErrorFromSudoCommand -eq 1 ] ; then echo "You entered an invalid password or you are not an admin user. Script aborted." >&2 ExitScript 1 fi if $PublicVersion ; then sudo -k # Make sudo require a password the next time it is run fi exit $ErrorFromSudoCommand # Exit so script doesn't run again
fi
# If no volumes were passed to script, the boot volume will be searched
if [ -z "$VolumesToUse" ] ; then BootVolumeWillBeSearched=true
fi
if [ $PublicVersion = true -a $CreateFilesRemovedListOnly = false -a $RemoveCrontabEntriesOnly = false -a $RemoveInvisibleFilesOnly = false -a $AutoRunScript = false -a $RunningFromWithinAppBundleOrSupportFolder = false ] ; then DetermineAction
fi
if [ $RemoveFromAllVolumes = true -a $CreateFilesRemovedListOnly = false -a $RemoveCrontabEntriesOnly = false -a $RemoveInvisibleFilesOnly = false -a $AutoRunScript = false -a $RunningFromWithinAppBundleOrSupportFolder = false ] ; then echo printf "Are you sure you want to remove Symantec files from ALL mounted volumes (y/n)? " if YesEntered ; then echo else echo echo "Script aborted. No files were removed." ExitScript 0 fi
fi
SetupCleanup
WillTense=will
if $CreateFilesRemovedListOnly ; then echo "Generating a list of files that would be removed by" >&2 echo " $FullScriptName (no files will be removed at this time)..." >&2 WillTense=would
elif $RemoveInvisibleFilesOnly ; then echo "Removing AntiVirus QuickScan files and Norton FS files..."
else if $BootVolumeWillBeSearched ; then if [ $RestartAutomatically = true -a $RemoveCrontabEntriesOnly = false ] ; then echo echo "Note: Computer will be restarted automatically if necessary." echo elif $QuitWithoutRestarting ; then echo echo "Note: This script will automatically quit when finished." echo fi fi echo "Removing Symantec files..." ! $RemoveInvisibleFiles && echo "Invisible Symantec files will not be deleted."
fi
if $RemoveCrontabEntriesOnly ; then echo "Only crontab entries $WillTense be removed."
fi
! $RemoveCrontabEntries && echo "Symantec crontab entries $WillTense not be removed."
! $RemoveInvisibleFiles && echo "AntiVirus QuickScan and Norton FS files $WillTense not be removed."
if $RemoveFromAllVolumes ; then VolumesToUse="/
"ls -d /Volumes/*
elif ! $RemoveFromOtherVolumes ; then VolumesToUse=/
fi
ListOfVolumesToUse=echo "$VolumesToUse" | sort -f | uniq
IFS='
'
for EachVolume in $ListOfVolumesToUse ; do [ -L "$EachVolume" ] && continue FilesFoundOnThisVolume=false RemoveAllNortonFiles "$EachVolume" if [ $CreateFilesRemovedListOnly = true -a $FilesFoundOnThisVolume = false -a $ListOnlyFilesThatExist = true ] ; then echo "No matching files were found on "basename "$EachVolume""." >> "$FilesRemovedList" fi
done
FinishCleanup
FinishedExitCode=$?
if [ $BootVolumeWillBeSearched = true -a $CreateFilesRemovedListOnly = false ] ; then if SymantecIsInMemory ; then echo echo "NOTE: You should now restart the computer to get Symantec processes" echo " and kexts out of memory." RestartComputer elif [ -e /Library/StartupItems/CleanUpSymWebKitUtils ] ; then echo echo "NOTE: You should now restart the computer to have CleanUpSymWebKitUtils" echo " finish removing SymWebKitUtils.framework." RestartComputer fi
fi
ExitScript $FinishedExitCode

# End of Commands to Execute

scottb
Honored Contributor

Thanks - at the same time I got it from Symantec. Is this the one that was having troubles with renaming to .sh and running in Casper?

sgoetz
Contributor

I packaged it in a DMG and it worked for me :D

acdesigntech
Contributor II

I wasn't able to get it to run properly without adding the '-A' parameter to the command. Removal script looks like this:

SymantecRemoval.command -A &
RemovalPID=`echo "$!"`
wait $RemovalPID
reboot

mapurcel
Contributor III

@acdesigntech can you elaborate on how your script works? do you run this after putting the SymantecRemoval.command onto the machine? thanks!

shoegazer
New Contributor

.

acdesigntech
Contributor II

yes you have to put the symantecremoval.command file on the Mac, then invoke it with the '-A' switch. it will tell the removal script to remove symantec from all attached drives.

nwiseman
Contributor

I think I must be missing something here. I've downloaded the latest removal tool and have it pkg in Casper. I'm able to run it in Self Service only to the point where think it kicks off the .command file. After that it hangs. I'm assuming that it's hanging, because it's expecting some input like what happens if you just run the .command file by double clicking it. I'm sure the answer is right in front of my face, but don't seem to see it. Any thoughts?

mapurcel
Contributor III

I put the .command file in a DMG, so that it gets dropped in the location of my choice on the machine, then use 'execute command' under Files and Processes in a JSS policy to run the script.

acdesigntech
Contributor II

I believe there are switches that you have to use, otherwise it will ask which drives to remove Symantec from. try using the '-A' switch I mentioned above.

roiegat
Contributor III

So I'm trying to package this uninstall command and having issues. Here's what I did:

1) Put it in a folder we keep our policies and scripts in on the machine locally.
2) Used a postinstall script to run the command :
cd <location of file>
SymantecRemovalTool.command -A

But what happens it goes into an endless loop with the following text:
" SymantecRemoval.command 7.0.34 **

WARNING: This script will remove all files and folders created by Symantec OS X products (except Symantec Adminstration Console for Macintosh files) and any files within those folders. Therefore, you will lose ALL files that reside in those folders, including any that you have created.

1 - Remove all Symantec files/folders.

2 - Quit. Do not remove any files.

Enter choice (1 or 2): "

I could run this manually and select 1 and it does the job nicely...but need to be able to automate it so it start and removes the files.

Also, have people had success with removing the file, and then installing a new version and then rebooting vs remove, reboot, install, reboot? Trying to minimize the reboots needed since we have filevault in play and would need to bypass it.

nessts
Valued Contributor II

you could just think about editing the script and hard code in choice 1.
you could look into expect scripting.
you could just write a script to do that same things that their tool is doing.

and yes you should probably reboot its going to be much more simple than figuring all the other pieces out that you have try to do. And since Symantec decided rebooting was the best solution you should heed their advice i think.

But why not just install the new version over the old version that i have been doing for years without issue.

roiegat
Contributor III

@nessts When we install it over the old version the apps don't seem to work. You click on them to open and they bounce in the dock for 5 seconds and then go away. Live Update is the only that actually works and seems to download the update - but the other apps won't open for us to verify that things installed correctly. Hence the uninstall and re-install method. If you have a fix for the apps not working, that would be even better.

nessts
Valued Contributor II

sorry @roiegat I have never seen that behavior. Of course I never jumped more than one version at a time, we kept up with the versions as we always needed the newest version.

Jae
New Contributor III

Hey I think i'm running into the issue with it trying to only look at the boot volume. Can some explain how to put in the -A parameter? I'm not the best at scripting but I have gone over the instructions for hours in their script and I still cannot make the change.

acdesigntech
Contributor II
SymantecRemoval.command -A

Jae
New Contributor III

Im pretty sure i'm doing this right, but maybe something has changed.

Once I run the PGK, self service says this:

7c870e2b96a04ede94f02b7d3e332888

it then just hangs there.

Jae
New Contributor III

@zmbarker Hey I found my issue here..

The link you have in the first post goes to a different command as the old one still exists under: [ftp://ftp.symantec.com/misc/tools/mactools/SymantecRemovalTool.zip](ftp://ftp.symantec.com/misc/tools/mactools/SymantecRemovalTool.zip)

This one does work correctly.

ardukes
New Contributor

I got the tool from https://support.symantec.com/en_US/article.TECH103489.html to work by creating a policy that installs a package that copies the RemoveSymantecMacFiles.command file to /private/tmp/ and in File and Processes - Execute Command:

echo 1 | /private/tmp/RemoveSymantecMacFiles.command

It'll pipe the 1 to the command and run automatically.

scottb
Honored Contributor

^^^ Thanks @ardukes - that is the ticket. Worked great.

tcandela
Valued Contributor II

I simple changed the file extension to .sh and then went to line 2090 and hard coded the case to "-A". I did this back on 6/3/15 and it has never had any problems uninstalling versions of SEP.

I have a smart group populated with macs running SEP 11.XXXXX I added this symantecremoval.sh script to a policy, policy runs once per-computer, scoped to this smart group. Never had an issue. runs the .sh straight through, no command entered if files and processes

I have a second policy that installs my updated version of SEP and I also install the SEP uninstaller.pkg with it.

grahamfw
New Contributor III

For anyone else who happens to try to run this script with Casper, I was able to get it to work by doing a few things:

  • Instead of reading the choice, comment it out and set it to "1" manually
       printf "Enter choice (1 or 2): "
    # read choice
    choice="1"
  • Comment out the if statement that makes you confirm you want to remove Symantec
    # if [ $RemoveFromAllVolumes = true -a $CreateFilesRemovedListOnly = false -a $RemoveCrontabEntriesOnly = false -a $RemoveInvisibleFilesOnly = false -a $AutoRunScript = false -a $RunningFromWithinAppBundleOrSupportFolder = false ] ; then
    #    echo
    #    printf "Are you sure you want to remove Symantec files from ALL mounted volumes (y/n)? "
    #    if YesEntered ; then
    #       echo
    #    else
    #       echo
    #       echo "Script aborted. No files were removed."
    #       ExitScript 0
    #    fi
    # fi
  • Comment out the section that asks to restart when the script is complete
    # if YesEntered ; then
    #          RestartAutomatically=true
    # fi
  • Change the all parameters argument $@ to be the home directory "/" instead:
    ProcessArguments --OptionIsOneArgument="-QQ" --OptionIsOneArgument="-re" "/"

Since any script run by the JSS passes parameters $1 through $3, we need to make sure they are not passed to a script not designed to run from the JSS.

Hope this helps someone! I spent more time than I'd like to admit on it.

rmacalpine
New Contributor II

Hey I have to say THANK YOU VERY MUCH as this worked for me. I wanted to use the more recent version of the Symantec script and your tweaks made it possible. I don't know how many people actually scroll all the way down here to read your post but I'm glad I did and I encourage anyone else getting this far to give this grahamfw suggestion a try.

mpebley
New Contributor III

Symantecs Tech Article for all this is here:
https://support.symantec.com/en_US/article.TECH103489.html

If you look at the bottom of the page, there is another script named SymantecRemovalTool.command that runs with no user input designed for ARD and of course casper

(ftp://ftp.symantec.com/misc/tools/mactools/SymantecRemovalTool.zip)

SymantecRemovalTool (ftp://ftp.symantec.com/misc/tools/mactools/SymantecRemovalTool.zip), a modification of RemoveSymantecMacFiles, is a script that is designed to be pushed out via Apple Remote Desktop. It requires no user input when run as root. As with RemoveSymantecMacFiles, all files and folders that Symantec OS X products (except Symantec Administration Console for Macintosh files) have created will be removed; therefore, you will lose all files that reside in those folders, including any that you have created. For more information, please see the Read Me file included with the SymantecRemovalTool download. SymantecRemovalTool is provided for your convenience only and is not a supported utility.

rderewianko
Valued Contributor II

Posted what @grahamfw did on a gist if anyone else needs it. Here

gachowski
Valued Contributor II

I used the 2nd script on the Symantec page, but it didn't work the 1st few times, Then I stole part grahamfw idea (Change the all parameters argument $@ to be the home directory "/" instead) and it worked on the 1st test.

Thanks @grahamfw

chris_kemp
Contributor III

Tried this today, but it doesn't seem to work anymore. :( For some reason it's throwing an error "Invalid option or volume name"...

ThijsX
Valued Contributor
Valued Contributor

Hi,

I also used the replace option with $@ to "/".
This did the trick for me !

Thanks!

Greetings,
Thijs

AHK
New Contributor

https://support.symantec.com/en_US/article.TECH103489.html

As you can read in the above article there are two versions of the script to remove Symantec files.
- One with user input - (RemoveSymantecMacFiles)
- One without user input - (SymantecRemovalTool)

Symantec suggests you use SymantecRemovalTool when using a remote deployment tool.

el2493
Contributor III

I tried doing this using the most recent SymantecRemovalTool and @grahamfw 's recommended tweaks. I saved the file as .sh, uploaded to JSS, created a Policy in JSS, and scoped it to a test computer. It seemed to run (had a spinning star at the bottom of the screen) and then rebooted the computer, but I found that if I looked in JSS logs after the reboot that it didn't seem to register that the policy had run. That's happened to me before if a script triggers a reboot without giving time for the script to pass information back to the JSS. From looking at the script it looks like what's triggering the restart is:

osascript -e 'tell application "System Events" to restart'

My test computer to 10.13.2. Did anyone need to change the above command (or add some sort of delay/pause) to get the JSS to register that it completed?

grahamfw
New Contributor III

@el2493 it is probably good to comment out any references to the restarting function RestartComputer. That's what is actually doing the restarting.

It is a best practice to let Jamf Pro do the rebooting as part of the policy. The script needs to send Jamf an exit code for the script to be deemed a success or failure, and if it sends nothing, Jamf assumes it didn't actually finish running yet (it eventually times out though).

Just set your policy to reboot automatically after commenting out the RestartComputer function calls and that should clear it up for you.

el2493
Contributor III

Thanks, still running into issues (still restarting while running the script). When you wrote:

Since any script run by the JSS passes parameters $1 through $3, we need to make sure they are not passed to a script not designed to run from the JSS.

...does that mean I need to make any changes to the script, or is that just generally useful information to keep in mind?

grahamfw
New Contributor III

@el2493 Yes, any script that you shoehorn into Jamf Pro will need to be edited to run successfully. Script parameters 1-3 (i.e. $1 $2 and $3) are passed when Jamf runs any script. If you catch it in flight, the actually see the script parameters running as part of the script.

Quick primer just in case you're not aware: in bash, script parameters are just arguments you run in addition to the script. If a script I run outside of Jamf is called updateUser.sh and script parameter $1 is the username I want to update, when I run it, I'll run it like this:

./updateUser.sh username

As such, Jamf runs each script with the second and third parameters including the user and computer name I believe.

Really, any script like this that you run from Jamf will need to have the parameters removed unless you know exactly what you're doing here.

el2493
Contributor III

Thanks again, I tried commenting out the entire RestartComputer function as well as the two times the script tries to invoke the function and it's still restarting when running the script. It's not doing the exact same thing (before there was a spinning star when the policy was running then it rebooted, now if I start the policy from the Terminal it starts running then the screen goes black then makes the startup sound). I also checked to make sure I definitely commented out the items that you mentioned.

Then I started from scratch with an unedited SymantecRemovalTool.sh and tried just replacing the "$@" instances with "/" (which a few people seemed to indicate was all they had to do) but it still restarted while running the script. If I look in jamf.log it shows as:

Executing Policy Symantec Uninstall
Daemon shutdown completed
Daemon exiting

Then tried commenting out RestartComputer invokations (toward the end of the script) and it still rebooted. Also went through the script and any time I saw $1, $2, or $3, I replaced it with $scriptVar1, $scriptVar2, or $scriptVar3 (hoping that would keep it from clashing with Jamf) but still restarts. I'm definitely aware that what I tried for that might not be the right thing, but I'd think that if it was just a matter of a variable not being assigned correctly then it would throw an error message and report the error back to JSS rather than doing a Daemon Shutdown. I saw what you wrote about updating the parameter to be an actual value (like username) but the Symantec script uses $1 for different things (at times it's for the volume, at other times it's the path of a directory or an exit code).

Plus after every Daemon shutdown it seems to not accurately pull recurring checkin policies, so I have to wait an hour before trying again.

Hopefully I'm just missing something obvious, I'd really like to use this since the alternative (based on the complexity of the script) is packaging (which doesn't work as well for logging in Jamf) or reimaging.