TweetFollow Us on Twitter

Uninstalling with AppleScript

Volume Number: 23 (2007)
Issue Number: 05
Column Tag: Scripting

Uninstalling with AppleScript

Building an uninstaller with AppleScript Studio

By José R.C. Cruz

Introduction

In a previous MacTech article, we learned how to use the PackageMaker tool to build a distribution package. We also learned how to localize that package for different languages, and how to customize it with scripts. But the one thing we were unable to do with the tool is to build an uninstaller.

Third-party tools such as ViseX and InstallerMaker can add an uninstall option to their installers. This feature is sadly missing from PackageMaker, though not without reason. In fact, most products are easy to remove -- they are contained in a single folder, and trashing that folder completely uninstalls the product. But some products will have multiple files installed in different directories. Others will create custom directories to store the files. A good example of such a product is Xcode. Its installer creates the custom directory Developer to contain its files. The installer also stores files in other directories such as /System/Library and /Library/Application Support. As a result, removing Xcode from the system can be a laborious process. In these situations, an uninstaller tool can be useful.

This article will demonstrate how to use AppleScript Studio to build an uninstaller. To get readers started on their own uninstallers, the Xcode project Uninstall is made available for downloading. A copy of this project can be obtained at the following URL: ftp://ftp.mactech.com/src/mactech/volume23_2007/23.05.sit.

The Receipts Bundle

After the Installer installs a software payload, it creates a copy of the package in the Receipts directory. The path to this directory is /Library/Receipts on the boot volume.

The copy of the installer package is known as a receipt bundle. Its presence indicates that a product has been installed successfully. It also tells the installer package if the latter has to do an upgrade, as opposed to an installation.

Figure 1 shows the internal structure of a typical receipt bundle. Notice that the bundle has most of the same files as an installer package. What is missing is the .paz.gz file containing the actual payload. Also missing are the two aliases to that file from the Resources subdirectory.


Figure 1. Structure of a typical receipts bundle.

There are software tools that purge the contents of the Receipts directory. This is often done to reclaim extra space, especially when the product associated with the receipt no longer exists. But removing a receipt, without removing the product, creates a new problem. Without the right receipt to guide it, an installer for a new product version may be unable to upgrade the current product correctly.

The BOM File

The BOM file is a list of all the files that comprise the software payload. It also defines the locations of each file on the target volume. This file is present in both the installer package and receipts bundle.

The BOM file format has its origins in the NeXTStep operating system. It is also a binary format and, as a result, is not directly readable. To read its contents, use the command-line tool lsbom to preprocess the BOM file.

The lsbom tool

The lsbom tool takes a BOM file as its input and renders its contents into human readable text. It then outputs the text to another file, or to stdout by default. The tool is a standard addition to the BSD subsystem of MacOS X. Its counterpart is the mkbom tool, which creates a BOM file for a given directory.

To use the lsbom tool, simply pass the path to the BOM file as its input. For example, to process the BOM file for the Sample.pkg receipt, type the following statement at the Terminal prompt.

   lsbom /Library/Receipts/Sample.pkg/Contents/Archive.bom

The tool will then parse the file and display its contents at lightning speed on the Terminal speed. To better read the output, pipe the results of the lsbom tool to the less tool.

   lsbom /Library/Receipts/Sample.pkg/Contents/Archive.bom | less

less will display the first N lines of text from lsbom. The number of lines displayed is dictated by the height of the Terminal window. To display the next N lines of text, tap on the Space bar. To display the previous N lines of text, tap on the B key while holding down the <CTRL> key.

Another way of handling the lsbom output is to save it to a file. To save the output to the file Sample.log, use the I/O redirection token '>'.

   lsbom /Library/Receipts/Sample.pkg/Contents/Archive.bom > Sample.log

Notice that, in both examples, the BOM file is always inside the Contents subdirectory of the receipt bundle. Also, the name of the BOM file is always Archive.bom. Most receipt bundles will follow the same conventions. Though it is possible for a BOM file to be located elsewhere in the bundle, this is rarely done.

The lsbom output

Listing 1 shows a sample output from the lsbom tool. Each entry corresponds to a file or directory installed by the package. The first three items of the BOM entry are arranged as follows.

directory_path file_modes user_id/group_id.

