PupName.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Hal Murray, June 3, 1986 9:56:31 pm PDT
This interface is used for simple translates between ROPEs and Pup.Addresses.
DIRECTORY
Pup USING [Address, Socket],
Rope USING [ROPE];
PupName: CEDAR DEFINITIONS = {
ROPE: TYPE = Rope.ROPE;
Naming
Most machines have names like Ivy or Cabernet.
The legal characters are alphanumerics, "-" and "/". Case doesn't matter.
The master list for the database lives on [Indigo]<Portola>Pup-network.txt.
Each entry in the database is a list of names and a list of addresses.
(The other text after each entry is just a comment.)
Most machines have only one name and one address.
If an entry has more than one name, the first one is the primary name.
If an entry has more than one address, the faster interfaces should be listed first.
A name can also represent a distributed service, for example GrapevineRServer = Aurora+GV-Expand, BacoNoir+..., Barbera+..., Cabernet+....
You can represent any address as a string of the form <net>#<host>#<socket>.
NB: All numbers are octal, and the B is never used.
For example, Ivy is "3#17#".
Unspecified fields default to 0. Thus 3## is 3#0#0 (broadcast to bogus socket on net 3), and 3# is 0#3#0, host 3 on net 0, the local net(s).
"+" can also be used to merge two lists of addresses.
"Merge" means take the valid subsets of all possible pairings of one address from the left side and one from the right. A combination is valid if the net, host, and socket slots are equal or one side is 0. If a field from one side is 0, then the other one is used to construct the resulting address.
Examples:
Ivy+FTP is [3#17#0] merged with [0#0#3] => [3#17#3]
Seward+131## is [131#363#0] and [324#363#0] merged with [131#0#0] => [131#363#0]. ([324#363#0] doesn't cross with [131#0#0].)
Seward+363# is [131#363#0] and [324#363#0] merged with [0#363#0] => [131#363#0] and [324#363#3]. (That was a noop since both possible pairs matched.)
Many workstations don't have a name.
Mostly, that's leftover from when the file was full.
Many DLions have a "name" that is a string of octal digits. You can't use that as a name because it looks like a socket number. (That's the octal representation of the number in their host ID prom. Those entrys are used to assign a Pup Host number to the DLion.)
Local name and address
If you only want the name/address of the local machine, please use ThisMachine to minimize compilation dependencies.
MyName: PROC RETURNS [ROPE];
Trys to get a human readable name for the local machine; e.g "Shark". It will call MyRope if can't contact a server or this machine is not in the database.
Errors: None.
MyRope: PROC RETURNS [ROPE];
Returns a ROPE of the form "3#313#". NIL might result if there are no active drivers. Remember that the concept of THE address for a machine is bogus. MyRope returns some valid Address. There may be others.
Errors: None.
Name/Address translation
The implementation might use a local cache, so all those sorts of problems can happen. The servers already have a cache, and the Dicentras sometimes don't notice updates as fast as they should, so local caching shouldn't make things much more complicated.
NameLookup: PROC [name: ROPE, default: Pup.Socket] RETURNS [Pup.Address];
Returns the best address for this machine to use when contacting the specified machine. (Remember, it might have more than one interface.)
"ME" is a special hack for the local machine. (Case is important.)
The name servers won't be contacted if the string is a valid address constant.
If name (or the database) doesn't specify any socket number, then default will be used. The idea is that programs like Chat will call NameLookup["Ivy", PupWKS.telnet]. That lets a wizard use things like "Chat Ivy+1000" to specify a special socket number for debugging. Use Pup.nullSocket if you want to leave it unspecified until later.
Errors: Error - noRoute, noResponse, errorFromServer.
HisAddresses: PROC [name: ROPE, default: Pup.Socket] RETURNS [LIST OF Pup.Address];
Like NameLookup, except it returns all the addresses, closest first.
AddressToRope: PROC [Pup.Address] RETURNS [ROPE];
Returns a ROPE of the form "1#12#123".
Hack: nullSocket => "1#13#" (no trailing 0)
Errors: None.
HisName: PROC [Pup.Address] RETURNS [ROPE];
The socket part of the Address is ignored/suppressed. HisName will call AddressToRope if can't contact a server or that machine is not in the database.
Errors: None.
AddressLookup: PROC [Pup.Address] RETURNS [ROPE];
The server will return "Ivy+FTP" if the database doesn't have any entry matching the whole address. If the socket isn't in the database, then you will get something like "Ivy+1234655443". Use HisName if you don't want big long octal socket numbers.
Don't use this extensively with unknown socket numbers. They will clutter up the caches on the servers.
Errors: Error - noResponse, errorFromServer.
If all goes well:
HisName[NameLookup[alias, Pup.nullSocket]] will return the primary name of a machine.
NameLookup[HisName[backDoor], Pup.nullSocket] will return best address for a machine.
Well Known Socket testing
IsWellKnown: PROC [Pup.Socket] RETURNS [yes: BOOL];
PupSocket.CreateServer and PupStream.CreateListener require a "WellKnown" Socket. There isn't any reasonable way to describe that sort of limitation to the TYPE checker. This is a way to avoid their errors. All the values defined in PupWKS are ok.
Errors: None.
Errors
Code: TYPE = {noRoute, noResponse, errorFromServer};
The servers don't return any code, so all their problems get lumped together.
Error: ERROR [code: Code, text: ROPE];
}.