/* This program implements the uucp (Unix-to-Unix CoPy) protocol, used to transfer mail, files, and Usenet news among Unix machines. UUCP comes free with Unix (unless you get a sleazeoid version like Xenix, where they charge you extra for it), but you don't get sources. You can buy a commercial program for MSDOS, called UULINK, which also implements this protocol. UULINK costs $300 and you still don't get sources. This program not only runs on Unix and MSDOS, but on many other machines, and comes with the Free Software Foundation copyright, which guarantees you access to sources. The protocol requires a full 8-bit data path with no characters inserted or deleted (e.g. ^S and ^Q are used as DATA characters). Simple serial ports and modems do this; most complicated networks do not, at least without setting up odd modes and such. Telenet's PC Pursuit works fine though. The basic flow of the protocol is that the calling machine will send down a line of text saying what it wants to do (send a file, receive a file, or hang up). (The lines of text are encapsulated into packets; see below.) The called machine responds with a "yes" or "no" answer, and if the answer was yes, it sends or receives the file. Files are terminated with a packet containing 0 bytes of data. Then the system that received the file sends a "copy succeeded" or "copy failed" line to the other end, and they go back to "what do we do now". A request to hang up should be answered "no" if the called machine has some mail or files it wants to send to the calling machine; the two machines reverse roles and the calling machine goes into "what do we do now". If a hangup request is answered "yes", the call is terminated. The data flow described above is actually sent by a lower level "protocol module". The default "g" protocol module sends the data in packets containing checksums and acknowledgements. Each packet can either hold a short control message, e.g. an ack, or a data block. The data blocks are numbered with a 3-bit counter, and sent with a checksum. If the sender has not received an acknowledgement for a data block within a certain time, it retransmits the block. The size of a data block is negotiated at the start of a call. To send a block with fewer bytes, a "short data" block is sent, which is just as big as a "long data" block, but contains a 1- or 2-byte count of "how many bytes in this block are just padding". This is a cute trick since it always works (e.g. if you want to send 1023 out of 1024 bytes, you only need one byte for the count; while if you want to send 1 byte out of 1024 then you have enough space for the count to be 2 bytes). The short control messages are used to start the call and negotiate the packet size and the "window size", to acknowledge or reject packets, and to terminate the packet protocol at the end of a call. The window size is how many packets one side can send before it will stop and wait for an acknowledgement from the other side. A window size of 1 makes for a half-duplex protocol (which is what gnuucp currently implements), but also makes it easy to implement on micros that don't handle serial lines with interrupts. In window 1, you just keep sending the same packet until the other side acknowledges it. Unix always uses a window size of 3, which is the max that can be dealt with given the 3-bit packet numbers (for reasons that would take more space than I want to spend here). This gives much better throughput, but requires full duplex serial port handling and more complicated acknowledgement strategies. In receiving data, the "g" protocol scans for a DLE (hex 10) which indicates the start of a packet, and the next 5 bytes are read and checked. If they pass, this is a good packet and it is acted upon. (If it's a data packet, we have to read in and check the data part too.) If the checks fail, all the bytes read so far should be rescanned for another DLE, since it's possible that some characters were dropped and the first DLE we saw was actually part of a data packet. Other protocol modules have been implemented; e.g. the "f" protocol which eliminates the packets and acknowledgements, for reduced overhead when running over an error-free, flow controlled connection on an X.25 network. There has been talk of a "z" protocol which implements ZMODEM. So far, none of these modules are supplied with gnuucp, though "f" is public domain and "z" is intended to be, because they are not ported and tested yet. At the start of a call, the caller sends the list of protocols it supports, and the callee picks the best one it knows and says "use this one please". At the low level, full 8-bit bytes are sent out and received on an async serial port. */