Each item is separated from the other by a single tab character (0x09). Now, if the entry is for a regular file, it will have two more items as shown below.

   directory_path file_modes user_id/group_id number_of_bytes crc_32

If it is for a symbolic link, its last item will be the path to the original file or directory.

   directory_path file_modes user_id/group_id number_of_bytes ¬
         original_path

Finally, if the entry is for a device file, its last item will be the assigned device number.

   directory_path file_modes user_id/group_id device_number

Listing 1. Sample output of the lsbom tool

.   40755   501/80
./Sample.app   40755   501/80
./Sample.app/Contents   40755   501/80
./Sample.app/Contents/Info.plist   100644   501/80   947 ¬
      1163649540
./Sample.app/Contents/MacOS   40755   501/80
./Sample.app/Contents/MacOS/Sample   100755   501/80   51956 ¬
      3193247409
./Sample.app/Contents/PkgInfo   100644   501/80   8 ¬
742937289
./Sample.app/Contents/Resources   40755   501/80
./Sample.app/Contents/Resources/Appearance.tiff   100644   501/80   4850 ¬
1276692542
...
./Sample.app/Contents/Resources/English.lproj   40755   501/80
./Sample.app/Contents/Resources/English.lproj/Credits.rtf   100644   501/80 ¬  
3163   3602318773
./Sample.app/Contents/Resources/English.lproj/Errors.strings   100644 ¬  
501/80   2978   2815210102
...

Most BOM file listings consist mostly of directories and regular files. Device files and symbolic links are seldom found. Also, the file_modes item is essentially the three permission flags written in octal form. Each of the lower three numbers represents the permission for world, group, and owner. The upper set of numbers represent the type of item in question. They are set to 40 for a directory, 100 for a generic file.

Notice that each directory_path item starts with a dot (.) character. This character is replaced by the IFPkgRelocatedPath value set in the Info.plist file. If that value is not set, the directory path is assumed to be relative to the OS X boot volume.

Also, if the package has installed payloads in other directories, the BOM listing will show these payloads. For example, if Sample.pkg has installed two files in the /usr/bin directory, the BOM listing may show these files as follows.

   ./usr/bin            40755      0/0
   ./usr/bin/foo      100755   0/0   12606   2275820725
   ./usr/bin/fubar      100755   0/0   12606   2275820725

Notice that both user_id and group_id items are set to 0 in the above example. This means that the owner of the two files and the directory is root. Removing the two files will require authentication. Do not, however, remove any directories or subdirectories with a root owner. Doing so may remove important files, and render the entire OS X platform unusable.

The lsbom options

The lsbom tool also provides a number of output options. Use these options to display specific entries from the BOM file as follows.

To display only the directories accessed or created during installation, use the -d option.

   lsbom -d /Library/Receipts/Sample.pkg/Contents/Archive.bom

The output listing will also include bundles such as .app, .bundle, and .lproj. To display only the paths of files that were installed or updated, use the -f option.

   lsbom -f /Library/Receipts/Sample.pkg/Contents/Archive.bom

To display only the paths of each directory and file, use the --s option.

   lsbom -s /Library/Receipts/Sample.pkg/Contents/Archive.bom

The lsbom tool also has options other than the ones shown above. To view a list of options, type the command lsbom -h at the Terminal prompt. Also, to view the tool's electronic manual, type info lsbom at the prompt.

AppleScript and the Shell

AppleScript is the native scripting language of the MacOS platform. First introduced in the 1990s, it is one of the first few languages that work in a GUI environment. It also uses a natural language syntax, which makes its scripts easy to read and write.

Another feature of AppleScript is that it can be extended using plug-ins. These plug-ins, or scripting additions, allow AppleScript to do tasks that are slow or impossible to do using the core language. The OS X version of AppleScript comes bundled with the plug-in named Standards Additions. With this plug-in, an AppleScript script can display simple dialogs and perform basic file I/O tasks. The script can also run Unix shell scripts using the do shell script function.

,b>The do shell script function

The do shell script function is AppleScript's gateway to the BSD subsystem of MacOS X. With this function, an AppleScript script can execute command-line tools or shell script files. It can also run a single-line shell script using this function. The function returns any results from the script as a string.

The function uses the interpreter set by the SHELL environment variable to do its tasks. To find out the current interpreter, launch the Script Editor tool, which is located in /Applications/AppleScripts. On the script window, type do shell script "printenv SHELL" and click on the Run button. If the current interpreter is bash, the function will return the string value of SHELL=/bin/bash on the Results pane.

