· 7 years ago · Jan 30, 2019, 06:28 PM
1#!/bin/sh
2# File Name: RemoveSymantecMacFiles.command
3 Version=7.0.61
4# Author: Corey Swertfager, Symantec Corporation
5# Created: 10/04/2001
6# Modified: 06/16/2017
7#
8# WARNING: This script will remove all files and folders created by
9# Symantec OS X products (except Symantec Adminstration Console
10# for Macintosh files) and any files within those folders.
11# Therefore, you will lose ALL files that reside in those folders,
12# including any that you have created.
13#
14# Usage: RemoveSymantecMacFiles.command [options] [volume ...]
15#
16# Summary: See ShowHelp() function.
17#
18# *** Variable Initializations ***
19
20PATH=/bin:/sbin:/usr/bin:/usr/sbin
21SymantecCleanupRestartFile="/private/tmp/com.symantec.cleanup.restart"
22AbbreviatedScriptName=`basename "$0" .command 2>/dev/null`
23AutoRunScript=false
24BackupLogLocationRootDirName="SymantecDiagnosticLogs"
25BackupLogLocationRootDir="/private/var/tmp/$BackupLogLocationRootDirName"
26CurrentVolumeBeingUsed="/"
27ExitCodeWhenSomeFileWasNotRemoved=0
28ExitCodeWhenFilesRemain=7
29# FilesThatDoNotRequireRebootPattern: paths that match this pattern will not trigger a reboot
30FilesThatDoNotRequireRebootPattern='\.log|\.txt|\.rtf|Caches/com.apple.helpd|/log/|/Logs/|/tmp/'
31FilesRemovedList="/private/tmp/${AbbreviatedScriptName}RemovesThese.txt"
32FilesRemovedFilesOnlyList="/private/tmp/${AbbreviatedScriptName}RemovesThese-FilesOnly.txt"
33FilesRemovedListOfOld="/Users/Shared/${AbbreviatedScriptName}RemovesThese.txt"
34FilesWereSaved=false
35FinishedExitCode=0
36FullScriptName=`basename "$0" 2>/dev/null`
37LANG=""
38LaunchLocationGrepPattern='/Library/Application Support/Symantec/Uninstaller\|\.app/Contents/Resources'
39# ----- ListOfProgramsThatShouldNotBackUpLogs BEGIN ------------------------------------------------
40ListOfProgramsThatShouldNotBackUpLogs="RemoveSymantecMacFiles.command
41SymantecRemovalTool
42SymantecRemovalTool.command"
43# ----- ListOfProgramsThatShouldNotBackUpLogs END --------------------------------------------------
44ListOfProgramsThatShouldNotKillProcesses="SymantecRemovalTool"
45ListOfProgramsThatShouldNotRemoveFSDFolders="SymantecRemovalTool"
46ListOfProgramsThatShouldNotRemoveInstallerLaunchAgents="SymantecRemovalTool"
47ListOfProgramsThatShouldNotRemoveLogs="SymantecRemovalTool"
48ListOfProgramsThatShouldNotRemoveSymantecIPUA="SymantecRemovalTool"
49LogFile="/private/tmp/${AbbreviatedScriptName}Log.txt"
50LogFileOfOld="/Users/Shared/${AbbreviatedScriptName}Log.txt"
51# ----- LoginKeychainPasswordsToDelete BEGIN ------------------------------------------------
52# (2 fields, tab delimited):
53# Item to delete / help text to show
54LoginKeychainPasswordsToDelete="com.norton.NFM.auth Norton Internet Security account info
55com.norton.mexico.auth Norton Zone saved sessions"
56# ----- LoginKeychainPasswordsToDelete END --------------------------------------------------
57LogsToBackUpPattern="/Logs/"
58LogsToNotBackUpPattern="SymantecTestPatchers\.log"
59# ----- NotRemovedByNIS6Uninstaller BEGIN ------------------------------------------------
60# A list of paths or partial paths that aren't removed by NIS 6 uninstaller.
61# Add only items that cannot be isolated by the -u option.
62NotRemovedByNIS6Uninstaller='/com.symantec.errorreporting.
63/etc/liveupdate.conf'
64# ----- NotRemovedByNIS6Uninstaller END --------------------------------------------------
65NotRemovedByNIS6UninstallerText=" [should not be removed by NIS 6 uninstaller]"
66# ----- NotRemovedBySymantecUninstaller BEGIN ------------------------------------------------
67# A list of paths or partial paths that aren't removed by Symantec Uninstaller.app.
68# Add only items that cannot be isolated by the -u option.
69NotRemovedBySymantecUninstaller='/Library/LaunchAgents/com.symantec.SCSInstaller.plist
70/Library/LaunchDaemons/com.symantec.nis.uninstall.plist
71/Library/LaunchDaemons/com.symantec.NWPService.plist
72/Library/Logs/SymantecTestPatchers.log
73/Library/Preferences/com.norton.WiFiPrivacy.plist
74/Library/Preferences/com.symantec.antivirus.special.plist'
75# ----- NotRemovedBySymantecUninstaller END --------------------------------------------------
76NotRemovedBySymantecUninstallerText=" [should not be removed by Symantec Uninstaller.app]"
77PrivateLinksPattern='^/etc/|^/tmp/|^/var/'
78PrivateDirectoriesPattern='^/private/etc/|^/private/tmp/|^/private/var/'
79PublicVersion=true
80# ----- ReceiptsTable BEGIN ------------------------------------------------
81# (2 fields, tab delimited):
82# Receipt name / Receipt option (-a = delete receipt*, -s = skip run of predelete script)
83ReceiptsTable='
84# Check to make sure there are no vague receipts that may be used by
85# third party software before releasing to the public.
86# This line may need to be removed to avoid deleting third party files:
87CompatibilityCheck.pkg
88# This line may need to be removed to avoid deleting third party files:
89Decomposer.pkg
90# This line may need to be removed to avoid deleting third party files:
91DeletionTracking.pkg
92FileSaver.pkg
93LiveUpdate -a
94NATRemoteLock.pkg
95NATSDPlugin.pkg
96NAVContextualMenu.pkg
97NAVcorporate.pkg
98NAVDefs.pkg
99NAVEngine.pkg
100NAVWidget.pkg
101navx.pkg
102NAV_App -a
103NAV_AutoProtect -a
104NFSCore.pkg
105NISLaunch.pkg
106Norton AntiVirus Application.pkg
107Norton AntiVirus Product Log.rtf
108Norton AntiVirus.pkg
109Norton AutoProtect.pkg
110Norton Disk Editor X.pkg
111Norton Internet Security Log.rtf
112Norton Personal Firewall 3.0 Log.rtf
113Norton Scheduled Scans.pkg
114Norton Scheduler.pkg
115Norton SystemWorks 3.0 Log.rtf
116Norton Utilities 8.0 Log.rtf
117nortonanti-theftPostflight.pkg
118nortonantitheftPostflight.pkg
119NortonAutoProtect.pkg
120# Remove all NortonAVDefs receipts
121NortonAVDefs -a
122NortonDefragger.pkg
123NortonDiskDoctor.pkg
124NortonFirewall -a
125NortonInternetSecurity -a
126NortonLauncher.pkg
127NortonParentalControl.pkg
128NortonPersonalFirewall.pkg
129NortonPersonalFirewallMenu.pkg
130NortonPrivacyControl.pkg
131NortonQuickMenu -a
132NPC Installer Log
133NPC.pkg
134NSMCore.pkg
135NSMCore.Universal.pkg
136NSWLaunch.pkg
137NUMCompatibilityCheck.pkg
138NumDocs.pkg
139NUMLaunch.pkg
140PredeleteTool.pkg
141SavLog.pkg
142# This line may need to be removed to avoid deleting third party files:
143Scheduled Scans.pkg
144# This line may need to be removed to avoid deleting third party files:
145Scheduler.pkg
146SDProfileEditor.pkg
147SMC.pkg
148SNAC.pkg
149SpeedDisk.pkg
150# NAV 9 installs the StuffIt engine if it needs to and creates the
151# StuffIt.pkg receipt for it. The following line may need to be removed
152# (but should not need to be) to avoid deleting third party files:
153StuffIt.pkg
154Symantec Alerts.pkg
155Symantec AntiVirus.pkg
156Symantec AutoProtect Prefs.pkg
157Symantec AutoProtect.pkg
158Symantec Decomposer.pkg
159Symantec Endpoint Protection.pkg
160Symantec Scheduled Scans.pkg
161Symantec Scheduler.pkg
162# Remove all SymantecAVDefs receipts
163SymantecAVDefs -a
164SymantecClientFirewall.pkg
165SymantecDecomposer.pkg
166SymantecDeepSightExtractor.pkg
167SymantecParentalControl.pkg
168SymantecQuickMenu.pkg
169SymantecSAQuickMenu.pkg
170SymantecSharedComponents -a
171SymantecUninstaller -a
172SymantecURLs.pkg
173SymAV10StuffItInstall.pkg
174SymAVScanServer.pkg
175SymConfidential -a
176SymConfidentialData.pkg
177SymDaemon -a
178SymDC.pkg
179SymDiskMountNotify.pkg
180SymErrorReporting.pkg
181SymEvent.pkg
182SymFileSecurity -a
183SymFirewall -a
184SymFS.pkg
185SymHelper.pkg
186SymHelpScripts.pkg
187SymInstallExtras.pkg
188SymInternetSecurity.pkg
189SymIntrusionPrevention -a
190SymIPS.pkg
191SymLicensing -a
192SymNCOApplication -a
193SymOxygen.pkg
194SymOSXKernelUtilities.pkg
195SymPersonalFirewallCore -a
196SymPersonalFirewallUI -a
197SymProtector.pkg
198SymPseudoLicensing -a
199SymSetupAssistant -a
200SymSharedFrameworks -a
201SymSharedSettings -a
202SymStuffit.pkg
203SymSubmission.pkg
204SymUIAgent -a
205SymWebFraud -a
206SymWebKitUtils.pkg
207Unerase.pkg
208# This line may need to be removed to avoid deleting third party files:
209URL.pkg
210VolumeAssist.pkg
211VolumeRecover.pkg
212WCIDEngine.pkg
213Wipe Info.pkg
214ZoneStandalone.pkg
215'
216# ----- ReceiptsTable END --------------------------------------------------
217# ----- RequiredPrograms BEGIN ------------------------------------------------
218RequiredPrograms='
219awk
220basename
221cat
222cd
223chmod
224cp
225crontab
226date
227defaults
228dirname
229echo
230egrep
231expr
232find
233grep
234head
235kill
236ls
237mkdir
238more
239printf
240ps
241pwd
242read
243rm
244sed
245sort
246sudo
247tail
248tr
249uniq
250'
251# ----- RequiredPrograms END --------------------------------------------------
252SavedFilesDir="/private/tmp/${AbbreviatedScriptName}SavedFiles"
253
254# *** Function Declarations ***
255
256AssignVolume()
257{
258 # Usage: AssignVolume $1
259 # Argument: $1 = Volume name. The name can begin with "/Volumes/"
260 # unless it is "/" (boot volume).
261 # Summary: Assigns the name of the volume passed as $1 to VolumesToUse.
262 # If volume is assigned, 0 is returned; else, 1 is returned.
263 #
264 # If nothing passed, skip assignment
265 [ -z "$1" ] && return 1
266 VolumeToAssign=`CheckIfValidVolume "$1"`
267 if [ -z "$VolumeToAssign" ] ; then
268 VolumeToAssign=`CheckIfValidVolume "/Volumes/$1"`
269 [ -z "$VolumeToAssign" ] && return 1
270 fi
271 [ "$VolumeToAssign" = "/" ] && BootVolumeWillBeSearched=true
272 VolumesToUse="$VolumesToUse
273$VolumeToAssign"
274 return 0
275}
276
277BackupLog()
278{
279 # Usage: BackupLog file
280 # Summary: Copies file into BackupLogLocationDir.
281 # BackupLogLocationDir must be defined prior
282 # to running this function.
283 #
284 local FileToBackUp="$1"
285 local BackupNumber=0
286 FileToBackupBase=`basename "$FileToBackUp"`
287 local DestinationFileName
288 if ! $DoBackupLogs ; then
289 return
290 elif [ ! -f "$FileToBackUp" ] ; then
291 return
292 # Else if this is not a file that should be backed up
293 elif [ -z "`printf "%s" "$FileToBackUp" | egrep -ie "$LogsToBackUpPattern" | egrep -ive "$LogsToNotBackUpPattern"`" ] ; then
294 return
295 fi
296 if [ ! -d "$BackupLogLocationDir" ] ; then
297 mkdir -p "$BackupLogLocationDir"
298 chmod 777 "$BackupLogLocationDir" "$BackupLogLocationRootDir"
299 fi
300 DestinationFileName="$FileToBackupBase"
301 while [ -f "$BackupLogLocationDir/$DestinationFileName" ] ; do
302 let BackupNumber=$BackupNumber+1
303 # If file name contains a period with a character on each side and no other periods
304 if [ "`printf "%s" "$FileToBackupBase" | grep -e '.\..' | grep -ve '\..*\.'`" ] ; then
305 DestinationFileName=`printf "%s" "$FileToBackupBase" | awk -v NUM="$BackupNumber" '{
306 # Put hyphen + NUM in front of the period
307 sub("\\\.", "-" NUM ".", $0)
308 print $0}'`
309 else
310 # Put hyphen + NUM at end of the file name
311 DestinationFileName="$FileToBackupBase-$BackupNumber"
312 fi
313 done
314 ditto "$FileToBackUp" "$BackupLogLocationDir/$DestinationFileName"
315 chmod 666 "$BackupLogLocationDir/$DestinationFileName"
316}
317
318CheckIfValidVolume()
319{
320 # Usage: CheckIfValidVolume volume
321 # Summary: If volume is a valid volume path, the path, with extra
322 # slashes removed, is written to standard output.
323 #
324 local PathToPrint=""
325 local VolumePathToCheck="$1"
326 # If VolumePathToCheck is the boot volume
327 if [ "$VolumePathToCheck" -ef / ] ; then
328 PathToPrint=/
329 # Else if VolumePathToCheck begins with /
330 elif [ "`printf "%s" "$VolumePathToCheck" | grep '^/'`" ] ; then
331 # If it is a directory and not a link
332 if [ -d "$VolumePathToCheck" -a ! -L "$VolumePathToCheck" ] ; then
333 # Strip any extra slashes
334 VolumePathToCheck=`printf "%s" "$VolumePathToCheck" | sed 's|//*|/|g'`
335 if [ "`dirname "$VolumePathToCheck"`" = "/Volumes" ] ; then
336 PathToPrint="/Volumes/`basename "$VolumePathToCheck"`"
337 fi
338 fi
339 fi
340 [ "$PathToPrint" ] && echo "$PathToPrint"
341}
342
343DeleteCrontabEntries()
344{
345 # Usage: DeleteCrontabEntries [$1]
346 # Argument: $1 = Volume name. The name should begin with "/Volumes/"
347 # unless it is "/" (boot volume). If NULL, then / is
348 # used as volume name.
349 # Authors: John Hansen, Corey Swertfager
350 # Summary: Deletes from / or volume specified the crontab entries
351 # created by Norton Scheduler and Symantec Scheduler.
352 # Note: User must be root when calling this function.
353 #
354 if [ "z$1" = z/ ] ; then
355 VolumeToDeleteCrontabsFrom=""
356 else
357 VolumeToDeleteCrontabsFrom="$1"
358 fi
359 CRONDIRNEW="$VolumeToDeleteCrontabsFrom/private/var/at/tabs" # OS 10.5 and later crontab directory
360 CRONDIROLD="$VolumeToDeleteCrontabsFrom/private/var/cron/tabs" # OS 10.4 and earlier crontab directory
361 if [ ! -d "$CRONDIRNEW" -a ! -d "$CRONDIROLD" ] ; then
362 if $CreateFilesRemovedListOnly ; then
363 if [ -z "$VolumeToDeleteCrontabsFrom" ] ; then
364 echo "No crontab directory was found on on the current boot volume." >> "$FilesRemovedList"
365 else
366 echo "No crontab directory was found on on the volume \"`basename "$VolumeToDeleteCrontabsFrom"`\"." >> "$FilesRemovedList"
367 fi
368 echo "" >> "$FilesRemovedList"
369 else
370 if [ -z "$VolumeToDeleteCrontabsFrom" ] ; then
371 echo "No crontab directory was found on on the current boot volume."
372 else
373 echo "No crontab directory was found on on the volume \"`basename "$VolumeToDeleteCrontabsFrom"`\"."
374 fi
375 fi
376 return 1
377 fi
378 TEMPFILETEMPLATE="/private/tmp/NortonTemp"
379 GREP1="^#SqzS"
380 GREP2="^#SYMANTEC SCHEDULER CRON ENTRIES"
381 GREP3="^#PLEASE DO NOT EDIT\.$"
382 GREP4="EvType1=.*EvType2=.*Sched="
383 GREP5="Norton Solutions Support/Scheduler/schedLauncher"
384 GREP6="Symantec/Scheduler/SymSecondaryLaunch.app/Contents/schedLauncher"
385 SymantecCrontabEntryExists=false
386 CurrentDir="`pwd`" # Save initial directory location
387 # Set IFS to only newline to get all crontabs
388 IFS='
389'
390 for CRONDIR in `ls -d "$CRONDIRNEW" "$CRONDIROLD" 2>/dev/null` ; do
391 cd "$CRONDIR"
392 # List each crontab, pipe through grep command and replace
393 for user in $ComputerUsers ; do
394 # If there is no crontab file for this user, skip user
395 [ ! -f "$user" ] && continue
396 # If deleting from boot volume
397 if [ -z "$VolumeToDeleteCrontabsFrom" ] ; then
398 # Check to see if there is a Symantec crontab entry
399 if [ "`crontab -u "$user" -l | grep -c "$GREP1\|$GREP2\|$GREP3\|$GREP4\|$GREP5\|$GREP6"`" != 0 ] ; then
400 SymantecCrontabEntryExists=true
401 else
402 continue # Nothing to remove, skip user
403 fi
404 $CreateFilesRemovedListOnly && break
405 TEMPFILE="$TEMPFILETEMPLATE`date +"%Y%m%d%H%M%S"`"
406 crontab -u "$user" -l | grep -v "$GREP1\|$GREP2\|$GREP3\|$GREP4\|$GREP5\|$GREP6" > $TEMPFILE
407 # Restore crontab file if it has more entries, else remove
408 if [ -s "$TEMPFILE" ] ; then
409 crontab -u "$user" $TEMPFILE &>/dev/null
410 else
411 echo "y" | crontab -u "$user" -r &>/dev/null
412 fi
413 else
414 # Check to see if there is a Symantec crontab entry
415 if [ "`grep -c "$GREP1\|$GREP2\|$GREP3\|$GREP4\|$GREP5\|$GREP6" "$user"`" != 0 ] ; then
416 SymantecCrontabEntryExists=true
417 else
418 continue # Nothing to remove, skip user
419 fi
420 $CreateFilesRemovedListOnly && break
421 TEMPFILE="$TEMPFILETEMPLATE`date +"%Y%m%d%H%M%S"`"
422 grep -v "$GREP1\|$GREP2\|$GREP3\|$GREP4\|$GREP5\|$GREP6" "$user" > $TEMPFILE
423 # Restore crontab file if it has more entries, else remove
424 if [ -s "$TEMPFILE" ] ; then
425 cat $TEMPFILE >"$user"
426 else
427 rm -f "$user" 2>/dev/null
428 fi
429 fi
430 /bin/rm "$TEMPFILE" 2>/dev/null
431 done
432 [ $CreateFilesRemovedListOnly = true -a $SymantecCrontabEntryExists = true ] && break
433 done
434 cd "$CurrentDir" # Return to intial directory
435 if $SymantecCrontabEntryExists ; then
436 if $CreateFilesRemovedListOnly ; then
437 if [ -z "$VolumeToDeleteCrontabsFrom" ] ; then
438 echo "Symantec crontab entries would be deleted from the current boot volume." >> "$FilesRemovedList"
439 else
440 echo "Symantec crontab entries would be deleted from the volume" >> "$FilesRemovedList"
441 echo "\"`basename "$VolumeToDeleteCrontabsFrom"`\"." >> "$FilesRemovedList"
442 fi
443 echo "" >> "$FilesRemovedList"
444 else
445 if [ -z "$VolumeToDeleteCrontabsFrom" ] ; then
446 echo "Symantec crontab entries were deleted from the current boot volume."
447 else
448 echo "Symantec crontab entries were deleted from the volume"
449 echo "\"`basename "$VolumeToDeleteCrontabsFrom"`\"."
450 fi
451 fi
452 NoFilesToRemove=false
453 else
454 if $CreateFilesRemovedListOnly ; then
455 if [ -z "$VolumeToDeleteCrontabsFrom" ] ; then
456 echo "There are no Symantec crontab entries on the current boot volume;" >> "$FilesRemovedList"
457 echo "no crontab entries would be removed from it." >> "$FilesRemovedList"
458 else
459 echo "There are no Symantec crontab entries on the volume \"`basename "$VolumeToDeleteCrontabsFrom"`\";" >> "$FilesRemovedList"
460 echo "no crontabs would be adjusted on that volume." >> "$FilesRemovedList"
461 fi
462 echo "" >> "$FilesRemovedList"
463 elif [ -z "$VolumeToDeleteCrontabsFrom" ] ; then
464 echo "There are no Symantec crontab entries to delete from the current boot volume."
465 else
466 echo "There are no Symantec crontab entries to delete from the volume"
467 echo "\"`basename "$VolumeToDeleteCrontabsFrom"`\"."
468 fi
469 fi
470 return 0
471}
472
473DeleteLaunchdPlists()
474{
475 # Usage: DeleteLaunchdPlists [$1]
476 # Argument: $1 = Volume name. The name should begin with "/Volumes/"
477 # unless it is "/" (boot volume). If NULL, then / is
478 # used as volume name.
479 # Summary: Deletes from / or volume specified the launchd plists
480 # created by Symantec Scheduler.
481 # Note: User must be root when calling this function.
482 #
483 if [ "z$1" = z/ ] ; then
484 VolumeToDeleteLaunchdPlistsFrom=""
485 else
486 VolumeToDeleteLaunchdPlistsFrom="$1"
487 fi
488 LaunchdPlists=`ls -d "$VolumeToDeleteLaunchdPlistsFrom/Library/LaunchDaemons/com.symantec.Sched"*.plist 2>/dev/null`
489 if [ "$LaunchdPlists" ] ; then
490 if $CreateFilesRemovedListOnly ; then
491 if [ -z "$VolumeToDeleteLaunchdPlistsFrom" ] ; then
492 echo "Symantec Scheduler launchd plists would be deleted from the current boot volume." >> "$FilesRemovedList"
493 else
494 echo "Symantec Scheduler launchd plists would be deleted from the volume" >> "$FilesRemovedList"
495 echo "\"`basename "$VolumeToDeleteLaunchdPlistsFrom"`\"." >> "$FilesRemovedList"
496 fi
497 echo "" >> "$FilesRemovedList"
498 else
499 IFS='
500'
501 for EachPlist in $LaunchdPlists ; do
502 rm -f "$EachPlist" 2>/dev/null
503 done
504 if [ -z "$VolumeToDeleteLaunchdPlistsFrom" ] ; then
505 echo "Symantec Scheduler launchd plists were deleted from the current boot volume."
506 else
507 echo "Symantec Scheduler launchd plists were deleted from the volume"
508 echo "\"`basename "$VolumeToDeleteLaunchdPlistsFrom"`\"."
509 fi
510 fi
511 NoFilesToRemove=false
512 else
513 if $CreateFilesRemovedListOnly ; then
514 if [ -z "$VolumeToDeleteLaunchdPlistsFrom" ] ; then
515 echo "There are no Symantec Scheduler launchd plists on the current boot volume," >> "$FilesRemovedList"
516 echo "so none would be removed from it." >> "$FilesRemovedList"
517 else
518 echo "There are no Symantec Scheduler launchd plists on the volume" >> "$FilesRemovedList"
519 echo "\"`basename "$VolumeToDeleteLaunchdPlistsFrom"`\", so none would be removed from it." >> "$FilesRemovedList"
520 fi
521 echo "" >> "$FilesRemovedList"
522 elif [ -z "$VolumeToDeleteLaunchdPlistsFrom" ] ; then
523 echo "There are no Symantec Scheduler launchd plists to delete from the current boot"
524 echo "volume."
525 else
526 echo "There are no Symantec Scheduler launchd plists to delete from the volume"
527 echo "\"`basename "$VolumeToDeleteLaunchdPlistsFrom"`\"."
528 fi
529 fi
530 return 0
531}
532
533DeleteSymantecLoginItems()
534{
535 # Usage: DeleteSymantecLoginItems [volume]
536 #
537 # Argument: volume - volume from which to remove login items; volume must
538 # begin with "/Volumes/" unless it is "/" (boot volume); if
539 # nothing is passed, / is assumed.
540 #
541 # Summary: Deletes Symantec items from all com.apple.loginitems.plist and
542 # loginwindow.plist files on volume specified.
543 #
544 # If a file is purged on the boot volume, file path defined by
545 # SymantecCleanupRestartFile is created so that reboot messaging
546 # can be displayed by scripts that use this function.
547 #
548 # Returns: The number of files purged.
549 #
550 # Note: If this function is run while booted in OS 10.1.x, it will
551 # not be able to adjust loginwindow.plist files on an OS 10.4
552 # or later volume because plutil did not ship with OS 10.1.x.
553 #
554 # The com.apple.loginitems.plist files are not purged if
555 # /usr/libexec/PlistBuddy does not exist (PlistBuddy first
556 # appeared in OS 10.5).
557 #
558 # GetComputerUsers() function must be run before calling this
559 # function so that ComputerUsersHomeDirsAndRootDir is defined.
560 #
561 # CreateFilesRemovedListOnly and FilesRemovedList variables are
562 # used only in Norton Cleanup scripts.
563 #
564 # Version: 3.0.2
565 #
566 local ArrayItem
567 local Base
568 local Buffer
569 local CheckSyntax
570 local CreateFilesRemovedListOnly="$CreateFilesRemovedListOnly"
571 local Line
572 local NameKeyValue
573 local NumberOfFilesPurged=0
574 local OriginalPlistFile
575 local PatternOfKeyNames="Norton WiFi Privacy\.app"
576 local PatternOfKeyNamesToExclude="Norton Solutions|Symantec|SymSecondaryLaunch|Norton"
577 local PlistBuddyError
578 local PropertyKeyToUse
579 local SavedIFS="$IFS"
580 local StartupPathPatterns="/Applications/Norton AntiVirus.app
581/Applications/Norton Internet Security.app
582/Applications/Norton Security.app
583/Applications/Symantec Cloud Security.app
584/Applications/Symantec Unified Endpoint Protection.app
585/Library/Application Support/Norton Solutions
586/Library/Application Support/Symantec
587/Library/StartupItems/Norton
588/Norton Zone.app
589/Scheduler/SymSecondaryLaunch.app
590Norton WiFi Privacy"
591 local SymantecLoginItemsWereFound=false
592 local SymantecLoginItemWasFound
593 local TargetVolume="$1"
594 local TempFileTemplate=/private/tmp/Delete_Symantec_Login_Items
595 local TempScrapFile=${TempFileTemplate}`date +"%Y%m%d%H%M%S"`-Scrap
596 local TempPlistFile=${TempFileTemplate}`date +"%Y%m%d%H%M%S"`-PlistCopy
597 [ "$1" -ef / ] && TargetVolume=""
598 [ "z$CreateFilesRemovedListOnly" != ztrue -o ! -f "$FilesRemovedList" ] && CreateFilesRemovedListOnly=false
599 [ -z "$SymantecCleanupRestartFile" ] && SymantecCleanupRestartFile="/private/tmp/com.symantec.cleanup.restart"
600 which plutil &>/dev/null
601 # If plutil program is not installed
602 if [ $? != 0 ] ; then
603 # If running OS 10.4 or later
604 if [ $OSXmajorVersion -gt 3 ] ; then
605 # Show message and skip plist adjustments because plists are in binary format in OS 10.4 and later
606 if $CreateFilesRemovedListOnly ; then
607 echo "NOTE: plutil is not installed, so loginwindow.plist files cannot be adjusted." >> "$FilesRemovedList"
608 else
609 echo "NOTE: plutil is not installed, so loginwindow.plist files cannot be adjusted."
610 fi
611 return
612 fi
613 fi
614 IFS='
615'
616 for Line in $StartupPathPatterns ; do
617 Base=`basename "$Line" .app`
618 if [ -z "`echo "$Base" | egrep -xe "$PatternOfKeyNamesToExclude"`" ] ; then
619 PatternOfKeyNames="${PatternOfKeyNames}|$Base"
620 fi
621 done
622 # Remove login items from loginwindow.plist files
623 for EachHomeDir in $ComputerUsersHomeDirsAndRootDir ; do
624 if [ "$EachHomeDir" = / ] ; then
625 OriginalPlistFile="$TargetVolume/Library/Preferences/loginwindow.plist"
626 else
627 OriginalPlistFile="$TargetVolume$EachHomeDir/Library/Preferences/loginwindow.plist"
628 fi
629 [ ! -f "$OriginalPlistFile" ] && continue
630 rm -rf "$TempPlistFile" 2>/dev/null
631 cp "$OriginalPlistFile" "$TempPlistFile"
632 CheckSyntax=true
633 plutil -convert xml1 "$TempPlistFile" 2>/dev/null
634 # If plutil failed to convert the plist, don't check syntax later
635 [ $? != 0 ] && CheckSyntax=false
636 IsBinaryFormat=false
637 # If original plist is different than converted plist, treat it as a binary file
638 [ -n "`diff "$OriginalPlistFile" "$TempPlistFile" 2>/dev/null`" ] && IsBinaryFormat=true
639 # If no Symantec login item was found, skip to next file
640 [ `grep -c -F "$StartupPathPatterns" "$TempPlistFile"` = 0 ] && continue
641 SymantecLoginItemsWereFound=true
642 if $CreateFilesRemovedListOnly ; then
643 echo "Symantec login items would be removed from:" >> "$FilesRemovedList"
644 echo " \"$OriginalPlistFile\"" >> "$FilesRemovedList"
645 continue
646 fi
647 # Purge Symantec login item(s)
648 printf "" > "$TempScrapFile"
649 Buffer=""
650 DoWriteBuffer=true
651 for Line in `cat "$TempPlistFile"` ; do
652 # If beginning of a dictionary key
653 if [ "`printf "%s" "$Line" | grep '<dict>$'`" ] ; then
654 [ "$Buffer" ] && echo "$Buffer" >> "$TempScrapFile"
655 Buffer="$Line"
656 DoWriteBuffer=true
657 else
658 if [ "$Buffer" ] ; then
659 Buffer="$Buffer
660$Line"
661 else
662 Buffer="$Line"
663 fi
664 # If end of a dictionary key
665 if [ "`printf "%s" "$Line" | grep '</dict>$'`" ] ; then
666 $DoWriteBuffer && echo "$Buffer" >> "$TempScrapFile"
667 Buffer=""
668 DoWriteBuffer=true
669 # Else if Symantec path was found
670 elif [ "`printf "%s" "$Line" | grep -F "$StartupPathPatterns"`" ] ; then
671 DoWriteBuffer=false
672 fi
673 fi
674 done
675 [ "$Buffer" ] && echo "$Buffer" >> "$TempScrapFile"
676 # If some login item information is missing
677 if [ `grep -c '<dict>$' "$TempScrapFile"` != `grep -c '</dict>$' "$TempScrapFile"` ] ; then
678 echo "ERROR: Could not remove Symantec login items from:"
679 echo " $OriginalPlistFile"
680 # Else if syntax is to be checked and plist contains bad syntax
681 elif [ $CheckSyntax = true -a -n "`plutil -s "$TempScrapFile" 2>/dev/null`" ] ; then
682 echo "ERROR: Could not remove Symantec login items (plutil conversion failed) from:"
683 echo " $OriginalPlistFile"
684 else
685 echo "Removing Symantec login items from:"
686 echo " \"$OriginalPlistFile\""
687 cat "$TempScrapFile" > "$OriginalPlistFile"
688 $IsBinaryFormat && plutil -convert binary1 "$OriginalPlistFile" 2>/dev/null
689 let NumberOfFilesPurged=$NumberOfFilesPurged+1
690 fi
691 done
692 rm -f "$TempScrapFile" 2>/dev/null
693 # Remove login items from com.apple.loginitems.plist files if PlistBuddy is installed
694 if [ -f /usr/libexec/PlistBuddy ] ; then
695 for EachHomeDir in $ComputerUsersHomeDirsAndRootDir ; do
696 if [ "$EachHomeDir" = / ] ; then
697 OriginalPlistFile="$TargetVolume/Library/Preferences/com.apple.loginitems.plist"
698 else
699 OriginalPlistFile="$TargetVolume$EachHomeDir/Library/Preferences/com.apple.loginitems.plist"
700 fi
701 [ ! -f "$OriginalPlistFile" ] && continue
702 rm -rf "$TempPlistFile" 2>/dev/null
703 cp "$OriginalPlistFile" "$TempPlistFile"
704 PropertyKeyToUse=':privilegedlist:CustomListItems'
705 NameKeyValue=`/usr/libexec/PlistBuddy "$TempPlistFile" -c "print ${PropertyKeyToUse}:0:Name" 2>/dev/null`
706 if [ -z "$NameKeyValue" ] ; then
707 PropertyKeyToUse=':SessionItems:CustomListItems'
708 NameKeyValue=`/usr/libexec/PlistBuddy "$TempPlistFile" -c "print ${PropertyKeyToUse}:0:Name" 2>/dev/null`
709 [ -z "$NameKeyValue" ] && continue
710 fi
711 PlistBuddyError=0
712 SymantecLoginItemWasFound=false
713 ArrayItem=0
714 while [ "$NameKeyValue" ] ; do
715 # If this is a Symantec login item that should be deleted
716 if [ "`printf "%s" "$NameKeyValue" | egrep -xe "$PatternOfKeyNames"`" ] ; then
717 SymantecLoginItemWasFound=true
718 $CreateFilesRemovedListOnly && break
719 /usr/libexec/PlistBuddy "$TempPlistFile" -c "delete ${PropertyKeyToUse}:$ArrayItem" 2>/dev/null
720 PlistBuddyError=$?
721 [ $PlistBuddyError != 0 ] && break
722 else
723 let ArrayItem=$ArrayItem+1
724 fi
725 NameKeyValue=`/usr/libexec/PlistBuddy "$TempPlistFile" -c "print ${PropertyKeyToUse}:$ArrayItem:Name" 2>/dev/null`
726 done
727 $SymantecLoginItemWasFound && SymantecLoginItemsWereFound=true
728 if $CreateFilesRemovedListOnly ; then
729 if $SymantecLoginItemWasFound ; then
730 echo "Symantec login items would be removed from:" >> "$FilesRemovedList"
731 echo " \"$OriginalPlistFile\"" >> "$FilesRemovedList"
732 fi
733 # Else if some login item could not be deleted
734 elif [ $PlistBuddyError != 0 ] ; then
735 echo "ERROR: Could not remove Symantec login items from:"
736 echo " $OriginalPlistFile"
737 elif $SymantecLoginItemWasFound ; then
738 echo "Removing Symantec login items from:"
739 echo " \"$OriginalPlistFile\""
740 cp "$TempPlistFile" "$OriginalPlistFile"
741 let NumberOfFilesPurged=$NumberOfFilesPurged+1
742 fi
743 done
744 fi
745 rm -f "$TempPlistFile" 2>/dev/null
746 if ! $SymantecLoginItemsWereFound ; then
747 if $CreateFilesRemovedListOnly ; then
748 echo "No Symantec login items were found." >> "$FilesRemovedList"
749 else
750 echo "No Symantec login items were found."
751 fi
752 fi
753 $CreateFilesRemovedListOnly && echo "" >> "$FilesRemovedList"
754 # If some Symantec items were purged from files on boot volume, trigger restart
755 [ $NumberOfFilesPurged -gt 0 -a -z "$TargetVolume" ] && touch "$SymantecCleanupRestartFile"
756 IFS="$SavedIFS"
757 return $NumberOfFilesPurged
758}
759
760DetermineAction()
761{
762 # Usage: DetermineAction
763 # Summary: Determines which action to take based on user input.
764 #
765 clear
766 echo
767 ShowVersion
768 echo "
769WARNING: This script will remove all files and folders created by Symantec
770 OS X products (except Symantec Adminstration Console for Macintosh
771 files) and any files within those folders. Therefore, you will
772 lose ALL files that reside in those folders, including any that
773 you have created.
774"
775 echo "1 - Remove all Symantec files/folders."
776 echo
777 echo "2 - Quit. Do not remove any files."
778 echo
779 printf "Enter choice (1 or 2): "
780 choice=1
781 echo
782 case "`echo "z$choice" | awk '{print tolower(substr($0,2))}'`" in
783 1) # Remove files
784 CreateFilesRemovedListOnly=false
785 ;;
786 2|q|quit) # Quit
787 echo "Program cancelled. No files were removed."
788 ExitScript 0
789 ;;
790 *) # Show choices again
791 DetermineAction
792 ;;
793 esac
794}
795
796DisableBrowserExtensionHostAssignment()
797{
798 # Usage: DisableBrowserExtensionHostAssignment
799 # Summary: Comments out browser extension host assignment in /etc/hosts.
800 #
801 local BrowserExtensionHost="macplugin.norton.com"
802 local BrowserExtensionHostPattern=`echo "$BrowserExtensionHost" | sed 's/\./\\\./g'`
803 local BrowserExtensionHostCommentedOutPattern
804 local HostsContent=""
805 local HostsFile="/etc/hosts"
806 local Line
807 BrowserExtensionHostPattern="[[:space:]]$BrowserExtensionHostPattern[[:space:][:cntrl:]]*$"
808 BrowserExtensionHostCommentedOutPattern="^[[:space:]]*#.*$BrowserExtensionHostPattern"
809 # If host assignment was found in hosts file that wasn't already commented out
810 if [ "`grep "$HostsFile" -e "$BrowserExtensionHostPattern" 2>/dev/null | egrep -ve "$BrowserExtensionHostCommentedOutPattern"`" ] ; then
811 echo "Commenting out $BrowserExtensionHost host assignment in $HostsFile"
812 for Line in `cat "$HostsFile" 2>/dev/null` ; do
813 # If line is a host assignment that has not been commented out
814 if [ "`printf "%s" "$Line" | egrep -e "$BrowserExtensionHostPattern" | egrep -ve "$BrowserExtensionHostCommentedOutPattern"`" ] ; then
815 # Comment it out
816 HostsContent="$HostsContent
817#$Line"
818 else
819 # Leave it as is
820 HostsContent="$HostsContent
821$Line"
822 fi
823 done
824 echo "$HostsContent" | grep . > "$HostsFile"
825 fi
826}
827
828ExitScript()
829{
830 # Usage: ExitScript [-b] [-e] [exit_number [error_string]]
831 # Summary: Checks to see if ShowQuitMessage and RunScriptAsStandAlone
832 # variables are set to true. If so, a message is displayed;
833 # otherwise, no message is displayed. The script is then
834 # exited and passes exit_number to exit command. If no
835 # exit_number is passed, then 0 is passed to exit command. If
836 # a non-integer is passed as exit_number, 255 is passed to
837 # exit command. If error_string is passed, it is printed to
838 # to standard out before exiting and is padded by blank lines
839 # if error_string is not "". Pass -b before exit_number to
840 # suppress beginning padding line, -e to suppress ending
841 # padding line, both to suppress both. Also removes temp
842 # files and kills Terminal if need be.
843 #
844 local PadBeginning=true
845 local PadEnd=true
846 while [ "$1" ] ; do
847 case "$1" in
848 -b)
849 PadBeginning=false
850 ;;
851 -e)
852 PadEnd=false
853 ;;
854 *)
855 break
856 ;;
857 esac
858 shift
859 done
860 rm -f "$FilesRemovedList" "$FilesRemovedFilesOnlyList" "$LogFile" 2>/dev/null 1>&2
861 if $QuitTerminalForcefully ; then
862 KillTerminal
863 fi
864 if [ $# -gt 1 ] ; then
865 if [ -z "$2" ] ; then
866 PadBeginning=false
867 PadEnd=false
868 fi
869 $PadBeginning && echo
870 printf "%s\n" "$2"
871 $PadEnd && echo
872 fi
873 if [ "z$ShowQuitMessage" = ztrue -a "z$RunScriptAsStandAlone" = ztrue ] ; then
874 [ $# -lt 2 -o \( $PadEnd = false -a -n "$2" \) ] && echo
875 echo "NOTE: If you double-clicked this program, quit Terminal application now."
876 [ $PadEnd = true -o -z "$2" ] && echo
877 fi
878 [ -z "$1" ] && exit 0
879 [ -z "`expr "$1" / 1 2>/dev/null`" ] && exit 255 || exit $1
880}
881
882FinishCleanup()
883{
884 # Usage: FinishCleanup
885 # Summary: Displays then deletes the file named by LogFile, a log
886 # of files not removed by RemoveItem function, if ErrorOccurred
887 # is true. If NoFilesToRemove is true, a message is shown
888 # and the function is exited. If RemoveInvisibleFilesOnly
889 # is true, a message is shown and the function is exited;
890 # otherwise, a message is shown. Returns value assigned to
891 # ExitCodeWhenSomeFileWasNotRemoved if ErrorOccurred is true,
892 # 0 otherwise.
893 #
894 if $DoShowOnlyFilesThatShouldHaveBeenUninstalled ; then
895 # Translate [ into \[ to avoid text in between [ and ] being treated as a bracket expression
896 PatternForOmission=`echo "$NotRemovedByNIS6UninstallerText|$NotRemovedBySymantecUninstallerText" | sed 's|\[|\\\[|g'`
897 FilesThatRemain=`cat "$FilesRemovedList" 2>/dev/null | grep '^/' | egrep -ve "$PatternForOmission"`
898 if [ "$FilesThatRemain" ] ; then
899 echo "$FilesThatRemain"
900 return $ExitCodeWhenFilesRemain
901 else
902 return 0
903 fi
904 elif $CreateFilesRemovedListOnly ; then
905 clear >&2
906 if $UseMore ; then
907 ShowContents "$FilesRemovedList"
908 else
909 cat "$FilesRemovedList"
910 fi
911 echo "" >&2
912 echo "NOTE: No files have been removed." >&2
913 echo "" >&2
914 /bin/rm -rf "$FilesRemovedList" "$FilesRemovedFilesOnlyList" 2>/dev/null 1>&2
915 return 0
916 elif $ErrorOccurred ; then
917 echo
918 # Display LogFile
919 ShowContents "$LogFile"
920 # Remove LogFile
921 /bin/rm -rf "$LogFile" 2>/dev/null 1>&2
922 echo
923 if $RemoveInvisibleFilesOnly ; then
924 echo "NOTE: Not all of the invisible Symantec files were removed."
925 echo " Make sure each volume passed is unlocked and accessible."
926 else
927 echo "NOTE: Not all folders/files were removed."
928 echo " Perhaps a file or folder listed above is in use or a folder"
929 echo " listed above is not empty."
930 if $RestartMayBeNeeded ; then
931 echo
932 echo "Some Symantec product files have been removed from the boot volume."
933 else
934 if $SomeFileWasRemoved ; then
935 echo
936 echo "Some folders or files have been removed."
937 fi
938 fi
939 fi
940 return $ExitCodeWhenSomeFileWasNotRemoved
941 fi
942 if $RemoveInvisibleFilesOnly ; then
943 if $NoFilesToRemove ; then
944 echo "There were no invisible Symantec files to be removed."
945 else
946 echo "AntiVirus QuickScan and/or Norton FS files have been removed."
947 fi
948 return 0
949 fi
950 if $NoFilesToRemove ; then
951 echo "There were no files that needed to be removed. No files were removed."
952 return 0
953 fi
954 $RemoveCrontabEntriesOnly && return 0
955 echo
956 if $RestartMayBeNeeded ; then
957 printf "Symantec product files have been removed from the boot volume"
958 if $SomeFileWasRemovedFromNonBootVolume ; then
959 echo
960 echo "and from other volume(s) listed above."
961 else
962 echo "."
963 fi
964 else
965 echo "Symantec product files have been removed from the above volume(s)."
966 fi
967 return 0
968}
969
970GetAdminPassword()
971{
972 # Usage: GetAdminPassword [$1]
973 # Argument: $1 - Prompt for password. If true is passed, a user that
974 # is not root will always be asked for a password. If
975 # something other than true is passed or if nothing is
976 # passed, then a user that is not root will only be
977 # prompted for a password if authentication has lapsed.
978 # Summary: Gets an admin user password from the user so that
979 # future sudo commands can be run without a password
980 # prompt. The script is exited with a value of 1 if
981 # the user enters an invalid password or if the user
982 # is not an admin user. If the user is the root user,
983 # then there is no prompt for a password (there is
984 # no need for a password when user is root).
985 # NOTE: Make sure ExitScript function is in the script.
986 #
987 # If root user, no need to prompt for password
988 [ "`whoami`" = "root" ] && return 0
989 echo >&2
990 # If prompt for password
991 if [ "$1" = "true" -o "$1" = "true" ] ; then
992 ShowVersion >&2
993 echo >&2
994 sudo -k >&2 # Make sudo require a password the next time it is run
995 echo "You must be an admin user to run this script." >&2
996 fi
997 # A dummy sudo command to get password
998 sudo -p "Please enter your admin password: " date 2>/dev/null 1>&2
999 if [ ! $? = 0 ] ; then # If failed to get password, alert user and exit script
1000 echo "You entered an invalid password or you are not an admin user. Script aborted." >&2
1001 ExitScript 1
1002 fi
1003}
1004
1005GetComputerUsers()
1006{
1007 # Usage: GetComputerUsers [-r] [volume]
1008 #
1009 # Version: 1.0.1
1010 #
1011 # Summary: Defines the following variables:
1012 #
1013 # ComputerUsers
1014 # ComputerUsersHomeDirs
1015 # ComputerUsersHomeDirsAndRootDir
1016 # ComputerUsersTable
1017 #
1018 # Omitted are users whose home directories contain no Library
1019 # directory and users that are not root whose home directory is
1020 # /var/root. If volume is passed and there is no /Users on that
1021 # volume, variables are all set to "". ComputerUsersTable is a
1022 # list of users and their home directories, separated by tabs.
1023 #
1024 # Note: This function must be run as root to find all users. When an
1025 # OS X volume other than / is passed or if the dscl program fails
1026 # or does not exist, non-root users that do not have their home
1027 # directories in /Users are not included and root's home directory
1028 # is assumed to be /var/root.
1029 #
1030 # History: 1.0.1 - 08/11/2014 - Corey Swertfager:
1031 # * Added ComputerUsersTable variable assignment.
1032 # * Now always includes root user in case this function
1033 # is not run as root.
1034 # * Added volume argument.
1035 #
1036 local CurrentDir
1037 local GCUHomeDir
1038 local CGLibraryDir
1039 local CGLibraryDirs
1040 local GCUUser
1041 local GCUUsers
1042 local SavedIFS="$IFS"
1043 local VolumePassed="$1"
1044 ComputerUsers=""
1045 ComputerUsersHomeDirs=""
1046 ComputerUsersHomeDirsAndRootDir=""
1047 ComputerUsersTable=""
1048 # If a directory other than / is passed
1049 if [ -d "$VolumePassed" -a ! "$VolumePassed" -ef / ] ; then
1050 # If not an OS X volume, skip it
1051 [ ! -d "$VolumePassed/Users" ] && return
1052 CurrentDir=`pwd`
1053 cd "$VolumePassed"
1054 CGLibraryDirs=`ls -d Users/*/Library 2>/dev/null | grep -v 'Users/Shared'`
1055 cd "$CurrentDir"
1056 # If no Library folders were found, skip
1057 [ -z "$CGLibraryDirs" ] && return
1058 CGLibraryDirs="$CGLibraryDirs
1059var/root/Library"
1060 IFS='
1061'
1062 for CGLibraryDir in $CGLibraryDirs ; do
1063 GCUHomeDir="/`dirname "$CGLibraryDir"`"
1064 GCUUser=`basename "$GCUHomeDir"`
1065 ComputerUsersHomeDirs="$ComputerUsersHomeDirs
1066$GCUHomeDir"
1067 ComputerUsers="$ComputerUsers
1068$GCUUser"
1069 ComputerUsersTable="$ComputerUsersTable
1070$GCUUser $GCUHomeDir"
1071 done
1072 else
1073 GCUUsers=`dscl . list /Users 2>/dev/null | egrep '^[[:alnum:]]' | egrep -vx 'daemon|nobody'`
1074 if [ -z "$GCUUsers" ] ; then
1075 GCUUsers="`ls /Users | egrep '^[[:alnum:]]' | grep -vx Shared`
1076root"
1077 fi
1078 IFS='
1079'
1080 for GCUUser in $GCUUsers ; do
1081 GCUHomeDir=`echo $(eval echo ~"$GCUUser")`
1082 # If home directory could not be evaluated
1083 if [ "`printf "%s" "$GCUHomeDir" | grep '^~'`" ] ; then
1084 continue
1085 elif [ "$GCUUser" != root ] ; then
1086 if [ ! -d "$GCUHomeDir/Library" ] ; then
1087 continue
1088 elif [ "$GCUHomeDir" = /var/root ] ; then
1089 continue
1090 fi
1091 fi
1092 ComputerUsers="$ComputerUsers
1093$GCUUser"
1094 ComputerUsersHomeDirs="$ComputerUsersHomeDirs
1095$GCUHomeDir"
1096 ComputerUsersTable="$ComputerUsersTable
1097$GCUUser $GCUHomeDir"
1098 done
1099 fi
1100 IFS="$SavedIFS"
1101 ComputerUsers=`echo "$ComputerUsers" | grep . | sort -f | uniq`
1102 ComputerUsersHomeDirs=`echo "$ComputerUsersHomeDirs" | grep / | sort -f | uniq`
1103 ComputerUsersHomeDirsAndRootDir="/
1104$ComputerUsersHomeDirs"
1105 ComputerUsersTable=`echo "$ComputerUsersTable" | grep / | sort -f | uniq`
1106}
1107
1108KillNortonZone()
1109{
1110 $CreateFilesRemovedListOnly && return
1111 ZoneProcesses=`ps -axww | grep "Norton Zone.app/Contents/MacOS/Norton Zone" | grep -v grep | awk '{print $1}'`
1112 for EachZoneAppPID in $ZoneProcesses ; do
1113 kill -9 "$EachZoneAppPID"
1114 done
1115 [ "$ZoneProcesses" ] && killall Finder
1116}
1117
1118KillSymantecProcesses()
1119{
1120 # Usage: KillSymantecProcesses [-n] [ProcessPattern [ProductName]]
1121 #
1122 # Kills Symantec processes that match extended regular expression
1123 # ProcessPattern. If ProcessPattern is not passed, all processes
1124 # that match those in ProcessPatternDefault are used. If ProductName
1125 # is passed, that name is shown when kill attempt is made; otherwise
1126 # "Symantec" is shown.
1127 #
1128 # If -n is passed as the first argument, no kill is attempted and no
1129 # output is shown.
1130 #
1131 # Returns 1 if there remains some matching process in memory, 0 if not.
1132 #
1133 # Version: 1.0.2
1134 #
1135 # History: 1.0.1 - 07/24/2014 - Corey Swertfager:
1136 # * Added ProcessPattern and ProductName arguments.
1137 # * Added definitions of ProcessesToSkipPattern and
1138 # ProcessPatternDefault.
1139 # * Added -n option.
1140 # 1.0.2 - 08/27/2014 - Corey Swertfager:
1141 # * Now uses egrep instead of grep for process matching.
1142 # * Now excludes process that include the name of the
1143 # script that is running this function.
1144 # * Now excludes Symantec Uninstaller.app and SymantecRemovalTool
1145 # when no ProcessPattern is passed.
1146 # * Changed -c to -n in Usage.
1147 #
1148 local aUID
1149 local DoKill=true
1150 local ExclusionPattern
1151 local NoKillOption="-n"
1152 local ProcessesToSkipPattern="/LiveUpdateAdminUtility/|/RemoveSymantecMacFiles\.command|/RemoveSymantecMacFiles\.command|/Symantec Uninstaller.app|/SymantecRemovalTool"
1153 local ProcessPattern
1154 local ProcessPatternDefault="/Application Support/Norton|/Application Support/Symantec|/Applications/Norton|/Applications/Symantec|PrivateFrameworks/NPF|PrivateFrameworks/Sym|/StartupItems/.*Norton|/StartupItems/NUMCompatibilityCheck|/StartupItems/SMac Client|/StartupItems/Sym|/StartupItems/TrackDelete|/StartupItems/VolumeAssist"
1155 local ProductName
1156 local SavedIFS="$IFS"
1157 local UIAGENT_USERS
1158 if [ "z$1" = "z$NoKillOption" ] ; then
1159 shift
1160 DoKill=false
1161 fi
1162 ProcessPattern="$1"
1163 ProductName="$2"
1164 ExclusionPattern=`basename "$0" 2>/dev/null | sed 's/\./\\\./g'`
1165 # If script name was successfully obtained
1166 if [ "$ExclusionPattern" ] ; then
1167 # Add / + current script name to ExclusionPattern
1168 ExclusionPattern=" egrep -|/$ExclusionPattern$|/$ExclusionPattern "
1169 else
1170 ExclusionPattern=" egrep -"
1171 fi
1172 if [ -z "$ProcessPattern" ] ; then
1173 ProcessPattern="$ProcessPatternDefault"
1174 ProcessesToSkipPattern="$ExclusionPattern|$ProcessesToSkipPattern"
1175 else
1176 ProcessesToSkipPattern="$ExclusionPattern"
1177 fi
1178 if [ -z "$ProductName" ] ; then
1179 ProductName="Symantec"
1180 fi
1181 Processes=`ps -wwax | egrep -i "$ProcessPattern" | egrep -v "$ProcessesToSkipPattern" | sort -f | uniq`
1182 if [ $DoKill = true -a -n "$Processes" ] ; then
1183 IFS='
1184'
1185 # If launchctl program exists, unload SymUIAgent
1186 if which launchctl &>/dev/null ; then
1187 # Code by Haridharan Nattamaig to unload SymUIAgent
1188 UIAGENT_USERS=`ps -aef | grep SymUIAgent | grep -v grep | awk '{print $1}' | sort | uniq`
1189 for aUID in ${UIAGENT_USERS} ; do
1190 id -u ${aUID} >& /dev/null
1191 if [ $? -eq 0 ] ; then
1192 echo "Unloading SymUIAgent for UID $aUID"
1193 sudo -u \#${aUID} launchctl unload /Library/LaunchAgents/com.symantec.uiagent.application.plist >& /dev/null
1194 fi
1195 done
1196 fi
1197 echo "Ending $ProductName processes..."
1198 for TheProcess in $Processes ; do
1199 echo "$TheProcess"
1200 kill -9 `echo "z $TheProcess" | awk '{print $2}'`
1201 done
1202 IFS="$SavedIFS"
1203 Processes=`ps -wwax | egrep -i "$ProcessPattern" | egrep -v "$ProcessesToSkipPattern" | sort -f | uniq`
1204 fi
1205 if [ "$Processes" ] ; then
1206 if $DoKill ; then
1207 echo "*** $ProductName processes still in memory:"
1208 echo "$Processes"
1209 fi
1210 return 1
1211 else
1212 if $DoKill ; then
1213 echo "*** There are no $ProductName processes in memory"
1214 fi
1215 return 0
1216 fi
1217}
1218
1219KillTerminal()
1220{
1221 ProcessLines=`ps -axww | grep -e "/Applications/Utilities/Terminal.app" | grep -v grep | sort -f`
1222 if [ -z "$ProcessLines" ] ; then
1223 return
1224 elif [ `echo "$ProcessLines" | grep . -c` -gt 1 -a $QuitTerminalForcefullyForAll = false ] ; then
1225 echo "NOTE: Terminal was launched more than once so it could not be quit."
1226 echo " Use the -QQ option to force Terminal to be quit for all users."
1227 return
1228 else
1229 echo "WARNING: Quitting Terminal."
1230 fi
1231 IFS='
1232'
1233 for ProcessLine in $ProcessLines ; do
1234 ProcessID=`printf "%s" "$ProcessLine" | awk '{print $1}'`
1235 kill -9 "$ProcessID"
1236 done
1237}
1238
1239ProcessArguments()
1240{
1241 # Usage: ProcessArguments [ --OptionTakesUnparsedArgument=string ] [ --OptionIsOneArgument=string ] "$@"
1242 #
1243 # Version: 1.0.1
1244 #
1245 # Summary: Processes arguments passed to script. Arguments beginning with a
1246 # single hyphen (-) are parsed into separate options except when an
1247 # argument is negative integer. Arguments beginning with two hypens
1248 # are treated as one argument; if the argument contains is an equals
1249 # sign (=), the string after the first "=" is treated as a separate
1250 # argument (i.e., the value assigned to the double-hyphen argument).
1251 #
1252 # For each --OptionTakesUnparsedArgument passed before "$@", the string
1253 # after "=" is used as an option that takes the next argument in full
1254 # without parsing it (see examples below); string must be a hyphen
1255 # followed by a single character.
1256 #
1257 # For each --OptionIsOneArgument passed before "$@", the string after
1258 # "=" is used as an option that should be treated as a single argument.
1259 # This is useful when processing an argument that begins with a single
1260 # hyphen to avoid having that argument parsed into separate options.
1261 # The referenced option cannot be embedded within other options (see
1262 # final example below).
1263 #
1264 # "$@" must be the last argument passed to ProcessArguments. Put all custom
1265 # option handling between "--- Customized argument handling begins here ---"
1266 # and "--- Customized argument handling ends here ---".
1267 #
1268 # Note: ProcessArgumentsNextArgument may be called to verify and obtain the
1269 # next argument after or before a given option; see that function's usage
1270 # for more details. OriginalArgumentNumber can be used to determine if
1271 # two arguments were originally passed within the same string of options.
1272 #
1273 # Examples: These examples have expanded the arguments passed as "$@".
1274 #
1275 # ProcessArguments -ab -c
1276 # Would process three arguments: -a, -b, and -c
1277 # ProcessArguments --ab -c
1278 # Would process two arguments: --ab and -c
1279 # ProcessArguments --equation=a=b+c
1280 # Would process two arguments: --equation and a=b+c
1281 # ProcessArguments -10
1282 # Would process one argument: -10
1283 # ProcessArguments -10a
1284 # Would process three arguments: -1, -0, -a
1285 # ProcessArguments --OptionTakesUnparsedArgument=-e -e -ger
1286 # Would process two arguments: -e and -ger
1287 # ProcessArguments --OptionTakesUnparsedArgument=-e -peer
1288 # Would process three arguments: -p, -e, and er
1289 # ProcessArguments --OptionTakesUnparsedArgument=-e --OptionTakesUnparsedArgument=-t -eter -ter
1290 # Would process four arguments: -e, ter, -t, and er
1291 # ProcessArguments --OptionIsOneArgument=-hi -hi
1292 # Would process one argument: -hi
1293 # ProcessArguments --OptionIsOneArgument=-hi -his
1294 # Would process three arguments: -h, -i, and -s
1295 #
1296 # History: 1.0.1 - 06/23/2013 - Corey Swertfager:
1297 # * Added processing of options within a string that begins
1298 # with a single hyphen.
1299 # * Added --OptionTakesUnparsedArgument option.
1300 # * Added --OptionIsOneArgument option.
1301 #
1302 local ArgList=""
1303 local ArgsToAdd
1304 local ArgWasAdded=false
1305 local CurrentArgNumber=1
1306 local CurrentArgument
1307 local CurrentCharacter
1308 local DoNotParseNextArgument=false
1309 local NextArgument=""
1310 local NumberOfArgumentsPassed
1311 local NumberOfArgumentsToUse=0
1312 local OptionToAdd
1313 local OriginalArgumentNumber=0
1314 local OriginalArgumentNumberList=""
1315 local RemainingOptionsInString
1316 local TableOfOptionsWithoutParsing="*** Each option in this table will have its succeeding argument left unparsed. ***"
1317 local TableOfUndividedArguments="*** Each item in this table should each be treated as single argument. ***"
1318 while [ "$1" ] ; do
1319 case "$1" in
1320 --OptionIsOneArgument)
1321 ExitScript 99 "WARNING: Bad use of --OptionIsOneArgument passed to ProcessArguments:
1322 \"$1\""
1323 ;;
1324 --OptionIsOneArgument=*)
1325 OptionToAdd=`printf "%s" "$1" | awk '{match($0,"=") ; print substr($0,RSTART+1)}'`
1326 [ -z "$OptionToAdd" ] && ExitScript 99 "WARNING: Bad use of --OptionIsOneArgument passed to ProcessArguments:
1327 \"$1\""
1328 TableOfUndividedArguments="$TableOfUndividedArguments
1329$OptionToAdd"
1330 ;;
1331 --OptionTakesUnparsedArgument|--OptionTakesUnparsedArgument=*)
1332 OptionToAdd=`printf "%s" "$1" | awk '{match($0,"=") ; print substr($0,RSTART+1)}'`
1333 [ -z "`printf "%s" "$OptionToAdd" | grep -xe '-.'`" ] && ExitScript 99 "WARNING: Bad use of --OptionTakesUnparsedArgument passed to ProcessArguments:
1334 \"$1\""
1335 TableOfOptionsWithoutParsing="$TableOfOptionsWithoutParsing
1336$OptionToAdd"
1337 ;;
1338 *)
1339 break
1340 ;;
1341 esac
1342 shift
1343 done
1344 NumberOfArgumentsPassed=$#
1345 while [ $# != 0 ] ; do
1346 let OriginalArgumentNumber=$OriginalArgumentNumber+1
1347 # If argument is in the list of arguments whose next argument should not be parsed
1348 if [ "`printf "%s" "$1" | grep -xF "$TableOfOptionsWithoutParsing"`" ] ; then
1349 ArgsToAdd="$1"
1350 OriginalArgumentNumberList="$OriginalArgumentNumberList
1351$OriginalArgumentNumber"
1352 DoNotParseNextArgument=true
1353 # Else if argument is in the list of arguments that should be treated as one argument
1354 elif [ "`printf "%s" "$1" | grep -xF "$TableOfUndividedArguments"`" ] ; then
1355 ArgsToAdd="$1"
1356 OriginalArgumentNumberList="$OriginalArgumentNumberList
1357$OriginalArgumentNumber"
1358 else
1359 case "$1" in
1360 -|-?)
1361 # If argument was a hyphen or a hyphen followed by a single character
1362 ArgsToAdd="$1"
1363 OriginalArgumentNumberList="$OriginalArgumentNumberList
1364$OriginalArgumentNumber"
1365 DoNotParseNextArgument=false
1366 ;;
1367 --*)
1368 # If a value was passed to the option that begins with --
1369 if [ "`printf "%s" "$1" | grep =`" ] ; then
1370 # Add the option and its value as separate arguments
1371 ArgsToAdd="`printf "%s" "$1" | awk -F = '{print $1}'`
1372`printf "%s" "$1" | awk '{match($0,"=") ; print substr($0,RSTART+1)}'`"
1373 OriginalArgumentNumberList="$OriginalArgumentNumberList
1374$OriginalArgumentNumber
1375$OriginalArgumentNumber"
1376 else
1377 ArgsToAdd="$1"
1378 OriginalArgumentNumberList="$OriginalArgumentNumberList
1379$OriginalArgumentNumber"
1380 fi
1381 DoNotParseNextArgument=false
1382 ;;
1383 -*)
1384 # If argument should not be parsed or is a negative integer
1385 if [ $DoNotParseNextArgument = true -o -z "`printf "%s" "$1" | awk '{print substr($0,2)}' | tr -d '[:digit:]'`" ] ; then
1386 # Treat argument as a single argument
1387 ArgsToAdd="$1"
1388 OriginalArgumentNumberList="$OriginalArgumentNumberList
1389$OriginalArgumentNumber"
1390 DoNotParseNextArgument=false
1391 else
1392 # Parse string into separate arguments
1393 ArgsToAdd=""
1394 RemainingOptionsInString=`printf "%s" "$1" | awk '{print substr($0,2)}'`
1395 while [ "$RemainingOptionsInString" ] ; do
1396 CurrentCharacter=`printf "%s" "$RemainingOptionsInString" | awk '{print substr($0,1,1)}'`
1397 # Prefix the character with a hyphen and add as an argument
1398 if [ "$ArgsToAdd" ] ; then
1399 ArgsToAdd="$ArgsToAdd
1400-$CurrentCharacter"
1401 else
1402 ArgsToAdd="-$CurrentCharacter"
1403 fi
1404 OriginalArgumentNumberList="$OriginalArgumentNumberList
1405$OriginalArgumentNumber"
1406 RemainingOptionsInString=`printf "%s" "$RemainingOptionsInString" | awk '{print substr($0,2)}'`
1407 # If this is an option whose next string should not be parsed
1408 if [ "`printf "%s" "$TableOfOptionsWithoutParsing" | grep -xe "-$CurrentCharacter"`" ] ; then
1409 # If string has characters remaining after that option
1410 if [ "$RemainingOptionsInString" ] ; then
1411 # Add remainder of string as the unparsed string argument
1412 ArgsToAdd="$ArgsToAdd
1413$RemainingOptionsInString"
1414 OriginalArgumentNumberList="$OriginalArgumentNumberList
1415$OriginalArgumentNumber"
1416 else
1417 # Use next argument passed as unparsed string argument
1418 DoNotParseNextArgument=true
1419 fi
1420 break
1421 fi
1422 done
1423 fi
1424 ;;
1425 *)
1426 ArgsToAdd="$1"
1427 OriginalArgumentNumberList="$OriginalArgumentNumberList
1428$OriginalArgumentNumber"
1429 DoNotParseNextArgument=false
1430 ;;
1431 esac
1432 fi
1433 if $ArgWasAdded ; then
1434 ArgList="$ArgList
1435$ArgsToAdd"
1436 else
1437 ArgList="$ArgsToAdd"
1438 fi
1439 ArgWasAdded=true
1440 shift
1441 done
1442 if [ $NumberOfArgumentsPassed -gt 0 ] ; then
1443 # Add a non-blank line to ArgList in case last argument passed was ""
1444 ArgList="$ArgList
1445 TheEnd"
1446 OriginalArgumentNumberList=`echo "$OriginalArgumentNumberList" | grep .`
1447 NumberOfArgumentsToUse=`printf "%s" "$ArgList" | grep "" -c`
1448 let NumberOfArgumentsToUse=$NumberOfArgumentsToUse-1
1449 fi
1450 # --- Customized argument handling begins here ---
1451 BootVolumeWillBeSearched=false
1452 CreateFilesRemovedListOnly=false
1453 DoBackupLogs=true
1454 DoKillProcesses=true
1455 DoRemoveFSDFolders=true
1456 DoRemoveInstallerLaunchAgents=true
1457 DoRemoveIPUA=true
1458 DoRemoveLogs=true
1459 DoRunPredeleteScripts=true
1460 DoShowOnlyFilesThatShouldHaveBeenUninstalled=false
1461 FindOption1=""
1462 FindOption2=""
1463 ListOnlyFilesThatExist=false
1464 NoFilesToRemove=true
1465 PauseBeforeRestarting=true
1466 QuitTerminalForcefully=false
1467 QuitTerminalForcefullyForAll=false
1468 QuitWithoutRestarting=false
1469 $AutoRunScript && QuitWithoutRestarting=true
1470 RemoveCrontabEntries=true
1471 RemoveCrontabEntriesOnly=false
1472 RemoveInvisibleFiles=true
1473 RemoveInvisibleFilesOnly=false
1474 RemoveFromAllVolumes=false
1475 RemoveFromOtherVolumes=false
1476 RestartAutomatically=false
1477 RestartMayBeNeeded=false
1478 ShowFilesAsRemoved=true
1479 ShowOnlyRegularFiles=false
1480 ShowPredeleteErrors=false
1481 ShowQuitMessage=true
1482 SomeFileWasRemoved=false
1483 SomeFileWasRemovedFromNonBootVolume=false
1484 SomeFileWasRemovedFromBootVolume=false
1485 UseMore=false
1486 while [ $CurrentArgNumber -le $NumberOfArgumentsToUse ] ; do
1487 CurrentArgument=`printf "%s" "$ArgList" | head -n $CurrentArgNumber | tail -n 1`
1488 OriginalArgumentNumber=`echo "$OriginalArgumentNumberList" | head -n $CurrentArgNumber | tail -n 1`
1489 case "$CurrentArgument" in
1490 -A)
1491 RemoveFromAllVolumes=true
1492 BootVolumeWillBeSearched=true
1493 ;;
1494 -c)
1495 RemoveCrontabEntriesOnly=true
1496 RemoveCrontabEntries=true
1497 RemoveInvisibleFilesOnly=false
1498 RemoveInvisibleFiles=false
1499 ;;
1500 -C)
1501 RemoveCrontabEntriesOnly=false
1502 RemoveCrontabEntries=false
1503 ;;
1504 -d)
1505 DoRunPredeleteScripts=false
1506 ;;
1507 -e)
1508 ShowPredeleteErrors=true
1509 ;;
1510 -F)
1511 CreateFilesRemovedListOnly=true
1512 ListOnlyFilesThatExist=true
1513 ShowOnlyRegularFiles=true
1514 FindOption1=-type
1515 FindOption2=f
1516 ;;
1517 -f)
1518 ShowFilesAsRemoved=false
1519 ;;
1520 -g)
1521 DoRemoveLogs=false
1522 ;;
1523 -H)
1524 ShowUsage 0
1525 ;;
1526 -h)
1527 ShowHelp 0
1528 ;;
1529 -i)
1530 RemoveInvisibleFilesOnly=true
1531 RemoveInvisibleFiles=true
1532 RemoveCrontabEntries=false
1533 RemoveCrontabEntriesOnly=false
1534 ;;
1535 -I)
1536 RemoveInvisibleFilesOnly=false
1537 RemoveInvisibleFiles=false
1538 ;;
1539 -k)
1540 DoKillProcesses=false
1541 ;;
1542 -l|-R)
1543 CreateFilesRemovedListOnly=true
1544 ListOnlyFilesThatExist=true
1545 ;;
1546 -L)
1547 CreateFilesRemovedListOnly=true
1548 ListOnlyFilesThatExist=false
1549 ;;
1550 -m)
1551 UseMore=true
1552 ;;
1553 -p)
1554 PauseBeforeRestarting=false
1555 ;;
1556 -q)
1557 QuitWithoutRestarting=true
1558 RestartAutomatically=false
1559 ;;
1560 -Q)
1561 # If -Q was previously passed, treat as -QQ
1562 if $QuitTerminalForcefully ; then
1563 # Treat as if -QQ was passed
1564 QuitTerminalForcefullyForAll=true
1565 else
1566 QuitTerminalForcefullyForAll=false
1567 fi
1568 QuitTerminalForcefully=true
1569 QuitWithoutRestarting=true
1570 RestartAutomatically=false
1571 ;;
1572 -QQ)
1573 QuitTerminalForcefully=true
1574 QuitTerminalForcefullyForAll=true
1575 QuitWithoutRestarting=true
1576 RestartAutomatically=false
1577 ;;
1578 -r|-re)
1579 RestartAutomatically=true
1580 QuitWithoutRestarting=false
1581 ;;
1582 -u)
1583 DoShowOnlyFilesThatShouldHaveBeenUninstalled=true
1584 ;;
1585 -V)
1586 echo $Version
1587 ExitScript 0
1588 ;;
1589 *)
1590 AssignVolume "$CurrentArgument" # Assign it to a Volume variable
1591 # If not a valid volume
1592 if [ $? = 1 ] ; then
1593 ShowUsage 4 "ERROR: Invalid option or volume name: \"$CurrentArgument\"."
1594 fi
1595 RemoveFromOtherVolumes=true
1596 ;;
1597 esac
1598 let CurrentArgNumber=$CurrentArgNumber+1
1599 done
1600 if $DoShowOnlyFilesThatShouldHaveBeenUninstalled ; then
1601 CreateFilesRemovedListOnly=true
1602 ListOnlyFilesThatExist=true
1603 fi
1604 [ "`echo "$ListOfProgramsThatShouldNotBackUpLogs" | grep -x "$FullScriptName"`" ] && DoBackupLogs=false
1605 [ "`echo "$ListOfProgramsThatShouldNotKillProcesses" | grep -x "$FullScriptName"`" ] && DoKillProcesses=false
1606 [ "`echo "$ListOfProgramsThatShouldNotRemoveFSDFolders" | grep -x "$FullScriptName"`" ] && DoRemoveFSDFolders=false
1607 [ "`echo "$ListOfProgramsThatShouldNotRemoveInstallerLaunchAgents" | grep -x "$FullScriptName"`" ] && DoRemoveInstallerLaunchAgents=false
1608 [ "`echo "$ListOfProgramsThatShouldNotRemoveLogs" | grep -x "$FullScriptName"`" ] && DoRemoveLogs=false
1609 [ "`echo "$ListOfProgramsThatShouldNotRemoveSymantecIPUA" | grep -x "$FullScriptName"`" ] && DoRemoveIPUA=false
1610 # --- Customized argument handling ends here ---
1611}
1612
1613ProcessArgumentsNextArgument()
1614{
1615 # Usage: ProcessArgumentsNextArgument [exit_code] [-F | -P] [-p | -r ] [operator]
1616 #
1617 # Version: 1.0.0
1618 #
1619 # Arguments: exit_code Pass integer in range 0-255 to ShowUsage when next
1620 # argument is missing or invalid. If exit_code is not
1621 # specified, 0 is assumed.
1622 #
1623 # -F Assign the full logical path to NextArgumentFullPath.
1624 # This is the default. ShowFullFilePath function must
1625 # be included in script. If no operator was passed, -E
1626 # is the assumed operator.
1627 #
1628 # -P Assign the full physical path to NextArgumentFullPath.
1629 # ShowFullFilePath function must be included in script.
1630 # If no operator was passed, -e is the assumed operator.
1631 #
1632 # -p Get previous argument instead of next argument. If
1633 # there is no previous argument, sets NextArgument to ""
1634 # and returns 1.
1635 #
1636 # -r Return 1 instead of exiting script if there is no next
1637 # argument. Sets NextArgument to "".
1638 #
1639 # operator Operator used to test next argument:
1640 # -d Folder
1641 # -E File, folder, or link
1642 # -e File, folder, or link to an existing file/folder
1643 # -f File
1644 # -i [min [max]]
1645 # Integer in range min-max; pass "" to min and
1646 # an integer to max if there is no minimum but
1647 # a maximum is desired; pass "" to to both min
1648 # and max if passing another option after the -i
1649 # option. Also tests to see if the value of the
1650 # next argument is out of range for the currently
1651 # running version of Mac OS.
1652 # -L Link; does not check to see if link is broken
1653 # unless -P option was also passed
1654 # -l Link to an existing file/folder
1655 # -n Non-null string
1656 #
1657 # Summary: Called by ProcessArguments 1.0.1 or later to assign values to:
1658 #
1659 # CurrentArgNumber
1660 # NextArgument
1661 # NextArgumentFullPath
1662 # NextArgumentOriginalArgumentNumber
1663 #
1664 # using pre-existing values of:
1665 #
1666 # ArgList
1667 # CurrentArgNumber
1668 # CurrentArgument
1669 # OriginalArgumentNumberList
1670 # NumberOfArgumentsToUse
1671 #
1672 # Returns 0 if next or previous argument was assigned to NextArgument,
1673 # CurrentArgNumber was incremented (or decremented if -p was passed),
1674 # and NextArgumentOriginalArgumentNumber was assigned.
1675 #
1676 # Assigns "" to NextArgument and NextArgumentFullPath and returns 1 if
1677 # -p is passed and there is no previous argument, or if -r is passed
1678 # and there is no next argument; otherwise, calls ShowUsage to show
1679 # error message and exit script if operator test fails or if there is
1680 # no next or previous argument.
1681 #
1682 # Note: ShowFullFilePath function must be included in script in order to
1683 # assign a value to NextArgumentFullPath.
1684 #
1685 # Examples: ProcessArgumentsNextArgument
1686 # Returns 0 if there was a next argument; otherwise, passes 0 to
1687 # ShowUsage and displays error message about missing argument.
1688 # ProcessArgumentsNextArgument -r
1689 # Returns 0 if there was a next argument; otherwise, assigns "" to
1690 # NextArgument and NextArgumentFullPath, then returns 1.
1691 # ProcessArgumentsNextArgument 2 -d
1692 # Returns 0 if NextArgument was set to a folder; otherwise, passes
1693 # 2 to ShowUsage and displays error message if the next argument is
1694 # missing or is not a folder.
1695 # ProcessArgumentsNextArgument 3 -r -d
1696 # Returns 0 if NextArgument was set to a folder. If the next argument
1697 # is missing, assigns "" to NextArgument and NextArgumentFullPath,
1698 # then returns 1. If next argument is not a folder, passes 3 to
1699 # ShowUsage and displays error message.
1700 # ProcessArgumentsNextArgument 4 -i 1
1701 # Returns 0 if NextArgument was set to an integer; otherwise, passes
1702 # 4 to ShowUsage and displays error message if the next argument is
1703 # missing, is not an integer, or is less than 1.
1704 # ProcessArgumentsNextArgument -i "" 100 5
1705 # Returns 0 if NextArgument was set to an integer; otherwise, passes
1706 # 5 to ShowUsage and displays error message if the next argument is
1707 # missing, is not an integer, or is greater than 100.
1708 # ProcessArgumentsNextArgument -i "" "" 6
1709 # Returns 0 if NextArgument was set to an integer; otherwise, passes
1710 # 6 to ShowUsage and displays error message if the next argument is
1711 # missing or is not an integer.
1712 #
1713 local DoShowMissingError=true
1714 local DirectionText=after
1715 local ExitCode=0
1716 local ErrorText=""
1717 local GoToPreviousArgument=false
1718 local Max
1719 local Min
1720 local NextArgumentOriginal
1721 local PathOption=""
1722 local TestOperator=""
1723 NextArgumentFullPath=""
1724 while [ "$1" ] ; do
1725 case "$1" in
1726 -d)
1727 ErrorText="folder"
1728 TestOperator="$1"
1729 ;;
1730 -E)
1731 ErrorText="file, folder, or link"
1732 TestOperator="$1"
1733 ;;
1734 -e)
1735 ErrorText="file or folder"
1736 TestOperator="$1"
1737 ;;
1738 -F)
1739 PathOption="$1"
1740 if [ -z "$ErrorText" ] ; then
1741 ErrorText="file, folder, or link"
1742 TestOperator="-E"
1743 fi
1744 ;;
1745 -f)
1746 ErrorText="file"
1747 TestOperator="$1"
1748 ;;
1749 -i)
1750 ErrorText="integer"
1751 TestOperator="$1"
1752 Min="$2"
1753 Max="$3"
1754 shift 2
1755 ;;
1756 -L)
1757 ErrorText="link"
1758 TestOperator="$1"
1759 [ "z$PathOption" = "z-P" ] && ErrorText="unbroken link"
1760 ;;
1761 -l)
1762 ErrorText="unbroken link"
1763 TestOperator="-L"
1764 ;;
1765 -n)
1766 ErrorText="non-null string"
1767 TestOperator="$1"
1768 ;;
1769 -P)
1770 PathOption="$1"
1771 if [ -z "$ErrorText" ] ; then
1772 ErrorText="file or folder"
1773 TestOperator="-e"
1774 elif [ "$ErrorText" = "link" ] ; then
1775 ErrorText="unbroken link"
1776 fi
1777 ;;
1778 -p)
1779 GoToPreviousArgument=true
1780 DirectionText=before
1781 ;;
1782 -r)
1783 DoShowMissingError=false
1784 ;;
1785 *)
1786 ExitCode=`printf "%s" "$1" | tr -d -c "[:digit:]"`
1787 [ -z "$ExitCode" ] && ExitCode=0
1788 ;;
1789 esac
1790 shift
1791 done
1792 if $GoToPreviousArgument ; then
1793 if [ $CurrentArgNumber -gt 1 ] ; then
1794 let CurrentArgNumber=$CurrentArgNumber-1
1795 NextArgument=`printf "%s" "$ArgList" | head -n $CurrentArgNumber | tail -n 1`
1796 NextArgumentOriginalArgumentNumber=`echo "$OriginalArgumentNumberList" | head -n $CurrentArgNumber | tail -n 1`
1797 else
1798 NextArgument=""
1799 NextArgumentFullPath=""
1800 return 1
1801 fi
1802 # Else if there are no more arguments in ArgList
1803 elif [ $CurrentArgNumber = $NumberOfArgumentsToUse ] ; then
1804 if $DoShowMissingError ; then
1805 ShowUsage $ExitCode "ERROR: Nothing was passed after $CurrentArgument" >&2
1806 else
1807 NextArgument=""
1808 NextArgumentFullPath=""
1809 return 1
1810 fi
1811 else
1812 let CurrentArgNumber=$CurrentArgNumber+1
1813 NextArgument=`printf "%s" "$ArgList" | head -n $CurrentArgNumber | tail -n 1`
1814 NextArgumentOriginalArgumentNumber=`echo "$OriginalArgumentNumberList" | head -n $CurrentArgNumber | tail -n 1`
1815 fi
1816 NextArgumentFullPath=`ShowFullFilePath $PathOption "$NextArgument"`
1817 if [ "z$ErrorText" = zinteger ] ; then
1818 NextArgumentOriginal="$NextArgument"
1819 if [ -z "$NextArgument" ] ; then
1820 ShowUsage $ExitCode "ERROR: Argument passed $DirectionText $CurrentArgument is not an integer: \"$NextArgumentOriginal\"" >&2
1821 # Else if argument contains something other than a hyphen or digits
1822 elif [ "`printf "%s" "$NextArgument" | tr -d "[:digit:]-"`" ] ; then
1823 ShowUsage $ExitCode "ERROR: Argument passed $DirectionText $CurrentArgument is not an integer:
1824 \"$NextArgumentOriginal\"" >&2
1825 # Else if argument contains a hyphen that is not at the beginning
1826 elif [ "`printf "%s" "$NextArgument" | grep '..*-'`" ] ; then
1827 ShowUsage $ExitCode "ERROR: Argument passed $DirectionText $CurrentArgument is not an integer:
1828 \"$NextArgumentOriginal\"" >&2
1829 fi
1830 NextArgument=`expr "$NextArgument" / 1 2>/dev/null`
1831 test "$NextArgumentOriginal" -eq "$NextArgument" 2>/dev/null
1832 if [ $? != 0 ] ; then
1833 ShowUsage $ExitCode "ERROR: Value passed $DirectionText $CurrentArgument is out of range for this OS:
1834 $NextArgumentOriginal" >&2
1835 fi
1836 # If minimum value was specified
1837 if [ "$Min" ] ; then
1838 [ $NextArgument -lt $Min ] && ShowUsage $ExitCode "ERROR: Value passed $DirectionText $CurrentArgument ($NextArgumentOriginal) is less than
1839 minimum value ($Min)." >&2
1840 fi
1841 # If maximum value was specified
1842 if [ "$Max" ] ; then
1843 [ $NextArgument -gt $Max ] && ShowUsage $ExitCode "ERROR: Value passed $DirectionText $CurrentArgument ($NextArgumentOriginal) is greater than
1844 maximum value ($Max)." >&2
1845 fi
1846 elif [ "z$ErrorText" = "zfile, folder, or link" ] ; then
1847 [ ! -e "$NextArgument" -a ! -L "$NextArgument" ] && ShowUsage $ExitCode "ERROR: Argument passed $DirectionText $CurrentArgument is not a $ErrorText:
1848 \"$NextArgument\"" >&2
1849 elif [ "z$ErrorText" = "zunbroken link" ] ; then
1850 if [ ! -L "$NextArgument" ] ; then
1851 ShowUsage $ExitCode "ERROR: Argument passed $DirectionText $CurrentArgument is not a link:
1852 \"$NextArgument\"" >&2
1853 # Else if link is broken
1854 elif [ ! -e "$NextArgument" ] ; then
1855 ShowUsage $ExitCode "ERROR: The target of the link passed $DirectionText $CurrentArgument does not exist:
1856 \"$NextArgument\"" >&2
1857 fi
1858 elif [ "$ErrorText" ] ; then
1859 [ ! $TestOperator "$NextArgument" ] && ShowUsage $ExitCode "ERROR: Argument passed $DirectionText $CurrentArgument is not a $ErrorText:
1860 \"$NextArgument\"" >&2
1861 fi
1862 if [ "$PathOption" ] ; then
1863 if [ -z "$NextArgumentFullPath" ] ; then
1864 if [ -L "$NextArgument" ] ; then
1865 ShowUsage $ExitCode "ERROR: The target of the link passed $DirectionText $CurrentArgument does not exist:
1866 \"$NextArgument\"" >&2
1867 else
1868 ExitScript $ExitCode "WARNING: ShowFullFilePath function could not resolve path for:
1869 \"$NextArgument\"" >&2
1870 fi
1871 fi
1872 fi
1873 return 0
1874}
1875
1876RemoveAllNortonFiles()
1877{
1878 # Usage: RemoveAllNortonFiles $1
1879 # Argument: $1 = Volume name. The name should begin with "/Volumes/"
1880 # unless it is "/" (boot volume).
1881 # Summary: Removes all OS X Norton products' files and folders
1882 # from volume named by $1 if RemoveInvisibleFilesOnly
1883 # equals false; otherwise, removes only the invisible Norton
1884 # files. Removes the invisible Norton files from other
1885 # volumes that are passed to the script. Symantec crontab
1886 # entries are removed if RemoveCrontabEntries = true.
1887 #
1888 # If not a valid volume, return 1
1889 [ -z "`CheckIfValidVolume "$1"`" ] && return 1
1890 CurrentVolumeBeingUsed="$1"
1891 GetComputerUsers "$CurrentVolumeBeingUsed"
1892 if $CreateFilesRemovedListOnly ; then
1893 printf "" > "$FilesRemovedFilesOnlyList"
1894 echo "" >> "$FilesRemovedList"
1895 if [ `echo "$ListOfVolumesToUse" | grep -c .` -gt 1 ] ; then
1896 if [ "$1" = / ] ; then
1897 echo "------ Volume: / (current boot volume) ------" >> "$FilesRemovedList"
1898 else
1899 echo "------ Volume: \"`basename "$1"`\" ------" >> "$FilesRemovedList"
1900 fi
1901 echo "" >> "$FilesRemovedList"
1902 fi
1903 fi
1904 $RemoveCrontabEntries && DeleteCrontabEntries "$1"
1905 $RemoveCrontabEntries && DeleteLaunchdPlists "$1"
1906 $RemoveCrontabEntriesOnly && return 0
1907 ! $RemoveInvisibleFilesOnly && DeleteSymantecLoginItems "$1"
1908 if $CreateFilesRemovedListOnly ; then
1909 if ! $RemoveInvisibleFilesOnly ; then
1910 RunPredeleteScripts "$1"
1911 echo "" >> "$FilesRemovedList"
1912 fi
1913 if $ListOnlyFilesThatExist ; then
1914 echo "The following files/folders currently exist and would be removed unless" >> "$FilesRemovedList"
1915 echo "otherwise noted:" >> "$FilesRemovedList"
1916 else
1917 echo "$FullScriptName would attempt to find and remove the following:" >> "$FilesRemovedList"
1918 fi
1919 echo "" >> "$FilesRemovedList"
1920 fi
1921 RemoveInvisibleFilesFromVolume "$1"
1922 $RemoveInvisibleFilesOnly && return 0
1923 # If not just creating a list of removed files
1924 if ! $CreateFilesRemovedListOnly ; then
1925 RunPredeleteScripts "$1"
1926 # If removing files from the boot volume
1927 if [ "z$CurrentVolumeBeingUsed" = z/ ] ; then
1928 echo "Removing system profile if it exists: com.symc.enroll"
1929 profiles -R -p com.symc.enroll &>/dev/null
1930 # 7.0.55: If Norton WiFi Privacy Service is installed
1931 if [ -e "/Library/LaunchDaemons/com.symantec.NWPService.plist" ] ; then
1932 # Unload it
1933 launchctl unload /Library/LaunchDaemons/com.symantec.NWPService.plist
1934 fi
1935 # Kill Symantec processes before attempting to remove visible files (Etrack 3442959)
1936 $DoKillProcesses && KillSymantecProcesses
1937 fi
1938 fi
1939 # If not an OS X volume, return 1
1940 [ ! -d "$1/Library/Application Support" ] && return 1
1941 if $CreateFilesRemovedListOnly ; then
1942 $DoShowOnlyFilesThatShouldHaveBeenUninstalled || echo "Finding visible Symantec files on: $1" >&2
1943 elif $ShowFilesAsRemoved ; then
1944 echo "Locating visible Symantec files in: $1"
1945 else
1946 echo "Removing visible Symantec files from: $1"
1947 fi
1948 cd "$1"
1949 if [ "`pwd`" = "/" ] ; then
1950 VolumePrefix=""
1951 else
1952 VolumePrefix="`pwd`"
1953 fi
1954 KillNortonZone
1955 RemoveItem "/.com_symantec_symfs_private"
1956 RemoveItem "/.symSchedScanLockxz"
1957 RemoveItem "/Applications/Firefox.app/Contents/MacOS/extensions/{0e10f3d7-07f6-4f12-97b9-9b27e07139a5}"
1958 RemoveItem "/Applications/Firefox.app/Contents/MacOS/extensions/{29dd9c80-9ea1-4aaf-9305-a0314aba24e3}"
1959 RemoveItem "/Applications/Firefox.app/Contents/MacOS/extensions/nortonsafetyminder@symantec.com"
1960 RemoveItem "/Applications/GatherSymantecInfo"
1961 RemoveItem "/Applications/Late Breaking News"
1962 RemoveItem "/Applications/LiveUpdate"
1963 RemoveItem "/Applications/LiveUpdate Folder"
1964 RemoveItem "/Applications/LiveUpdate Folder (OS X)"
1965# Remove navx incorrectly installed by NAV 800.007 installer:
1966 RemoveItem "/Applications/navx"
1967 # 7.0.55: Exclude NWP so that it doesn't show up when -u script option is used
1968 RemoveItem "/Applications/Norton " "*" -x "Norton WiFi Privacy.app"
1969 # 7.0.55: Remove NWP app
1970 RemoveItem "/Applications/Norton WiFi Privacy.app" -u
1971 RemoveItem "/Applications/Symantec AntiVirus"
1972 RemoveItem "/Applications/Symantec Cloud Security.app"
1973 RemoveItem "/Applications/Symantec Endpoint Protection.app"
1974 RemoveItem "/Applications/Symantec Endpoint Protection Cloud.app"
1975 RemoveItem "/Applications/Symantec Solutions"
1976 RemoveItem "/Applications/Symantec Unified Endpoint Protection.app"
1977# The next 3 items are erroneously created by early builds of NAV 10 installer
1978 RemoveItem "/Applications/Symantec/LiveUpdate.app"
1979 RemoveItem "/Applications/Symantec/Read Me Files"
1980 RemoveItem "/Applications/Symantec" -e
1981 RemoveItem "/Applications/Trash Running Daemons"
1982 RemoveItem "/Applications/uDelete Preferences"
1983 RemoveItem "/Applications/Register Your Software"
1984 RemoveItem "/etc/liveupdate.conf"
1985 RemoveItem "/etc/mach_init.d/SymSharedSettings.plist"
1986 RemoveItem "/etc/Symantec.conf"
1987# Folder erroneously created by NPF 300.001 - removed if empty:
1988 RemoveItem "/Firewall" -e -u
1989 RemoveItem "/Library/Application Support/com.symantec.NWPService" -u
1990 RemoveItem "/Library/Application Support/NAVDiagnostic.log"
1991 RemoveItem "/Library/Application Support/NAV.history"
1992 RemoveItem "/Library/Application Support/nat_" "*" -u
1993 RemoveItem "/Library/Application Support/nat_" "*" -u
1994 RemoveItem "/Library/Application Support/nav_" "*" -u
1995 RemoveItem "/Library/Application Support/nis_" "*" -u
1996 RemoveItem "/Library/Application Support/nsm_" "*" -u
1997 RemoveItem "/Library/Application Support/Norton Application Aliases"
1998 RemoveItem "/Library/Application Support/Norton Solutions Support"
1999 RemoveItem "/Library/Application Support/norton_" "*" -u
2000 RemoveItem "/Library/Application Support/o2spy.log"
2001 RemoveItem "/Library/Application Support/regid.1992-12.com.symantec" "*"
2002 RemoveItem "/Library/Application Support/Symantec"
2003 $DoRemoveIPUA && RemoveItem "/Library/Application Support/Symantec_IPUA"
2004 RemoveItem "/Library/Application Support/symantec_uninstalldashboard" "*"
2005 RemoveItem "/Library/Application Support/SymRun"
2006 RemoveItem "/Library/Authenticators/SymAuthenticator.bundle"
2007 RemoveItem "/Library/CFMSupport/Norton Shared Lib"
2008 RemoveItem "/Library/CFMSupport/Norton Shared Lib Carbon"
2009 RemoveItem "/Library/Contextual Menu Items/NAVCMPlugIn.plugin"
2010 RemoveItem "/Library/Contextual Menu Items/SAVCMPlugIn.plugin"
2011 RemoveItem "/Library/Contextual Menu Items/SymFileSecurityCM.plugin"
2012 RemoveItem "/Library/Documentation/Help/LiveUpdate Help"
2013 RemoveItem "/Library/Documentation/Help/LiveUpdate-Hilfe"
2014 RemoveItem "/Library/Documentation/Help/Norton AntiVirus Help"
2015 RemoveItem "/Library/Documentation/Help/Norton AntiVirus-Hilfe"
2016 RemoveItem "/Library/Documentation/Help/Norton Help"
2017 RemoveItem "/Library/Documentation/Help/Norton Help Scripts"
2018 RemoveItem "/Library/Documentation/Help/Norton Help Scripts Folder"
2019 RemoveItem "/Library/Documentation/Help/Norton Utilities Help"
2020 RemoveItem "/Library/Extensions/FileSecurity.kext"
2021 RemoveItem "/Library/Extensions/ndcengine.kext"
2022 RemoveItem "/Library/Extensions/NortonForMac.kext"
2023 RemoveItem "/Library/Extensions/SymAPComm.kext"
2024 RemoveItem "/Library/Extensions/SymFirewall.kext"
2025 RemoveItem "/Library/Extensions/SymInternetSecurity.kext"
2026 RemoveItem "/Library/Extensions/SymIPS.kext"
2027 RemoveItem "/Library/Extensions/SymPersonalFirewall.kext"
2028 RemoveItem "/Library/Extensions/SymXIPS.kext"
2029 RemoveItem "/Library/Frameworks/mach_inject_bundle.framework"
2030 RemoveItem "/Library/InputManagers/Norton Confidential for Safari"
2031 RemoveItem "/Library/InputManagers/Norton Safety Minder"
2032 RemoveItem "/Library/InputManagers/SymWebKitUtils"
2033 RemoveItem "/Library/Internet Plug-Ins/Norton Confidential for Safari.plugin"
2034 RemoveItem "/Library/Internet Plug-Ins/Norton Family Safety.plugin"
2035 RemoveItem "/Library/Internet Plug-Ins/Norton Safety Minder.plugin"
2036 RemoveItem "/Library/Internet Plug-Ins/NortonFamilyBF.plugin"
2037 RemoveItem "/Library/Internet Plug-Ins/NortonInternetSecurityBF.plugin"
2038 RemoveItem "/Library/Internet Plug-Ins/NortonSafetyMinderBF.plugin"
2039 RemoveItem "/Library/LaunchDaemons/com.norton" "*"
2040 RemoveItem "/Library/LaunchDaemons/com.symantec" "*" -x 'com\.symantec\.saturn\.plist'
2041 RemoveCrashReporterLogs
2042 RemoveItem "/Library/Plug-ins/DiskImages/NUMPlugin.bundle"
2043 RemoveItem "/Library/Plug-ins/DiskImages/VRPlugin.bundle"
2044 RemoveItem "/Library/Plug-ins/DiskImages" -e -u
2045 RemoveItem "/Library/Plug-ins" -e -u
2046 RemoveItem "/Library/PreferencePanes/APPrefPane.prefPane"
2047 RemoveItem "/Library/PreferencePanes/FileSaver.prefPane"
2048 RemoveItem "/Library/PreferencePanes/Norton Family Safety.prefPane"
2049 RemoveItem "/Library/PreferencePanes/Norton Safety Minder.prefPane"
2050 RemoveItem "/Library/PreferencePanes/Ribbon.Norton.prefPane"
2051 RemoveItem "/Library/PreferencePanes/SymantecQuickMenu.prefPane"
2052 RemoveItem "/Library/PreferencePanes/SymAutoProtect.prefPane"
2053 RemoveItem "/Library/PrivateFrameworks/NPF.framework"
2054 RemoveItem "/Library/PrivateFrameworks/NPFCoreServices.framework"
2055 RemoveItem "/Library/PrivateFrameworks/NPFDataSource.framework"
2056 RemoveItem "/Library/PrivateFrameworks/PlausibleDatabase.framework"
2057 RemoveItem "/Library/PrivateFrameworks/SymAppKitAdditions.framework"
2058 RemoveItem "/Library/PrivateFrameworks/SymAVScan.framework"
2059 RemoveItem "/Library/PrivateFrameworks/SymBase.framework"
2060 RemoveItem "/Library/PrivateFrameworks/SymConfidential.framework"
2061 RemoveItem "/Library/PrivateFrameworks/SymDaemon.framework"
2062 RemoveItem "/Library/PrivateFrameworks/SymFirewall.framework"
2063 RemoveItem "/Library/PrivateFrameworks/SymInternetSecurity.framework"
2064 RemoveItem "/Library/PrivateFrameworks/SymIPS.framework"
2065 RemoveItem "/Library/PrivateFrameworks/SymIR.framework"
2066 RemoveItem "/Library/PrivateFrameworks/SymLicensing.framework"
2067 RemoveItem "/Library/PrivateFrameworks/SymNetworking.framework"
2068 RemoveItem "/Library/PrivateFrameworks/SymOxygen.framework"
2069 RemoveItem "/Library/PrivateFrameworks/SymPersonalFirewall.framework"
2070 RemoveItem "/Library/PrivateFrameworks/SymScheduler.framework"
2071 RemoveItem "/Library/PrivateFrameworks/SymSEP.framework"
2072 RemoveItem "/Library/PrivateFrameworks/SymSharedSettings.framework"
2073 RemoveItem "/Library/PrivateFrameworks/SymSubmission.framework"
2074 RemoveItem "/Library/PrivateFrameworks/SymSystem.framework"
2075 RemoveItem "/Library/PrivateFrameworks/SymUIAgent.framework"
2076 RemoveItem "/Library/PrivateFrameworks/SymUIAgentUI.framework"
2077 if [ ! -e "$VolumePrefix/Library/PrivateFrameworks/SymWebKitUtils.framework/Versions/A/Resources/SymWKULoader.dylib" \
2078 -o \( $CreateFilesRemovedListOnly = true -a $ListOnlyFilesThatExist = false \) ] ; then
2079 RemoveItem "/Library/PrivateFrameworks/SymWebKitUtils.framework"
2080 fi
2081 RemoveItem "/Library/PrivilegedHelperTools/com.symantec" "*" -x "com\.symantec\.NWPService"
2082 RemoveItem "/Library/PrivilegedHelperTools/com.symantec.NWPService" -u
2083 RemoveItem "/Library/PrivilegedHelperTools/NATRemoteLock.app"
2084 IFS='
2085'
2086 for EachReceiptLine in `echo "$ReceiptsTable" | grep . | grep -v '^#'` ; do
2087 ReceiptName=`echo "$EachReceiptLine" | awk -F " " '{print $1}'`
2088 ReceiptArg=`echo "$EachReceiptLine" | awk -F " " '{print $2}'`
2089 if [ "z$ReceiptArg" = z-a ] ; then
2090 RemoveItem "/Library/Receipts/$ReceiptName" "*"
2091 RemoveItem "/Library/Receipts/$ReceiptName"Dev "*"
2092 else
2093 if [ "z$ReceiptName" = zSymWebKitUtils.pkg -o "z$ReceiptName" = zSymWebKitUtilsDev.pkg ] ; then
2094 # If SymWKULoader exists and CleanUpSymWebKitUtils does not, skip deletion of SymWebKitUtils receipt
2095 [ -e "$VolumePrefix/Library/PrivateFrameworks/SymWebKitUtils.framework/Versions/A/Resources/SymWKULoader.dylib" -a ! -e /Library/StartupItems/CleanUpSymWebKitUtils ] && continue
2096 fi
2097 RemoveItem "/Library/Receipts/$ReceiptName"
2098 if [ "`echo "$ReceiptName" | grep '\.pkg$'`" ] ; then
2099 ReceiptName="`basename "$ReceiptName" .pkg`Dev.pkg"
2100 RemoveItem "/Library/Receipts/$ReceiptName"
2101 fi
2102 fi
2103 done
2104 RemoveItem "/Library/ScriptingAdditions/SymWebKitUtils.osax"
2105 RemoveItem "/Library/ScriptingAdditions/SymWebKitUtilsSL.osax"
2106 RemoveItem "/Library/Services/Norton for Mac.service"
2107 RemoveItem "/Library/Services/ScanService.service"
2108 RemoveItem "/Library/Services/Symantec" "*"
2109 RemoveItem "/Library/Services/SymSafeWeb.service"
2110 RemoveItem "/Library/Services" -e -u
2111 RemoveItem "/Library/StartupItems/NortonAutoProtect"
2112 RemoveItem "/Library/StartupItems/NortonAutoProtect.kextcache"
2113 RemoveItem "/Library/StartupItems/NortonLastStart"
2114 RemoveItem "/Library/StartupItems/NortonMissedTasks"
2115 RemoveItem "/Library/StartupItems/NortonPersonalFirewall"
2116 RemoveItem "/Library/StartupItems/NortonPrivacyControl"
2117 RemoveItem "/Library/StartupItems/NUMCompatibilityCheck"
2118 RemoveItem "/Library/StartupItems/SMC"
2119 RemoveItem "/Library/StartupItems/SymAutoProtect"
2120 RemoveItem "/Library/StartupItems/SymAutoProtect.kextcache"
2121 RemoveItem "/Library/StartupItems/SymDCInit"
2122 RemoveItem "/Library/StartupItems/SymMissedTasks"
2123 RemoveItem "/Library/StartupItems/SymProtector"
2124 RemoveItem "/Library/StartupItems/SymQuickMenuOSFix"
2125 RemoveItem "/Library/StartupItems/SymWebKitUtilsOSFix"
2126 RemoveItem "/Library/StartupItems/TrackDelete"
2127 RemoveItem "/Library/StartupItems/VolumeAssist"
2128 RemoveItem "/Library/Symantec/tmp"
2129 RemoveItem "/Library/Symantec" -E -u
2130 RemoveItem "/Library/Widgets/NAV.wdgt"
2131 RemoveItem "/Library/Widgets/Symantec Alerts.wdgt"
2132 RemoveItem "/Library/Widgets" -E -u
2133 RemoveItem "/Norton AntiVirus Installer Log"
2134# Folder with files erroneously created by an early Corsair installer:
2135 RemoveItem "/opt/Symantec"
2136# Folder erroneously created by that Corsair installer - removed if empty:
2137 RemoveItem "/opt" -E -u
2138# Folder erroneously created by NPF 300.001 - removed if empty:
2139 RemoveItem "/Personal" -e -u
2140# Folder erroneously created by NPF 300.001 - removed if empty:
2141 RemoveItem "/Solutions" -e -u
2142# Folder erroneously created by NPF 300.001 - removed if empty:
2143 RemoveItem "/Support/Norton" -e -u
2144# Folder erroneously created by NPF 300.001 - removed if empty:
2145 RemoveItem "/Support" -e -u
2146 RemoveItem "/symaperr.log"
2147 RemoveItem "/symapout.log"
2148# Four frameworks erroneously installed by early builds of NAV 9.0.1:
2149 RemoveItem "/SymAppKitAdditions.framework"
2150 RemoveItem "/SymBase.framework"
2151 RemoveItem "/SymNetworking.framework"
2152 RemoveItem "/SymSystem.framework"
2153 RemoveItem "/System/Library/Authenticators/SymAuthenticator.bundle"
2154 RemoveItem "/System/Library/CFMSupport/Norton Shared Lib Carbon"
2155 RemoveItem "/System/Library/CoreServices/NSWemergency"
2156 RemoveItem "/System/Library/CoreServices/NUMemergency"
2157 RemoveItem "/System/Library/Extensions/DeleteTrap.kext"
2158 RemoveItem "/System/Library/Extensions/KTUM.kext"
2159 RemoveItem "/System/Library/Extensions/ndcengine.kext"
2160 RemoveItem "/System/Library/Extensions/NortonForMac.kext"
2161 RemoveItem "/System/Library/Extensions/NPFKPI.kext"
2162 RemoveItem "/System/Library/Extensions/SymDC.kext"
2163 RemoveItem "/System/Library/Extensions/SymEvent.kext"
2164 RemoveItem "/System/Library/Extensions/symfs.kext"
2165 RemoveItem "/System/Library/Extensions/SymInternetSecurity.kext"
2166 RemoveItem "/System/Library/Extensions/SymIPS.kext"
2167 RemoveItem "/System/Library/Extensions/SymOSXKernelUtilities.kext"
2168 RemoveItem "/System/Library/Extensions/SymPersonalFirewall.kext"
2169 RemoveItem "/System/Library/Extensions/SymXIPS.kext"
2170 RemoveItem "/System/Library/StartupItems/NortonAutoProtect"
2171 RemoveItem "/System/Library/StartupItems/SymMissedTasks"
2172 RemoveItem "/System/Library/Symantec"
2173 RemoveItem "/System/Library/SymInternetSecurity.kext"
2174 RemoveItem "/SystemWorks Installer Log"
2175 RemoveItem "/tmp/com.symantec.liveupdate.reboot"
2176 RemoveItem "/tmp/com.symantec.liveupdate.restart"
2177 RemoveItem "/tmp/com.symantec.NFM.liveupdate.reboot"
2178 RemoveItem "/tmp/jlulogtemp"
2179 RemoveItem "/tmp/LiveUpdate." "*"
2180 RemoveItem "/tmp/liveupdate"
2181 RemoveItem "/tmp/lulogtemp"
2182 RemoveItem "/tmp/O2Spy.log"
2183 RemoveItem "/tmp/SymSharedFrameworks" "*"
2184 RemoveItem "/tmp/symask"
2185 RemoveItem "/Users/dev/bin/smellydecode"
2186 RemoveItem "/Users/dev/bin" -E -u
2187 RemoveItem "/Users/dev" -E -u
2188 RemoveItem "/Users/Shared/NAV Corporate"
2189 RemoveItem "/Users/Shared/NIS Corporate"
2190 RemoveItem "/Users/Shared/RemoveSymantecMacFilesRemovesThese.txt"
2191 RemoveItem "/Users/Shared/RemoveSymantecMacFilesLog.txt"
2192 RemoveItem "/Users/Shared/RemoveSymantecMacFilesRemovesThese.txt"
2193 RemoveItem "/Users/Shared/RemoveSymantecMacFilesLog.txt"
2194 RemoveItem "/Users/Shared/SymantecRemovalToolRemovesThese.txt"
2195 RemoveItem "/Users/Shared/SymantecRemovalToolLog.txt"
2196 RemoveItem "/usr/bin/nortonscanner"
2197 RemoveItem "/usr/bin/nortonsettings"
2198 RemoveItem "/usr/bin/MigrateQTF"
2199 RemoveItem "/usr/bin/navx"
2200 RemoveItem "/usr/bin/npfx"
2201 RemoveItem "/usr/bin/savx"
2202 RemoveItem "/usr/bin/scfx"
2203 RemoveItem "/usr/bin/symsched"
2204 RemoveItem "/usr/lib/libsymsea." "dylib"
2205 RemoveItem "/usr/lib/libwpsapi.dylib"
2206 RemoveItem "/usr/local/bin/CoreLocationProviderTest"
2207 RemoveItem "/usr/local/bin/KeyGenerator"
2208 RemoveItem "/usr/local/bin/LocationProviderInterfaceTest"
2209 RemoveItem "/usr/local/bin/LocationProviderTest"
2210 RemoveItem "/usr/local/bin/MigrateQTF"
2211 RemoveItem "/usr/local/bin/navx"
2212 RemoveItem "/usr/local/bin/nortonscanner"
2213 RemoveItem "/usr/local/bin/nortonsettings"
2214 RemoveItem "/usr/local/bin/npfx"
2215 RemoveItem "/usr/local/bin/SkyhookProviderTest"
2216 RemoveItem "/usr/local/bin" -E -u
2217 RemoveItem "/usr/local/lib/libAPFeature.a"
2218 RemoveItem "/usr/local/lib/libcx_lib.so"
2219 RemoveItem "/usr/local/lib/libecomlodr.dylib"
2220 RemoveItem "/usr/local/lib/libgecko3parsers.dylib"
2221 RemoveItem "/usr/local/lib/liblux.so." "*"
2222 RemoveItem "/usr/local/lib/libnlucallback.dylib"
2223 RemoveItem "/usr/local/lib/libsymsea." "dylib"
2224 RemoveItem "/usr/local/lib" -E -u
2225 RemoveItem "/usr/share/man/man1/NAVScanIDs.h"
2226 RemoveItem "/var/db/NATSqlDatabase.db"
2227 RemoveItem '/var/db/receipts/$(SYM_SKU_REVDOMAIN).install.bom'
2228 RemoveItem '/var/db/receipts/$(SYM_SKU_REVDOMAIN).install.plist'
2229 RemoveItem "/var/db/receipts/com.symantec" "*" -x "com\.symantec-it\..*"
2230 RemoveItem "/var/db/receipts/com.Symantec" "*" -x "com\.Symantec-it\..*"
2231 RemoveItem "/var/log/du.log" "*"
2232 RemoveItem "/var/log/dulux.log" "*"
2233 RemoveItem "/var/log/lut.log" "*"
2234 RemoveItem "/var/log/lux.log" "*"
2235 RemoveItem "/var/log/luxtool.log" "*"
2236 RemoveItem "/var/log/mexd.log" "*"
2237 RemoveItem "/var/log/microdef.log" "*"
2238 RemoveItem "/var/log/nortondns.log"
2239 RemoveItem "/var/log/Npfkernel.log.fifo"
2240 RemoveItem "/var/root/Applications/Norton Internet Security.app"
2241 RemoveItem "/var/root/Applications" -E
2242 RemoveItem "/var/root/Library/Bundles/NAVIR.bundle"
2243 RemoveItem "/var/root/Library/Bundles" -E -u
2244 RemoveItem "/var/root/Library/Contextual Menu Items/NAVCMPlugIn.plugin"
2245 RemoveItem "/var/root/Library/Contextual Menu Items" -E -u
2246 RemoveItem "/var/tmp/com.symantec" "*"
2247 RemoveItem "/var/tmp/com.Symantec" "*"
2248 RemoveItem "/var/tmp/symantec_error_report" "*"
2249 # Delete logs listed in logging conf files within /etc/symantec
2250 IFS='
2251'
2252 for LUXLogFile in `cat "/Library/Application Support/Symantec/Silo/NFM/LiveUpdate/Conf/lux.logging.conf" /etc/symantec/dulux.logging.conf /etc/symantec/lux.logging.conf /etc/symantec/microdef.logging.conf 2>/dev/null | tr '\015' '\012' | grep logger.sink.file.filePath= | awk -F = '{print $2}' | sort -f | uniq` ; do
2253 RemoveItem "$LUXLogFile" "*"
2254 done
2255 if [ -f /etc/symantec/defutils.conf ] ; then
2256 DefUtilsLogContents=`cat /etc/symantec/defutils.conf 2>/dev/null | tr '\015' '\012'`
2257 DefUtilsLogDir=`printf "%s" "$DefUtilsLogContents" | grep defutillog_dir= | awk -F = '{print $2}'`
2258 if [ "$DefUtilsLogDir" ] ; then
2259 DefUtilsLogBaseName=`printf "%s" "$DefUtilsLogContents" | grep defutillog_name= | awk -F = '{print $2}'`
2260 [ "$DefUtilsLogBaseName" ] && RemoveItem "$DefUtilsLogDir/$DefUtilsLogBaseName".log "*"
2261 fi
2262 fi
2263 RemoveItem "/etc/symantec" -d -x "saturn"
2264 RemoveItem "/etc/symantec" -E -u
2265 if [ -f "$VolumePrefix/etc/syslog.conf" -a $CreateFilesRemovedListOnly = false ] ; then
2266 # Remove Norton Personal Firewall entries from /etc/syslog.conf
2267 sed -e "/Norton Personal Firewall/d" -e "/Npfkernel.log.fifo/d" "$VolumePrefix/etc/syslog.conf" > /tmp/NPF.syslog.conf
2268 if [ -s /tmp/NPF.syslog.conf ] ; then
2269 /bin/cp -f /tmp/NPF.syslog.conf "$VolumePrefix/etc/syslog.conf"
2270 fi
2271 /bin/rm -f /tmp/NPF.syslog.conf
2272 fi
2273 RemoveFilesFromLibraryAndUserDirectories "$1"
2274 RemoveItem /Library/Preferences/Network -E -u
2275 if [ -s "$FilesRemovedFilesOnlyList" ] ; then
2276 sort -f "$FilesRemovedFilesOnlyList" | uniq | grep . >> "$FilesRemovedList"
2277 fi
2278 RemoveLoginKeychainPasswords "$CurrentVolumeBeingUsed"
2279 # If removing files from the boot volume
2280 if [ $CreateFilesRemovedListOnly = false -a "z$CurrentVolumeBeingUsed" = z/ ] ; then
2281 # Kill Symantec processes and attempt to remove Symantec folder again in case Symantec
2282 # folder was re-created with incorrect permissions (Etrack 3442959) while other files
2283 # were removed
2284 $DoKillProcesses && KillSymantecProcesses &>/dev/null
2285 RemoveItem "/Library/Application Support/Symantec"
2286 fi
2287}
2288
2289RemoveCrashReporterLogs()
2290{
2291 # Usage: RemoveCrashReporterLogs
2292 # Summary: Removes CrashReporter logs. GetComputerUsers function must be run
2293 # and VolumePrefix must be defined before running this function.
2294 #
2295 # CrashLogGrepPattern will match visible or invisible (name begins with a period) Symantec files
2296 local CrashLogGrepPattern='/\.?com\.norton|/\.?com\.symantec|/\.?LiveUpdate|\.?/LUTool|/\.?NFM|/\.?Norton|/\.?Sym'
2297 local LogsToDelete=""
2298 local LogToDelete
2299 local UserDir
2300 IFS='
2301'
2302 for UserDir in $ComputerUsersHomeDirsAndRootDir ; do
2303 [ "$UserDir" = / ] && UserDir=""
2304 LogsToDelete="$LogsToDelete
2305`find "$VolumePrefix$UserDir/Library/Application Support/CrashReporter" "$VolumePrefix$UserDir/Library/Application Support/DiagnosticReports" "$VolumePrefix$UserDir/Library/Logs/CrashReporter" "$VolumePrefix$UserDir/Library/Logs/DiagnosticReports" -type f 2>/dev/null | egrep -i "$CrashLogGrepPattern"`"
2306 done
2307 LogsToDelete=`echo "$LogsToDelete" | grep / | sort -f`
2308 if [ "$VolumePrefix" ] ; then
2309 # Remove VolumePrefix from beginning of paths
2310 LogsToDelete=`echo "$LogsToDelete" | awk -v VOLUME="$VolumePrefix" '{print substr($0,length(VOLUME)+1)}'`
2311 fi
2312 if [ "$LogsToDelete" ] ; then
2313 for LogToDelete in $LogsToDelete ; do
2314 RemoveItem "$LogToDelete" -u
2315 done
2316 fi
2317}
2318
2319RemoveEmptyDirectory()
2320{
2321 # Usage: RemoveEmptyDirectory $1
2322 # Argument: $1 = Full path name of directory
2323 # Summary: Removes directory $1 if it is empty or if it contains
2324 # only .DS_Store and/or .localized (the next best thing
2325 # to being empty).
2326 #
2327 # If $1 is a directory and not a link
2328 if [ -d "$1" -a ! -L "$1" ] ; then
2329 # If folder contains only .DS_Store and/or .localized, or is empty
2330 if [ -z "`ls "$1" 2>/dev/null | grep -v "^\.DS_Store\|^\.localized"`" ] ; then
2331 $ShowFilesAsRemoved && echo " Removing: \"$1\""
2332 # Clear immutable bit to remove any Finder lock
2333 chflags -R nouchg "$1" 2>/dev/null 1>&2
2334 /bin/rm -rf "$1" 2>/dev/null 1>&2 # Remove folder
2335 fi
2336 fi
2337}
2338
2339RemoveFilesFromLibraryAndUserDirectories()
2340{
2341 # Usage: RemoveFilesFromLibraryAndUserDirectories $1
2342 # Argument: $1 = Name of volume from which to remove preferences.
2343 # The name must begin with "/Volumes/"
2344 # unless it is "/" (boot volume).
2345 # Summary: Removes all Symantec files & folders from each user's
2346 # preferences, /Library/Caches, and /Library/Preferences.
2347 # Removes help files from /Library/Documentation. Removes
2348 # folders incorrectly created by NAV 7.0.2 from each
2349 # user's home directory.
2350 #
2351 local FSDDir
2352 local UserHomeDir
2353 local UserLibraryDir
2354 CurrentVolumeBeingUsed="$1"
2355 if [ "$1" = "/" ] ; then
2356 VolumeToCheck=""
2357 else
2358 VolumeToCheck="$1"
2359 fi
2360 # set IFS to only newline to get all user names
2361 IFS='
2362'
2363 for UserHomeDir in $ComputerUsersHomeDirsAndRootDir ; do
2364 if [ "$UserHomeDir" = "/" ] ; then
2365 UserHomeDir=""
2366 fi
2367 UserLibraryDir="$UserHomeDir/Library"
2368 # If UserLibraryDir is not a directory, skip to the next name
2369 [ ! -d "$VolumeToCheck$UserLibraryDir" ] && continue
2370 cd "$VolumeToCheck/"
2371 # If a user's home directory, delete folders from user's home directory
2372 # that were incorrectly created by NAV 7.0.2
2373 if [ "$UserHomeDir" ] ; then
2374 RemoveItem "$UserHomeDir/Applications/LiveUpdate Folder (OS X)"
2375 RemoveItem "$UserHomeDir/Applications/Norton AntiVirus (OS X)"
2376 RemoveItem "$UserHomeDir/Applications" -e -u
2377 fi
2378 FirefoxExtensions=`find "$UserLibraryDir/Application Support/Firefox/Profiles/"*/extensions/*"@symantec.com.xpi" 2>/dev/null`
2379 for FirefoxExtension in $FirefoxExtensions ; do
2380 RemoveItem "$FirefoxExtension"
2381 done
2382 RemoveItem "$UserLibraryDir/Application Support/Norton" "*"
2383 # If a user directory
2384 if [ "$UserHomeDir" ] ; then
2385 RemoveItem "$UserLibraryDir/Application Support/Symantec"
2386 RemoveItem "$UserHomeDir/Application Support/Symantec"
2387 RemoveItem "$UserHomeDir/Application Support" -e
2388 # If .fsd folders should be removed
2389 if $DoRemoveFSDFolders ; then
2390 # For each .fsd folder in user's Downloads folder
2391 for FSDDir in `find "$UserHomeDir/Downloads" -type d -name ".fsd" 2>/dev/null` ; do
2392 RemoveItem "$FSDDir"
2393 done
2394 fi
2395 elif ! $CreateFilesRemovedListOnly ; then
2396 # Make second attempt to remove "/Application Support/Symantec/ErrorReporting"
2397 RemoveItem "$UserLibraryDir/Application Support/Symantec/ErrorReporting"
2398 RemoveItem "$UserLibraryDir/Application Support/Symantec"
2399 fi
2400 RemoveItem "$UserLibraryDir/Documentation/Help/Norton Privacy Control Help"
2401 RemoveItem "$UserLibraryDir/Documentation/Help/Norton Personal Firewall Help"
2402 RemoveItem "$UserLibraryDir/Caches/com.apple.Safari/Extensions/Norton" "*" -u
2403 RemoveItem "$UserLibraryDir/Caches/com.apple.Safari/Extensions/Symantec" "*" -u
2404 RemoveItem "$UserLibraryDir/Caches/com.norton" "*" -u
2405 RemoveItem "$UserLibraryDir/Caches/com.symantec" "*" -u
2406 RemoveItem "$UserLibraryDir/Caches/Norton" "*" -u
2407 RemoveItem "$UserLibraryDir/Caches/Symantec" "*" -u
2408 if $DoRemoveIPUA ; then
2409 # If not a user directory
2410 if [ -z "$UserHomeDir" ] ; then
2411 RemoveItem "$UserLibraryDir/LaunchAgents/com.symantec" "*"
2412 elif $DoRemoveInstallerLaunchAgents ; then
2413 RemoveItem "$UserLibraryDir/LaunchAgents/com.symantec" "*"
2414 else
2415 RemoveItem "$UserLibraryDir/LaunchAgents/com.symantec" "*" -x 'com\.symantec\..*Installer\.plist'
2416 fi
2417 else
2418 # If not a user directory
2419 if [ -z "$UserHomeDir" ] ; then
2420 RemoveItem "$UserLibraryDir/LaunchAgents/com.symantec" "*" -x 'com\.symantec\.ipua\.plist'
2421 elif $DoRemoveInstallerLaunchAgents ; then
2422 RemoveItem "$UserLibraryDir/LaunchAgents/com.symantec" "*" -x 'com\.symantec\.ipua\.plist'
2423 else
2424 RemoveItem "$UserLibraryDir/LaunchAgents/com.symantec" "*" -x 'com\.symantec\..*Installer\.plist' -x 'com\.symantec\.ipua\.plist'
2425 fi
2426 fi
2427 RemoveItem "$UserLibraryDir/Logs/.ipuaint"
2428 RemoveItem "$UserLibraryDir/Logs/.ipualog"
2429 RemoveItem "$UserLibraryDir/Logs/LUTool.txt"
2430 RemoveItem "$UserLibraryDir/Logs/Norton" "*"
2431 RemoveItem "$UserLibraryDir/Logs/o2spy.log"
2432 RemoveItem "$UserLibraryDir/Logs/Symantec" "*"
2433# RemoveItem "$UserLibraryDir/Logs/Symantec" "*" -u # May need to add this back with refined matching
2434 RemoveItem "$UserLibraryDir/Logs/SymaIpua" "*"
2435 RemoveItem "$UserLibraryDir/Logs/SymAPErr.log"
2436 RemoveItem "$UserLibraryDir/Logs/SymAPOut.log"
2437 RemoveItem "$UserLibraryDir/Logs/SymBfw_NFM.log"
2438 RemoveItem "$UserLibraryDir/Logs/SymCommP" "*"
2439 RemoveItem "$UserLibraryDir/Logs/SymDebugLeaks.log"
2440 RemoveItem "$UserLibraryDir/Logs/SymDeepsight" "*"
2441 RemoveItem "$UserLibraryDir/Logs/SymFWDeepSightTrie.txt"
2442 RemoveItem "$UserLibraryDir/Logs/SymFWLog.log"
2443 RemoveItem "$UserLibraryDir/Logs/SymFWRules.log" "*"
2444 RemoveItem "$UserLibraryDir/Logs/SymHTTPSubmissions.txt"
2445 RemoveItem "$UserLibraryDir/Logs/SymInstall" "*"
2446 RemoveItem "$UserLibraryDir/Logs/SymIpua" "*"
2447 RemoveItem "$UserLibraryDir/Logs/SymOxygen" "*"
2448 RemoveItem "$UserLibraryDir/Logs/SymQual" "*"
2449 RemoveItem "$UserLibraryDir/Logs/SymScanServerDaemon.log"
2450 RemoveItem "$UserLibraryDir/Logs/SymSharedSettingsd.log"
2451 RemoveItem "$UserLibraryDir/Logs/SymUninstall" "*"
2452 RemoveItem "$UserLibraryDir/Logs/UIAgent" "*"
2453 RemoveItem "$UserLibraryDir/Preferences/ByHost/com.symantec" "*"
2454 RemoveItem "$UserLibraryDir/Preferences/com.norton" "*"
2455 if $DoRemoveIPUA ; then
2456 RemoveItem "$UserLibraryDir/Preferences/com.symantec" "*" -x 'com\.symantec\.sacm.*' -x 'com\.symantec\.smac.*'
2457 else
2458 RemoveItem "$UserLibraryDir/Preferences/com.symantec" "*" -x 'com\.symantec\.sacm.*' -x 'com\.symantec\.smac.*' -x 'com\.symantec\.ipua\.plist'
2459 fi
2460 RemoveItem "$UserLibraryDir/Preferences/group.com.symantec" "*"
2461 RemoveItem "$UserLibraryDir/Preferences/group.symantec" "*"
2462 RemoveItem "$UserLibraryDir/Preferences/LiveUpdate Preferences"
2463 RemoveItem "$UserLibraryDir/Preferences/LU Admin Preferences"
2464 RemoveItem "$UserLibraryDir/Preferences/LU Host Admin.plist"
2465 RemoveItem "$UserLibraryDir/Preferences/NAV8.0.003.plist"
2466 RemoveItem "$UserLibraryDir/Preferences/Network/com.symantec" "*"
2467 RemoveItem "$UserLibraryDir/Preferences/Norton AntiVirus Prefs Folder"
2468 RemoveItem "$UserLibraryDir/Preferences/Norton Application Aliases"
2469 RemoveItem "$UserLibraryDir/Preferences/Norton Personal Firewall Log"
2470 RemoveItem "$UserLibraryDir/Preferences/Norton Scheduler OS X.plist"
2471 RemoveItem "$UserLibraryDir/Preferences/Norton Utilities Preferences"
2472 RemoveItem "$UserLibraryDir/Preferences/Norton Zone"
2473 RemoveItem "$UserLibraryDir/Preferences/wcid"
2474 RemoveItem "$UserLibraryDir/Safari/Extensions/Norton" "*"
2475 RemoveItem "$UserLibraryDir/Safari/Extensions/Symantec" "*"
2476 RemoveItem "$UserLibraryDir/Saved Application State/com.symantec" "*" -u
2477 done
2478}
2479
2480RemoveInvisibleFilesFromVolume()
2481{
2482 # Usage: RemoveInvisibleFilesFromVolume $1
2483 # Argument: $1 = Volume name. The name should begin with "/Volumes/"
2484 # unless it is "/" (boot volume).
2485 # Summary: Removes the invisible Symantec for OS X files - Norton FS
2486 # and AntiVirus QuickScan files - from $1.
2487 #
2488 ! $RemoveInvisibleFiles && return
2489 CurrentVolumeBeingUsed="$1"
2490 cd "$1"
2491 if $CreateFilesRemovedListOnly ; then
2492 $DoShowOnlyFilesThatShouldHaveBeenUninstalled || echo "Finding invisible Symantec files on: $1" >&2
2493 elif $ShowFilesAsRemoved ; then
2494 echo "Locating invisible Symantec files in: $1"
2495 else
2496 echo "Removing invisible Symantec files from: $1"
2497 fi
2498 RemoveItem "/.SymAVQSFile"
2499 RemoveItem "/NAVMac800QSFile"
2500 RemoveItem "/Norton FS Data"
2501 RemoveItem "/Norton FS Index"
2502 RemoveItem "/Norton FS Volume"
2503 RemoveItem "/Norton FS Volume 2"
2504}
2505
2506RemoveItem()
2507{
2508 # Usage: RemoveItem ["private_was_added"] FilePath [-d] [-e | -E] [-u] [-x <pattern>] [FileExtension]
2509 #
2510 # Summary: Deletes the file or folder passed, FilePath, from the
2511 # current directory. FilePath should be full path beginning
2512 # with /.
2513 #
2514 # Options:
2515 # -d Treat FilePath as a directory in which to match FileExtension
2516 # or when using the -x option. See FileExtension and -x option
2517 # below. The -d must be passed prior to passing the -x option.
2518 # FilePath itself will not be deleted, only the matching items
2519 # within it will be deleted. If no FileExtension is passed, "*"
2520 # is assumed.
2521 # -e Delete FilePath only if it is a directory that is empty or
2522 # that contains only ".DS_Store" and/or ".localized" files.
2523 # If the folder could not be deleted, error message is shown.
2524 # -E Same as the -e option, except no error message is shown if
2525 # the folder could not be deleted.
2526 # -u Item is not removed by Symantec Uninstaller.app.
2527 # -x <Pattern>
2528 # Pattern to exclude from file list. Pattern will become
2529 # ^FilePathPattern$ (or ^FilePath/Pattern$ if -d was passed
2530 # before -x was passed) so add wildcards as needed. Make sure
2531 # to prefix special characters you wish to match with \
2532 # (example: to match a period, \.). You may pass several
2533 # -x <pattern> groupings. Pattern is an extended regular
2534 # expression. Letter case is ignored.
2535 # <FileExtension>
2536 # All files are deleted that match FilePath.*FileExtension or
2537 # if -d was passed that match FilePath/.*FileExtension.
2538 # To match any files that begin with FilePath, pass "*" as
2539 # FileExtension (don't pass * unquoted). Only the last
2540 # FileExtension passed will be used. Periods will be escaped
2541 # (i.e., each . will become \.).
2542 # "private_was_added"
2543 # This gets passed as the first argument by RemoveItem() when
2544 # FilePath is a link in PrivateLinksPattern. This option is
2545 # only to be passed by RemoveItem() itself.
2546 #
2547 # Note: Make sure to run the SetupCleanup function before the
2548 # first run of this function and run the FinishCleanup
2549 # function before exiting the script.
2550 #
2551 # Make sure to change directory to root of the volume you
2552 # want the file or folder removed from before calling this
2553 # function.
2554 #
2555 # FilePath must be the first argument unless "private_was_added"
2556 # was passed as the first. The other options may appear after
2557 # FilePath in any order.
2558 #
2559 local ExclusionPattern=""
2560 local FilePath="$1"
2561 shift
2562 # If / or no file name passed
2563 if [ "z$FilePath" = z/ -o -z "$FilePath" ] ; then
2564 return
2565 # Else if this is a call by RemoveItem() with /private added to original path
2566 elif [ "z$FilePath" = zprivate_was_added ] ; then
2567 FilePath="$1"
2568 shift
2569 # Else if original path begins with /private/ and is targeted by a link in /
2570 elif [ "`echo "$FilePath" | egrep -e "$PrivateDirectoriesPattern"`" ] ; then
2571 # Remove /private from beginning of path
2572 FilePath=`echo "$FilePath" | awk '{print substr($0,9)}'`
2573 fi
2574 VolumeFromWhichToRemove="`pwd`"
2575 # If path passed begins with /etc/, /tmp/, or /var/
2576 if [ "`echo "$FilePath" | egrep -e "$PrivateLinksPattern"`" ] ; then
2577 PrivateLinkName=`echo "$FilePath" | awk -F / '{print $2}'`
2578 PrivateLinkRoot="$VolumeFromWhichToRemove/$PrivateLinkName"
2579 PrivateDirRoot="$VolumeFromWhichToRemove/private/$PrivateLinkName"
2580 # If path does not point to the same file as "/private/" + path
2581 if [ ! "$PrivateLinkRoot" -ef "$PrivateDirRoot" ] ; then
2582 FilePathOriginal="$FilePath"
2583 # Attempt to remove path from within /private first
2584 RemoveItem "private_was_added" "/private$FilePath" "$@"
2585 # Then attempt to remove path itself
2586 FilePath="$FilePathOriginal"
2587 fi
2588 fi
2589 if [ "$VolumeFromWhichToRemove" = "/" ] ; then
2590 FullFilePath="$FilePath"
2591 else
2592 FullFilePath="$VolumeFromWhichToRemove$FilePath"
2593 fi
2594 # If logs should not be removed
2595 if ! $DoRemoveLogs ; then
2596 # If file path contains "/Library/Logs/", skip removal
2597 if [ "`echo "$FullFilePath" | egrep '/Library/Logs/'`" ] ; then
2598 return
2599 fi
2600 fi
2601 PathDir=`dirname "$FullFilePath"`
2602 [ -z "$PathDir" ] && return
2603 # Set PathBasePattern = basename of path with each . translated to \.
2604 PathBasePattern=`basename "$FullFilePath" | sed s/"\."/"\\\\\."/g`
2605 [ -z "$PathBasePattern" ] && return
2606 DeleteOnlyIfEmptyDir=false
2607 ExtensionPassed=""
2608 PathIsDirectory=false
2609 SkipErrorMessageIfEmptyDirNotFound=false
2610 ShouldNotBeRemovedBySymantecUninstaller=false
2611 while [ "$1" ] ; do
2612 case "$1" in
2613 -d)
2614 PathDir="$FullFilePath"
2615 PathBasePattern=""
2616 PathIsDirectory=true
2617 ;;
2618 -e)
2619 DeleteOnlyIfEmptyDir=true
2620 SkipErrorMessageIfEmptyDirNotFound=false
2621 ;;
2622 -E)
2623 DeleteOnlyIfEmptyDir=true
2624 SkipErrorMessageIfEmptyDirNotFound=true
2625 ;;
2626 -u)
2627 ShouldNotBeRemovedBySymantecUninstaller=true
2628 ;;
2629 -x)
2630 if [ "$2" ] ; then
2631 shift
2632 if [ "$ExclusionPattern" ] ; then
2633 ExclusionPattern="$ExclusionPattern|^$PathDir/$1$"
2634 else
2635 ExclusionPattern="^$PathDir/$1$"
2636 fi
2637 fi
2638 ;;
2639 *)
2640 ExtensionPassed="$1"
2641 ;;
2642 esac
2643 shift
2644 done
2645 if [ "z$ExtensionPassed" = "z*" ] ; then
2646 ListOfPaths=`find "$PathDir" -mindepth 1 -maxdepth 1 2>/dev/null | grep -i "^$PathDir/$PathBasePattern" | sort -f`
2647 PathToShow="$FullFilePath`$PathIsDirectory && echo /`*"
2648 elif [ "$ExtensionPassed" ] ; then
2649 ExtensionPassedPattern=`printf "%s" "$ExtensionPassed" | sed s/"\."/"\\\\\."/g`
2650 ListOfPaths=`find "$PathDir" -mindepth 1 -maxdepth 1 2>/dev/null | grep -i "^$PathDir/$PathBasePattern.*$ExtensionPassedPattern$" | sort -f`
2651 PathToShow="$FullFilePath*$ExtensionPassed"
2652 elif $PathIsDirectory ; then
2653 ListOfPaths=`find "$FullFilePath" -mindepth 1 -maxdepth 1 2>/dev/null | sort -f`
2654 PathToShow="$FullFilePath/*"
2655 else
2656 ListOfPaths=`ls -d "$FullFilePath" 2>/dev/null`
2657 PathToShow="$FullFilePath"
2658 fi
2659 # If there are items to exclude from the list and there are matching items
2660 if [ "z$ExclusionPattern" != z -a -n "$ListOfPaths" ] ; then
2661 ListOfPaths=`printf "%s" "$ListOfPaths" | egrep -i -v -e "$ExclusionPattern"`
2662 fi
2663 if $CreateFilesRemovedListOnly ; then
2664 # If -E passed, then don't list the item
2665 $SkipErrorMessageIfEmptyDirNotFound && return
2666 if ! $ListOnlyFilesThatExist ; then
2667 echo "$PathToShow`$DeleteOnlyIfEmptyDir && echo " [folder deleted only if empty]"`" >> "$FilesRemovedList"
2668 # Else if file exists
2669 elif [ "$ListOfPaths" ] ; then
2670 ItemsToAddToList=""
2671 IFS='
2672'
2673 if $DeleteOnlyIfEmptyDir ; then
2674 $ShowOnlyRegularFiles || ItemsToAddToList="$ListOfPaths"
2675 else
2676 for EachItemListed in $ListOfPaths ; do
2677 if [ -f "$EachItemListed" ] ; then
2678 ItemsToAddToList="$ItemsToAddToList
2679$EachItemListed"
2680 elif [ -L "$EachItemListed" -a $ShowOnlyRegularFiles = false ] ; then
2681 ItemsToAddToList="$ItemsToAddToList
2682$EachItemListed"
2683 else
2684 ItemsToAddToList="$ItemsToAddToList
2685`find "$EachItemListed" $FindOption1 $FindOption2 2>/dev/null`"
2686 fi
2687 done
2688 fi
2689 for EachItemFound in $ItemsToAddToList ; do
2690 if $ShouldNotBeRemovedBySymantecUninstaller ; then
2691 AddedText="$NotRemovedBySymantecUninstallerText"
2692 elif [ "`echo "$EachItemFound" | grep -F "$NotRemovedByNIS6Uninstaller"`" ] ; then
2693 AddedText="$NotRemovedByNIS6UninstallerText"
2694 elif [ "`echo "$EachItemFound" | grep -F "$NotRemovedBySymantecUninstaller"`" ] ; then
2695 AddedText="$NotRemovedBySymantecUninstallerText"
2696 else
2697 AddedText=""
2698 fi
2699 if $ShowOnlyRegularFiles ; then
2700 # If would be an empty folder or would not be removed by Symantec Uninstaller, don't add item to the list
2701 [ $DeleteOnlyIfEmptyDir = true -o -n "$AddedText" ] && continue
2702 fi
2703 echo "$EachItemFound`$DeleteOnlyIfEmptyDir && echo " [folder deleted only if empty]"`$AddedText" >> "$FilesRemovedFilesOnlyList"
2704 done
2705 NoFilesToRemove=false
2706 FilesFoundOnThisVolume=true
2707 fi
2708 return
2709 fi
2710 IFS='
2711'
2712 for EachFullPath in $ListOfPaths ; do
2713 # If -e or -E was passed
2714 if $DeleteOnlyIfEmptyDir ; then
2715 # remove directory only if empty
2716 RemoveEmptyDirectory "$EachFullPath"
2717 # If -E passed, then skip error reporting
2718 $SkipErrorMessageIfEmptyDirNotFound && continue
2719 else
2720 $ShowFilesAsRemoved && echo " Removing: \"$EachFullPath\""
2721 # Clear immutable bit to remove any Finder lock
2722 chflags -R nouchg "$EachFullPath" 2>/dev/null 1>&2
2723 BackupLog "$EachFullPath"
2724 /bin/rm -rf "$EachFullPath" 2>/dev/null 1>&2 # Remove file/folder
2725 fi
2726 # If file still exists
2727 if [ "`ls -d "$EachFullPath" 2>/dev/null`" ] ; then
2728 TheFileWasRemoved=false
2729 else
2730 TheFileWasRemoved=true
2731 SomeFileWasRemoved=true
2732 fi
2733 # If the file/folder was not removed
2734 if ! $TheFileWasRemoved ; then
2735 if ! $ErrorOccurred ; then
2736 # Create LogFile
2737 echo "Symantec files/folders not removed:" >"$LogFile"
2738 chmod a=rw "$LogFile"
2739 ErrorOccurred=true
2740 fi
2741 echo " $EachFullPath" >>"$LogFile"
2742 # Else if boot volume
2743 elif [ "$CurrentVolumeBeingUsed" = "/" ] ; then
2744 RestartMayBeNeeded=true
2745 # If it's not a file that does not require a restart (Etrack 3925328)
2746 if [ -z "`printf "%s" "$EachFullPath" | egrep -ie "$FilesThatDoNotRequireRebootPattern"`" ] ; then
2747 touch "$SymantecCleanupRestartFile"
2748 fi
2749 SomeFileWasRemovedFromBootVolume=true
2750 else
2751 SomeFileWasRemovedFromNonBootVolume=true
2752 fi
2753 NoFilesToRemove=false
2754 FilesFoundOnThisVolume=true
2755 done
2756}
2757
2758RemoveLoginKeychainPasswords()
2759{
2760 # Usage: RemoveLoginKeychainPasswords volume
2761 # Summary: Removes items from login keychains.
2762 # If volume is not / (current boot volume), removal is skipped.
2763 # If volume is not specified, / is assumed.
2764 #
2765 local VolumeBeingPurged="$1"
2766 local ComputerUserEntry
2767 local EachLoginKeychain
2768 local HelpTextToShow
2769 local LoginKeychainPasswordToDelete
2770 local LoginKeychainPasswordToDeleteLine
2771 local UserDir
2772 local UserOfKeychain
2773 # If volume not specified, assume it is boot volume
2774 [ -z "$VolumeBeingPurged" ] && VolumeBeingPurged=/
2775 # If volume being cleaned up is not the boot volume, skip purge
2776 [ "z$VolumeBeingPurged" != z/ ] && return
2777 $DoShowOnlyFilesThatShouldHaveBeenUninstalled || echo "Looking for Symantec login keychain items" 2>/dev/null
2778 IFS='
2779'
2780 for ComputerUserEntry in $ComputerUsersTable ; do
2781 UserOfKeychain=`echo "$ComputerUserEntry" | awk -F ' ' '{print $1}'`
2782 UserDir=`echo "$ComputerUserEntry" | awk -F ' ' '{print $2}'`
2783 EachLoginKeychain="$UserDir/Library/Keychains/login.keychain"
2784 [ ! -f "$EachLoginKeychain" ] && continue
2785 for LoginKeychainPasswordToDeleteLine in $LoginKeychainPasswordsToDelete ; do
2786 LoginKeychainPasswordToDelete=`echo "$LoginKeychainPasswordToDeleteLine" | awk -F ' ' '{print $1}'`
2787 HelpTextToShow=`echo "$LoginKeychainPasswordToDeleteLine" | awk -F ' ' '{print $2}'`
2788 /usr/bin/security find-generic-password -s "$LoginKeychainPasswordToDelete" "$EachLoginKeychain" 2>/dev/null 1>&2
2789 if [ $? = 0 ] ; then
2790 if $CreateFilesRemovedListOnly ; then
2791 echo "$HelpTextToShow ($LoginKeychainPasswordToDelete) would be removed" >> "$FilesRemovedList"
2792 echo "from $UserOfKeychain's login keychain" >> "$FilesRemovedList"
2793 echo "" >> "$FilesRemovedList"
2794 else
2795 echo "Removing $HelpTextToShow ($LoginKeychainPasswordToDelete)"
2796 echo "from $UserOfKeychain's login keychain"
2797 /usr/bin/security delete-generic-password -s "$LoginKeychainPasswordToDelete" "$EachLoginKeychain" 2>/dev/null 1>&2
2798 fi
2799 fi
2800 done
2801 done
2802}
2803
2804RemoveNortonZoneDirectories()
2805{
2806 # Usage: RemoveNortonZoneDirectories user_home_directory
2807 # Summary: Removes Norton Zone paths listed in zoneDirectoryManagerRegistryKey in
2808 # user_home_directory/Preference/com.symantec.nds.Norton-Zone.plist
2809 #
2810 local UserHomeDir="$1"
2811 local ZonePath
2812 local ZonePaths
2813 [ ! -d "$UserHomeDir" ] && return
2814 ZonePaths=`defaults read "$UserHomeDir/Library/Preferences/"com.symantec.nds.Norton-Zone zoneDirectoryManagerRegistryKey 2>/dev/null | grep = | awk -F '"' '{print $2}'`
2815 IFS='
2816'
2817 for ZonePath in $ZonePaths ; do
2818 RemoveItem "$ZonePath"
2819 done
2820 RemoveItem "$UserHomeDir/Norton Zone" "*"
2821}
2822
2823RestartComputer()
2824{
2825 # Usage: RestartComputer
2826 # Summary: Prompts to see if user would like to restart. Restarts
2827 # computer using 'reboot' command if 'yes' or 'y' is
2828 # entered; exits the script otherwise.
2829 # Note: User must be root or an admin for reboot to work, so this
2830 # function should only be used in scripts run as root or
2831 # admin user.
2832 #
2833 echo
2834 if $RunningFromWithinAppBundleOrSupportFolder ; then
2835 ExitScript $FinishedExitCode
2836 elif $QuitWithoutRestarting ; then
2837 echo "Exited the script without restarting the computer."
2838 ExitScript $FinishedExitCode
2839 fi
2840 if $RestartAutomatically ; then
2841 if $PauseBeforeRestarting ; then
2842 printf "Computer will restart in 3 seconds (ctrl-C to cancel restart)..."
2843 sleep 1 &>/dev/null
2844 printf " 3"
2845 sleep 1 &>/dev/null
2846 printf " 2"
2847 sleep 1 &>/dev/null
2848 printf " 1"
2849 sleep 1 &>/dev/null
2850 fi
2851 echo
2852 echo "Computer is restarting..."
2853 reboot
2854 else
2855 echo "Exited the script without restarting the computer."
2856 ExitScript $FinishedExitCode
2857 fi
2858}
2859
2860RunPredeleteScripts()
2861{
2862 # Usage: RunPredeleteScripts [$1]
2863 # Argument: $1 = Path of current volume.
2864 # Summary: If $1 is "" or /, predelete scripts in receipts listed in
2865 # ReceiptsTable are run.
2866 #
2867 local EachReceiptLine
2868 local EachReceiptMatchingAll
2869 local ReceiptList
2870 local ReceiptListMatchingAll=""
2871 local VolumePathPassed="$1"
2872 [ "z$VolumePathPassed" = z/ ] && VolumePathPassed=""
2873 if $CreateFilesRemovedListOnly ; then
2874 if [ "$VolumePathPassed" ] ; then
2875 echo "Receipt predelete scripts would not be run on that volume." >> "$FilesRemovedList"
2876 elif $DoRunPredeleteScripts ; then
2877 echo "Receipt predelete scripts would be run as they are found." >> "$FilesRemovedList"
2878 else
2879 echo "Receipt predelete scripts would not be run because the -d option was specified." >> "$FilesRemovedList"
2880 fi
2881 return
2882 elif [ "$VolumePathPassed" ] ; then
2883 echo "Receipt predelete scripts were not run on that volume."
2884 return
2885 elif ! $DoRunPredeleteScripts ; then
2886 echo "Receipt predelete scripts were not run because the -d option was specified."
2887 return
2888 fi
2889 SYMANTEC_SAVED_DATA_DIR="/private/tmp/$FullScriptName-SYMANTEC_SAVED_DATA_DIR-`date +"%Y%m%d%H%M%S"`"
2890 mkdir -p "$SYMANTEC_SAVED_DATA_DIR" 2>/dev/null
2891 IFS='
2892'
2893 echo "Looking for predelete scripts in Symantec Uninstaller's Receipts folder"
2894 for PredeleteScript in `find "/Library/Application Support/Symantec/Uninstaller" 2>/dev/null | grep -E 'predelete$|pre_delete$'` ; do
2895 if [ -x "$PredeleteScript" ] ; then
2896 echo "--- Running $PredeleteScript ---"
2897 export SYMANTEC_SAVED_DATA_DIR
2898 if $ShowPredeleteErrors ; then
2899 "$PredeleteScript"
2900 else
2901 "$PredeleteScript" 2>/dev/null 1>&2
2902 fi
2903 fi
2904 done
2905 echo "Looking for predelete scripts in /Library/Receipts"
2906 ReceiptList=`echo "$ReceiptsTable" | grep '\.pkg' | grep -v '^#'`
2907 for EachReceiptMatchingAll in `echo "$ReceiptsTable" | grep ' -a' | grep -v '^#' | awk -F ' ' '{print $1}'` ; do
2908 ReceiptListMatchingAll="$ReceiptListMatchingAll
2909`ls -d "/Library/Receipts/$EachReceiptMatchingAll"* 2>/dev/null`"
2910 done
2911 for EachReceiptMatchingAll in $ReceiptListMatchingAll ; do
2912 ReceiptList="$ReceiptList
2913`basename "$EachReceiptMatchingAll"`"
2914 done
2915 for EachReceiptLine in $ReceiptList ; do
2916 ReceiptArg=`echo "$EachReceiptLine" | awk -F " " '{print $2}'`
2917 [ "z$ReceiptArg" = z-s ] && continue
2918 ReceiptName=`echo "$EachReceiptLine" | awk -F " " '{print $1}'`
2919 [ -z "`echo "$ReceiptName" | grep '\.pkg$'`" ] && continue
2920 if [ -d "/Library/Receipts/$ReceiptName" ] ; then
2921 for PredeleteScript in `find "/Library/Receipts/$ReceiptName" 2>/dev/null | grep -E 'predelete$|pre_delete$'` ; do
2922 if [ -x "$PredeleteScript" ] ; then
2923 echo "--- Running $PredeleteScript ---"
2924 export SYMANTEC_SAVED_DATA_DIR
2925 if $ShowPredeleteErrors ; then
2926 "$PredeleteScript"
2927 else
2928 "$PredeleteScript" 2>/dev/null 1>&2
2929 fi
2930 fi
2931 done
2932 fi
2933 ReceiptName="`basename "$ReceiptName" .pkg`Dev.pkg"
2934 if [ -d "/Library/Receipts/$ReceiptName" ] ; then
2935 for PredeleteScript in `find "/Library/Receipts/$ReceiptName" 2>/dev/null | grep -E 'predelete$|pre_delete$'` ; do
2936 if [ -x "$PredeleteScript" ] ; then
2937 echo "--- Running $PredeleteScript ---"
2938 export SYMANTEC_SAVED_DATA_DIR
2939 if $ShowPredeleteErrors ; then
2940 "$PredeleteScript"
2941 else
2942 "$PredeleteScript" 2>/dev/null 1>&2
2943 fi
2944 fi
2945 done
2946 fi
2947 done
2948 rm -rf "$SYMANTEC_SAVED_DATA_DIR" 2>/dev/null
2949}
2950
2951SetupCleanup()
2952{
2953 # Usage: SetupCleanup
2954 # Summary: Initializes variables needed for the RemoveItem function.
2955 #
2956 BackupLogLocationDir="$BackupLogLocationRootDir/`date +"%Y-%m-%d_%H-%M-%S"`"
2957 ErrorOccurred=false
2958 NoFilesToRemove=true
2959 /bin/rm -rf "$FilesRemovedList" "$FilesRemovedFilesOnlyList" 2>/dev/null 1>&2
2960 if $CreateFilesRemovedListOnly ; then
2961 if $ListOnlyFilesThatExist ; then
2962 echo "Summary of what $FullScriptName would do, based on files" > "$FilesRemovedList"
2963 echo "`$RemoveCrontabEntries && echo "and crontab entries "`that currently exist:" >> "$FilesRemovedList"
2964 else
2965 echo "Summary of what $FullScriptName would attempt to do:" > "$FilesRemovedList"
2966 fi
2967 fi
2968}
2969
2970ShowContents()
2971{
2972 # Usage1: ShowContents [-c] [-w] File [TextToShow]
2973 # Usage2: ShowContents [-c] [-w] -s String [TextToShow]
2974 # Summary: Displays contents of File or String. If there are more than
2975 # $LINES or 23 lines, more command is used, using TextToShow as
2976 # the name of the file; if TextToShow is not passed, "....." is
2977 # used. If -c is specified, screen is cleared beforehand.
2978 # If -w is specified, then width of strings will be factored
2979 # into the line count (this option makes output slower when
2980 # the number of lines is less than $LINES or 23).
2981 #
2982 local SCLineCount
2983 local SCCurrentDir
2984 local SCTempFolder
2985 local SCTempFile
2986 local SCColumns
2987 local SCColumnsMax
2988 local SCColumnsMaxDefault=80
2989 local SCColumnsRemainder
2990 local CSDoAdjustForWidth=false
2991 local CSDoUseString=false
2992 local SCEachLine
2993 local SCGrepPattern='.'
2994 local SCLineFactor
2995 local SCLines
2996 local SCLinesMax
2997 local SCLinesMaxDefault=23
2998 local SCText
2999 while [ "$1" ] ; do
3000 if [ "z$1" = z-c ] ; then
3001 clear
3002 elif [ "z$1" = z-s ] ; then
3003 CSDoUseString=true
3004 elif [ "z$1" = z-w ] ; then
3005 CSDoAdjustForWidth=true
3006 else
3007 break
3008 fi
3009 shift
3010 done
3011 [ "$COLUMNS" ] && SCColumnsMax=`expr "$COLUMNS" - 0 2>/dev/null`
3012 [ -z "$SCColumnsMax" ] && SCColumnsMax=$SCColumnsMaxDefault
3013 [ "$LINES" ] && SCLinesMax=`expr "$LINES" - 1 2>/dev/null`
3014 [ -z "$SCLinesMax" ] && SCLinesMax=$SCLinesMaxDefault
3015 [ $SCColumnsMax -ge $SCColumnsMaxDefault ] && SCGrepPattern='.................................................................................'
3016 if $CSDoUseString ; then
3017 SCLineCount=`printf "%s\n" "$1" | grep -c ""`
3018 $CSDoAdjustForWidth && SCText=`printf "%s\n" "$1" | grep "$SCGrepPattern"`
3019 elif [ -f "$1" ] ; then
3020 SCLineCount=`grep -c "" "$1"`
3021 $CSDoAdjustForWidth && SCText=`grep "$SCGrepPattern" "$1"`
3022 else
3023 return 1
3024 fi
3025 if $CSDoAdjustForWidth ; then
3026 if [ $SCLineCount -le $SCLinesMax ] ; then
3027 IFS='
3028'
3029 for SCColumns in `printf "%s" "$SCText" | awk '{print length($0)}'` ; do
3030 [ $SCLineCount -gt $SCLinesMax ] && break
3031 SCLineFactor=`expr $SCColumns / $SCColumnsMax`
3032 [ `expr $SCColumns % $SCColumnsMax` -gt 0 ] && let SCLineFactor=$SCLineFactor+1
3033 [ $SCLineFactor -gt 1 ] && let SCLineCount=$SCLineCount+$SCLineFactor-1
3034 done
3035 fi
3036 fi
3037 if $CSDoUseString ; then
3038 if [ $SCLineCount -gt $SCLinesMax ] ; then
3039 SCCurrentDir=`pwd`
3040 SCTempFolder="/private/tmp/$FullScriptName-SC-`date +"%Y%m%d%H%M%S"`"
3041 mkdir "$SCTempFolder" 2>/dev/null
3042 [ ! -d "$SCTempFolder" ] && return 1
3043 cd "$SCTempFolder" 2>/dev/null
3044 [ "$2" ] && SCTempFile="$2" || SCTempFile="....."
3045 printf "%s\n" "$1" >"$SCTempFile"
3046 more -E "$SCTempFile"
3047 cd "$SCCurrentDir" 2>/dev/null
3048 rm -rf "$SCTempFolder" 2>/dev/null
3049 else
3050 printf "%s\n" "$1"
3051 fi
3052 elif [ -f "$1" ] ; then
3053 if [ $SCLineCount -gt $SCLinesMax ] ; then
3054 SCCurrentDir=`pwd`
3055 SCTempFolder="/private/tmp/$FullScriptName-SC-`date +"%Y%m%d%H%M%S"`"
3056 mkdir "$SCTempFolder" 2>/dev/null
3057 [ ! -d "$SCTempFolder" ] && return 1
3058 [ "$2" ] && SCTempFile="$2" || SCTempFile="....."
3059 cat "$1" >"$SCTempFolder/$SCTempFile"
3060 cd "$SCTempFolder" 2>/dev/null
3061 more -E "$SCTempFile"
3062 cd "$SCCurrentDir" 2>/dev/null
3063 rm -rf "$SCTempFolder" 2>/dev/null
3064 else
3065 cat "$1"
3066 fi
3067 fi
3068 return 0
3069}
3070
3071ShowFullFilePath()
3072{
3073 # Usage: ShowFullFilePath [-a] [-P | -L] [-e] Path [[-e] Path]
3074 # Version: 1.0.2
3075 # Summary: Prints the full path starting at / of Path if Path exists
3076 # and Path is accessible by the user calling this function.
3077 # Run this function as root to ensure full path displaying.
3078 # If there is more than one existing file that matches the
3079 # name, then only the first path that the shell matches is
3080 # printed unless -a or more than one path is specified.
3081 # You can specify wild card characters ? and * and other
3082 # argument operators in the Path (e.g., "../*", "a?.txt",
3083 # "[ab]*").
3084 # Options: -a Show all matching paths, sorted alphanumerically. If
3085 # -P is not passed, the same file may be shown multiple
3086 # times if there is more than one matching link that
3087 # points to it.
3088 # -e <Path>
3089 # Treat argument after -e as a path. Use -e to treat
3090 # -a, -e, -L, or -P as a path.
3091 # -L Show logical path, even if a file pointed to by a link
3092 # doesn't exist. This is the default.
3093 # -P Show physical path. If a link points to a file that
3094 # does not exist, the path won't be shown.
3095 # History: 1.0.1 - Added -e option and ability to pass multiple paths.
3096 # Arguments can now be passed in any order.
3097 # Fixed error that could occur when resolving links
3098 # with long paths.
3099 # 1.0.2 - Modified for case-sensitive volume compatibility.
3100 # Made temporary file names more distinctive.
3101 #
3102 local SFFPArgCount=$#
3103 local SFFPCurrentDir
3104 local SFFPCurrentDirTranslated
3105 local SFFPEachLine
3106 local SFFPEachPath
3107 local SFFPFile
3108 local SFFPLDir
3109 local SFFPLLinkLS
3110 local SFFPLLinkPath
3111 local SFFPLPath
3112 local SFFPPathOption=-L
3113 local SFFPSaveIFS="$IFS"
3114 local SFFPShowAll=false
3115 local SFFPTempBase=/private/tmp/ShowFullFilePath-`/usr/bin/basename "$0"`-`/bin/date +"%Y%m%d%H%M%S"`
3116 local SFFPTempFile="$SFFPTempBase.tmp"
3117 local SFFPTempFile2="$SFFPTempBase-2.tmp"
3118 /bin/rm -f "$SFFPTempFile" 2>/dev/null
3119 while [ $SFFPArgCount != 0 ] ; do
3120 case "$1" in
3121 -a)
3122 SFFPShowAll=true
3123 ;;
3124 -L|-P)
3125 SFFPPathOption="$1"
3126 ;;
3127 *)
3128 [ "z$1" = z-e ] && shift
3129 if [ "$1" ] ; then
3130 [ -s "$SFFPTempFile" ] && SFFPShowAll=true
3131 /usr/bin/printf "%s\n" "$1" >>"$SFFPTempFile"
3132 fi
3133 ;;
3134 esac
3135 shift
3136 let SFFPArgCount=$SFFPArgCount-1
3137 done
3138 [ ! -s "$SFFPTempFile" ] && return
3139 SFFPCurrentDir=`/bin/pwd`
3140 SFFPCurrentDirTranslated=`/bin/pwd $SFFPPathOption 2>/dev/null`
3141 if [ ! -d "$SFFPCurrentDirTranslated" ] ; then
3142 /bin/rm -f "$SFFPTempFile" 2>/dev/null
3143 return
3144 fi
3145 cd "$SFFPCurrentDirTranslated" 2>/dev/null
3146 if [ $? != 0 ] ; then
3147 /bin/rm -f "$SFFPTempFile" 2>/dev/null
3148 return
3149 fi
3150 /usr/bin/printf "" >"$SFFPTempFile2"
3151 IFS='
3152'
3153 for SFFPEachLine in `/bin/cat "$SFFPTempFile" 2>/dev/null` ; do
3154 cd "$SFFPCurrentDirTranslated" 2>/dev/null
3155 [ $? != 0 ] && break
3156 if [ "z$SFFPPathOption" = z-P ] ; then
3157 SFFPLPath="$SFFPEachLine"
3158 while [ -L "$SFFPLPath" ] ; do
3159 [ ! -e "$SFFPLPath" ] && break
3160 cd "`/usr/bin/dirname "$SFFPLPath" 2>/dev/null`" 2>/dev/null
3161 [ $? != 0 ] && break
3162 SFFPLDir=`/bin/pwd -P 2>/dev/null`
3163 [ ! -d "$SFFPLDir" ] && break
3164 SFFPLLinkLS=`/bin/ls -ld "$SFFPLPath" 2>/dev/null`
3165 [ -z "$SFFPLLinkLS" ] && break
3166 # If link or link target contains " -> " in its name
3167 if [ "`echo "z$SFFPLLinkLS" | grep ' -> .* -> '`" ] ; then
3168 SFFPLLinkPath=`/usr/bin/printf "%s" "$SFFPLLinkLS" | /usr/bin/awk -v THESTR="$SFFPLPath -> " '{ match($0,THESTR) ; print substr($0,RSTART+RLENGTH)}'`
3169 else
3170 SFFPLLinkPath=`echo "$SFFPLLinkLS" | awk -F " -> " '{print $2}'`
3171 fi
3172 # If link target begins with /
3173 if [ "`/usr/bin/printf "%s" "$SFFPLLinkPath" | grep '^/'`" ] ; then
3174 SFFPLPath="$SFFPLLinkPath"
3175 else
3176 SFFPLPath="$SFFPLDir/$SFFPLLinkPath"
3177 fi
3178 [ "`/usr/bin/printf "%s" "$SFFPLPath" | grep '^//'`" ] && SFFPLPath=`echo "$SFFPLPath" | /usr/bin/awk '{print substr($0,2)}'`
3179 done
3180 cd "$SFFPCurrentDirTranslated" 2>/dev/null
3181 [ $? != 0 ] && break
3182 if [ ! -e "$SFFPLPath" ] ; then
3183 $SFFPShowAll && continue || break
3184 fi
3185 SFFPEachPath="$SFFPLPath"
3186 else
3187 SFFPEachPath="$SFFPEachLine"
3188 fi
3189 if [ -d "$SFFPEachPath" ] ; then
3190 cd "$SFFPEachPath" 2>/dev/null
3191 if [ $? != 0 ] ; then
3192 $SFFPShowAll && continue || break
3193 fi
3194 SFFPFile=""
3195 elif [ -d "`/usr/bin/dirname "$SFFPEachPath" 2>/dev/null`" ] ; then
3196 cd "`/usr/bin/dirname "$SFFPEachPath" 2>/dev/null`" 2>/dev/null
3197 if [ $? != 0 ] ; then
3198 $SFFPShowAll && continue || break
3199 fi
3200 SFFPFile=`basename "$SFFPEachPath" 2>/dev/null`
3201 [ "z$SFFPFile" = z/ -o "z$SFFPFile" = z. -o "z$SFFPFile" = z.. ] && SFFPFile=""
3202 elif $SFFPShowAll ; then
3203 continue
3204 else
3205 break
3206 fi
3207 SFFPDir=`/bin/pwd $SFFPPathOption 2>/dev/null`
3208 if [ ! -d "$SFFPDir" ] ; then
3209 $SFFPShowAll && continue || break
3210 fi
3211 SFFPPath="$SFFPDir`[ "z$SFFPFile" != z -a "z$SFFPDir" != z/ -a "z$SFFPDir" != z// ] && echo /`$SFFPFile"
3212 if [ ! -e "$SFFPPath" -a ! -L "$SFFPPath" ] ; then
3213 $SFFPShowAll && continue || break
3214 fi
3215 [ "`echo "$SFFPPath" | grep '^//'`" ] && SFFPPath=`echo "$SFFPPath" | /usr/bin/awk '{print substr($0,2)}'`
3216 echo "$SFFPPath" >>"$SFFPTempFile2"
3217 # If neither option -a nor more than one path was passed, don't show any more names
3218 ! $SFFPShowAll && break
3219 done
3220 IFS=$SFFPSaveIFS
3221 [ -s "$SFFPTempFile2" ] && /usr/bin/sort -f "$SFFPTempFile2" | /usr/bin/uniq
3222 /bin/rm -f "$SFFPTempFile" "$SFFPTempFile2" 2>/dev/null
3223 cd "$SFFPCurrentDir" 2>/dev/null
3224}
3225
3226ShowHelp()
3227{
3228 # Usage: ShowHelp [$1]
3229 # Argument: $1 = Exit code.
3230 # Summary: Displays script usage and help then exits script.
3231 # If a number is passed to $1, then script exits with
3232 # that number; else, script is not exited.
3233 #
3234 TEMPFILETEMPLATE="/private/tmp/SymantecTemp"
3235 TEMPFILE="$TEMPFILETEMPLATE`date +"%Y%m%d%H%M%S"`-1"
3236 ShowVersion >>"$TEMPFILE"
3237 $AutoRunScript && echo "
3238Note: This script requires no user interaction if run as root. You can
3239 run this script on several machines at once by using Symantec
3240 Endpoint Protection to push this script to client Macs." >>"$TEMPFILE"
3241 echo "
3242WARNING: This script will remove all files and folders created by Symantec
3243 Mac OS X products (LiveUpdate Administration Utility files) and
3244 any files within those folders. Therefore, you will lose ALL files
3245 that reside in those folders, including any that you have created.
3246
3247Usage: $FullScriptName [-CcdeFfghIikLlmpQqRrV] [-QQ] [-re] [volume ...]
3248
3249Summary: If no option or volume is specified, then all Symantec files are
3250 removed from the current boot volume, including the invisible
3251 Symantec files (i.e., AntiVirus QuickScan and Norton FS files),
3252 and Symantec crontab entries are removed from all users' crontabs;
3253 otherwise, for each volume specified, all Symantec files and
3254 Symantec crontab entries will be removed from that volume if no
3255 options are specified. If files are removed from the current boot
3256 volume, receipt predelete scripts are run unless -d is passsed
3257 and Symantec processes are killed unless -k is passed.
3258
3259 If a volume does not have OS X installed on it, then only the
3260 invisible Symantec files are removed from that volume.
3261
3262 Each volume name may begin with \"/Volumes/\", unless it is \"/\".
3263 The easiest way to specify a volume is to drag the volume onto the
3264 Terminal window.
3265
3266Note: The Terminal application does not support high ASCII or
3267 double-byte character entry via keyboard or via drag-and-drop.
3268 If you want to have files removed from a volume that is not
3269 the current boot volume and that has a name containing high
3270 ASCII or double-byte characters, use the -A option.
3271
3272Options: -A Remove all Symantec files from all mounted volumes.
3273 Crontab entries are also removed from the current boot
3274 volume, but not from other volumes. If a volume does not
3275 have OS X installed on it, then only the invisible Symantec
3276 files are removed from that volume.
3277 -C Do not remove crontab entries.
3278 -c Only remove crontab entries from all users' crontabs.
3279 Nothing is removed from any volume.
3280 -d Bypass the running of receipt predelete scripts. It is best
3281 to have predelete scripts run for more thorough uninstalls.
3282 -e Show errors and other output when run predelete scripts are
3283 run. Predelete scripts are run only when removing files from
3284 the current boot volume.
3285 -F List only regular files that are currently installed and
3286 that would be deleted. No note is added if a file is not
3287 supposed to be removed by Symantec Uninstaller.
3288 -f Do not show files as they are removed. If -f is not
3289 specified, file names are shown as files are removed.
3290 -g Do not remove items located within:
3291 /Library/Logs
3292 {each user's home}/Library/Logs
3293 -h Display help.
3294 -I Do not remove invisible Symantec files.
3295 -i Only remove invisible Symantec files.
3296 -k Do not attempt to kill Symantec processes.
3297 -l List only files that are currently installed and that
3298 would be deleted. As of version 6.0.0, contents of folders
3299 are also shown. Nothing is deleted by this option.
3300 -L List all files that $FullScriptName will attempt
3301 to find and delete. Nothing is deleted by this option.
3302 -m Show output from -l, -L, or -R options using more program.
3303 This is no longer the default action as of version 5.52
3304 of $FullScriptName.
3305 -p Eliminate pause before restarting computer. If option -p
3306 is not specified, then there is a three second delay
3307 before the restart occurs.
3308 -q Quit script without restarting. This also suppresses
3309 the prompt to restart.
3310 -Q Quits Terminal application when script is done. If
3311 Terminal is being run by more than one user at once,
3312 Terminal is not quit. If passed a second time, it is
3313 the same as -QQ option.
3314 -QQ Quits Terminal application for all users when script is
3315 done.
3316 -R This option is equivalent to the -l option.
3317 -r Automatically restart computer when script is done if
3318 there are Symantec processes and/or kexts in memory and
3319 there were non-invisible files removed from /.
3320 -re Same as -r option. Though -re is deprecated, it remains
3321 for backwards compatibility.
3322 -u Only output files that are installed that should have been
3323 removed by the UI uninstaller. If there are files found,
3324 exit with $ExitCodeWhenFilesRemain; otherwise, exit with 0. No progress is shown
3325 and nothing is deleted.
3326 -V Show version only.
3327
3328Examples:
3329 $FullScriptName
3330 Deletes all Symantec files and Symantec crontab entries
3331 from the boot volume.
3332
3333 $FullScriptName /Volumes/OS\ 10.2
3334 Deletes all Symantec files and Symantec crontab entries
3335 from the volume named \"OS 10.2\".
3336 Nothing is deleted from the boot volume.
3337
3338 $FullScriptName Runner /
3339 Deletes all Symantec files and Symantec crontab entries
3340 from the volume named \"Runner\" and from the boot volume.
3341
3342 $FullScriptName -i \"Test Disk\"
3343 Deletes only invisible Symantec files from the volume named
3344 \"Test Disk\".
3345
3346 $FullScriptName -A -r
3347 Deletes all Symantec files and Symantec crontab entries
3348 from all mounted volumes that have OS X installed on them.
3349 Deletes only invisible Symantec files from volumes that do
3350 not have OS X installed on them.
3351 Computer is restarted automatically if necessary.
3352
3353 $FullScriptName -Ai
3354 Deletes only invisible Symantec files from all volumes.
3355
3356 $FullScriptName -I
3357 Deletes all but the invisible Symantec files from the boot
3358 volume. Crontab entries are removed from the boot volume.
3359
3360 $FullScriptName -C
3361 Deletes all Symantec files from the boot volume. No crontab
3362 entries are removed.
3363
3364 $FullScriptName -L -A
3365 Lists all the files that $FullScriptName looks
3366 for on all volumes. The files may or may not be currently
3367 installed. Nothing is deleted.
3368
3369 $FullScriptName -R -A
3370 Lists only the Symantec files that are currently installed
3371 on all volumes. Files within existing folders will also be
3372 shown. Nothing is deleted.
3373
3374 $FullScriptName -l -i
3375 Lists the invisible Symantec files that are currently
3376 installed on the boot volume. Nothing is deleted.
3377
3378Note: You must be root or an admin user to run this script. You can
3379 simply double-click on $FullScriptName to remove all
3380 Symantec files and crontab entries from the boot volume.
3381" >>"$TEMPFILE"
3382 ShowContents "$TEMPFILE"
3383 /bin/rm "$TEMPFILE" 2>/dev/null
3384 [ "$1" ] && exit $1
3385}
3386
3387ShowUsage()
3388{
3389 # Usage: ShowUsage [$1 [$2]]
3390 # Arguments: $1 = Exit code.
3391 # $2 = Error message to display before showing usage.
3392 # Summary: Displays script usage. If an exit code is passed,
3393 # script is exited with that value.
3394 #
3395 if [ "$2" ] ; then
3396 echo
3397 echo "$2"
3398 echo
3399 fi
3400 ShowHelp | grep "^Usage.*:"
3401 [ "$2" ] && echo
3402 [ -n "$1" ] && exit "$1"
3403}
3404
3405ShowVersion()
3406{
3407 # Usage: ShowVersion
3408 # Summary: Displays the name and version of script.
3409 #
3410 echo "********* $FullScriptName $Version *********"
3411}
3412
3413SymantecIsInMemory()
3414{
3415 # Usage: SymantecIsInMemory
3416 # Summary: If a Symantec process or kext is in memory,
3417 # 0 is returned; 1 is returned.
3418 #
3419 local SymantecIsInMemoryResult=1
3420 # If there are no more Symantec processes in memory
3421 if KillSymantecProcesses -n ; then
3422 : # 7.0.49: Commented out the following to avoid potential hang of kextstat (Etrack 3925328)
3423# # Check to see if Symantec kexts are in memory
3424# kextstat 2>/dev/null 1>&2
3425# # If kextstat failed to run
3426# if [ $? -gt 0 ] ; then
3427# # try running kmodstat (for old versions of OS X)
3428# if [ "`kmodstat | grep -i Symantec | grep -v " grep -"` 2>/dev/null" ] ; then
3429# SymantecIsInMemoryResult=0
3430# fi
3431# elif [ "`kextstat | grep -i Symantec | grep -v " grep -"`" ] ; then
3432# SymantecIsInMemoryResult=0
3433# fi
3434# if [ $SymantecIsInMemoryResult = 0 ] ; then
3435# echo "*** There are Symantec kexts loaded."
3436# fi
3437 else
3438 SymantecIsInMemoryResult=0
3439 fi
3440 return $SymantecIsInMemoryResult
3441}
3442
3443YesEntered()
3444{
3445 # Usage: YesEntered
3446 # Summary: Reads a line from standard input. If "y" or "yes"
3447 # was entered, true is shown and 0 is returned; otherwise,
3448 # false is shown and 1 is returned. The case of letters is
3449 # ignored. Sample call:
3450 # if `YesEntered`
3451 #
3452 read YesEnteredString
3453 YesEnteredString=`echo "z$YesEnteredString" | awk '{print tolower(substr($0,2))}'`
3454 if [ "'$YesEnteredString" = "'y" -o "'$YesEnteredString" = "'yes" ] ; then
3455 echo true
3456 return 0
3457 fi
3458 echo false
3459 return 1
3460}
3461
3462# *** Beginning of Commands to Execute ***
3463
3464# Verify that all required programs are installed - Etrack 3539262
3465which which &>/dev/null
3466if [ $? = 0 ] ; then
3467 MissingRequiredPrograms=""
3468 SavedIFS="$IFS"
3469 IFS='
3470'
3471 for RequiredProgram in $RequiredPrograms ; do
3472 which "$RequiredProgram" &>/dev/null
3473 [ $? != 0 ] && MissingRequiredPrograms="$MissingRequiredPrograms
3474 $RequiredProgram"
3475 done
3476 IFS="$SavedIFS"
3477else
3478 MissingRequiredPrograms="
3479 which"
3480fi
3481if [ "$MissingRequiredPrograms" ] ; then
3482 echo
3483 echo "WARNING: Could not continue because the following program(s) could not be found:"
3484 echo "$MissingRequiredPrograms"
3485 echo
3486 exit 2
3487fi
3488ScriptPath=`ShowFullFilePath "$0" -P`
3489ScriptDir=`dirname "$ScriptPath"`
3490if [ $# -eq 0 ] ; then # If no arguments were passed to script
3491 # Run script as if it was double-clicked in Finder so that
3492 # screen will be cleared and quit message will be displayed.
3493 RunScriptAsStandAlone=true
3494else
3495 # Run script in command line mode so that
3496 # screen won't be cleared and quit message won't be displayed.
3497 RunScriptAsStandAlone=false
3498fi
3499# If script was run from support folder or from within an app bundle
3500if [ "`echo "$ScriptDir" | grep -e "$LaunchLocationGrepPattern"`" ] ; then
3501 RunScriptAsStandAlone=false
3502 RunningFromWithinAppBundleOrSupportFolder=true
3503else
3504 RunningFromWithinAppBundleOrSupportFolder=false
3505fi
3506if $RunScriptAsStandAlone ; then
3507 clear >&2
3508fi
3509ProcessArguments --OptionIsOneArgument="-QQ" --OptionIsOneArgument="-re" "$@"
3510if [ "`whoami`" != "root" ] ; then # If not root user,
3511 if $PublicVersion ; then
3512 GetAdminPassword true # Prompt user for admin password
3513 elif ! $DoShowOnlyFilesThatShouldHaveBeenUninstalled ; then
3514 ShowVersion >&2
3515 echo >&2
3516 fi
3517 # Run this script again as root
3518 sudo -p "Please enter your admin password: " "$0" "$@"
3519 ErrorFromSudoCommand=$?
3520 # If unable to authenticate
3521 if [ $ErrorFromSudoCommand -eq 1 ] ; then
3522 echo "You entered an invalid password or you are not an admin user. Script aborted." >&2
3523 ExitScript 1
3524 fi
3525 if $PublicVersion ; then
3526 sudo -k # Make sudo require a password the next time it is run
3527 fi
3528 exit $ErrorFromSudoCommand # Exit so script doesn't run again
3529fi
3530OSXVersion=`cat /System/Library/CoreServices/SystemVersion.plist 2>/dev/null | tr '\015' '\012' | grep . | grep -A1 '<key>ProductVersion' | tail -n 1 | grep '<string>10\.' | awk -F '>' '{print $2}' | awk -F '<' '{print $1}'`
3531OSXmajorVersion=`printf "%s" "$OSXVersion" | awk -F . '{print $2}'`
3532# If no volumes were passed to script, the boot volume will be searched
3533if [ -z "$VolumesToUse" ] ; then
3534 BootVolumeWillBeSearched=true
3535fi
3536if [ $PublicVersion = true -a $CreateFilesRemovedListOnly = false -a \
3537 $RemoveCrontabEntriesOnly = false -a $RemoveInvisibleFilesOnly = false -a \
3538 $AutoRunScript = false -a $RunningFromWithinAppBundleOrSupportFolder = false ] ; then
3539 DetermineAction
3540fi
3541if [ $RemoveFromAllVolumes = true -a $CreateFilesRemovedListOnly = false -a $RemoveCrontabEntriesOnly = false -a $RemoveInvisibleFilesOnly = false -a $AutoRunScript = false -a $RunningFromWithinAppBundleOrSupportFolder = false ] ; then
3542 echo
3543 printf "Are you sure you want to remove Symantec files from ALL mounted volumes (y/n)? "
3544 if `YesEntered` ; then
3545 echo
3546 else
3547 echo
3548 echo "Script aborted. No files were removed."
3549 ExitScript 0
3550 fi
3551fi
3552SetupCleanup
3553WillTense=will
3554if $CreateFilesRemovedListOnly ; then
3555 if ! $DoShowOnlyFilesThatShouldHaveBeenUninstalled ; then
3556 echo "Generating a list of files that would be removed by" >&2
3557 echo " $FullScriptName (no files will be removed at this time)..." >&2
3558 fi
3559 WillTense=would
3560elif $RemoveInvisibleFilesOnly ; then
3561 echo "Removing AntiVirus QuickScan files and Norton FS files..."
3562else
3563 if $BootVolumeWillBeSearched ; then
3564 if [ $RestartAutomatically = true -a $RemoveCrontabEntriesOnly = false ] ; then
3565 echo
3566 echo "Note: Computer will be restarted automatically if necessary."
3567 echo
3568 elif $QuitWithoutRestarting ; then
3569 echo
3570 echo "Note: This script will automatically quit when finished."
3571 echo
3572 fi
3573 fi
3574 echo "Removing Symantec files..."
3575 ! $RemoveInvisibleFiles && echo "Invisible Symantec files will not be deleted."
3576fi
3577if $RemoveCrontabEntriesOnly ; then
3578 echo "Only crontab entries $WillTense be removed."
3579fi
3580! $RemoveCrontabEntries && echo "Symantec crontab entries $WillTense not be removed."
3581! $RemoveInvisibleFiles && echo "AntiVirus QuickScan and Norton FS files $WillTense not be removed."
3582if $RemoveFromAllVolumes ; then
3583 VolumesToUse="/
3584"`ls -d /Volumes/*`
3585elif ! $RemoveFromOtherVolumes ; then
3586 VolumesToUse=/
3587fi
3588ListOfVolumesToUse=`echo "$VolumesToUse" | sort -f | uniq`
3589IFS='
3590'
3591for EachVolume in $ListOfVolumesToUse ; do
3592 [ -L "$EachVolume" ] && continue
3593 FilesFoundOnThisVolume=false
3594 RemoveAllNortonFiles "$EachVolume"
3595 if [ $CreateFilesRemovedListOnly = true -a $FilesFoundOnThisVolume = false -a $ListOnlyFilesThatExist = true ] ; then
3596 echo "No matching files were found on \"`basename "$EachVolume"`\"." >> "$FilesRemovedList"
3597 fi
3598done
3599FinishCleanup
3600FinishedExitCode=$?
3601if [ $BootVolumeWillBeSearched = true -a $CreateFilesRemovedListOnly = false ] ; then
3602 # If some Symantec process or kext is in memory, touch restart file
3603 if SymantecIsInMemory ; then
3604 # touch of Extensions folders may not be necessary, since restart is triggered (Etrack 3925328)
3605 touch "$SymantecCleanupRestartFile" # /Library/Extensions /System/Library/Extensions
3606 # May run kextcache in a future release:
3607 # echo "Rebuilding kext caches"
3608 # kextcache -u /
3609 fi
3610 if [ -f "$SymantecCleanupRestartFile" ] ; then
3611 echo
3612 echo "NOTE: You should now restart the computer to get Symantec processes"
3613 echo " and kexts out of memory and/or to remove login items."
3614 RestartComputer
3615 elif [ -e /Library/StartupItems/CleanUpSymWebKitUtils ] ; then
3616 echo
3617 echo "NOTE: You should now restart the computer to have CleanUpSymWebKitUtils"
3618 echo " finish removing SymWebKitUtils.framework."
3619 RestartComputer
3620 fi
3621fi
3622ExitScript $FinishedExitCode
3623
3624# *** End of Commands to Execute ***