--- netclient.mm	2002/10/24 05:15:05	4.1
+++ netclient.mm	2003/05/18 02:18:28
@@ -1,106 +1,183 @@
 .\" This file is in -*- nroff-fill -*- mode
-.\" STATUS: review draft 4th edition
-.\" $Id: netclient.mm,v 4.1 2002/10/24 05:15:05 grog Exp $
+.\" STATUS: 4th edition
+.\" $Id: netclient.mm,v 4.15 2003/05/18 02:18:28 grog Exp $
 .\"
-.Chapter \*[nchclient] "Basic network access: Clients"
+.Chapter \*[nchclient] "Basic network access: clients"
 Finally we have set up the network connections, and everything is working.  What
 can we do with the network?  In this part of the book, we'll take a look at some
-of the more important services which make up the application layer:
-.Ls B
-.LI
-In the rest of this chapter, we'll look at \fIclients\fP\| running programs on
-other machines, copying files from one machine to another, and accessing the
-\fIWorld-Wide Web\fP.
-.LI
-In
-.Sref "\*[chserver]" ,
-we'll look at the view of the same operations from the other end of the link.
-.LI
-In chapter
-.Sref "\*[chmua]" ,
-we'll look at electronic mail clients (\fIMUA\fP\|s or \fIMail User
-Agents\fP\|).
-.LI
-In chapter
-.Sref "\*[chmta]" ,
-we'll look at electronic mail servers (\fIMTA\fP\|s or \fIMail Transfer
-Agents\fP\|).
-.Le
-From a networking point of view, the most basic services are the ability to
-execute commands and to move data around.  The Internet protocols perform these
-tasks with a pair of processes: a \fIclient\fP\| which actively asks for
-services at one end of the link, and a \fIserver\fP\| at the other end of the
-link which responds to requests and perform the requested activity.  These terms
-are also used to describe computer systems, but here we're talking about
-processes, not systems.  In this chapter, we'll look at the client side of
-things: in the next section we'll look  executing programs remotely, on page
-.Sref "\*[filecopy]" \&
-we'll look at copying files, and on page
-.Sref "\*[www]" \&
-we'll look at browsing the World-Wide web. 
+of the more important services that make up the application layer.
 .P
-In the olden days, you would use
-.Command telnet
+.X "network, client"
+.X "network, server"
+The Internet protocols perform most services with a pair of processes: a
+\fIclient\fP\/ at one end of the link that actively asks for services, and a
+\fIserver\fP\/ at the other end of the link that responds to requests and
+performs the requested activity.  These terms are also used to describe computer
+systems, but here we're talking about processes, not systems.  In this chapter,
+we'll look at the client side of things, and in
+.Sref "\*[chserver]" \&
+we'll look at the corresponding servers.
+.P
+.X "Hypertext Transfer Protocol"
+.X "HTTP"
+Probably the single most important network service is the \fIHypertext Transfer
+Protocol\fP\/ or \fIHTTP\fP, the service that web browsers use to access the
+Web.  We'll look at web browsers in the next section.
+.P
+.X "Simple Mail Transfer Protocol"
+.X "SMTP"
+.X "Post Office Protocol"
+.X "POP"
+The next most important service is probably the \fISimple Mail Transfer
+Protocol\fP\/ or \fISMTP\fP, the primary service for sending mail round the
+Internet.  There's also the \fIPost Office Protocol\fP\/ or \fIPOP\fP, which is
+used by systems unable to run SMTP.  This topic is so important that we'll
+devote Chapters
+.Sref \*[nchmua] \&
 and
+.Sref \*[nchmta] \&
+to it.
+.P
+To use a remote machine effectively, you need better access than such
+specialized servers can give you.  The most powerful access is obviously when
+you can execute a shell on the remote machine; that gives you effectively the
+same control over the machine as you have over your local machine.  A number of
+services are available to do this.  In the olden days, you would use
+.Command telnet
+or
 .Command rlogin
-to log into another machine, and
-.Command ftp
-and
+to log into another machine.  These programs are still with us, but security
+concerns make them effectively useless outside a trusted local network.  We'll
+look at them briefly on page
+.Sref \*[telnet] .
+.P
+The preferred replacement is
+.Command ssh ,
+.X "secure shell"
+which stands for \fIsecure shell\fP.  In fact, it's not a shell at all, it's a
+service to communicate with a remote shell.  It encrypts the data sent over the
+network, thus making it more difficult for crackers to abuse.  We'll look at it
+in detail on page
+.Sref \*[ssh] .
+.P
+Another important service is the ability to move data from one system to
+another.  There are a number of ways of doing this.
+The oldest programs are
 .Command rcp
-to transfer files across the network.  These programs are still with us, but
-security concerns make
-.Command rlogin
 and
-.Command rcp
-.Command ftp
-effectively obsolete, and
+.Command ftp .
+These programs have the same security concerns as
 .Command telnet
 and
+.Command rlogin ,
+though
 .Command ftp
-are only of limited use.  For normal situations, you would replace
-.Command telnet
-and
-.Command rlogin
-with
-.Command ssh ,
-a \fIsecure shell\fP.  Similarly, you would use
+still has some uses.  More modern copying programs use
 .Command scp ,
-an \fIssh\fP\|-based copy program, instead of
-.Command ftp
-and
-.Command rcp .
-.H2 "Running programs on another computer"
-Your main interface with the local machine is the \fIshell\fP, which we looked
-at in \*[chunixref].  You can access remote machines in pretty much the same way
-as local machines: you just need a program to relay your input to the remote
-computer and the output from the remote computer back to your machine.
+which is based on
+.Command ssh .
+We'll look at file copy programs on page
+.Sref \*[filecopy] .
+In addition,
+.Command rsync
+is a useful program for maintaining identical copies files on different
+systems.  We'll look at it on page
+.Sref \*[rsync] .
 .P