Working with file paths

When using the do shell script function to manipulate files, it requires the file paths expressed using the POSIX format. In short, a forward slash character </> must separate each path name. For example, to parse the BOM file for Sample.pkg, pass the script to the function as follows.

   do shell script ¬
      "lsbom /Library/Receipts/Sample.pkg/Contents/Archive.bom"

Now if a path name contains any spaces, a reverse slash <\> character must precede each space. For example, to parse the BOM file for Test Sample.pkg, pass the script as follows.

   do shell script ¬
      "lsbom /Library/Receipts/Test\\ Sample.pkg/Contents/Archive.bom"

Notice that two reverse slashes precede the space in Test Sample.pkg. This is necessary due to a little quirk in AppleScript. The first reverse slash tells AppleScript to treat the second slash is part of the string. The second slash tells the shell interpreter to treat the space as part of the script text.

AppleScript, however, expresses its file paths using the MacOS format. Instead of a forward slash, each path name is separated by a colon <:> character. Also, each path name can contain spaces without the need for any reverse slashes. For example, the file path to the BOM file for Test Sample.pkg is written in MacOS format as follows.

   OS X:Library:Receipts:Test Sample.pkg:Contents:Archive.bom

Converting between file path formats can be quite tedious. To address this issue, the Standards Additions plug-in provides the POSIX file class. To convert the MacOS file path to Sample.pkg to the POSIX format, type the following statement in the Script Editor window.

   POSIX path of alias "OS X:Library:Receipts:Sample.pkg"

This will return the converted path as /Library/Receipts/Sample.pkg. To convert it back to a MacOS format, type the following on the editor window.

   POSIX file "/Library/Receipts/Sample.pkg"

Both examples have file paths set relative to the boot volume. Both also assume that the MacOS name of the boot volume is OS X. Now if a file path is set relative to a volume other than boot, the conversion will reflect that volume. For example, if the MacOS file path is set to Users:Applications:Public:, it will be /Volumes/Users/Applications/Public/ in POSIX format.

Authenticating a command

Some shell commands require authentication in order to perform their tasks. They are usually invoked in the Terminal window using the sudo command. For example, to create the subdirectory foo in /usr, type the following line at the Terminal prompt.

   sudo mkdir /usr/foo

The sudo command first prompts the user for an administrative password. When the correct password is entered, sudo then executes the mkdir command. Otherwise, it aborts after the user fails to enter the right password thrice in a row.

Using the sudo command through the do shell script function is both tedious and unnecessary. Instead, the function can authenticate the desired command by itself. For example, to create the same subdirectory shown above, type the following line on the Script Editor window.

   do shell script "mkdir /usr/foo" with administrator privileges

The function first prompts the user for a password using the dialog shown in Figure 2. Again, when the user enters the correct username and password, the function then executes the mkdir command. Otherwise, it aborts with an error message after the user fails to enter the right information three times in a row. The same also happens if the user clicks on the Cancel button.


Figure 2. The authentication dialog.

To use either approach, make sure that you have a user account with administrative privileges. To learn how to create such an account, consult one of the references listed at the end of this article.

Building with AppleScript Studio

There are many ways to build an uninstaller. One way is to build it as a shell script. One example is Xcode, which comes with a Perl script to uninstall its various components. This approach is easy to implement and test. It does, however, require the use of the Terminal window. It also provides very poor user interaction and feedback, if any.

Another way is to build the uninstaller as a Cocoa application. Cocoa gives the uninstaller a better way of interacting with the user. It also allows the uninstaller to perform tasks not possible with a shell command. But this approach requires too much resources and time to implement. It also has a very high learning curve.

A more practical way is to build the uninstaller as an AppleScript application. This is now easy to do with AppleScript Studio. The uninstaller gets a decent interface with which to interact with the user. It will be easy to build and test due to AppleScript's user-friendly syntax. This is the approach used for the Xcode project Uninstall.

Laying out the user interface

The Uninstall project has a single main window named Uninstall Demo. The window is subdivided into two panels by an NSTabView control. Both panels contain a single NSTableView control. The first table displays the contents of the Receipts directory (Figure 3). The second table displays the contents of the BOM file for the selected receipt (Figure 4).


Figure 3. The Uninstall window, Receipts panel.


