All the hosts mentioned in the command arguments must have nfrcp installed on them.
If the configuration file (see below) specifies a db-root, nfrcp will attempt to store and retrieve checksums for transferred files in an sqlite database. The database entries are keyed by file inode and modification time, so they should be immune to file renames within a filesystem. Ideally the checksums would be stored iin extended attributes of the files themselves instead of in a database, but not all filesystems (most notably QFS) support extended attributes.
When sending a file, nfrcp will first try to retrieve its checksum from the local database. If there is no database entry for a source file (either because there is no database at the sending end, or no database record can be found for the file), a checksum is generated from the file data at the sending end. This checksum is compared against the file as it is received by the other host, and recorded in the database if one exists at the receiving end. If a received checksum does not match the received file, an error is generated.
hostname my.preferred.interface.hostname
When set on the sending end, this forces the receiver to connect to the sender via the specified hostname, and avoids the peer-detection heuristic described below. Set this to the hostname or doted-decimal ip address of the host's preferred interface if required (see below). This string will be sent by the sending nfrcp to the receiving end as part of the handshake, and the receiving end will then try to connect to that hostname or ip address, so it must make sense to the receiving nfrcp.
If this is not set (e.g. where there is no configuration file), the receiving nfrcp will attempt to work out whether there is a firewall or rsh-proxy between it and the sender. If there is, the receiver will attempt to connect to the hostname that the sender sent in the handshake (as returned by gethostname() on the sender). If there isn't, the receiver will attempt to contact the sender via the address used in the rsh (rcmd()) connection. The firewall/proxy detection works by having the sender send the ip address and port of its end of the rsh connection in the handshake. If the receiver sees the handshake coming from the address and port mentioned in the handshake, it can be reasonably sure there is no NAT or rsh-proxy in between. That said, it's possible to construct a NAT setup whereby the rsh connection goes through untranslated, but other things don't. For these weird cases, override the connection address by setting the hostname in the config file.
db-root /path/to/checksum/database/root/directory
If this appears, file checksums will be written to a database rooted at the specified path.
hash-name sha1|md5|....
The OpenSSL algorithm name of the checksum to use.
If a user writes to a file that is recorded by nfrcp in its database, the database entry is effectively hidden by virtue of the file mtime changing. If the user conspires to keep the mtime unchanged, nfrcp will report a checksum error when retrieving the file, but the file will still be copied as normal.
nfrcp must be in the user's PATH on the remote end. i.e. 'rsh hostname which nfrcp' must find nfrcp.
The checksum database has the following features:
1. Checksums are indexed by file inode and mtime. This menas files can be renamed within a filesystem without losing their checksums.
2. By using a daemon-less database (sqlite), database access is controlled by standard unix file permissions. nfrcp needs to be setuid root so it can call rcmd() (just like rcp ) but should also be setgid to protect access to the checksum database. The checksum database root directory should only be writable by the group that owns the nfrcp executable.
Each database entry records the inode number, modification time, writer uid, checksum, and checksum state of a file and some associated timestamps.
3. File pathnames are not stored. They are not needed due to the inode indexing, and might present an information disclosure risk if they were.