-.Command telnet
-and
-.Command rlogin
-both do this, but they suffer from the disadvantage that they transmit data in
-clear text.  Any sniffer program, for example
-.Command tcpdump ,
-can intercept the data and use it (passwords for example) to break into one of
-the machines.
-.Command telnet
+.X "Network File System"
+.X "NFS"
+A somewhat different approach is the \fINetwork File System\fP\/ or \fINFS\fP,
+which mounts file systems from another machine as if they were local.  We look
+at NFS clients on page
+.Sref \*[NFS-client] .
+.H2 "The World Wide Web"
+.X "World Wide Web"
+For the vast majority of the public, the Internet and the \fIWorld Wide Web\fP\/
+are the same thing.  FreeBSD is an important contender in this area.  Some of
+the world's largest web sites, including Yahoo!  (\fIhttp://www.yahoo.com/\fP\/)
+run FreeBSD.  Even Microsoft runs FreeBSD on its Hotmail service
+(\fIhttp://www.hotmail.com/\fP\/), though they have frequently denied it, and
+for image reasons they are moving to their own software.
+.H2 "Web browsers"
+.Pn www
+.X "web, browser"
+.X "browser, web"
+A \fIweb browser\fP\/ is a program that retrieves documents from the Web and
+displays them.  The base FreeBSD system does not include a web browser, but a
+large number are available in the Ports Collection.  All web browsers seem to
+have one thing in common: they are buggy.  They frequently crash when presented
+with web pages designed for Microsoft, and in other cases they don't display the
+page correctly.  In many cases this is due to poorly designed web pages, of
+course.
+.P
+Currently, the most important web browsers are:
+.Ls B
+.LI
+.Command netscape
+was once the only game in town, but it's now showing its age.  In addition, many
+web sites only test their software with Microsoft, and their bugs cause problems
+with
+.Command netscape .
+.LI
+.Command mozilla
+is derived from the same sources as
+.Command netscape ,
+but comes in source form.  It has now reached the stage where it is less buggy
+than
+.Command netscape .
+A number of other browsers, such as
+.Command galeon
 and
-.Command rlogin
-are still of marginal use on trusted local networks.
-.Command telnet
-has a couple of other uses, so we'll look at it briefly on page
-.Sref "\*[telnet]" .
+.Command skipstone ,
+are based on
+.Command mozilla .
+They're all available in the Ports Collection.
+.Command galeon
+is included in the \fIinstant-workstation\fP\/ port described in Chapter
+.Sref \*[nchpostinstall] .
+.LI
+.Command konqueror
+is included with the KDE port.
+.LI
+.Command Opera
+is a new browser that some people like.  The version in the Ports Collection is
+free, but it makes up for it by giving you even more advertisements than the web
+pages give you anyway.  You can buy a version that doesn't display the
+advertisements.
+.LI
+.Command lynx
+is a web browser for people who don't use X.  It displays text only.
+.Le
+.X "internet explorer, Microsoft"
+.X "Microsoft, internet explorer"
+You may note two omissions from this list.  Microsoft's \fIInternet
+Explorer\fP\/ is not available for FreeBSD.  Not many people have missed it.
+Also,
+.Command mosaic ,
+the original web browser, is now completely obsolete, and it has been removed
+from the Ports Collection.
+.P
+.X "StarOffice"
+.X "OpenOffice"
+In addition to these browsers, \fIStarOffice\fP\/ and \fIOpenOffice\fP\/ include
+integrated browsers.  You may find you prefer them.
+.P
+This book does not deal with how to use a web browser: just about everybody
+knows how to use one.  You can also get help from just about any browser; just
+click on the text or icon marked \f(CWHelp\fP or \f(CW?\fP.
 .H2 "ssh"
 .Pn ssh
 .Command ssh
+.X "secure shell"
 is a \fIsecure shell\fP, a means of executing programs remotely using encrypted
 data transfers.
 .X OpenBSD
 There are a number of different implementations of
-.Command ssh \|:
+.Command ssh \/:
 there are two different protocols, and the implementations are complicated both
 by bugs and license conditions.  FreeBSD comes with an implementation of
 .Command ssh
+.X "OpenSSH"
 called
 \fIOpenSSH\fP, originally developed as part of the OpenBSD project.
 .P
@@ -108,13 +185,12 @@
 .Command ssh
 is simple:
 .Dx
-.ps 7
 $ \f(CBssh freebie\fP
 The authenticity of host 'freebie.example.org (223.147.37.1)' can't be established.
 DSA key fingerprint is 08:f7:c4:14:48:0b:14:06:0e:2c:93:4b:1f:f6:ce:b5.
 Are you sure you want to continue connecting (yes/no)? \f(CByes\fP
 Warning: Permanently added 'freebie.example.org' (DSA) to the list of known hosts.
-grog@freebie.example.org's password:		\fIas usual, doesn't echo\fP\|
+grog@freebie.example.org's password:            \fIas usual, doesn't echo\fP\/
 Last login: Mon May 13 14:21:11 2002
 Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994
         The Regents of the University of California.  All rights reserved.
@@ -122,42 +198,46 @@
 
 Welcome to FreeBSD!
 $ \f(CBtty\fP
-/dev/ttype
+/dev/ttyp3
 $
 .De
 .X "tty"
 .X "pseudo-tty"
 .X "pty"
 .X "pity"
-.X "xterm"
-Once you get this far, you are connected to the machine in almost identical
+Once you get this far, you are connected to the machine in almost the same
 manner as if you were directly connected.  This is particularly true if you are
 running X.  As the output of the
 .Command tty
-command shows, your ``terminal'' is a \fIpseudo-tty\fP\| or \fIpty\fP\|
+command shows, your ``terminal'' is a \fIpseudo-tty\fP\/ or \fIpty\fP\/
 (pronounced ``pity'').  This is the same interface that you have with an
 .Command xterm .
 .P
+.ne 5v
 It's worth looking in more detail at how the connection is established:
 .Ls B
 .LI
-The first line (\fIThe authenticity...\fP\|) appears once
+The first line (\fIThe authenticity...\fP\/) appears once
 .Command ssh
 has established preliminary contact with the remote system.  It indicates that
 you're connected, but that the local system has no information about the remote
 system.  Theoretically you could be connected to a different machine
 masquerading as the machine you want to connect to.
+.Command ssh
+saves the fingerprint in
+.File ~/.ssh/known_hosts
+and checks it every time you connect to that machine thereafter.
 .LI
 The reference to DSA keys indicates that
 .Command ssh
 is using the
 .Command ssh
-version 2 protocol.  We'll look at the differences between the protocols below.
+Version 2 protocol.  We'll look at the differences between the protocols below.
 .LI
 The password prompt is for the same password as you would see locally.  The
-slightly different format is in order to clarify exactly which password you
-should enter.  Again, a number of exploits are possible where you might find
-yourself giving away a password to an intruder, so this caution is justified.
+slightly different format is to clarify exactly which password you should enter.
+Again, a number of exploits are possible where you might find yourself giving
+away a password to an intruder, so this caution is justified.
 .Le
 When you log in via
 .Command ssh ,
@@ -166,25 +246,28 @@
 .Sref \*[environment-variable-table-page] \&
 for more details.  Remember that \f(CWTERM\fP describes the display at your end
 of the link.  There is no display at the other end, but the other end needs to
-know the \fItermcap\fP\| parameters for your display.  If you're running an
+know the \fItermcap\fP\/ parameters for your display.  If you're running an
 .Command xterm ,
 this shouldn't be a problem: the name \f(CWxterm\fP propagates to the other end.
-If you're using a character-oriented display (\fI/dev/ttyv\|\f(BIx\fR\|),
+If you're using a character-oriented display (\fI/dev/ttyv\/\f(BIx\fR\/),
 however, your \f(CWTERM\fP variable is probably set to \f(CWcons25\fP, which
-many systems don't know.  If you have problems where systems refuse to start
-full-screen modes when you connect from a virtual terminal, try setting the
-\f(CWTERM\fP variable to \f(CWansi\fP.
+many systems don't know.  If systems refuse to start full-screen modes when you
+connect from a virtual terminal, try setting the \f(CWTERM\fP variable to
+\f(CWansi\fP.
 .P
 To exit
 .Command ssh ,
-you just log out.  If you run into problems, however, like a hung network, you
-can also hit the combination \fBEnter\fP\ \f(CB~.\fP\ \fBEnter\fP, which always
+just log out.  If you run into problems, however, like a hung network, you can
+also hit the combination \fBEnter\fP\ \f(CB~.\fP\ \fBEnter\fP, which always
 drops the connection.
 .H2 "Access without a password"
-Sending passwords across the net, even if they're encrypted, is not a complete
+.Pn no-password
+Sending passwords across the Net, even if they're encrypted, is not a complete
 guarantee that nobody else can get in: there are a number of brute-force ways to
-crack a password.  To address this issue,
+crack an encrypted password.  To address this issue,
 .Command ssh
+.X "public key cryptography"
+.X "cryptography, public key"
 has an access method that doesn't require passwords: instead it uses a technique
 called \fIpublic key cryptography\fP.  You have two keys, one of which you can
 give away freely, and the other of which you guard carefully.  You can encrypt
@@ -192,30 +275,36 @@
 with the private key, and data encrypted with the private key can be decrypted
 with the public key.
 .P
-Once you have these keys in place, you can use the \fIchallenge-response\fP\|
+.X "challenge-response authentication"
+.X "authentication, challenge-response"
+Once you have these keys in place, you can use the \fIchallenge-response\fP\/
 method for authentication.  To initiate an
 .Command ssh
 connection,
 .Command ssh
 sends your public key to the
-.Command sshd
+.Daemon sshd
 process on the remote system.  The remote system must already have a copy of
 this key.  It uses it to encrypt a random text, a \fIchallenge\fP, which it
 sends back to your system.  The
 .Command ssh
 process on your system decrypts it with your private key, which is not stored
 anywhere else, and sends the decrypted key back to the remote
-.Command sshd .
-Since only your system can decode the challenge, this is evidence to the remote
-.Command sshd
+.Daemon sshd .
+Only your system can decode the challenge, so this is evidence to the remote
+.Daemon sshd
 that it's really you.
 .P
-By default, the private key for version 1 of the protocol is stored in the file
+.ne 3v
+By default, the private key for Version 1 of the protocol is stored in the file
 .File ~/.ssh/identity ,
 and the public key is stored in the file
 .File ~/.ssh/identity_pub .
-For version 2, you have a choice of two different encryption schemes,
-\fIDSA\fP\| and \fIRSA\fP.  The corresponding private and public keys are stored
+.X "DSA encryption"
+.X "RSA encryption"
+.X "encryption"
+For Version 2, you have a choice of two different encryption schemes,
+\fIDSA\fP\/ and \fIRSA\fP.  The corresponding private and public keys are stored
 in the files
 .File ~/.ssh/id_dsa ,
 .File ~/.ssh/id_dsa.pub ,
@@ -223,62 +312,65 @@
 and
 .File ~/.ssh/id_rsa.pub
 respectively.  If you have the choice between DSA keys and RSA keys for protocol
-version 2, use DSA keys.  You still should have an RSA key pair in case you want
-to connect to a system which doesn't support DSA keys.
+Version 2, use DSA keys, which are considered somewhat more secure.  You still
+should have an RSA key pair in case you want to connect to a system that
+doesn't support DSA keys.
 .P
 There's still an issue of unauthorized local access, of course.  To ensure that
 somebody doesn't compromise one system and then use it to compromise others, you
 need a kind of password for your private keys.  To avoid confusion,
 .Command ssh
+.X "ssh, passphrase"
+.X "passphrase, ssh"
 refers to it as a \fIpassphrase\fP.  If
 .Command ssh
 finds keys in the
-.File ~/.ssh
+.Directory ~/.ssh
 directory, it attempts to use them:
 .Dx
 $ \f(CBssh hub\fP
-Enter passphrase for key '/home/grog/.ssh/id_rsa': \fI(no echo)\fP\|
+Enter passphrase for key '/home/grog/.ssh/id_rsa': \fI(no echo)\fP\/
 Last login: Sat Jul 13 17:27:33 2002 from wantadilla.lemis
 Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994
         The Regents of the University of California.  All rights reserved.
 FreeBSD 5.0-STABLE (HUB) #7: Thu Jun 26 12:44:34 PDT 2003
-\fI(etc)\fP\|
+\fI(etc)\fP\/
 .De
 .SPUP
 .H3 "Creating and distributing keys"
 You create keys with the program
 .Command ssh-keygen .
-Here's an example of
-generating all three keys:
+Here's an example of generating all three keys:
 .Dx
 $ \f(CBssh-keygen -t rsa1\fP
 Generating public/private rsa1 key pair.
-Enter file in which to save the key (/home/grog/.ssh/identity): \fI(ENTER pressed)\fP\|
-Enter passphrase (empty for no passphrase): \fI(no echo)\fP\|
-Enter same passphrase again:  \fI(no echo)\fP\|
+Enter file in which to save the key (/home/grog/.ssh/identity): \fI(ENTER pressed)\fP\/
+Enter passphrase (empty for no passphrase): \fI(no echo)\fP\/
+Enter same passphrase again:  \fI(no echo)\fP\/
 Your identification has been saved in /home/grog/.ssh/identity.
 Your public key has been saved in /home/grog/.ssh/identity.pub.
 The key fingerprint is:
 02:20:1d:50:78:c5:7c:56:7b:1d:e3:54:02:2c:99:76 grog@bumble.example.org
 $ \f(CBssh-keygen -t rsa \fP
 Generating public/private rsa key pair.
-Enter file in which to save the key (/home/grog/.ssh/id_rsa): \fI(ENTER pressed)\fP\|
-Enter passphrase (empty for no passphrase):  \fI(no echo)\fP\|
-Enter same passphrase again:  \fI(no echo)\fP\|
+Enter file in which to save the key (/home/grog/.ssh/id_rsa): \fI(ENTER pressed)\fP\/
+Enter passphrase (empty for no passphrase):  \fI(no echo)\fP\/
+Enter same passphrase again:  \fI(no echo)\fP\/
 Your identification has been saved in /home/grog/.ssh/id_rsa.
 Your public key has been saved in /home/grog/.ssh/id_rsa.pub.
 The key fingerprint is:
 95:d5:01:ca:90:04:7d:84:f6:00:32:7a:ea:a6:57:2d grog@bumble.example.org
 $ \f(CBssh-keygen -t dsa\fP
 Generating public/private dsa key pair.
-Enter file in which to save the key (/home/grog/.ssh/id_dsa): \fI(ENTER pressed)\fP\|
-Enter passphrase (empty for no passphrase):  \fI(no echo)\fP\|
-Enter same passphrase again:  \fI(no echo)\fP\|
+Enter file in which to save the key (/home/grog/.ssh/id_dsa): \fI(ENTER pressed)\fP\/
+Enter passphrase (empty for no passphrase):  \fI(no echo)\fP\/
+Enter same passphrase again:  \fI(no echo)\fP\/
 Your identification has been saved in /home/grog/.ssh/id_dsa.
 Your public key has been saved in /home/grog/.ssh/id_dsa.pub.
 The key fingerprint is:
 53:53:af:22:87:07:10:e4:5a:2c:21:31:ec:29:1c:5f grog@bumble.example.org
 .De
+.ne 3v
 Before you can use these keys, you need to get the public keys on the remote
 site in the file
 .File ~/.ssh/authorized_keys .
@@ -286,7 +378,7 @@
 .Command ssh
 used a second file,
 .File ~/.ssh/authorized_keys2 ,
-for protocol version 2, but modern versions store all the keys in the one file
+for protocol Version 2, but modern versions store all the keys in the one file
 .File ~/.ssh/authorized_keys .
 There are a number of ways to get the keys in these files.  If you already have
 access to the machine (via password-based authentication, for example), you can
@@ -327,12 +419,13 @@
 .De
 .SPUP
 .H3 "Authenticating automatically"
-Having to supply the passphrase can become both a nuisance and a serious
+Having to supply the passphrase can become a nuisance and even a serious
 problem.  If you want to run
 .Command ssh
 from scripts, it may not even be possible to supply the passphrase.
 .Command ssh
-has another feature available here: it has an \fIauthentication agent\fP\| which
+.X "authentication agent"
+has another feature available here: it has an \fIauthentication agent\fP\/ that
 keeps track of the keys.
 .P
 The authentication agent is called
@@ -352,17 +445,18 @@
 $ \f(CBssh-add\fP
 Could not open a connection to your authentication agent.
 .De
+.ne 10v
 To solve this problem, execute the agent in your current environment with
 .Command eval ,
 then run
-.Command ssh-add \|:
+.Command ssh-add \/:
 .Dx
 $ \f(CBeval `ssh-agent`\fP
 $ \f(CBssh-add\fP
-Enter passphrase for /home/grog/.ssh/id_rsa: \fI(enter the passphrase)\fP\|
+Enter passphrase for /home/grog/.ssh/id_rsa: \fI(enter the passphrase)\fP\/
 Identity added: /home/grog/.ssh/id_rsa (/home/grog/.ssh/id_rsa)
 Identity added: /home/grog/.ssh/id_dsa (/home/grog/.ssh/id_dsa)
-Identity added: /home/grog/.ssh/identity (grog@zaphod.lemis.com)
+Identity added: /home/grog/.ssh/identity (grog@zaphod.example.org)
 .De
 You can use
 .Command ssh-add 's
@@ -370,11 +464,13 @@
 about:
 .Dx
 $ \f(CBssh-add -l\fP
-1024 02:20:1d:50:78:c5:7c:56:7b:1d:e3:54:02:2c:99:76 grog@zaphod.lemis.com (RSA1)
+1024 02:20:1d:50:78:c5:7c:56:7b:1d:e3:54:02:2c:99:76 grog@zaphod.example.org (RSA1)
 1024 95:d5:01:ca:90:04:7d:84:f6:00:32:7a:ea:a6:57:2d /home/grog/.ssh/id_rsa (RSA)
 1024 53:53:af:22:87:07:10:e4:5a:2c:21:31:ec:29:1c:5f /home/grog/.ssh/id_dsa (DSA)
 .De
-If you're using a Bourne-style shell such as \fIbash\fP, you can automate a lot
+If you're using a Bourne-style shell such as
+.Command bash ,
+you can automate a lot
 of this by putting the following commands in your
 .File .bashrc
 or
@@ -391,11 +487,11 @@
 This first uses the
 .Command tty
 command to check if this is an interactive shell, then checks if you already
-have an authentication agent.  If it doesn't, it starts one. It's important not
-to start a new authentication agent if you already have one, since you'd lose
-any keys that the agent already knows.  This script doesn't add keys, since this
-requires your intervention and could be annoying if you had to do it every time
-you start a shell.
+have an authentication agent.  If it doesn't, it starts one. Don't start a new
+authentication agent if you already have one: you'd lose any keys that the agent
+already knows.  This script doesn't add keys, because this requires your
+intervention and could be annoying if you had to do it every time you start a
+shell.
 .H3 "Setting up X to use ssh"
 If you work with X, you have the opportunity to start a large number of
 concurrent
@@ -403,10 +499,10 @@
 sessions.  It would be annoying to have to enter keys for each session, so
 there's an alternative method: start X with an
 .Command ssh-agent ,
-and it will inherit the information to any
-.Command xterm \|s
-which it starts.  Add the following commands to your
-.File .xinitrc \|:
+and it will pass the information on to any
+.Command xterm \/s
+that it starts.  Add the following commands to your
+.File .xinitrc \/:
 .Dx
 eval `ssh-agent`
 ssh-add < /dev/null
@@ -415,23 +511,26 @@
 .Command ssh-add
 in this manner, without an input file, it runs a program to prompt for the
 passphrase.  By default it's
-.Command /usr/X11R6/bin/ssh-askpass ,
+.X "ssh-askpass, command"
+.X "command, ssh-askpass"
+.Command -n /usr/X11R6/bin/ssh-askpass ,
 but you can change it by setting the \f(CWSSH_ASKPASS\fP environment variable.
-.Command /usr/X11R6/bin/ssh-askpass
+.Command -n /usr/X11R6/bin/ssh-askpass
 opens a window and prompts for a passphrase.  From then on, anything started
 under the X session will automatically inherit the keys.
 .H2 "ssh tunnels"
 .Pn tunneling
-\fITunneling\fP\| is a technique for encapsulating an IP connection inside
+.X "tunneling"
+\fITunneling\fP\/ is a technique for encapsulating an IP connection inside
 another IP connection.  Why would you want to do that?  One reason is to add
 encryption to an otherwise unencrypted connection, such as
 .Command telnet
-or \fIPOP\fP.  Another is to get access to a service on a system which does not
+or \fIPOP\fP.  Another is to get access to a service on a system that does not
 generally supply this service to the Internet.
 .P
-Let's consider using \fIhttp\fP\| first.  Assume you are travelling, and you
+Let's consider using \fIhttp\fP\/ first.  Assume you are travelling, and you
 want to access your private web server back home.  Normally a connection to the
-\f(CWhttp\fP port of \fIpresto.example.com\fP\| might have the following
+\f(CWhttp\fP port of \fIpresto.example.com\fP\/ might have the following
 parameters:
 .PS
 	boxht = .4i
@@ -450,12 +549,13 @@
 	"Port \f(CW\s880\s0\fP" at PRESTO.w+(-.1,-.1) rjust
 
 .PE
-.\" Grrr
-.ps \n(PS
 But what if the server is firewalled from the global Internet, so you can't
-access it directly?  That's when you need the \fIssh\fP\| tunnel.  The
-\fIssh\fP\| tunnel creates a local connection at each end and a separate secure
-connection across the Internet:
+access it directly?  That's when you need the
+.Command ssh
+tunnel.  The
+.Command ssh
+tunnel creates a local connection at each end and a separate secure connection
+across the Internet:
 .PS
 	boxht = .4i
 	boxwid = .6i
@@ -485,10 +585,8 @@
 	"\f(CW\s8127.1\s0\fP" at LB.c+(0,.1)
 	"\f(CW\s880\s0\fP" at LB.c+(0,-.1)
 .PE
-.\" Grrr
-.ps \n(PS
-The \fIssh\fP\| connection is shown in \f(CIfixed italic\fP font.  It looks just
-like any other \fIssh\fP\| connection.  The difference are the local connections
+The \fIssh\fP\/ connection is shown in \f(CIfixed italic\fP font.  It looks just
+like any other \fIssh\fP\/ connection.  The difference are the local connections
 at each end: instead of talking to presto port 80 (\f(CWhttp\fP), you talk to
 port 4096 on your local machine.  Why 4096?  It's your choice; you can use any
 port above 1024.  If you're on \fIandante\fP, you can set up this tunnel with
@@ -496,12 +594,14 @@
 .Dx
 $ \f(CBssh -L 4096:presto.example.org:80 presto.example.org\fP
 .De
-To do the same thing from the \fIpresto\fP\| end, you'd set up a \fIreverse
-tunnel\fP\| with the \f(CW-R\fP option:
+.X "reverse tunnel"
+.X "tunnel, reverse"
+To do the same thing from the \fIpresto\fP\/ end, you'd set up a \fIreverse
+tunnel\fP\/ with the \f(CW-R\fP option:
 .Dx
 $ \f(CBssh -R 4096:presto.example.org:80 andante.example.org\fP
 .De
-These commands both set up a tunnel from port 4096 on \fIandante\fP\| to port 80
+These commands both set up a tunnel from port 4096 on \fIandante\fP\/ to port 80
 on the host \fIpresto.example.org\fP.  You still need to supply the name of the
 system to connect to; it doesn't have to be the same.  For example, you might
 not be able to log in to the web server, but you could access your machine back
@@ -512,12 +612,14 @@
 .De
 In addition to setting up the tunnel,
 .Command ssh
-also creates a normal interactive session.  If you don't want this, you can use
-the \f(CW-f\fP option tell
+creates a normal interactive session.  If you don't want this, you can use the
+\f(CW-f\fP option to tell
 .Command ssh
 to go into the background after authentication.  You also need a command to
-execute; in case of doubt, use \fIsleep\fP, which simply sleeps for a specified
-time.  If this is what you want to do, you could enter a command like
+execute; in case of doubt, use
+.Command sleep ,
+which simply delays for a specified time.  If this is what you want to do, you
+could enter a command like:
 .Dx
 $ \f(CBssh -L 4096:presto.example.org:80 presto.example.org -f sleep 3600\fP
 .De
@@ -527,25 +629,23 @@
 .H3 "Tunneling X"
 Running X clients on the remote machine is special enough that
 .Command ssh
-provides a special form of tunneling to deal with it.  In order to use it, you
-must tell
+provides a special form of tunneling to deal with it.  To use it, you must tell
 .Command ssh
 the location of an
 .File .Xauthority
 file.  Do this by adding the following line to the file
-.File ~/.ssh/environment \|:
+.File ~/.ssh/environment \/:
 .Dx
-XAUTHORITY=/home/\f(BIyourname\fP\|/.Xauthority
+XAUTHORITY=/home/\f(BIyourname\fP\//.Xauthority
 .De
 The name must be in fully qualified form:
 .Command ssh
 does not understand the shortcut
-.File ~/
+.Directory ~/
 to represent your home directory.  You don't need to create
-.File ~/.Xauthority ,
+.File -n ~/.Xauthority ,
 though:
-.Command
-ssh
+.Command ssh
 can do that for you.
 .P
 Once you have this in place, you can set up X tunneling in two different ways.
@@ -556,13 +656,23 @@
 As before, the \f(CW-f\fP option tells
 .Command ssh
 to go into the background.  The \f(CW-X\fP option specifies X tunneling, and
-\fIssh\fP\| runs an \fIxterm\fP on the local machine.  The \f(CWDISPLAY\fP
-environment variable points to the (remote) local host:
+.Command ssh
+runs an
+.Command xterm
+on the local machine.  The \f(CWDISPLAY\fP environment variable points to the
+(remote) local host:
 .Dx
 $ \f(CBecho $DISPLAY\fP
 localhost:13.1
 .De
 .SPUP
+.H3 "Other uses of tunnels"
+Tunneling has many other uses.  Another interesting one is bridging networks.
+For example,
+.URI http://unix.za.net/gateway/documentation/networking/vpn/fbsd.html
+describes how to set up a VPN (Virtual Private Network) using User PPP and an
+.Command ssh
+tunnel.
 .H2 "Configuring ssh"
 It can be a bit of a nuisance to have to supply all these parameters to
 .Command ssh ,
@@ -570,19 +680,17 @@
 in a configuration file.  On startup,
 .Command ssh
 checks for configuration information in a number of places.  It checks for them
-first in the command line options, then in you configuration file
+first in the command-line options, then in you configuration file
 .File ~/.ssh/config ,
 and finally in the system-wide configuration file
 .File /etc/ssh/ssh_config .
 The way it treats duplicate information is pretty much the opposite of what
-you'd expect: unlike most other programs, options found in a later configuration
-file do \fInot\fP\| replace the earlier ones.  If you specify an option on the
-command line, and a configuration file contains a different value for the
-option,
-.Command ssh
-chooses the one on the command line.
+you'd expect: unlike most other programs, options found in a configuration file
+read in later do \fInot\fP\/ replace the options found in an earlier file.
+Options on the command line replace those given in configuration files.
 .P
-In practice, this happens less often than you would expect.  The file
+.ne 3v
+In practice, such conflicts happen less often than you might expect.  The file
 .File /etc/ssh/ssh_config ,
 the main configuration file for the system, normally contains only comments, and
 by default you don't even get a local
@@ -594,8 +702,8 @@
 this section we'll look at some of the more common configuration options.
 .Ls B
 .LI
-The entry \f(CWHost\fP is special: the options which follow, up to the end of
-the file or the next following \f(CWHost\fP argument, relate only to hosts which
+The entry \f(CWHost\fP is special: the options that follow, up to the end of
+the file or the next following \f(CWHost\fP argument, relate only to hosts that
 match the arguments on the \f(CWHost\fP line.
 .LI
 Optionally,
@@ -607,12 +715,12 @@
 but you can also do so by setting \f(CWCompression yes\fP in the configuration
 file.
 .LI
-\f(CWEscapeChar\fP: You can \fIescape\fP\| out of an
+You can \fIescape\fP\/ out of an
 .Command ssh
 session to issue commands to
 .Command ssh
-with this character.  By default it's the \fItilde\fP\| character, \f(CW~\fP.
-Other programs, notably
+with the \f(CWEscapeChar\fP.  By default it's the \fItilde\fP\/ character,
+\f(CW~\fP.  Other programs, notably
 .Command rlogin ,
 use this character as well, so you may want to change it.  You can set this
 value from the
@@ -624,22 +732,22 @@
 frequently access a remote machine and require X forwarding.  This also sets the
 \f(CWDISPLAY\fP environment variable correctly to go over the secure channel.
 .LI
-\f(CWKeepAlive\fP:  By default,
+By default,
 .Command ssh
 sends regular messages to the remote
-.Command sshd
-server in order to notice if the remote system has gone down.  This can cause
-connections to be dropped on a flaky connection.  Set \f(CWKeepAlive\fP to
+.Daemon sshd
+server to check if the remote system has gone down.  This can cause connections
+to be dropped on a flaky connection.  Set the \f(CWKeepAlive\fP option to
 \f(CWno\fP to disable this behaviour.
 .LI
 Use the \f(CWLocalForward\fP parameter to set up a tunnel.  The syntax is
 similar to that of the \f(CW-L\fP option above: on \fIandante\fP, instead of the
-command line
+command line:
 .Dx
 $ \f(CBssh -L 4096:presto.example.org:80 presto.example.org\fP
 .De
 you would put the following in your
-.File ~/.ssh/config:
+.File ~/.ssh/config \/:
 .Dx
 host presto.example.org
 LocalForward 4096 presto.example.org:80
@@ -647,13 +755,14 @@
 Note that the first port is separated from the other two parameters by a space,
 not a colon.
 .LI
+.ne 8v
 Similarly, you can set up a reverse tunnel with the \f(CWRemoteForward\fP
-parameter.  On \fIpresto\fP, Instead of the command line
+parameter.  On \fIpresto\fP, instead of the command line:
 .Dx
 $ \f(CBssh -R 4096:presto.example.org:80 andante.example.org\fP
 .De
 you would put the following in your
-.File ~/.ssh/config:
+.File ~/.ssh/config \/:
 .Dx
 host andante.example.org
 RemoteForward 4096 presto.example.org:80
@@ -686,8 +795,8 @@
 .LI
 By default,
 .Command ssh
-refuses to connect to a known host if its key changes.  Instead, you must
-manually remove the entry for the system from the
+refuses to connect to a known host if its key fingerprint changes.  Instead, you
+must manually remove the entry for the system from the
 .File ~/.ssh/known_hosts
 or
 .File ~/.ssh/known_hosts2
@@ -719,15 +828,15 @@
 .Command ssh
 assumes that your user name on the remote system is the same as the name on the
 local system.  If that's not the case, you can use the \f(CWUser\fP keyword to
-specify the remote user name.  Alternatively, you can use the format
-.Dx
+specify the remote user name.  Alternatively, you can use the format:
+.Dx 1
 $ \f(CBssh newuser@remotehost.org\fP
 .De
 .Le
 .SPUP
 .H3 "Summary of files in ~/.ssh"
 In addition to the files we have discussed, you will find two other files in the
-.File ~/.ssh
+.Directory ~/.ssh
 directory:
 .Ls B
 .LI
@@ -743,10 +852,11 @@
 is a seed used to generate the keys.
 .Le
 In summary, then, you can expect the following files in your
-.File ~/.ssh \|:
+.Directory ~/.ssh \/:
 .Dx
+drwx------  2 grog  grog   512 Jan 18 21:04 .                   \fIdirectory\fP\/
 -rw-r--r--  1 grog  grog  1705 Oct 26  1999 authorized_keys		\fIkeys\f(CW
--rw-r--r--  1 grog  grog   844 Jan 27 22:18 authorized_keys2	\fIkeys, version 2 only\f(CW
+-rw-r--r--  1 grog  grog   844 Jan 27 22:18 authorized_keys2    \fIkeys, Version 2 only\f(CW
 -rw-r--r--  1 grog  grog    25 Oct 20 01:35 environment		\fIenvironment for sshd\f(CW
 -rw-------  1 grog  grog   736 Jul 19 15:40 id_dsa			\fIDSA private key\f(CW
 -rw-r--r--  1 grog  grog   611 Jul 19 15:40 id_dsa.pub		\fIDSA public key\f(CW
@@ -757,10 +867,11 @@
 -rw-------  1 grog  grog  1000 Jul 25  1999 known_hosts		\fIlist of known hosts\f(CW
 -rw-------  1 grog  grog   512 Jul 25  1999 random_seed		\fIfor key generation\f(CW
 .De
-Note particularly the permissions and the ownership of the files.  If they are
-wrong,
+Note particularly the permissions and the ownership of the files and the
+directory itself.  If they are wrong,
 .Command ssh
-won't work, and it won't tell you why not.
+won't work, and it won't tell you why not.  In particular, the directory must
+not be group writeable.
 .H2 "Troubleshooting ssh connections"
 A surprising number of things can go wrong with setting up
 .Command ssh
@@ -779,9 +890,45 @@
 ssh: connect to address 223.147.37.65 port 22: Connection refused
 .De
 This means that the remote host is up, but no
-.Command sshd
+.Daemon sshd
 is running.
 .LI
+You have set up keys, but you still get a message asking for a password.
+.P
+This can mean a number of things: your
+.Command ssh-agent
+isn't running, you haven't added the keys, the other end can't find them, or the
+security on the keys at the other end is incorrect.  You can check the first two
+like this:
+.Dx 2
+$ \f(CBssh-add -l\fP
+Could not open a connection to your authentication agent.
+.De
+.ne 4v
+This means that you haven't run
+.Command ssh-agent .
+Do it like this:
+.Dx
+$ eval `ssh-agent`
+Agent pid 95180
+$ \f(CBssh-add -l\fP
+The agent has no identities.
+$ \f(CBssh-add\fP
+Enter passphrase for /home/grog/.ssh/id_rsa: \f(BIno echo\fP\/
+Identity added: /home/grog/.ssh/id_rsa (/home/grog/.ssh/id_rsa)
+Identity added: /home/grog/.ssh/id_dsa (/home/grog/.ssh/id_dsa)
+Identity added: /home/grog/.ssh/identity (grog@freebie.lemis.com)
+$ \f(CBssh-add -l\fP
+1024 02:20:1d:50:78:c5:7c:56:7b:1d:e3:54:02:2c:99:76 grog@zaphod.example.org (RSA1)
+1024 95:d5:01:ca:90:04:7d:84:f6:00:32:7a:ea:a6:57:2d /home/grog/.ssh/id_rsa (RSA)
+1024 53:53:af:22:87:07:10:e4:5a:2c:21:31:ec:29:1c:5f /home/grog/.ssh/id_dsa (DSA)
+.De
+This shows that all three keys are set correctly.  If you have, say, only an
+RSA1 (protocol Version 1) key, and the other end doesn't support protocol
+Version 1, you'll get this kind of message.
+.br
+.ne 5v
+.LI
 You get a message like this:
 .Dx
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@ -800,14 +947,14 @@
 that somebody is trying to intercept the connection, and the other one is that
 the remote system has changed its host key.  The latter is by far the more
 common.  To fix this problem, you have two choices:
-.Ls B
+.Ls
 .LI
 Edit your
 .File ~/.ssh/known_hosts2
 file and remove references to the remote system.  The message suggests changing
 line 39, but you might have more than one key for this system in this file.  If
-one is wrong, there's a good chance that the other one will be too, so you
-should remove all references.
+one is wrong, there's a good chance that any others will be too, so you should
+remove all references.
 .LI
 Add the following line to your
 .File ~/.ssh/config
@@ -820,8 +967,8 @@
 .Le
 .Le
 .Command ssh
-includes debugging options which may help debug problems setting up
-connections.  Use the \f(CW-v\fP option, up to three times, to get 
+includes debugging options that may help debug problems setting up connections.
+Use the \f(CW-v\fP option, up to three times, to get
 .Command ssh
 to display largely undocumented information about what is going on.  The output
 is pretty verbose; with three \f(CW-v\fP options you get nearly 200 lines of
@@ -830,23 +977,23 @@
 .Pn telnet
 As mentioned above,
 .Command telnet
-is an older, unencrypted program which connects to a shell on a remote system.
-You might find it of use when connecting to a system which doesn't have
+is an older, unencrypted program that connects to a shell on a remote system.
+You might find it of use when connecting to a system that doesn't have
 .Command ssh .
 Be very careful not to use valuable passwords, since they are transmitted in the
 clear.  Apart from that, you use it pretty much in the same way as
-.Command ssh \|:
+.Command ssh \/:
 .Dx
 $ \f(CBtelnet freebie\fP
 Trying 223.147.37.1...
 Connected to freebie.example.org.
 Escape character is '^]'.
 login: \f(CBgrog\fP
-Password: \fI(no echo)\fP\|
+Password: \fI(no echo)\fP\/
 
-FreeBSD/i386 (wantadilla.lemis.com) (ttypj)
+FreeBSD/i386 (wantadilla.example.org) (ttypj)
 
-Last login: Mon Oct 14 17:51:57 from sydney.lemis.com
+Last login: Mon Oct 14 17:51:57 from sydney.example.org
 Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994
         The Regents of the University of California.  All rights reserved.
 
@@ -874,21 +1021,20 @@
 .X "pseudo-tty"
 .X "pty"
 .X "pity"
-Once you get this far, you are connected to the machine in almost identical
+Once you get this far, you are connected to the machine in an almost identical
 manner as if you were directly connected.  This is particularly true if you are
 running X.  As the output of the
 .Command tty
-command shows, your ``terminal'' is a \fIpseudo-tty\fP\| or \fIpty\fP\|
+command shows, your ``terminal'' is a \fIpseudo-tty\fP\/ or \fIpty\fP\/
 (pronounced ``pity'').  This is the same interface that you will have with an
 .Command xterm .
 .P
 It's worth looking in more detail at how the connection is established:
 .Ls B
 .LI
-The first line (\fITrying...\fP\|) appears as soon as
+The first line (\fITrying...\fP\/) appears as soon as
 .Command telnet
-has
-resolved the IP address.
+has resolved the IP address.
 .LI
 The next three lines appear as soon as it has a reply from the other end.  At
 this point, there can be a marked delay before
@@ -900,26 +1046,25 @@
 correctly.  After DNS times out, it will continue normally, but the delay is a
 nuisance.
 .LI
-.X "/etc/ttys"
 Logging in is almost exactly the same as logging in locally.  Normally you won't
 be able to log in directly as \f(CWroot\fP, unless you have set
-\fI/dev/pty\f(BIx\fR\| as \f(CWsecure\fP in your
+\fI/dev/pty\f(BIx\fR\/ as \f(CWsecure\fP in your
 .File /etc/ttys
 (see page
-\*[ptys] for further details).  It's not a good idea to set your \fIpty\fP\|s as
+\*[ptys] for further details).  It's not a good idea to set your \fIpty\fP\/s as
 secure.  Use \f(CWsu\fP instead if you want to become \f(CWroot\fP.
 .Le
 When you log in via
 .Command telnet ,
 there's a good chance that your \f(CWTERM\fP environment variable will be set
-incorrectly.  See table \*[environment-variable-table] on page
-\*[environment-variable-table-page] for more details.  Remember that
-\f(CWTERM\fP describes the display at your end of the display, not the other
-end.  If you're running an
+incorrectly.  See Table \*[environment-variable-table] on page
+\*[environment-variable-table-page] for more details.  \f(CWTERM\fP describes
+the display at your end of the display, not the other end.  If you're running an
 .Command xterm ,
-this shouldn't be a problem: probably the name \f(CWxterm\fP will propagate to
-the other end.  If you're using a character-oriented display
-(\fI/dev/ttyv\f(BIx\fR\|), however, your \f(CWTERM\fP variable will probably be
+this shouldn't be a problem: probably the name
+.Command xterm
+will propagate to the other end.  If you're using a character-oriented display
+(\fI/dev/ttyv\f(BIx\fR\/), however, your \f(CWTERM\fP variable will probably be
 set to \f(CWcons25\fP, which many systems don't know.  If the remote system
 refuses to start programs in full-screen modes, try setting the \f(CWTERM\fP
 variable to \f(CWansi\fP.
@@ -936,12 +1081,13 @@
 $
 .De
 If you hit \fBCtrl-\f(CB]\fR by accident, just hit \fBEnter\fP to return to the
-telnet session.
+.Command telnet
+session.
 .H3 "Secure telnet"
-Recent versions of FreeBSD
+Recent releases of FreeBSD
 .Command telnet
 include a secure connection option.  You can recognize it by the different
-messages which appear when you connect:
+messages that appear when you connect:
 .Dx
 $ \f(CBtelnet freebie\fP
 Trying 223.147.37.1...
@@ -953,7 +1099,7 @@
 [ SRA accepts you ]
 .De
 There's no particular reason to use this version of
-.Command telnet \|;
+.Command telnet \/;
 it's non-standard, and you're still better off with
 .Command ssh .
 .H3 "Using telnet for other services"
@@ -964,12 +1110,14 @@
 .File /etc/services ).
 This isn't the only possibility, though: you can tell
 .Command telnet
-which port to connect to.  In \*[chmta], we'll see how to communicate with
-.Command sendmail
+which port to connect to.  In Chapter
+.Sref "\*[chmta]" ,
+we'll see how to communicate with
+.Daemon sendmail
 using
 .Command telnet
 on port \f(CWsmtp\fP page \*[telnet-to-smtp], and how to communicate with
-\fIPOP\fP\| on port \f(CWpop\fP, page \*[telnet-to-pop].  There are many other
+\fIPOP\fP\/ on port \f(CWpop\fP, page \*[telnet-to-pop].  There are many other
 such uses.
 .H2 "Copying files"
 .Pn filecopy
@@ -986,53 +1134,103 @@
 .Command ftp
 has its uses.  About the only use for
 .Command rcp
-is on systems which don't support
+is on systems that don't support
 .Command scp ,
 or systems where security is not an issue, and
 .Command scp
 is so slow that it's not practical.  The good news: you use
 .Command rcp
 in pretty much the same manner as
-.Command scp ,
-since
+.Command scp \/:
 .Command scp
 was designed to be compatible with
 .Command rcp ,
 so you don't need to learn anything else if you want to use it.
-.H3 "\fIftp\fP"
+.H2 "scp"
+.Command scp
+is a variant of
+.Command ssh
+used for remote copying.  The same access considerations apply as for
+.Command ssh .
+The syntax for copying is similar to the syntax used by NFS: to copy a file
+.File /var/log/messages
+from \fIpresto\fP\/ to the file
+.File -n prestomessages
+on the local machine, you might enter:
+.Dx
+$ \f(CBscp presto:/var/log/messages prestomessages\fP
+.De
+As with
+.Command ssh ,
+if you need to authenticate as a different user, you can use the form
+\fIuser@system\fP.
+.Command scp
+does not support the \f(CW-l\fP option to specify the user name.
+.P
+.Command scp
+has a number of options reminiscent of
+.Command cp \/:
+.Ls B
+.LI
+Use the \f(CW-p\fP option to preserve modification times and permissions where
+possible.  Note that this means you can't use
+.Command ssh 's
+\f(CW-p\fP option to specify an alternative port.
+.Command scp
+uses the \f(CW-P\fP option for this instead.
+.LI
+Use the \f(CW-r\fP option to recursively copy directories.
+.Le
+You don't have to supply full path names to
+.Command scp \/;
+you can write things like:
+.Dx
+$ \f(CBscp remotehost:file .\fP
+.De
+This looks for a file called
+.File -n file
+in your home directory on the remote machine and copies it to your current local
+directory.  Note the difference: there is no way for
+.Command scp
+to know a different remote directory, so relative paths are always relative to
+the home directory on that machine.
+.H2 "ftp"
+.Pn ftp
 .X "NFS"
-\fIftp\fR is the Internet File Transfer Program, and is the standard way to
-transfer large files long distances across the net.  It works for small files and
-short distances too, but you may find that
+.Command ftp
+is the Internet File Transfer Program, and is the standard way to transfer large
+files long distances across the Net.  It works for small files and short
+distances too, but you may find that
 .Command scp
-or \fINFS\fR are better alternatives in these areas.
+or \fINFS\fP\/ are better alternatives in these areas.
 .P
+.ne 2v
 One serious drawback in duplicating files across the net is that you need to
-have permission to access the remote system.  Traditionally, you need a user id
+have permission to access the remote system.  Traditionally, you need a user ID
 to access a system.  Of course, the file server could have a specific user ID
 without a password, but that would throw the system open to attack from
 crackers.
-.X "FTP, anonymous"
-.X "anonymous FTP"
+.X "ftp, anonymous"
+.X "anonymous ftp"
 .X "anonymous, user name"
-.X "user name, anonymous"
+.X "user, name, anonymous"
 .X "ftp, user name"
-.X "user name, ftp"
-\fIftp\fR solves this problem by recognizing the special user \f(CWftp\fP.  This
-user name used to be \f(CWanonymous\fP, but it turned out to be a problem to
-spell.
+.X "user, name, ftp"
+.Command ftp
+solves this problem by recognizing the special user \f(CWftp\fP.  This user name
+used to be \f(CWanonymous\fP, but it turned out to be a problem to spell.
 .Command ftp
 servers still accept the name \f(CWanonymous\fP as well.  Login is special: you
 don't need a password, but by convention, to help the system administrators with
 their bookkeeping, you should enter your real user ID in place of the password
-when logging in as \f(CWftp\fR.  A typical session might look like:
-.Dx
+when logging in as \f(CWftp\fP.  A typical session might look like:
+.Dx 10
 $ \f(CBftp ftp.freebsd.org\fP
 Connected to ftp.beastie.tdk.net.
 cd 220 ftp.beastie.tdk.net FTP server (Version 6.00LS) ready.
 331 Guest login ok, send your email address as password.
 230- The FreeBSD mirror at Tele Danmark Internet.
-\&\fIMore messages omitted\fP\|
+\&\fIMore messages omitted\fP\/
 Name (grog): \f(CBftp\fP
 331 Guest login ok, send ident as password.
 Password: 				\fIuser name does not echo\f(CW
@@ -1058,37 +1256,43 @@
 .LI
 The server may have multiple names, and the one you use may not be its canonical
 name (the name specified in the server's DNS A record\(emsee page \*[DNS-RR]).
-By convention, the first part of the name of an FTP server is \fIftp\fR.  Here
-we connected to the server with the name \fIftp.FreeBSD.org\fP, but the
+By convention, the first part of the name of an \fIftp\fP\/ server is \fIftp\fP.
+Here we connected to the server with the name \fIftp.FreeBSD.org\fP, but the
 canonical name of the server is \fIftp.beastie.tdk.net\fP.
 .LI
 .X "ftp, binary transfer"
 .X "ftp, ASCII transfer"
-Some versions of \fIftp\fR transmit in ASCII mode by default: they change every
-incidence of the ASCII line feed character (the C language constant
-\&\f(CW\en\fR) to the sequence \f(CW\er\en\fR (they prepend an ASCII carriage
-return character).  This permits you to print the results on normal printers,
-but makes a terrible mess of binary files.  Transmitting in binary form always
-works.  As the message shows, the FreeBSD \fIftp\fP\| server uses binary mode,
-but it doesn't harm to enter the \f(CWbin\fP command.  The message \f(CWType set
-to I.\fR is \fIftp\fR's way of telling you that it has set binary transmission
-mode.
+Some versions of
+.Command ftp
+transmit in ASCII mode by default: they change every incidence of the ASCII line
+feed character (the C language constant \f(CW\en\fP) to the sequence
+\f(CW\er\en\fP (they prepend an ASCII carriage return character).  This permits
+you to print the results on normal printers, but makes a terrible mess of binary
+files.  Transmitting in binary form always works.  As the message shows, the
+FreeBSD \fIftp\fP\/ server uses binary mode, but it doesn't harm to enter the
+\f(CWbin\fP command.  The message \f(CWType set to I.\fP is
+.Command ftp 's
+way of telling you that it has set binary transmission mode.
 .LI
 The line of \f(CW****\fP is an indication of the progress of the transfer.  It's
-specific to BSD; other \fIftp\fP\| clients don't show you anything here.
+specific to BSD; other
+.Command ftp
+clients don't show you anything here.
 .Le
-.H3 "Downloading in URL form"
+.SPUP
+.H3 "Specifying file names as  URIs"
 This transmission is fairly typical, and it's the traditional way to do it.
 FreeBSD has another method, though, which can be of use: instead of the
-interactive approach, you can specify the file name as a URL, and you can use
-\fIftp\fP\| to download HTTP documents from a web server.  For example, the last
-transfer can be simplified to:
-.Dx
+interactive approach, you can specify the file name as a URI, and you can use
+.Command ftp
+to download HTTP documents from a web server.  For example, the last transfer
+can be simplified to:
+.Dx 10
 $ \f(CBftp ftp://ftp.freebsd.org/pub/FreeBSD/ports/distfiles/xtset-1.0.tar.gz\fP
 Connected to ftp.beastie.tdk.net.
 220 ftp.beastie.tdk.net FTP server (Version 6.00LS) ready.
 331 Guest login ok, send your email address as password.
-\&\fI...\fP\|
+\&\fI...\fP\/
 230 Guest login ok, access restrictions apply.
 Remote system type is UNIX.
 Using binary mode to transfer files.
@@ -1105,7 +1309,7 @@
 4239 bytes received in 00:00 (5.81 KB/s)
 221 Goodbye.
 .De
-Note that this method implies anonymous ftp: you don't have to log in.
+Note that this method implies anonymous \fIftp\fP\/: you don't have to log in.
 .P
 In the same way, you can download a web page like this:
 .Dx
@@ -1114,15 +1318,15 @@
 100% |*************************************| 26493      12.20 KB/s    00:02    
 26493 bytes retrieved in 00:02 (12.17 KB/s)
 .De
-Note that in this case you can't just specify the URL as
-\fIhttp://www.FreeBSD.org/\fP\|: you must specify the real file name.
+Note that in this case you can't just specify the URI as
+\fIhttp://www.FreeBSD.org/\fP\/: you must specify the real file name.
 .H3 "Other ftp commands"
 .Command ftp
 has about sixty commands, some of which can be of use.  We'll look at the most
 useful commands in the following sections.
 .H3 "mget"
 Frequently you need to copy more than a single file.  For example, if you
-currently have \fIgcc-2.5.0\fR and want to get \fIgcc-2.5.8\fR, you will
+currently have \fIgcc-2.5.0\fP\/ and want to get \fIgcc-2.5.8\fP\/, you will
 discover the following files on the file server:
 .Dx
 ftp> \f(CBls\f(CW
@@ -1142,15 +1346,18 @@
 226 Transfer complete.
 ftp>
 .De
+.ne 3v
 .Pn get-patches
-In other words, you have the choice of transferring 6 megabytes of software in
-\fIgcc-2.5.8.tar.gz\fR or 7 incremental patch files with a total of less than
-250 kilobytes.  On the other hand, copying the diffs requires typing all these
+In other words, you have the choice of transferring 6 MB of software in
+\fIgcc-2.5.8.tar.gz\fP\/ or seven incremental patch files with a total of less
+than 250 kB.  On the other hand, copying the diffs requires typing all these
 long, complicated file names, so you might decide it's easier just to duplicate
 the whole 6 MB.
 .P
-There is an easier way: \f(CWmget\fR (multiple get) duplicates files matching a
-wild card.  You could perform the complete transfer with
+There is an easier way:
+.Command -n mget
+(multiple get) duplicates files matching a wild card.  You could perform the
+complete transfer with:
 .Dx
 ftp> \f(CBmget gcc-2*diff.gz\f(CW
 mget gcc-2.5.0-2.5.2.diff.gz?\f(CBy\f(CW
@@ -1169,46 +1376,73 @@
 \fI\&... etc
 .De
 .H3 "prompt"
-Using \f(CWmget\fR saves a lot of network bandwidth and copies the files faster,
-but it has one disadvantage: \fIftp\fR prompts you for each file name, so you
-have to wait around to answer the prompts.  If you don't, \fIftp\fR disconnects
-after 15 minutes of inactivity.  It would be simpler to perform all the
-\f(CWget\fRs without any intervention.  This is where the \f(CWprompt\fR command
-comes in.
-.P
-The \f(CWprompt\fR command specifies whether to issue certain prompts or
-not\(emthe \f(CWmget\fR command is one example.  This command is a toggle\(emin
-other words, if prompting is on, \f(CWprompt\fR turns it off, and if prompting
-is off, \f(CWprompt\fR turns it on.  If prompting is off, the \f(CWmget\fR
+Using
+.Command -n mget
+saves a lot of network bandwidth and copies the files faster, but it has one
+disadvantage:
+.Command ftp
+prompts you for each file name, so you have to wait around to answer the
+prompts.  If you don't,
+.Command ftp
+disconnects after 15 minutes of inactivity.  It would be simpler to perform all
+the
+.Command -n mget s
+without any intervention.  This is where the
+.Command -n prompt
+command comes in.
+.P
+The
+.Command -n prompt
+command specifies whether to issue certain prompts or not\(emthe
+.Command -n mget
+command is one example.  This command is a toggle\(emin other words, if
+prompting is on,
+.Command -n prompt
+turns it off, and if prompting
+is off,
+.Command -n prompt
+turns it on.  If prompting is off, the
+.Command -n mget
 command in the previous example would have gone through with no interruptions.
 .P
 In the previous example, you don't really want to transfer the file
-\fIgcc-2.5.1-2.5.2.diff.gz\fR, since you don't need it to perform the patches:
+\fIgcc-2.5.1-2.5.2.diff.gz\fP, because you don't need it to perform the patches:
 you can upgrade from 2.5.0 to 2.5.2 directly with the file
-\fIgcc-2.5.0-2.5.2.diff.gz\fR.  On the other hand, not copying the file would
+\fIgcc-2.5.0-2.5.2.diff.gz\fP.  On the other hand, not copying the file would
 mean sitting around for the duration of the transfer and answering the prompt
-for each file, and the file is only 1 kilobyte long.  In this case, it is
-reasonable to copy it as well\(emin other cases, you may need to consider other
-alternatives.
+for each file, and the file is only 1 kB long.  In this case, it is reasonable
+to copy it as well\(emin other cases, you may need to consider alternatives.
 .H3 "reget"
 Sooner or later, you will lose a connection in the middle of a transfer.
-According to Murphy's law, this will usually happen with a file like
-\fIgcc-2.5.8.tar.gz\fR in the previous example, and it will be shortly before
-the transfer is finished.  You may be able to save the day with \f(CWreget\fR,
+According to Murphy's law, this will usually happen with a big file, and it will
+be shortly before the transfer is finished.  You may be able to save the day
+with
+.Command -n reget ,
 which picks up the transfer where it left off.  The semantics are the same as
-for \f(CWget\fR.
+for
+.Command -n get .
 .P
-Unfortunately, not all versions of \fIftp\fR have the \f(CWreget\fR command, and
-on many systems that do have the command, it doesn't work correctly.  If you
-\fIdo\fR decide to use it, you should first make a copy of the partially copied
-file, in case something goes wrong.
+Unfortunately, not all versions of
+.Command ftp
+have the
+.Command -n reget
+command, and on many systems that do have the command, it doesn't work
+correctly.  If you \fIdo\fP\/ decide to use it, you should first make a copy of
+the partially copied file, in case something goes wrong.
 .H3 "user"
-.X ".netrc"
-Normally, \fIftp\fR attempts to log in using the user name of the user who
-started the \fIftp\fR program.  To make establishing connections easier,
-\fIftp\fR checks for a file called \fI.netrc\fR when perfoming a login sequence.
-\fI\&.netrc\fR contains information on how to log in to specific systems.  A
-typical \fI.netrc\fR might look like:
+Normally,
+.Command ftp
+attempts to log in using the user name of the user who started the
+.Command ftp
+program.  To make establishing connections easier,
+.Command ftp
+checks for a file called
+.File .netrc
+when performing a login sequence.
+.File .netrc
+contains information on how to log in to specific systems.  A typical
+.File .netrc
+might look like:
 .Dx
 machine freebie		login grog	password foo
 machine presto		login grog	password bar
@@ -1216,12 +1450,14 @@
 machine wait		login grog	password zot
 default			login ftp	password grog@example.org
 .De
-Lines starting with the keyword \fImachine\fR specify login name (\fIgrog\fR in
+Lines starting with the keyword \fImachine\fP\/ specify login name (\fIgrog\fP\/ in
 this example) and password for each system.  The last line is the important one:
-if the system is not mentioned by name, \fIftp\fR attempts a login with user
-name \f(CWftp\fR and password \f(CWgrog@example.org\fR.  Though this may be of
-use with systems you don't know, it causes a problem: if you want to connect to
-a machine without anonymous ftp, you will need to explicitly tell
+if the system is not mentioned by name,
+.Command ftp
+attempts a login with user name \f(CWftp\fP and password
+\f(CWgrog@example.org\fP.  Though this may be of use with systems you don't
+know, it causes a problem: if you want to connect to a machine without anonymous
+\fIftp\fP\/, you will need to explicitly tell
 .Command ftp
 not to attempt an auto-login.  Do this with the \f(CW-n\fP option:
 .Dx
@@ -1245,12 +1481,13 @@
 Using binary mode to transfer files.
 ftp>
 .De
-.X "ftp, command"
-.X "command, ftp"
 This error message is not very obvious: although you're not logged in, you still
-get the same prompt, and \fIftp\fR produces enough verbiage that it's easy to
-oversee that the login attempt failed.  In order to complete the login, you need
-to use the \fIuser\fR command:
+get the same prompt, and
+.Command ftp
+produces enough verbiage that it's easy to oversee that the login attempt
+failed.  To complete the login, use the
+.Command -n user
+command:
 .Dx
 ftp> \f(CBuser ftp\f(CW
 331 Guest login ok, send ident as password.
@@ -1258,56 +1495,13 @@
 230 Guest login ok, access restrictions apply.
 .De
 .SPUP
-.H2 "scp"
-.Command scp
-is a variant of
-.Command ssh
-used for remote copying.  The same access considerations apply as for
-.Command ssh .
-The syntax for copying is similar to the syntax used by NFS: to copy a file
-.File /var/log/messages
-from \fIpresto\fP\| to the file
-.File -n prestomessages
-on the local machine, you might enter:
-.Dx
-$ \f(CBscp presto:/var/log/messages prestomessages\fP
-.De
-As with
-.Command ssh ,
-if you need to authenticate as a different user, you can use the form
-\fIuser@system\fP, or you can use the \f(CW-l\fP option to specify the user
-name.
-.P
-\fIscp\fP\| has a number of options reminiscent of
-.Command cp \|:
-.Ls B
-.LI
-Use the \f(CW-p\fP option to preserve modification times and permissions where
-possible.
-.LI
-Use the \f(CW-r\fP option to recursively copy directories.
-.Le
-You don't have to supply full path names to
-.Command scp \|:
-you can write things like:
-.Dx
-$ \f(CBcp remotehost:file .\fP
-.De
-This looks for a file called
-.File -n file
-in your home directory on the remote machine and copies it to your current local
-directory.  Note the difference: there is no way for 
-.Command scp
-to know a different remote directory, so relative paths are always relative to
-the home directory on that machine.
 .H2 "sftp"
-Yet another
+.Command sftp
+is yet another
 .Command ssh -based
-program is
-.Command sftp .
-Use it exactly like
-.Command ftp .
-As with other
+program.  It's designed to be as compatible as possible with
+.Command ftp ,
+so you use it in exactly the same manner.  As with other
 .Command ssh -related 
 commands, you need to authenticate in an
 .Command ssh -specific
@@ -1315,17 +1509,25 @@
 .Command -n exec
 command, which allows you to run programs on the remote machine.
 .P
-In order to use
+To use
 .Command sftp ,
 the remote machine must be able to run the
-.Command sftpserv
-server.  If the server is in your \f(CWPATH\fP,
-.Command sftp
-will start it automatically, so it doesn't need to be running already.
+.Daemon sftp-server
+server.  It is normally started from
+.Daemon sshd .
+See page
+.Sref \*[sftp-server] \&
+for more details.
 .H2 "rsync"
-\fIrsync\fP\| is a program designed to keep identical copies of files on
-different machines and to optimize network bandwidth while doing so.  It's in
-the Ports Collection.  Install in the normal manner:
+.Pn rsync
+Frequently you want to keep identical copies of files on different machines.
+You can copy them, of course, but if there are only small changes in large
+files, this can be relatively inefficient.  You can perform this task more
+efficiently with
+.Command rsync ,
+which is designed to keep identical copies of files on two different systems and
+to optimize network bandwidth while doing so.  It's in the Ports Collection.
+Install in the normal manner:
 .Dx
 # \f(CBcd /usr/ports/net/rsync\fP
 # \f(CBmake install\fP
@@ -1336,17 +1538,20 @@
 .Command ssh
 to perform the transfer, so you need to have
 .Command ssh
-configured correctly.
+configured correctly.  In particular, you should be using
+.Command ssh-agent
+authentication.
 .P
 You can use
 .Command rsync
 like
-.Command scp \|:
+.Command scp \/:
 the syntax is compatible up to a point.  For example, you could copy a file from
 a remote system with:
-.Dx
+.Dx 1
 $ \f(CBrsync presto:/var/log/messages prestomessages\fP
 .De
+.ne 3v
 You don't need to install
 .Command rsync
 just for that, of course: you can do exactly the same thing with
@@ -1358,8 +1563,8 @@
 difference.  But files like
 .File /var/log/messages
 grow at the end, and the rest doesn't change.  That's an ideal situation for
-.Command rsync \|:
-it uses an algorithm which recognizes common parts of files (not necessarily at
+.Command rsync \/:
+it uses an algorithm that recognizes common parts of files (not necessarily at
 the beginning) and optimizes the transfer accordingly.  The first time you run
 the program, you might see:
 .Dx
@@ -1384,22 +1589,23 @@
 script to update the remote pages with commands like:
 .Dx
 rsync -LHzav --exclude=RCS --exclude="*~" ~grog/public_html/* website:htdocs/grog
-# There's stuff here we don't want to copy, so don't go recursive.
 rsync -LHztpgov --exclude="*~" website:htdocs
 .De
 The first
 .Command rsync
 command synchronizes the local directory
-.File ~grog/public_html/
+.Directory ~grog/public_html
 to the remote directory
-.File htdocs/grog/ 
+.Directory -n htdocs/grog
 on the system \fIwebsite\fP.  It includes all subdirectories with the exception
 of the
 .File RCS
 directories.  The second command synchronizes the top level web directory only,
 and not the subdirectories, many of which shouldn't be maintained on the remote
 site.  In each case, files ending in \f(CW~\fP are excluded (these are normally
-.Command Emacs
+.X "emacs, command"
+.X "command, emacs"
+.Command -n Emacs
 backup files), and in the second case the
 .File RCS
 subdirectories are also excluded.  Let's look more carefully at all those
@@ -1412,6 +1618,8 @@
 may be broken (depending on whether a file of that name exists on the
 destination system or not).  In this example, a number of files are really
 located elsewhere, so it makes sense to copy them as files.
+.br
+.ne 10v
 .LI
 \f(CW-H\fP is pretty much the opposite of \f(CW-L\fP: by default,
 .Command rsync
@@ -1437,8 +1645,9 @@
 .LI
 \f(CW-D\fP: copy device nodes (only for \f(CWroot\fP).
 .Le
-The other options are \f(CW-p\fP, \f(CW-t\fP, \f(CW-g\fP and \f(CW-o\fP.  Since
-we don't want to copy subdirectories in the second example, we state them
+.ne 3v
+The other options are \f(CW-p\fP, \f(CW-t\fP, \f(CW-g\fP and \f(CW-o\fP.  We
+don't want to copy subdirectories in the second example, so we state them
 explicitly.  Together, they roughly correspond to the \f(CW-p\fP (preserve)
 option to some other copy programs.
 .LI
@@ -1475,13 +1684,13 @@
 $ \f(CBrsync -zHLav presto:/home/grog/Mail Mail\fP
 .De
 This would seem to duplicate the directory
-.File /home/grog/Mail
+.Directory /home/grog/Mail
 on the remote system to a directory of the same name on the local system.  In
 fact, it moves the contents of the host
-.File /home/grog/Mail
+.Directory /home/grog/Mail
 to 
-.File /home/grog/Mail/Mail 
-on the local machine.  To do what you expect, write
+.Directory /home/grog/Mail/Mail
+on the local machine.  To do what you expect, write:
 .Dx
 $ \f(CBrsync -zHLav presto:/home/grog/Mail .\fP
 .De
@@ -1492,10 +1701,10 @@
 that we've seen so far doesn't require a server, but it does require an
 .Command ssh .
 .Command rsync
-also offers a different means of access which uses a server,
-.Command rsyncd .
+also offers a different means of access that uses a server,
+.Daemon rsyncd .
 This method is intended more for access to systems for which you don't have a
-password, something like anonymous ftp.
+password, something like anonymous \fIftp\fP\/.
 .P
 We'll look at setting up an
 .Command rsync
@@ -1505,13 +1714,13 @@
 remote system.  For example, you might enter:
 .Dx
 $ \f(CBrsync freebie::\fP
-This is echunga.lemis.com.  Be gentle.
+This is freebie.example.org.  Be gentle.
 
 groggy          Greg's web pages
 tivo            TiVo staging area
 .De
 The first line is simply an identification message, referred to as a message of
-the day in the documentation.  The others represent directory hierarchies which
+the day in the documentation.  The others represent directory hierarchies that
 the server makes available, along with a comment about their purpose.  The
 documentation calls them modules.  As we'll see on page
 .Sref "\*[rsyncd]" ,
@@ -1519,10 +1728,10 @@
 need to be related.
 .P
 To find out what is in these directories, you can use the following kind of
-command, which specifies a specific module, but no destination:
+command, which specifies a particular module, but no destination:
 .Dx
-$ \f(CBrsync echunga::groggy\fP
-This is echunga.lemis.com.  Be gentle.
+$ \f(CBrsync freebie::groggy\fP
+This is freebie.example.org.  Be gentle.
 
 drwxr-xr-x        5632 2002/10/24 12:40:38 .
 -rw-r--r--        3855 2002/03/16 13:51:12 20feb99.html
@@ -1531,12 +1740,12 @@
 -rw-r--r--       11590 2002/03/16 13:51:12 AOSS-programme.html
 -rw-r--r--        1798 2002/03/16 13:51:12 BSDCon-2002.html
 -rw-r--r--        1953 2002/03/16 13:51:12 Essey-20020222.html
-\&\fI...etc\fP\|
+\&\fI...etc\fP\/
 .De
 To transfer a file, specify its name and a destination:
 .Dx
-$ \f(CBrsync -v echunga::groggy/AOSS-programme.html .\fP 
-This is echunga.lemis.com.  Be gentle.
+$ \f(CBrsync -v freebie::groggy/AOSS-programme.html .\fP
+This is freebie.example.org.  Be gentle.
 
 AOSS-programme.html
 wrote 98 bytes  read 11744 bytes  23684.00 bytes/sec
@@ -1546,11 +1755,12 @@
 .Command rsync
 has done; without it, there would be no output.
 .P
+.ne 10v
 If you want to transfer the entire module, use the \f(CW-r\fP or \f(CW-a\fP
 options we looked at above:
 .Dx
-$ \f(CBrsync -r -v echunga::groggy .\fP
-This is echunga.lemis.com.  Be gentle.
+$ \f(CBrsync -r -v freebie::groggy .\fP
+This is freebie.example.org.  Be gentle.
 
 receiving file list ... done
 skipping non-regular file "Images/20001111"
@@ -1559,169 +1769,365 @@
 AOSS-programme-orig.html
 AOSS-programme.html
 BSDCon-2002.html
-\&\fI...etc\fP\|
+\&\fI...etc\fP\/
 .De
 .SPUP
-.H2 "Web browsers"
-.X "World-Wide Web"
-For the vast majority of the public, the Internet and the \fIWorld-Wide Web\fP\|
-are the same thing.  FreeBSD is an important contender in this area.  Some of
-the world's largest Web sites, including Yahoo!  (\fIhttp://www.yahoo.com/\fP\|)
-run FreeBSD.  FreeBSD's web performance appears to be at least an order of
-magnitude better than that of Microsoft NT, not to mention other Microsoft
-platforms.  Even Microsoft runs FreeBSD on its Hotmail service
-(\fIhttp://www.hotmail.com/\fP\|), though they have frequently denied it, and
-for image reasons they are moving to their own software.
+.H2 "The Network File System"
+.X "NFS, setting up"
+.Pn NFS-client
+.Pn NFS-setup
+.X "Network File System"
+The \fINetwork File System\fP, or \fINFS\fP, is the standard way to share UNIX
+files across a network.
+.P
+We've already seen that UNIX file systems are accessible in a single tree by
+.Command mount ing
+them on a specific directory.  NFS continues this illusion across the network.
+.P
+From a user point of view, there is little difference: you use the same
+.Command mount
+command, and it performs what looks like the same function.  For example, if
+system \fIpresto\fP\/'s system administrator wants to mount \fIfreebie\fP\/'s
+file systems
+.Directory -n / ,
+.Directory -n /usr
+and
+.Directory -n /home ,
+he could enter:
+.Dx
+# \f(CBmkdir /freebie
+# \f(CBmount freebie:/ /freebie\fP
+# \f(CBmount freebie:/usr /freebie/usr\fP
+# \f(CBmount freebie:/home /freebie/home\fP
+.De
+You'll note how to specify the file systems: the system name, a colon
+(\f(CW:\fP), and the file system name.  This terminology predates URIs;
+nowadays, people would probably write \f(CWnfs://freebie/usr\fP.
 .P
-We'll look at web browsers first, then on page \*[web-server] we'll look at how
-to set up a web server.
-.H3 "Uniform Resource Identifier"
-.Pn URL
-.X "Uniform Resource Locator"
-.X "URL"
-.X "Uniform Resource Identifier"
-.X "URI"
-Another term has become widely known in connection with the World Wide Web: the
-concept of a \fIUniform Resource Locator\fP\| or \fIURL\fP.  Nowadays a URL is a
-special kind of \fIUniform Resource Identifier\fP\| or \fIURI\fP.  They're
-defined in RFC 2396, which you can find at
-\fIhttp://www.ietf.org/rfc/rfc2396.txt\fP.  The most usual kind of URL can
-consist of up to 6 components, although most contain only 3.  The syntax is
-(roughly translated into UNIX terminology):
-.Ds
-\fIservice\fP\|://\fIuser\fP\|:\fIpassword\fP\|@\fIhost\fP\|:\fIport\fP\|/\fIpath\fP\|
+Note also that you don't need to create
+.Directory /freebie/usr
+and
+.Directory /freebie/home \/:
+assuming that the directories
+.Directory -n /usr
+and
+.Directory -n /home
+exist on once you have mounted
+.Directory /freebie ,
+they will become visible.
+.P
+If you look at NFS more closely, things don't look quite as similar to disks as
+they do at first sight.  You access local file systems via the disk driver,
+which is part of the kernel.  You access NFS file systems via the NFS processes.
+.P
+Older implementations of NFS had a plethora of processes.  If you're used to
+such systems, don't let the lack of processes make you think that there's
+something missing.
+.H2 "NFS client"
+.X "NFS, client"
+.X "client, NFS"
+.X "nfsiod, daemon"
+.X "daemon, nfsiod"
+You don't need any particular software to run as an NFS client, but the program
+.Daemon nfsiod
+greatly improves performance.  It's started at bootup time if you specify
+\f(CWnfs_client_enable="YES"\fP in your
+.File /etc/rc.conf ,
+but you can also start it manually if it's not running:
+.Dx
+# \f(CBnfsiod -n 6\fP
+.De
+The parameter \f(CW-n 6\fP tells
+.Daemon nfsiod
+how many copies of itself to start.  The default is four.  Each
+.Daemon nfsiod
+can handle a concurrent I/O request, so if you find that your performance isn't
+what you would like it to be, and the CPU time used by each
+.Daemon nfsiod
+is similar, then you might like to increase this value.  To ensure it's done
+automatically at boot time, add the following to
+.File /etc/sysctl.conf \/:
+.Dx
+vfs.nfs.iothreads=6
 .De
-These names have the following meaning:
+We'll look at
+.File /etc/rc.conf
+and
+.File /etc/sysctl.conf
+in more detail in Chapter
+.Sref \*[nchstarting] .
+.H3 "Mounting remote file systems"
+.X "mounting, remote file system"
+.X "file system, mounting remote"
+As we've seen, we mount NFS files with the same
+.Command mount
+command that we use for local file systems.  This is another illusion:
+.Command mount
+is just a front-end program that determines which program to start.  In the
+case of local file systems, it will start
+.Command mount_ufs ,
+and for NFS file systems it will start
+.Command mount_nfs .
+.P
+There are a number of options you may wish to use when mounting NFS file
+systems.  Unfortunately, the options that
+.Command mount_nfs
+uses are not the same as the options you would use in
+.File /etc/fstab .
+Here's an overview:
 .br
 .ne 1i
-.TB "URL syntax"
+.Table-heading "NFS mount options"
+.Pn NFS-mount-flags
 .TS H
 tab(#) ;
-lf(I) | lw52 .
-Component#Meaning
+lfCWp9 | lfCWp9 | lw42 .
+\fRfstab\fP\/#\fRmount_nfs\fP\/#Meaning
+\fRoption#\fRoption
 _
 .TH
-.X "/etc/services"
-service#T{
-Usually an IP service, described in \fI/etc/services\fP.  See page \*[services]
-for more details.  Some exceptions are the string \f(CWmailto\fP, which
-identifies the \fIuser\fP\| and \fIhost\fP\| components as a mail ID, and
-\f(CWfile\fP, which identifies the following pathname as the name of a local
-file.  The most common services are \fIhttp\fP, \fIhttps\fP, \fIftp\fP\| and
-\fItelnet\fP.
+bg#-b#T{
+Continue attempting the mount in the background if it times out on the initial
+attempt.  This is a very good idea in
+.File /etc/fstab ,
+because otherwise the boot process waits until all mounts have completed.  If
+you've just had a power failure, this can cause deadlocks otherwise.
 T}
 .sp .4v
-.X "/etc/passwd"
-user#T{
-The name of a user on whose behalf the operation is performed.  For example,
-when using the \fIftp\fP\| service, this would be the user name to use for
-logging in to the FTP server.  We've seen that it represents the name of the
-recipient for mail.  From a UNIX perspective, the \fIuser\fP\| information comes
-from \fI/etc/passwd\fP.
+nfsv2#-2#T{
+Use NFS Version 2 protocol.  By default,
+.Command mount_nfs
+tries NFS Version
+3 protocol first, and falls back to Version 2 if the other end can't handle
+Version 3.  Don't use NFS Version 2 unless you have to.
 T}
 .sp .4v
-.X "/etc/spwd.db"
-password#T{
-Where authentication is needed, the password to use.  You'll see this
-occasionally in FTP URLs.  Traditionally, this information is stored in
-\fI/etc/passwd\fP, but FreeBSD stores it in a separate file, \fI/etc/spwd.db\fP,
-which is accessible only to \f(CWroot\fP.
+retry=\f(BInum\fP\/#-R\f(BInum\fP\/#T{
+Retry up to \fInum\fP\/ times before aborting an I/O operation.
 T}
 .sp .4v
-.X "/etc/namedb/db.domain"
-host#T{
-The DNS name of the system on which the resource is located.  Some non-UNIX
-sites also use an IP address here.  This information is stored in a file such as
-\fI/etc/namedb/db.domain\fP\| for the local system, and retrieved via DNS.
+-o ro#-o ro#T{
+Mount the file system for read-only access.
 T}
 .sp .4v
-port#T{
-The port number to connect to.  This may be necessary if the service uses a
-non-standard port.  Normally it's implicit in the service: for example,
-\f(CWhttp\fP usually runs on port 80, but it's possible to run web servers on
-other ports, in which case you need to specify the port number here.
+-o rw#-o rw#T{
+Mount the file system for read and write access.
 T}
 .sp .4v
-.X "/usr/local/www/data/"
-.X "~user/public_html/"
-path#T{
-A UNIX path name, in other words a complete file name.  Unlike other UNIX path
-names, the root is not normally the root file system.  For the \fIhttp\fP\|
-service, the root is implementation defined.  For Apache on FreeBSD, it's
-normally \fI/usr/local/www/data/\fP.  If you use the \f(CW~\fP\| notation to mean
-\fIhome directory\fP\| (see page \*[home-directory]), you will get
-\fI~user/public_html/\fP.
-.P
-For \fIftp\fP, it's the directory which belongs to \fIuser\fP.  If you omit
-\fIuser\fP for \fIftp\fP, you'll get the user \fIftp\fP, so the pathname
-\fI/pub\fP\| maps to the UNIX file name \fI~ftp/pub\fP.
+-R \f(BInum\fP\/#-R \f(BInum\fP\/#T{
+Retry the mount operation up to \fInum\fP\/ times.  If you have chosen soft
+mounting, fail I/O operations after \fInum\fP\/ retries.  The default value is
+10.
+T}
+.sp .4v
+-r \f(BIsize\fP\/#-r \f(BIsize\fP\/#T{
+Set the read data block size to \fIsize\fP\/ bytes.  \fIsize\fP\/ should be a
+power of 2 between 1024 and  32768.  The default value is 8192.
+Use smaller block sizes
+for UDP mounts if you have frequent ``fragments dropped due to timeout''
+messages on the client.
+T}
+.sp .4v
+soft#-s#T{
+If operations on the file system time out, don't retry forever.  Instead, give
+up after \fIRetry\fP\/ timeouts.  See option \f(CW-R\fP.
+T}
+.sp .4v
+-t \f(BInum\fP\/#-t \f(BInum\fP\/#T{
+Time out and retry an operation if it doesn't complete with in \f(BInum\fP\//10
+seconds.  The default value is 10 (1 second).
+T}
+.sp .4v
+tcp#-T#T{
+Use TCP instead of UDP for mounts.  This is more reliable, but slightly slower.
+In addition, not all implementations of NFS support TCP transport.
+T}
+.sp .4v
+-w \f(BIsize\fP\/#-w \f(BIsize\fP\/#T{
+Set the write data block size to \fIsize\fP\/ bytes.  \fIsize\fP\/ should be a
+power of 2 between 1024 and 32768.  The default value is 8192.  Use smaller
+block sizes for UDP mounts if you have frequent ``fragments dropped due to
+timeout'' messages on the server.
 T}
 .TE
 .sp 1.5v
-Normally, you don't specify user name, password or port, so URL syntax reduces
-to:
-.Ds
-\fIservice\fP\|://\fIhost\fP\|/\fIpath\fP\|
-.De
-Note that one character is not defined in URI or URL syntax: the backslash,
-\f(CW\e\fP.  The directory delimiter is a slash (\f(CW/\fP), but many Microsoft
-clients and even servers don't notice that, and some even translate \f(CW\e\fP
-into \f(CW/\fP without telling you.  That makes it difficult to view web sites
-like \fIhttp://www.lemis.com/why\ebackslashes\eare\enot\eslashes.html\fP.
-.H2 "Web browsers"
-.Pn www
-.X "web browser"
-.X "browser, web"
-A \fIweb browser\fP\| is a program which retrieves documents from the Web and
-displays them.  FreeBSD does not include a web browser, but a large number are
-available in the Ports Collection.  The most important are:
+Normally, the only options that are of interest are \f(CW-o ro\fP, if you
+specifically want to restrict write access to the file system, and \f(CWsoft\fP,
+which you should always use.
+.Aside
+Purists claim that \f(CWsoft\fP compromises data integrity, because it may leave
+data on the server machine in an unknown state.  That's true enough, but in
+practice the alternative to soft mounting is to reboot the client machine.  This
+is not only a nuisance, it \fIalso\fP\/ compromises data integrity.  The only
+solution that doesn't always compromise data integrity is to wait for the server
+machine to come back online.  It's unlikely that anybody will wait more than a
+few hours at the outside for a server to come back.
+.End-aside
+.ne 3v
+A typical mount operation might be:
+.Dx 1
+# \f(CBmount -o soft presto:/usr /presto/usr
+.De
+.sp -1v
+.H3 "Where to mount NFS file systems"
+.X "mounting, NFS file system"
+.X "NFS, file system, mounting"
+.Pn NFS-mount-points
+You can mount an NFS file system just about anywhere you would mount a local
+file system.  Still, a few considerations will make life easier.  In this
+discussion, we'll assume that we have a large number of file systems mounted on
+\fIfreebie\fP, and we want to make them accessible to \fIpresto\fP.
 .Ls B
 .LI
-.X "lynx, command"
-.X "command, lynx"
-\fIlynx\fP\| is a web browser for people who don't use X.  It displays text
-only.
-.LI
-.X "netscape, command"
-.X "command, netscape"
-\fInetscape\fP\| was once the only game in town, but it's now showing its age.
-In addition, many web sites only test their software with Microsoft, and their
-bugs cause problems with Netscape.
+If you have a ``special'' file system that you want to mount on multiple
+systems, it makes sense to mount it on the same mount point on every system.
+\fIfreebie\fP\/ has two file systems,
+.Directory -n /S
+and
+.Directory -n /src ,
+which contain source files and are shared between all systems on the network.
+It makes sense to mount the file system on the same directory.
 .LI
-.Command mozilla
-is derived from the same sources as Netscape, but comes in source form.  It has
-now reached the stage where it is less buggy than Netscape.  A number of other
-browsers, such as
-.Command galeon ,
-.Command konqueror
+\fIfreebie\fP\/ has a CD-ROM changer, and mounts the disks on
+.Directory -n /cdrom/1
+to
+.Directory -n /cdrom/7 .
+\fIpresto\fP\/ finds that too confusing, and mounts one of them on
+.Directory -n /cdrom .
+.LI
+Some other file systems can't be mounted in the same place.  For example,
+.Directory freebie:/usr
+can't be mounted on
+.Directory -n /usr .
+Mount them on directories that match the system name.  For example, mount
+.Directory freebie:/usr
+on
+.Directory /freebie/usr .
+.Le
+After doing this, you might find the following file systems mounted on
+\fIfreebie\fP\/:
+.Dx
+# \f(CBdf\fP
+Filesystem  1024-blocks     Used    Avail Capacity  Mounted on
+/dev/ad0s1a       30206    26830      960    97%    /
+/dev/ad0s1e     1152422  1016196    44034    96%    /usr
+/dev/da0h        931630   614047   243052    72%    /src
+/dev/da1h       2049812  1256636   629192    67%    /home
+procfs                4        4        0   100%    /proc
+/dev/cd0a        656406   656406        0   100%    /cdrom/1
+/dev/cd1a        664134   664134        0   100%    /cdrom/2
+/dev/cd2a        640564   640564        0   100%    /cdrom/3
+/dev/cd3a        660000   660000        0   100%    /cdrom/4
+/dev/cd4a        525000   525000        0   100%    /cdrom/5
+/dev/cd5a        615198   615198        0   100%    /cdrom/6
+/dev/cd6a        278506   278506        0   100%    /cdrom/7
+.De
+On \fIpresto\fP, you might see:
+.Dx
+# \f(CBdf\fP
+Filesystem       1024-blocks     Used    Avail Capacity  Mounted on
+/dev/da0s1a            29727    20593     6756    75%    /
+/dev/da0s1e          1901185   742884  1006207    42%    /usr
+procfs                     4        4        0   100%    /proc
+freebie:/              30206    26830      960    97%    /freebie
+freebie:/usr         1152422  1016198    44032    96%    /freebie/usr
+freebie:/home        2049812  1256638   629190    67%    /home
+freebie:/src          931630   614047   243052    72%    /src
+freebie:/S           3866510  1437971  2119219    40%    /S
+freebie:/cdrom/1      656406   656406        0   100%    /cdrom
+.De
+.sp -1v
+.H3 "Mounting NFS file systems automatically"
+If you want to mount NFS files automatically at boot time, make an entry for
+them in the file
+.File /etc/fstab .
+You can even do this if you don't necessarily want to mount them: just add the
+keyword \f(CWnoauto\fP, and
+.Command mountall
+will ignore them at boot time.  The advantage is that you then just need to
+specify, say,
+.Dx
+# \f(CBmount /src\fP
+.De
+instead of:
+.Dx
+# \f(CBmount -s freebie:/src /src\fP
+.De
+See the description of
+.File /etc/fstab
+on page \*[/etc/fstab] for more information.
+.H2 "NFS strangenesses"
+.X "NFS, strangenesses"
+.X "strangenesses, NFS"
+NFS mimics a local file system across the network.  It does a pretty good job,
+but it's not perfect.  Here are some things that you should consider.
+.H3 "No devices"
+NFS handles disk files and directories, but not devices.  Actually, it
+handles devices too, but not the way you would expect.
+.P
+.X "device node"
+.X "node, device"
+In a UNIX file system, a device is more correctly known as a \fIdevice
+node\fP\/: it's an inode that \fIdescribes\fP\/ a device in terms of its major
+and minor numbers (see page \*[devices]).  The device itself is implemented by
+the device driver.  NFS exports device nodes in UFS file systems, but it doesn't
+interpret the fact that these devices are on another system.  If you refer to
+the devices, one of three things will happen:
+.Ls B
+.LI
+If a driver for the specified major number exists on your local system, and the
+devices are the same on both systems, you will access the local device.
+Depending on which device it is, this could create some subtle problems that
+could go undetected for quite a while.
+.LI
+If a driver for the specified major number exists on your local system, and the
+devices are different on the two systems, you will still access the local device
+with the same major and minor numbers, if such a device exists.  The results
+could be very confusing.
+.LI
+If no driver for the specified major number exists on your local system, the
+request will fail.  This can still cause considerable confusion.
+.Le
+If the NFS server system runs \fIdevfs\fP, the device nodes are not exported.
+You won't see anything unless there are leftover device nodes from before the
+time of migration to \fIdevfs\fP.
+.H3 "Just one file system"
+NFS exports file systems, not directory hierarchies.  Consider the example on
+page \*[NFS-mount-points].  \fIpresto\fP\/ has mounted both
+.Directory freebie:/
 and
-.Command skipstone ,
-are based on
-.Command mozilla .
-They're all available in the Ports Collection.
+.Directory freebie:/usr .
+If it were just to mount
+.Directory freebie:/ ,
+we would see the directory
+.Directory /freebie/usr ,
+but it would be empty.
+.P
+Things can get even stranger: you can mount a remote file system on a directory
+that is not empty.  Consider the following scenario:
+.Ls B
 .LI
-\fIOpera\fP\| is a new browser which some people like.  The version in the Ports
-collection is free, but it makes up for it by giving you even more
-advertisements than the web pages give you anyway.
+You install FreeBSD on system \fIfreebie\fP\/.  In single-user mode, before
+mounting the other file systems, you create a directory
+.Directory -n /usr/bin
+and a file
+.File -n /usr/bin/vi .
+Since the
+.Directory -n /usr
+file system isn't mounted, this file goes onto the root file system.
+.LI
+You go to multi-user mode and mount the other file systems, including the file
+system for
+.Directory -n /usr .
+You can no longer see the
+.File -n /usr/bin/vi
+you put there in single-user mode.  It hasn't gone away, it's just masked.
+.LI
+On \fIpresto\fP, you mount the file system \fIfreebie:/\fP\/ on
+.Directory -n /freebie .
+If you list the contents of the directory
+.Directory -n /freebie/usr ,
+you will see the original file
+.Command vi ,
+and not the contents that the users on \fIfreebie\fP\/ will see.
 .Le
-.X "internet explorer, Microsoft"
-.X "Microsoft, internet explorer"
-You'll note one exception on this list: Microsoft's \fIInternet Explorer\fP\| is
-not available for FreeBSD.  Nobody seems to have missed it.  In view of the fact
-that Microsoft appears to be trying to fragment the web market,
-.P
-.X "mosaic, command"
-.X "command, mosaic"
-One other browser is no longer in this list: \fImosaic\fP, the original web
-browser.  It's now completely obsolete, and it has been removed from the Ports
-Collection.
-.P
-In addition to these browsers, \fIStarOffice\fP\| and \fIOpenOffice\fP\| include
-an integrated browsers.  You may find you prefer them.
-.P
-All web browsers seem to have one thing in common: they are very buggy.  They
-frequently crash when presented with web pages designed for Microsoft, and in
-other cases they don't display the page correctly.  In many cases this is due to
-poorly designed web pages, of course.  Microsoft itself is a good example of
-this: many people get a blank page when they try to aceess
-\fIhttp://www.microsoft.com/\fP, though it's not clear what causes the problem.