Figure 4. The Uninstall window, Files panel.

The entire window layout is that of a basic Assistant. On the lower right corner are two pushbuttons, Prev and Next. The Next button is also set as the default button.

Both buttons are disabled by default. The Next button is enabled when the Receipts table has a selected entry. The Prev button is enabled when the current panel is the one with the Files table. Also, when the Files table has a selected entry, the Next button becomes the Uninstall button.

On the lower left corner of the window is the Cancel button. This button is set to respond to the <Esc> key. It also sends a performClose: message to the window when clicked.

Binding the widgets

The window and some of the controls are then bound to specific AppleScript handlers. The bindings are set in the AppleScript panel of the Show Inspector dialog (Figure 5). To display the dialog, choose Show Inspector from the Tools menu. Then select AppleScript from the drop-down list at the top of the dialog.


Figure 5. The Show Inspector dialog, AppleScript panel.

Table 1 is a list of the bindings set for each interface widget. The handlers shown in this table are all defined in the source file Uninstall.applescript. Notice that some widgets are bound to the same handlers. To identify which widget called the handler, check its name property. For instance, the following code fragment shows how to determine which button was clicked.

on clicked theObject
   local tBtn
   
   set tBtn to the (name of theObject) as string
   if (tBtn is equal to "prev") then
      -- the Previous button has been clicked
   else if (tBtn is equal to "next") then
      -- the Next button has been clicked
   end if -- (tBtn is equal to "prev")
end clicked -- theObject

Widget Name Class AppleScript Settings
Name Event Handler
Uninstall Demo NSWindow demo Nib awake from nib
Prev NSButton prev Action clicked
Next NSButton image/next Action clicked
Receipts NSTableView rcpt Nib awake from nib
Data View selection changed
Lists NSTableView list Nib awake from nib
Data View selection changed

Table 1. AppleScript settings for the Uninstall UI widgets.

Not shown in the table are the bindings for the application itself. To bind the application, select the File's Owner icon on the MainMenu.nib window. Then, from the Show Inspector dialog, click on the Application checkbox. Then set the bindings as shown in Figure 6.


Figure 6. Binding the AppleScript application.

Binding the Cancel button

On the other hand, the Cancel button is not bound to any AppleScript handler. Instead, it is bound directly to an action handler.

To set the binding, control-drag a line from the button to the main window. This will display the Show Inspector dialog with the Connections panel view active. Click on the Target/Action tab on the dialog. Then choose performClose: from the list of window actions (Figure 7).


Figure 7. Selecting the performClose: action.

The Quit Uninstall menu item is also bound in the same way. But this will be left as an exercise to the readers.

Building with Xcode

The Xcode project Uninstall contains three AppleScript source files. The Uninstall.applescript file has all the handlers called by the UI widgets. The Receipts.applescript file has the code to access the Receipts directory. Finally, the Files.applescript file has the code for processing the BOM file. It also has the code that will do the uninstall task.

For reasons of length, this article will only show code that is relevant and interesting. Readers can always view the entire source files by downloading the project from the MacTech website.

Accessing the Receipts directory

Shown in Listing 2 is the function handler that retrieves the contents of the Receipts directory. It takes a path to the directory as its input argument. It returns the results of the retrieval as a list of records.

First, the handler calls the list folder function to read the directory contents. The function responds by returning the contents as a list of filenames. Next, the handler parses each filename in the list. If the name belongs to a receipt bundle, the handler retrieves its bundle signature. Otherwise, the handler proceeds to the next name.

The handler uses the bundle signature to create a record together with the name. When done, it appends the record to the return list tPkg.

Listing 2. Retrieving a list of receipt bundles (Receipts.applescript).

property pRcptRec : {bnom:"", bsig:""}
to getBundles from aPath
   local tLst, tPkgs
   local tItem, tNom
   local isPkg
   
   -- read the contents of the directory
   set tLst to (list folder aPath)
   
   -- parse the list results
   set tPkgs to {}
   copy pRcptRec to tRec
   
   repeat with tNom in tLst
      -- prepare a path to a list item
      set tItem to aPath & ":" & tNom
      get info for file tItem
      
      -- is the item a bundle?
      set isPkg to package folder of result
      
      if (isPkg) then
         -- retrieve the bundle signature
         set tSig to (getBundleSignature for tItem)
         
         -- update the record template
         set bnom of tRec to tNom
         set bsig of tRec to tSig
         
         -- add the updated record to the list
         copy tRec to the end of tPkgs
      end if -- (isPkg)
   end repeat -- with tNom in tLst
   
   -- return the retrieval results
   return (tPkgs)
