// sendReadRequest send RRQ to server and negotiates transfer options // // If the server doesn't support options and responds with data, the data will be added // to rxBuf. func (c *conn) sendReadRequest(filename string, opts map[string]string) error { // Build RRQ c.tx.writeReadReq(filename, c.mode, opts) // Send request if err := c.sendRequest(); err != nil { return wrapError(err, "sending RRQ") } // Should have received OACK if server supports options, or DATA if not switch op := c.rx.opcode(); op { case opCodeOACK: // Got OACK, parse options if err := c.readSetup(); err != nil { return wrapError(err, "got OACK, read setup") } case opCodeDATA: // Server doesn't support options, // write data to the buf so it's available for reading var writer io.Writer = &c.rxBuf if c.mode == ModeNetASCII { na := netascii.NewWriter(writer) defer errorDefer(na.Flush, c.log, "error flushing netascii encoder") writer = na } n, err := writer.Write(c.rx.data()) if err != nil { return wrapError(err, "writing RRQ response data") } // Set optionsParsed c.optionsParsed = true // If less than blksize, we're done if n < int(c.blksize) { c.done = true } // Ack data if err := c.sendAck(c.rx.block()); err != nil { return wrapError(err, "sending ACK for RRQ DATA") } c.block = c.rx.block() case opCodeERROR: // Received an error return wrapError(c.remoteError(), "RRQ OACK response") default: return wrapError(&errUnexpectedDatagram{dg: c.rx.String()}, "RRQ OACK response") } return nil }
// Write implements io.Writer and wraps write(). // // If mode is ModeNetASCII, wrap write() with netascii.EncodeWriter. func (c *conn) Write(p []byte) (int, error) { // Can't write if an error has been sent/received if c.err != nil { return 0, wrapError(c.err, "checking conn err before Write") } if c.mode == ModeNetASCII { if c.netasciiEnc == nil { c.netasciiEnc = netascii.NewWriter(writerFunc(c.write)) } n, err := c.netasciiEnc.Write(p) return n, wrapError(err, "writing through netascii encoder") } n, err := c.write(p) return n, wrapError(err, "writing through standard writer") }