hostExtDB is a perl5 library used to extract information from the external-format Princeton University Host Database.
NOTE WELL the retirement of the Princeton University Host Database and Related Services; see https://www.net.princeton.edu/announcements/hostdb-retirement.html . Access to that data via this library was retired March 19 2019.
This library is the official API published by Princeton University’s OIT Network Systems for accessing the data; the format (and location) of the underlying data file read by this library should not be relied upon directly.
The library is available via an NFS filesystem that may be mounted by NFS clients at Princeton University.
Typical Setup: # mkdir /usr/hostdatabase # mount -F nfs -o ro nassau.princeton.edu:/vol/unixdepot_vol/unixdepot/hostdatabase /usr/hostdatabase
Perl:
#!/usr/bin/perl
use lib ’/usr/hostdatabase/lib’;
require "hostExtDB.pl" or die "require failed for hostExtDB.pl\n";
...
Perl functions:
string account(HostEntry) array *HostEntry
string acct1059(HostEntry) array *HostEntry
string adminDomain(Entry) array *Entry
array alias(HostEntry) array *HostEntry
int aliasCount(HostEntry) array *HostEntry
string AppleTalkRange(SubnetEntry) array *SubnetEntry
string assetNumber(HostEntry) array *HostEntry
string bootpParams(HostEntry) array *HostEntry
string building(HostEntry) array *HostEntry
string dateCreated(HostEntry) array *HostEntry
string dateLastChanged(HostEntry) array *HostEntry
string dateToDelete(HostEntry) array *HostEntry
array defaultRouters(SubnetEntry) array *SubnetEntry
string deptName(HostEntry) array *HostEntry
string dnet2enet(area, node) int area, node
int dnsCount(SubnetEntry) array *SubnetEntry
string dnsDomain(Entry) array *Entry
array dnsServers(SubnetEntry) array *SubnetEntry
string DormnetSubscriberNetid(HostEntry) array *HostEntry
string entryName(Entry) array *Entry
string entryType(Entry) array *Entry
int ifCount(HostEntry) array *HostEntry
string infoContact(HostEntry) array *HostEntry
array interface(HostEntry, interfaceNumber, interfaceSubfieldNames) array *HostEntry int interfaceNumber array interfaceSubfieldNames
string IPAddress(SubnetEntry) array *SubnetEntry
array license(HostEntry) array *HostEntry
int licenseCount(HostEntry) array *HostEntry
array mx(HostEntry) array *HostEntry
int mxCount(HostEntry) array *HostEntry
array netgroup(HostEntry) array *HostEntry
int netgroupCount(HostEntry) array *HostEntry
string NovellNet(SubnetEntry) array *SubnetEntry
string OS(HostEntry) array *HostEntry
array parseExtEntry(extDBLine) string *extDBLine
void printHost(Entry) array *Entry
void printHostFriendly(Entry) array *Entry
string ROMversion(HostEntry) array *HostEntry
string room(HostEntry) array *HostEntry
array routerCount(SubnetEntry) array *SubnetEntry
string serialNumber(HostEntry) array *HostEntry
array SNalias(SubnetEntry) array *SubnetEntry
int SNaliasCount(SubnetEntry) array *SubnetEntry
string SNdateCreated(SubnetEntry) array *SubnetEntry
string SNdateLastChanged(SubnetEntry) array *SubnetEntry
array sprintHostFriendly(Entry) array *Entry
string subnetMask(SubnetEntry) array *SubnetEntry
string sysType(HostEntry) array *HostEntry
array tc(HostEntry) array *HostEntry
int tcCount(HostEntry) array *HostEntry
string ttl(HostEntry) array *HostEntry
string user(HostEntry) array *HostEntry
array wks(HostEntry) array *HostEntry
int wksCount(HostEntry) array *HostEntry
These perl functions are used to extract information from the external-format Princeton University Host Database file.
Before using the
library, you must mount the NFS filesystem containing the library and the
data. The /vol/unixdepot_vol/unixdepot/hostdatabase filesystem is exported
by nassau.princeton.edu. You must mount it on your host as /usr/hostdatabase;
the library expects to be mounted at that mount point. The steps to mount
an NFS filesystem vary from platform to platform; for example, in UNIX
(as root):
# mkdir /usr/hostdatabase # mount -F nfs -o ro nassau.princeton.edu:/vol/unixdepot_vol/unixdepot/hostdatabase /usr/hostdatabase
This NFS filesystem is exported to clients on the campus network at Princeton University. It is not intended to be available off-campus. Availability is the same as that of OIT NFS file service; scheduled outages to OIT NFS file services are typically announced in advance by OIT.
The library provides read access to the "external format" version of the Princeton University Host Database. The Host Database is described at https://www.net.princeton.edu/hostmaster/
The "external format database" (or simply "the external database") is a snapshot taken of the Host Database at a particular time. These snapshots ("database rebuilds") are normally taken at least once per day; usually they are taken far more often. The process of taking this snapshot and pushing the new data into production is known as "rebuilding the Host Database."
Once the library has been required in your perl script, a number of global variables in package main are defined, including $parmEXTERNDB. This variable contains the name of a file; that file contains the external database.
Your perl program should open that file, read its contents, and rely upon the library to parse the contents.
Each line in the file is a blank line, a comment, or a single Host Database entry. You are responsible for skipping blank lines and comment lines (lines beginning with the character ’#’). Any other line you should assume is a Host Database entry.
Because the file may contain very long lines, be sure that anything you use to read or manipulate the file can handle arbitrarily-long lines. (Perl should have no difficulty with very long lines.)
Other than recognizing and skipping blank lines and comment lines, never attempt to parse the contents of the file yourself. The format is non-trivial, and changes with no public announcement. Use of the library normally insulates your program from these changes.
To extract
data from a line containing a Host Database entry, remove any trailing
newline from the line, then pass the resulting line to the parseExtEntry()
function. Capture the results in an array, by convention called @entry
throughout this document. You should treat the @entry array as an opaque
object; the layout of information in that array may change at any time.
As the @entry variable will be passed to subroutines using a typeglob,
the variable must be in the symbol table; that means that if you choose
to scope the variable, you must use a dynamically-scoped variable rather
than a lexically-scoped variable. For example,
our $parmEXTERNDB;
open(EXTERNDB, $parmEXTERNDB) or die;
our @entry;
while (<EXTERNDB>) {
next if (/^\s*#/ or /^\s*$/);
chomp;
@entry = parseExtEntry($_);
# ... make use of the parsed information here
}
close(EXTERNDB);
The parseExtEntry() function parses the line you passed it into static storage that is private to the library. After you have called parseExtEntry() to parse an entry, you may call the library’s other functions to retrieve specific fields from that Host Database entry.
Most of the other functions take as an argument a typeglob to the array returned by parseExtEntry(). These functions returns scalars or arrays; for the purpose of this manual page, the scalars are specified as integers or strings.
After you are done with the current entry, you typically proceed to read the next line from the external database file, and repeat the process. (I.e. pass it to parseExtEntry(), then call other library fuctions to retrieve specific fields from the entry.)
This is simpler than it sounds; taking a brief look now at the EXAMPLE section below should makes things clear.
There are two kinds of entries in the Host Database: a HostEntry, and a SubnetEntry.
A SubnetEntry is one that defines a campus network; the entry’s ENTRY-TYPE field begins with the string SUBNET.
A HostEntry is any other entry. While some of these entries indeed have an ENTRY-TYPE field that begins with the string HOST, others have an ENTRY-TYPE field with other values. The fact that we call this kind of entry a HostEntry doesn’t mean that the ENTRY-TYPE is necessarily HOST, it just means that the ENTRY-TYPE begins with something other than SUBNET.
Although some of the library functions may be used with either a SubnetEntry or a HostEntry, many library functions work only with one kind of entry or the other. This is because many fields are only defined to exist in one or the other kind of entry. Therefore, after parsing an entry with parseExtEntry(), the next step is to retrieve the ENTRY-TYPE field using the entryType() function. If the ENTRY-TYPE value begins with SUBNET, you will usually want to do something different than if the value begins with anything else.
The SYNOPSIS section above shows whether a function works on any kind of Entry, a SubnetEntry, or a HostEntry. The detailed function descriptions below are organized into those three groups. Calling a function on a type of entry which the function is not designed to handle may produce unpredictable results.
parseExtEntry() takes a line you have extracted from the $parmEXTERNDB file, and parses it into an internal form used by the rest of the functions, returning that format as an array. It also stores some information about the entry in internal static storage used by the library.
The line you pass should be from the $parmEXTERNDB file, but not a line that is blank or begins with a ’#’ character. Remove any trailing newline before passing the line to this function.
There is no error return for this function.
Store the return value in an array. Treat the returned array as an opaque object; do not attempt to use the contents of the array directly.
Most of the other functions in this library expect to be passed a typeglob to this array. E.g. if you store the results of this function in an array named @entry, pass it to the other functions as *entry. Note this implies you must not store this array in a lexically-scoped variable (e.g. a my variable), since it is not possible to take a typeglob to such a variable.
dnet2enet() takes as arguments a DECNET area number and node number. It returns the corresponding IEEE 802.2 MAC address. This function does not extract any data from the database, it is simply a data conversion utility.
These functions may be used on any kind of entry:
adminDomain() returns the entry’s ADMIN-DOMAIN field.
entryName() returns the entry’s ENTRY-NAME field. This field is always defined and non-empty.
entryType() returns the entry’s ENTRY-TYPE field. This field is always defined and non-empty.
dnsDomain() returns the entry’s DNS-DOMAIN field. This field is always defined and non-empty.
printHost() performs the same function as printHostFriendly().
printHostFriendly() prints the entry to STDOUT. The format is intended for human consumption. Do not try to parse this format, as it is not guaranteed to remain the same.
sprintHostFriendly() creates a formatted entry in the same format produced by printHostFriendly, but returns the result as an array instead of printing to STDOUT. The format is intended for human consumption. Do not try to parse this format, as it is not guaranteed to remain the same.
These functions should be used only on entries whose ENTRY-TYPE begins with SUBNET:
AppleTalkRange() refers to an obsolete field, so this function’s return value isn’t meaningful. The function is deprecated, and may be removed in the future.
defaultRouters() returns a (possibly empty) array of the entry’s default IPv4 routers (each in dotted-decimal format). routerCount() returns the number of elements in that array.
dnsServers() returns a (possibly empty) array of the entry’s DNS (Domain Name System) servers (each in dotted-decimal format). dnsCount() returns the number of elements in that array.
IPAddress() returns the subnet’s IP-SUBNET-OR-ADDRESS field. This is an IPv4 address, in dotted-decimal format.
NovellNet() refers to an obsolete field, so this function’s return value isn’t meaninful. The function is deprecated, and may be removed in the future.
SNalias() returns a (possibly empty) array of the entry’s ALIAS and ADD-ALIAS fields. SNaliasCount() returns the number of the elements in that array.
SNdateCreated() and SNdateLastChanged() return the entry’s DATE-CREATED and DATE-LAST-CHANGED fields, respectively.
subnetMask() returns the entry’s SUBNET-MASK field.
These functions should be used only with entries whose ENTRY-TYPE begins with anything other than SUBNET.
account() refers to an obsolete field, so this function’s return value isn’t meaninful. The function is deprecated, and may be removed in the future.
acct1059() refers to an obsolete field, so this function’s return value isn’t meaninful. The function is deprecated, and may be removed in the future.
alias() returns a (possibly empty) list of the entry’s ALIAS and ADD-ALIAS fields. aliasCount() return a count of the number of elements in that list.
assetNumber() returns the entry’s ASSET-NUMBER field.
bootpParams() returns the entry’s BOOTP-PARAMETERS field.
building() return’s the entry’s BUILDING field.
dateCreated() and dateLastChanged() return the entry’s DATE-CREATED and DATE-LAST-CHANGED fields.
dateToDelete() returns the entry’s DATE-TO-DELETE field.
deptName() return’s the entry’s DEPARTMENT field. This contains the name of the department.
Customers needing to translate the department names appearing in Host Database entries into department numbers may find https://www.net.princeton.edu/hostmaster/departments.txt useful. That file may be programmatically retrieved, and contains an easily-parsed mapping from department numbers to names. (There is no guarantee that University department names are unique.) Some department names appearing in Host Database entries may not appear in this file. This can happen when a department is retired, renamed, or split into multiple departments, but no new department name can be determined for existing Host Database entries citing the old department name. It can also happen during transition periods while a department is being removed, renamed, or renumbered.
DormnetSubscriberNetid() returns the OIT netID of the person responsible for the entry if the entry is a Dormnet Host Database entry. (That is, if the entry is associated with a Dormnet subscription, regardless of whether the entry is currently subscribed or unsubscribed.) If called on an entry that is not a Dormnet Host Database entry, the return value is not meaningful.
ifCount() returns a count of the number of network interfaces that appear in the entry. This is the maximum of the number of the entry’s IPv4 addresses and hardware addresses. For example, if the entry contains two IPv4 addresses and three hardware addresses, it has three interfaces. (The first IPv4 and hardware address belong to the first interface, the second IPv4 and hardware address belong to the second interface, and the third hardware address belongs to the third interface.)
infoContact() refers to an obsolete field, so this function’s return value isn’t meaninful. The function is deprecated, and may be removed in the future.
interface() takes as arguments an interface number and an optional array of interface subfield names. Interface numbers start at 1. Valid subfield names are: ifType, ifSubnet, ifIPAddress, ifISOAddress, ifdnetAddress, ifMACaddress, ifPassword, ifWireType, ifLink, ifAliasCount, and ifAlias.
The function returns an array containing the values of the requested interface subfields (in the order requested) for the specified interface. The value returned for each subfield is a scalar, except the ifAlias subfield, which is a (possibly empty) array. For each subfield that is a scalar, if the subfield is empty, then the value returned is variously undef or defined by but false; we never simply "skip" returning a value, as that would make it impossible for you to parse the array we return.
If you do not specify any interface subfield names, all of the interface subfield values are returned, in the order they appear listed above.
If you specify an interface number of 0, the requested subfields for all the entry’s interfaces are returned (i.e. all the requested fields for the first interface, followed by the fields for the second interface, etc.).
The ifType subfield contains a string describing the physical media type of the interface. The ifSubnet subfield contains the canonical name of the IP subnet for this interface’s IPv4 address, if any. The ifIPAddress subfield contains the IPv4 address for this interface, if any, in dotted-decimal format. The ifISOAddress subfield refers to a field that never had any meaning, so its value is not meaningful. The ifdnetAddress subfield contains the DECNET address for this interface, if any. The ifMACaddress subfield contains the IEEE 802.2 MAC address for this interface, if any. The ifPassword subfield refers to an obsolete field, so its value is not meaningful. The ifWireType subfield refers to an obsolete field, so its value is not meaningful. The ifLink subfield refers to an obsolete field, so its value is not meaninful. The ifAlias subfield contains a (possibly empty) array of the interface aliases for this interface. The ifAliasCount subfield contains a count of the elements in the ifAlias array.
license() returns a (possibly empty) list of the entry’s LICENSE-SCHEME fields.
licenseCount() returns a count of the number of elements in that list.
mx() returns a (possibly empty) list of the entry’s MAIL-METHOD fields. mxCount() returns a count of the number of elements in that list.
netgroup() returns a (possibly empty) list of the entry’s OIT-NETGROUP and ADD-OIT-NETGROUP fields. netgroupCount() return a count of the number of elements in that list.
OS() returns the entry’s OPERATING-SYTEM field.
ROMversion() refers to an obsolete field, so this function’s return value isn’t meaninful. The function is deprecated, and may be removed in the future.
room() returns the entry’s ROOM field.
serialNumber() returns the entry’s SERIAL-NUMBER field.
sysType() returns the entry’s SYSTEM-TYPE field.
tc() returns a (possibly empty) list of the entry’s TECH-CONTACT and ADD-TECH-CONTACT fields. tcCount() returns a count of the number of elements in that list.
ttl() returns the DNS TTL override for the entry, if any.
user() returns the entry’s USER-MAIL field.
wks() and wksCount() refer to an obsolete field, so these function’s return values aren’t meaninful. The functions are deprecated, and may be removed in the future.
This library was available for many years via the /usr/princeton NFS filesystem exported by OIT.
While it is still available via that filesystem, use of the library via that filesystem is no longer practical for most clients. The version of the library in /usr/princeton relies upon the use of /usr/princeton/bin/perl, a version of perl built for certain operating systems that were popular years ago. OIT no longer maintains the /usr/princeton filesystem (and most hosts rely on a locally-installed copy of perl).
There are still a few hosts with that old /usr/princeton filesystem mounted. Depending on the operating system those hosts are running, it may still be possible to call this library on those hosts as follows:
#!/usr/princeton/bin/perl require "princeton/hostExtDB.pl" or die; ...
We no longer recommend that approach. Instead, we recommend accessing the library via the /usr/hostdatabase filesystem as described in the SYNOPSIS section above.
Assuming the /usr/hostdatabase filesystem is mounted, any program that used the old /usr/princeton version can easily be modified to use the /usr/hostdatabase version by changing the beginning of the program to:
#!/usr/bin/perl use lib ’/usr/hostdatabase/lib’; require "hostExtDB.pl" or die;
You will need to adjust the first line to refer to a copy of perl5 available to your host; on most systems this is /usr/bin/perl or /usr/local/bin/perl.
We cannot stress too highly the importance of treating as opaque objects the contents of the external database entry lines read from the data file named by $parmEXTERNDB, and the array returned by parseExtEntry(). Any program that tries to interpret the contents of the external database file itself (other than skipping blank lines and comment lines), or relies on the innards of the array returned by parseExtEntry() will eventually break. Always rely on the functions provided by this library to retrieve information from the database.
When checking to see whether an entry is a SubnetEntry, be sure to check that the ENTRY-TYPE begins with SUBNET, rather than checking to see if it is equal to SUBNET.
Unless specified otherwise above, none of the functions that extract a field from an entry returns an error. If the function is declared to return a scalar (and is intended to extract a field from a Host Database entry), when the requested field is empty the function will variously return undef or a defined by false value. If the function is declared to return an array (and is intended to extract a field from a Host Database entry), when the requested field is empty the function will return an empty array. (The lone exception is interface(), whose behavior is described in detail above.) If the function is declared to return a scalar which is a count of the number of elements that would be returned by another array-returning function, then when that array would be empty, the scalar that is returned is 0.
The library uses
internal static storage, and does not support having more than one entry
"parsed" at a time. That is, do not expect to be able to do something
like the following:
$line1 = <EXTERNDB>;
chomp $line1;
next if $line1 =~ /^\s*#/ or $line1 =~ /^\s*$/;
@entry1 = parseExtEntry($line1);
$line2 = <EXTERNDB>;
chomp $line2;
next if $line2 =~ /^\s*#/ or $line2 =~ /^\s*$/;
@entry2 = parseExtEntry($line2);
# WRONG!
$entryname = entryName(*entry1);
Example 1:
#!/usr/bin/perl
# Example of how to use the hostExtDB library.
# Iterate through the entire database, skipping SubnetEntries and entries
# where the BUILDING field is "EQuad".
# For all other entries, print the entry’s fully-qualified name, room
# building, the first interface’s IP address,
# and the first interface’s hardware address.
use lib ’/usr/hostdatabase/lib’;
require "hostExtDB.pl" or die "require failed for hostExtDB.pl\n";
our $parmEXTERNDB;
open(EXTERNDB, $parmEXTERNDB) or die "cannot open $parmEXTERNDB : $!\n";
printf STDOUT "NAME\tROOM\tBUILDING\tIP-ADDRESS-1\tMAC-ADDRESS-1\tTECHNICAL-CONTACTS\n";
our @entry;
while (<EXTERNDB>) {
next if (/^\s*#/ or /^\s*$/);
chomp;
@entry = parseExtEntry($_);
# skip SubnetEntries
my $entrytype = entryType(*entry);
next if $entrytype =~ /^SUBNET/;
my $name = entryName(*entry);
unless ($name =~ s/\.$//) { # remove trailing dot if fully qualified
# name is not already fully-qualified, append DNS domain
$name = $name . "." . dnsDomain(*entry);
}
# $name is now fully-qualified
my $building = building(*entry) || "N/A";
# skip entries in EQuad
next if $building eq "EQuad";
my $room = room(*entry) || "N/A";
my @tech_contacts = tc(*entry);
my $tech_contacts = join(",", @tech_contacts);
# retrieve IP address and MAC address for interface 1
my ($firstIP, $firstMAC) = interface(*entry, 1 , "ifIPAddress", "ifMACaddress");
$firstIP = "N/A" unless ($firstIP);
$firstMAC = "N/A" unless ($firstMAC);
printf STDOUT "%s\t%s\t%s\t%s\t%s\t%s\n",
$name, $room, $building, $firstIP, $firstMAC, $tech_contacts;
}
close(EXTERNDB);
Example 2:
#!/usr/bin/perl
# Example of how to use the hostExtDB library.
# Iterate through the entire database, skipping SubnetEntries.
# Print those entries where the DEPARTMENT field is "English"
# or the BUILDING is "McCosh Hall".
# By default only the entry’s name is printed;
# the ’-l’ option causes us to print the entire entry.
use Getopt::Std;
use lib ’/usr/hostdatabase/lib’;
require "hostExtDB.pl" or die "require failed for hostExtDB.pl\n";
our($opt_h, $opt_l);
&getopts("hl");
if ($opt_h) {
print "Usage: $0 [-h] [-l]\n";
exit 0;
}
our $parmEXTERNDB;
open(EXTERNDB, $parmEXTERNDB) or die "cannot open $parmEXTERNDB : $!\n";
our @entry;
while (<EXTERNDB>) {
next if (/^\s*#/ or /^\s*$/);
chomp;
@entry = parseExtEntry($_);
# skip SubnetEntries
my $entrytype = entryType(*entry);
next if $entrytype =~ /^SUBNET/;
next unless building(*entry) eq ’McCosh Hall’ or deptName(*entry) eq ’English’;
my $name = entryName(*entry);
unless ($name =~ s/\.$//) { # remove trailing dot if fully qualified
# name is not already fully-qualified, append DNS domain
$name = $name . "." . dnsDomain(*entry);
}
# $name is now fully-qualified
if ($opt_l) {
# long format output
printHostFriendly(*entry);
print "\n\n";
} else {
# short format output
print STDOUT $name, "\n";
}
}
close(EXTERNDB);
Example 3:
#!/usr/bin/perl
# Example of how to use the hostExtDB library.
#
# Iterate through the entire database, skipping SubnetEntries.
# Print those entries where the canonical entry name begins with ’chm-’
# and the entry contains at least one IP address on the ’recyclenet’ subnet.
#
# By default only the entry’s name is printed;
# the ’-l’ option causes us to print the entire entry.
use Getopt::Std;
use lib ’/usr/hostdatabase/lib’;
require "hostExtDB.pl" or die "require failed for hostExtDB.pl0;
our ($opt_h, $opt_l);
&getopts("hl");
if ($opt_h) {
print "Usage: $0 [-h] [-l]0;
exit 0;
}
our $parmEXTERNDB; # from hostExtDB.pl
open(EXTERNDB, $parmEXTERNDB) or die "cannot open $parmEXTERNDB : $!0;
our @entry;
while (<EXTERNDB>) {
next if (/^#/ or /^$/);
chomp;
@entry = parseExtEntry($_);
# skip SubnetEntries
my $entrytype = entryType(*entry);
next if $entrytype =~ /^SUBNET/;
# interface(*entry, 0, ’ifSubnet’) returns a (possibly-empty) array
containing the names the subnets
# for all the entry’s IP addresses
next unless (
(entryName(*entry) =~ /^chm-/i)
and
(grep { $_ eq ’recyclenet’ } interface(*entry, 0, ’ifSubnet’))
);
my $name = entryName(*entry);
unless ($name =~ s/.$//) { # remove trailing dot if fully qualified
# name is not already fully-qualified, append DNS domain
$name = $name . "." . dnsDomain(*entry);
}
# $name is now fully-qualified
if ($opt_l) {
# long format output
printHost(*entry);
print "0n";
} else {
# short format output
print STDOUT $name, "0;
}
close(EXTERNDB);
Some sample programs may be found in /usr/hostdatabase/examples/.
In legal terms:
The Princeton University Host Database is Copyright (c) 2013 The Trustees of Princeton University. All rights reserved.
Permission is hereby granted by the Princeton University Office of Information Technology for faculty, staff, and students of Princeton University to reproduce, copy, store in a retrieval system, or transmit information obtained via the software described in this document ("the hostExtDB.pl library"), provided that access to the information is limited to devices directly attached to the Princeton University data network, or to persons or organizations that demonstrate a current affiliation with Princeton University by authenticating with a current and valid OIT netid and password.
Except as described above, no part of the information provided by the software described in this document ("the hostExtDB.pl library") may be reproduced, copied, stored in a retrieval system, or transmitted, in any form, or by any means, electronic, mechanical, photocopying, recording, or otherwise, without the prior consent of the Princeton University Office of Information Technology.
perl(1)
The home of the Princeton University Host Database is https://www.net.princeton.edu/hostmaster/
For detailed descriptions of the fields in the Princeton University Host Database, see https://www.net.princeton.edu/hostmaster/fields.html
The manual page you are currently reading is available at https://www.net.princeton.edu/hostmaster/hostExtDB.3.html and in UNIX man page format in /usr/hostdatabase/man/man3/hostExtDB.3 (after you have mounted the /usr/hostdatabase NFS filesystem).
None.