end getBundles -- from aPath

Reading the BOM file

Listing 3 shows the function handler used to convert the BOM file. It also shows how to use the do shell script function to call the lsbom tool. The handler takes a path to the receipt bundle as its input argument. If successful, it returns the file path to a temp file; otherwise, it returns an empty string.

First, the handler gets a path to the TemporaryItems directory. It converts the path to a POSIX formant, and appends the name of the temp file bom.out. This file will store the output results of the lsbom tool.

The handler then prepares the script to be executed with the do shell script function. The script consists of the file path to the BOM file, as well as the path to bom.out. For example, if the target receipt is Sample.pkg, the script will read as follows.

   lsbom --p fs /Library/Receipts/Sample.pkg/Contents/Archive.bom ¬ 
               > ~/Library/TemporaryFiles/bom.out

Note that, in actual practice, the entire script will consists only of a single line. It will also state the full path to the bom.out file on the user home directory.

Notice as well that a --p fs option is passed to the lsbom tool. This option tells the tool to display only the file paths and sizes of each BOM item. If the item happens to be a directory, its entry in the bom.out file will not have any size data.

Listing 3. Generating a BOM file for a given receipt (Files.applescript).

property pBOMPath : "/Contents/Archive.bom"
property pBOMTemp : "bom.out"
property pCmd : "lsbom "
property pOpts : "-p fs "
to getBOM for aRcpt
   local tTmp, tCmd
   
   -- retrieve a path to a temp directory
   set tTmp to path to temporary items from user domain
   set tTmp to POSIX path of tTmp
   
   -- prepare the output file path
   set tTmp to tTmp & "/" & pBOMTemp
   
   -- prepare the shell command
   set tCmd to pCmd & pOpts
   set tCmd to tCmd & aRcpt & pBOMPath
   set tCmd to tCmd & " > " & tTmp
   
   -- execute the shell command
   do shell script tCmd
   
   -- was it successful?
   try
      set tTmp to (POSIX file tTmp) as string
      alias tTmp
      return (tTmp)
   on error tErr number tTyp
      display dialog ("[FATAL]" & tErr as string)
      return ("")
   end try
end getBOM -- for aRcpt

Listing 4 shows the function handler used to parse the contents of the bom.out file. It takes the path to that file as its input argument. When done, it returns a list of records, each record representing a BOM entry.

The handler first opens a read-only access to the bom.out file. It reads all the entries in the file, and then closes the access.

The entries consist of a list of strings. Each entry alternates between the file path and size of a BOM item. The handler creates a BOM record for each entry. It then appends the record to the list variable tBOM, which is returned to the calling handler.

Listing 4. Reading the BOM file (Files.applescript).

property pBOMRec : {fnom:"", fsiz:""}
property pLF : 10
property pHT : 9
to loadBOMItems from theFile
   local tSrc, tSiz, tPos, tLen
   local tLst, tBOM, tDat, tRec, tNom
   local tTkn, tOdd
   
   -- initialize the following locals
   set tBOM to {}
   set tTkn to {}
   set tTkn to tTkn & (ASCII character pLF)
   set tTkn to tTkn & (ASCII character pHT)
   
   try
      -- start a read-only access to the file
      open for access theFile without write permission
      set tSrc to result
      if (tSrc > 0) then
         -- read the contents of the file
         read tSrc using delimiter tTkn
         set tLst to result
         
         -- close the read-only access to the file
         close access tSrc
      end if -- (tSrc > 0)
      
      -- parse the BOM entries
      copy pBOMRec to tRec
      set tLen to the length of tLst
      
      if (tLen > 0) then
         repeat with tPos from 1 to tLen by 2
            -- retrieve the following BOM items
            set tNom to item tPos of tLst
            set tSiz to item (tPos + 1) of tLst
            if (tSiz is equal to "") then
               set tSiz to "-1"
            end if -- (tSiz is equal to "")
            
            -- prepare the BOM record
            set fnom of tRec to (tNom as string)
            set fsiz of tRec to (tSiz as string)
            
            -- append the record to the return list
            copy tRec to the end of tBOM
         end repeat -- with tPos from 1 to tLen by 2
         
         -- remove the first two items
         set tLen to length of tBOM
         set tBOM to items 3 thru tLen of tBOM
