-- AlpineDoc.tioga
-- Last edited by
-- MBrown on June 7, 1983 9:42 am
-- Kolling on June 23, 1983 3:42 pm

The following message is sent to new Alpine account holders, and is the only user-level documentation for Alpine. Client-level documentation exists as [Indigo]<Alpine>Doc>AlpineInterfaces.*.

Subject: Instructions for using Alpine
To: YourName.pa
Reply-To: Kolling.pa


I. Introduction

Welcome to the community of Alpine users!

The publicly-available Alpine server is called "Luther.alpine". (The server runs on a Dorado named Bataan, whose terminal is in the nursery.)

An Alpine server keeps track of the space occupied by files. Each file has an owner, denoted by a character string (such as "YourName.pa" or "CedarDocs"), and each owner has an associated page quota. To create a personal file on the Alpine server, your RName must be established as an owner, and (unlike IFS!) the act of creating the file must not put you over your quota. (It is possible to create a file owned by a non-individual, such as "CedarDocs", or, with sufficient permission, in another owner's space, but we'll not go into the details here.) The fact that you have received this message probably means that you are established as an owner on "Luther.alpine". If you run out of space, I may be able to increase your quota.

Alpine provides access control on files. Each file contains a "read access list" (default "world") and a "modify access list (default "owner"). These lists may contain RNames, plus the special values "world" and "owner". The lists must fit into a fixed amount of space associated with the file, so it is a good idea to grant access to groups rather than individuals (say, grant modify access to [CSL^.pa, ISL^.pa] rather than to [Atkinson.pa, Birrell.pa, ... ]).

An Alpine server does not provide text names for files. However a package (included in AlpineUserImpls.bcd, and run on the workstation) provides a simple directory system. A file is named by a character string of the form "[server]<owner>file", for instance "[Luther.alpine]<YourName.pa>Walnut.segment". (This package is an interim directory implementation; it does not handle large directories efficiently, or version numbers at all.)

An Alpine server does not have a Telnet "executive" interface (you can't talk to it via Chat). It also does not support the FTP protocol (you can't talk to it via the FileTool). However a package (called AlpineCmds, included in AlpineUserImpls.bcd, and run on the workstation) allows you to perform operations such as copying files to and from Alpine servers, deleting files, listing your directory, determining how far you are from exceeding your Alpine disk quota, and reading and changing the access lists for files. The package is callable from the interpreter.

To retrieve to your local workstation the packages that you will need to be an Alpine user, do:

Bringover /a /p <PreCedar>Top>AlpineUser

One of the files retrieved by this command is AlpineUserImpls.bcd. AlpineUserImpls.bcd must be Run (see examples below) before you can use Alpine; however, it should not be run more than once between boots of the workstation.


II. A sample session showing the use of AlpineCmds:

AlpineCmds currently implements these commands: Copy, Delete, List, ReadQuota, GetReadAccess, SetReadAccess, GetModifyAccess, SetModifyAccess, GetCreateTime, GetSize, SetSize, GetOwnerCreateAccess, and SetOwnerCreateAccess.

&1 Run AlpineUserImpls.bcd -- unless you have already done so.
(there are unbound imports)
Loaded and started: AlpineUserImpls.bcd

&2 ← AlpineCmds.List["[Luther.alpine]<YourName.pa>"]
("List.mesa", "Rope.mesa", "Walnut.segment")

&3 ← AlpineCmds.Delete["[Luther.alpine]<YourName.pa>Rope.mesa"]
TRUE -- returns TRUE if file found, otherwise returns FALSE.

&4 ← AlpineCmds.List["[Luther.alpine]<YourName.pa>*.mesa"]
("List.mesa")

&5 ← AlpineCmds.Copy[to: "[Luther.alpine]<YourName.pa>Rope.mesa", from: "Rope.mesa"]
{does not return a value}

&6 ← AlpineCmds.Copy[to: "Walnut.segment", from: "[Luther.alpine]<YourName.pa>Walnut.segment"]
{does not return a value}

&7 ← AlpineCmds.ReadQuota["[Luther.alpine]<YourName.pa>"]
[pageLimit: 6000, spaceInUse: 3130]

&8 ← AlpineCmds.GetReadAccess["[Luther.alpine]<YourName.pa>List.mesa"];
[fileFound: TRUE, accessList: ("world")]

&9 ← AlpineCmds.GetModifyAccess["[Luther.alpine]<YourName.pa>zot"];
[fileFound: FALSE, accessList: NIL]

&10 ← AlpineCmds.GetSize["[Luther.alpine]<YourName.pa>List.mesa"];
[fileFound: TRUE, size: 7] -- The number of data pages currently allocated to the file.

&11 ← AlpineCmds.SetSize[file: "[Luther.alpine]<YourName.pa>List.mesa", size: 10];
[fileFound: TRUE, newSize: 10]; -- You may wish to set a file's size to longer than it needs to be to contain all its current data, to, for example, optimize allocation. If you don't understand this comment, you don't want to do this.

&12 ← AlpineCmds.SetSize[file: "[Luther.alpine]<YourName.pa>List.mesa", size: 0];
[fileFound: TRUE, newSize: 7] -- SetSize won't truncate to before any "real" data in the file.

