Do-it-Yourself Package Installation

One of the Newton 2.x OS Q&As
Copyright © 1997 Newton, Inc. All Rights Reserved. Newton, Newton Technology, Newton Works, the Newton, Inc. logo, the Newton Technology logo, the Light Bulb logo and MessagePad are trademarks of Newton, Inc. and may be registered in the U.S.A. and other countries. Windows is a registered trademark of Microsoft Corp. All other trademarks and company names are the intellectual property of their respective owners.


For the most recent version of the Q&As on the World Wide Web, check the URL: http://www.newton-inc.com/dev/techinfo/qa/qa.htm
If you've copied this file locally, click here to go to the main Newton Q&A page.
This document was exported on 7/23/97.


Do-it-Yourself Package Installation (8/26/96)

Q: I want to have a newer version of my package downloaded over an endpoint, and replace the older version. How do I do this?

A: There are a few steps, but they're fairly straightforward.

First, you need to remove the old package if the new version has the same unique name. (See code below which you can use if you don't know whether the new package has the same name or not.) Then call SafeRemovePackage().

Second, you need to get the new package to the Newton device. Use the endpoint method SuckPackageFromEndpoint(), or the store method SuckPackageFromBinary() depending on where the package is coming from.

In some cases, you don't want to remove the old package until you're sure the new one works. If you're in this situation, the new package will have to have a different unique name. Just defer the call to SafeRemovePackage until after you verify (most likely with a deferred call) that the SuckPackageFromEndpoint or SuckPackageFromBinary has succeeded.

Also note that you can't call SafeRemovePackage from a function that's in the target package. You'll need to create a small function which does nothing but remove the old package, and then TotalClone that small function before executing it via a deferred call. Otherwise you'd be chopping your package's legs out from under itself, causing no end of havoc!

In some cases, it is appropriate to have a "loader" package which has a small amount of code to check whether or not to install the real package. This is accomplished by writing a small auto part which has the "Auto Remove Package" flag turned on, and the real package in a binary object within itself. This auto part installscript performs whatever checks are necessary, and then conditionally calls SuckPackageFromBinary, providing the binary object which holds the real package.

To create a binary object from a package, you need to move the data from the .pkg file that NTK produces into an object in the NewtonScript environment in NTK. On Windows NTK, LoadDataFile does this. On Macintosh NTK, the easiest thing to do is use a utility such as Clipboard Magician to copy the data from the .pkg file into a resource, then use GetNamedResource to get the data in your installer package. GetNamedResource and LoadDataFile are documented in the Newton Toolkit User's Guide. The MonacoTest sample code is a working example of a package installer that uses this technique.

To get the unique name for a package inside a binary object, you can use the following NewtonScript code. It takes the package object as its argument, and will return the string holding the unique name.

func(pkgRef)
begin
  local thelen:=extractword(pkgRef,26) div 2 -1;
  local s:="             ";

  while strlen(s)<thelen do 
    s:=s&s;
  s:=substr(s,0,thelen);

  BinaryMunger(s, 0, thelen*2, pkgRef,
       52+(extractlong(pkgRef,48)*32)+extractword(pkgRef,24), thelen*2);
  s;
end