end if -- (tSiz > 0)
   on error tErr
      -- something wrong has happened
      display dialog ("[FATAL] loadBOMItems:" & tErr as string)
   end try
   
   -- return a list of BOM entries
   return (tBOM)
end loadBOMItems -- theFile

Removing a BOM item

There are a many ways to remove a software product. The direct way is to locate the topmost directory from the BOM, and delete it together with its contents. Another way is to select specific items from the BOM for deletion. Choosing the right approach depends on the aim of the uninstaller. The Uninstall project, for instance, uses a variant of the second approach.

Shown in Listing 5 is the function handler that will remove a BOM item. It is called after the user selected an item from the Files listbox, and clicked on the Uninstall button.

The handler first creates an Uninstall folder in the TemporaryItems directory. Next, it moves the BOM item from its original path to the folder. It also deletes the item at the specified path. Once the handler completes its task, it returns a true to the calling handler. Otherwise, it returns a false if any errors occurred.

Listing 5. Removing a BOM item (Files.applescript).

   property pDirTrash : "Uninstall"
   to removeTheItem given path:aTgt, folder:aDir
      local tTmp, tBin, tCmd
      
      -- initialize the following locals
      set tTmp to path to temporary items from user domain as string
      set tBin to tTmp & pDirTrash
      
      -- create the temporary uninstall directory
      tell application "Finder"
         try
            if not (exists alias tBin) then
               make new folder at folder tTmp ¬
                  with properties {name:"Uninstall"}
            end if -- (exists alias tBin)
         on error tErr
            display dialog ¬
               "[FATAL] Failed to create the Uninstall directory"
            return false
         end try
      end tell -- application "Finder"
      
      -- attempt to remove the item
      tell application "Finder"
         try
            -- is the item a directory or a file?
            if (aDir) then -- it is a directory
               -- test delete the directory
               move folder aTgt to folder tBin with replacing
               delete folder aTgt
            else -- it is a file
               -- test delete the file
               move file aTgt to folder tBin with replacing
               delete file aTgt
            end if -- (aDir)
         on error tErr
            display dialog "[ERROR] " & tErr
            return false
         end try
      end tell -- application "Finder"
      
      -- the removal was successful
      return (true)
   end removeTheItem -- given path:aTgt, type:aTyp

Notice that the handler uses the Finder to delete the BOM item. While this works in most cases, it will fail if the item is inside a restricted directory such as /usr. For that case, replace the delete code with the following script statements.

   set aTgt to the POSIX path of alias aTgt
   set tCmd to "rm -Rf " & aTgt
   do shell script tCmd with administrator privileges

The above statements will prompt the user to validate the deletion that is about to occur.

Also, notice that the handler first makes a copy of the BOM item it is about to delete. This gives the user a chance to restore the deleted item back to its former location.

Final Thoughts

Product removal is just as important as product installation. Though most products are easy to remove manually, some require the use of an uninstaller tool. The tool will peruse the receipt package for the product, and delete all the files that belong to that product. This will help ensure that future products installations will be more successful.

AppleScript Studio makes it quite easy to build an uninstaller tool. It has a much lower learning curve compared to Cocoa. This alone makes for a faster build and deployment cycle. It allows the addition of a user-friendly interface, which is not possible through shell scripts.

Hopefully, this article helps to get you started in writing your own uninstaller. Until Apple adds an uninstall option to the Installer tool, writing your own is, for now, the next best solution.

Bibliography and References

Apple Computers. AppleScript Resources. Retrieved 2007 Feb 24. Online: http://www.apple.com/applescript/resources.

Apple Computers. "do shell script in AppleScript". Technical Note TN2065. Copyright 2003, 2005, 2006. Apple Computers, Inc.

Apple Computers. "Administrative Accounts". An Introduction to MacOS X Security for Web Developers. Copyright 2007. Apple Computers, Inc. 2004 Aug 25. Online: http://developer.apple.com/internet/security/securityintro.html

Apple Computers. "lsbom -- list contents of a bom file". Mac OS X Man Pages. Copyright 2003. Apple Computers, Inc. 2003 Apr 16. Online: http://developer.apple.com/documentation/Darwin/Reference/Manpages/man8/lsbom.8.html.