&13 ← AlpineCmds.SetReadAccess[file: "[Luther.alpine]<YourName.pa>List.mesa", list: LIST["AlpineImplementors^.pa", "owner", "Cattell.pa"]];
TRUE -- returns TRUE if file found, otherwise returns FALSE.

&14 ← AlpineCmds.SetModifyAccess[file: "[Luther.alpine]<YourName.pa>List.mesa", list: LIST["world"]];
TRUE -- returns TRUE if file found, otherwise returns FALSE.

&15 ← AlpineCmds.GetOwnerCreateAccess["[Luther.alpine]<YourName.pa>"];
[ownerFound: TRUE, ownerAccessList: ("owner")]

&16 ← AlpineCmds.SetOwnerCreateAccess[directory: "[Luther.alpine]<YourName.pa>", list: LIST["AlpineImplementors^.pa", "CedarImplementors^.pa"]];
TRUE -- returns TRUE if owner found, otherwise returns FALSE.


Note that the List procedure allows '* to be embedded within the "simple" file name only, not within the server name or the owner name.

The procedures in AlpineCmds are not designed for heavy use, they are just a way to get off the ground with Alpine. They do not handle exceptional cases very gracefully. For instance, if you exceed your quota with Copy, you will get an uncaught signal. When you get an uncaught signal, try to understand whether it represents a problem of this sort (the argument to the signal is often descriptive). If not or you can't tell, please call me (Karen).


III. Using Walnut with Alpine:

Cypress knows how to access files stored on Alpine. This means that you can store your Walnut database ("Walnut.segment"), and other databases, on Alpine. You cannot usefully store your Walnut log on Alpine yet (but this is coming soon).

Here are the initialization procedures that you must follow if you want Walnut to use Alpine for your copy of Walnut.segment:

&1 Run AlpineUserImpls.bcd -- unless you have already done so.
(there are unbound imports)
Loaded and started: AlpineUserImpls.bcd

&2 ← AlpineCmds.Copy[to: "[Luther.alpine]<YourName.pa>Walnut.segment", from: "Walnut.segment"];
{does not return a value}

Then change YourName.profile to say Walnut.WalnutSegmentFile: "[Luther.Alpine]<YourName.pa>Walnut.segment", and Walnut.WalnutLogFile: "Walnut.DBLog".

Copying your Walnut.segment to Alpine and changing your YourName.profile are "one time only" procedures, and do not normally need to be done each time you invoke Walnut.

When you want to invoke Walnut, do:

&1 Run AlpineUserImpls.bcd -- unless you have already done so.
(there are unbound imports)
Loaded and started: AlpineUserImpls.bcd

&2 Walnut -- The Walnut control viewer should appear.
Opening Walnut transaction...


Notes:

You may include AlpineUserImpls and Walnut in your checkpoint. Since AlpineUserImpls' rollback procedure must be called before Walnut's, be sure to run AlpineUserImpls before Walnut is run. For example, putting

 Run AlpineUserImpls Walnut; Walnut

in the CommandsFrom entry of YourName.profile, then booting and checkpointing will automatically bringup Walnut after rollback. Another possible CommandsFrom entry is simply

 Run AlpineUserImpls Walnut

which makes rollback faster if you don't expect to start up Walnut every time.


You may wish to keep a copy of your Walnut.segment on your workstation, to facilitate switching between running Walnut with Alpine and without it. (Difficult as it is to believe, the Alpine server is occasionally down.) It is not necessary to keep these segments completely in synch, as Walnut will quickly update the segment from its log; however, if you do an Expunge and you are keeping segments in both places, you should definitely copy the result, otherwise you'll have to scavenge the next time you switch. Otherwise, copying the segment once a week or so should be sufficient synchronization.

If both your Alpine and local copies of Walnut.segment are lost, you can, of course, recover your mail through a Walnut scavenge, because all the information needed is in the Walnut log.

Under normal circumstances, to return to using your workstation for your Walnut.segment be sure you have a reasonably current copy of Walnut.segment on the workstation, and change your YourName.profile to say Walnut.WalnutSegmentFile: "Walnut.segment". Then return to a state where Walnut has not started (boot, rollback, or whatever is appropriate), and reinvoke Walnut; Of course, AlpineUserImpls does not need to be loaded when Walnut is using your local workstation.

One symptom of an Alpine crash is a total lack of response in Walnut. You may not see an uncaught signal. The reason is that RPC does not time out long calls. For now, the only way to be sure is to go look at the server (its terminal is in the nursery; to wake up the display hold the space bar down for a second or two). If you suspect that the server is acting strangely, please tell one of the implementors (MBrown, Kolling, or Taft) right away.

Walnut's handling of Alpine exceptions is improving. Walnut generally recovers from Alpine transaction aborts with only a small disruption. When you see Walnut fail to handle an Alpine exception, you should report this to a Walnut implementor (Willie-Sue, Donahue). You may have to roll back in order to restart Walnut.



Our warranty:

It is our hope that even in its present embryonic state, Alpine provides a useful service to its clientele. We shall make reasonable efforts to make the Alpine server available at all times, and to preserve the files that you store on the Alpine server. However, we may find it convenient to lose files rather than recover them with bit-tweezers, and we reserve the right to do so until further notice.

 --mark, karen, and ed