JC is a freelance engineering consultant and writer currently residing in North Vancouver, British Columbia. He divides his time between writing technical articles, and teaching origami at his local district's public library. He can be reached at anarakisware@cashette.com.

 
AAPL
$500.72
Apple Inc.
+2.04
MSFT
$34.67
Microsoft Corpora
+0.18
GOOG
$894.72
Google Inc.
+12.71

MacTech Search:
Community Search:

Software Updates via MacUpdate

Apple HP Printer Drivers 2.16.1 - For OS...
Apple HP Printer Drivers includes the latest HP printing and scanning software for Mac OS X 10.6, 10.7 and 10.8. For information about supported printer models, see this page.Version 2.16.1: This... Read more
Yep 3.5.1 - Organize and manage all your...
Yep is a document organization and management tool. Like iTunes for music or iPhoto for photos, Yep lets you search and view your documents in a comfortable interface, while offering the ability to... Read more
Apple Canon Laser Printer Drivers 2.11 -...
Apple Canon Laser Printer Drivers is the latest Canon Laser printing and scanning software for Mac OS X 10.6, 10.7 and 10.8. For information about supported printer models, see this page.Version 2.11... Read more
Apple Java for Mac OS X 10.6 Update 17 -...
Apple Java for Mac OS X 10.6 delivers improved security, reliability, and compatibility by updating Java SE 6.Version Update 17: Java for Mac OS X 10.6 Update 17 delivers improved security,... Read more
Arq 3.3 - Online backup (requires Amazon...
Arq is online backup for the Mac using Amazon S3 and Amazon Glacier. It backs-up and faithfully restores all the special metadata of Mac files that other products don't, including resource forks,... Read more
Apple Java 2013-005 - For OS X 10.7 and...
Apple Java for OS X 2013-005 delivers improved security, reliability, and compatibility by updating Java SE 6 to 1.6.0_65. On systems that have not already installed Java for OS X 2012-006, this... Read more
DEVONthink Pro 2.7 - Knowledge base, inf...
Save 10% with our exclusive coupon code: MACUPDATE10 DEVONthink Pro is your essential assistant for today's world, where almost everything is digital. From shopping receipts to important research... Read more
VirtualBox 4.3.0 - x86 virtualization so...
VirtualBox is a family of powerful x86 virtualization products for enterprise as well as home use. Not only is VirtualBox an extremely feature rich, high performance product for enterprise customers... Read more
Merlin 2.9.2 - Project management softwa...
Merlin is the only native network-based collaborative Project Management solution for Mac OS X. This version offers many features propelling Merlin to the top of Mac OS X professional project... Read more
Eye Candy 7.1.0.1191 - 30 professional P...
Eye Candy renders realistic effects that are difficult or impossible to achieve in Photoshop alone, such as Fire, Chrome, and the new Lightning. Effects like Animal Fur, Smoke, and Reptile Skin are... Read more

The Blockheads Creator David Frampton Gi...
The Blockheads Creator David Frampton Gives a Postmortem on the Creation Process of the Game Posted by Andrew Stevens on October 16th, 2013 [ permalink ] Hey, a | Read more »
Sorcery! Enhances the Gameplay in Latest...
Sorcery! | Read more »
PROVERBidioms Paints English Sayings in...
PROVERBidioms Paints English Sayings in a Picture for Users to Find Posted by Andrew Stevens on October 16th, 2013 [ permalink ] | Read more »
OmniFocus 2 for iPhone Review
OmniFocus 2 for iPhone Review By Carter Dotson on October 16th, 2013 Our Rating: :: OMNIPOTENTiPhone App - Designed for the iPhone, compatible with the iPad OmniFocus 2 for iPhone is a task management app for people who absolutely... | Read more »
Ingress – Google’s Augmented-Reality Gam...
Ingress – Google’s Augmented-Reality Game to Make its Way to iOS Next Year Posted by Andrew Stevens on October 16th, 2013 [ permalink ] | Read more »
CSR Classics is Full of Ridiculously Pre...
CSR Classics is Full of Ridiculously Pretty Classic Automobiles Posted by Rob Rich on October 16th, 2013 [ permalink ] | Read more »
Costume Quest Review
Costume Quest Review By Blake Grundman on October 16th, 2013 Our Rating: :: SLIGHTLY SOURUniversal App - Designed for iPhone and iPad This bite sized snack lacks the staying power to appeal beyond the haunting season.   | Read more »
Artomaton – The AI Painter is an Artific...
Artomaton – The AI Painter is an Artificial Artistic Intelligence That Paints From Photos You’ve Taken Posted by Andrew Stevens on October 16th, 2013 [ | Read more »
Hills of Glory 3D Review
Hills of Glory 3D Review By Carter Dotson on October 16th, 2013 Our Rating: :: BREACHED DEFENSEUniversal App - Designed for iPhone and iPad Hills of Glory 3D is the most aggravating kind of game: one with good ideas but sloppy... | Read more »
FitStar: Tony Gonzalez Adds New 7 Minute...
FitStar: Tony Gonzalez Adds New 7 Minute Workout Program for Those Who Are in a Hurry Posted by Andrew Stevens on October 16th, 2013 [ permalink ] | Read more »

Price Scanner via MacPrices.net

Updated MacBook Price Trackers
We’ve updated our MacBook Price Trackers with the latest information on prices, bundles, and availability on MacBook Airs, MacBook Pros, and the MacBook Pros with Retina Displays from Apple’s... Read more
13-inch Retina MacBook Pros on sale for up to...
B&H Photo has the 13″ 2.5GHz Retina MacBook Pro on sale for $1399 including free shipping. Their price is $100 off MSRP. They have the 13″ 2.6GHz Retina MacBook Pro on sale for $1580 which is $... Read more
AppleCare Protection Plans on sale for up to...
B&H Photo has 3-Year AppleCare Warranties on sale for up to $105 off MSRP including free shipping plus NY sales tax only: - Mac Laptops 15″ and Above: $244 $105 off MSRP - Mac Laptops 13″ and... Read more
Apple’s 64-bit A7 Processor: One Step Closer...
PC Pro’s Darien Graham-Smith reported that Canonical founder and Ubuntu Linux creator Mark Shuttleworth believes Apple intends to follow Ubuntu’s lead and merge its desktop and mobile operating... Read more
MacBook Pro First, Followed By iPad At The En...
French site Info MacG’s Florian Innocente says he has received availability dates and order of arrival for the next MacBook Pro and the iPad from the same contact who had warned hom of the arrival of... Read more
Chart: iPad Value Decline From NextWorth
With every announcement of a new Apple device, serial upgraders begin selling off their previous models – driving down the resale value. So, with the Oct. 22 Apple announcement date approaching,... Read more
SOASTA Survey: What App Do You Check First in...
SOASTA Inc., the leader in cloud and mobile testing announced the results of its recent survey showing which mobile apps are popular with smartphone owners in major American markets. SOASTA’s survey... Read more
Apple, Samsung Reportedly Both Developing 12-...
Digitimes’ Aaron Lee and Joseph Tsai report that Apple and Samsung Electronics are said to both be planning to release 12-inch tablets, and that Apple is currently cooperating with Quanta Computer on... Read more
Apple’s 2011 MacBook Pro Lineup Suffering Fro...
Appleinsider’s Shane Cole says that owners of early-2011 15-inch and 17-inch MacBook Pros are reporting issues with those models’ discrete AMD graphics processors, which in some cases results in the... Read more
Global Notebook Shipments To Grow Less Than 3...
Digitimes Research’s Joanne Chien reports that Taiwan’s notebook shipments grew only 2.5% sequentially, and dropped 8.6% year-over-year in the third quarter despite the fact that notebook ODMs have... Read more

Jobs Board

Senior Mac / *Apple* Systems Engineer - 318...
318 Inc, a top provider of Apple solutions is seeking a new Senior Apple Systems Engineer to be based out of our Santa Monica, California location. We are a Read more
*Apple* Retail - Manager - Apple Inc. (Unite...
Job Summary Keeping an Apple Store thriving requires a diverse set of leadership skills, and as a Manager, you’re a master of them all. In the store’s fast-paced, Read more
*Apple* Solutions Consultant - Apple (United...
**Job Summary** Apple Solutions Consultant (ASC) - Retail Representatives Apple Solutions Consultants are trained by Apple on selling Apple -branded products Read more
Associate *Apple* Solutions Consultant - Ap...
**Job Summary** The Associate ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The Associate ASC's role is to Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.