func GetFileCore(request *GetFileRequest) { conn := request.Socket file := request.File commandParameters := request.FileName if request.VerifyMode { commandParameters = fmt.Sprintf("%s -v", commandParameters) } // Send the command err := common.WriteMessage("get", commandParameters, conn) if err != nil { fmt.Println("Error writing command:", err) return } // Read the status response command, value, err := common.ReadMessage(conn.Reader) if err != nil { fmt.Println("Error reading status:", err) return } if command == "error" { fmt.Println("Server sent error:", value) return } if command != "length" { fmt.Printf("Unexpected message type '%s'\n", command) return } segments := strings.Split(value, " ") var hash string if request.VerifyMode { hash = segments[1] } length, err := strconv.Atoi(segments[0]) if err != nil { fmt.Printf("Protocol error: %s. DEBUG: %s", err, segments[0]) return } fmt.Printf("Status OK, starting transfer of %d bytes\n", length) hasher := md5.New() totalRead := 0 buffer := make([]byte, 1024) for totalRead < length { read, err := conn.Read(buffer) if err == io.EOF { break } if err != nil { fmt.Printf("Error reading from network: %s. Aborting transfer\n", err) return } _, err = file.Write(buffer[:read]) if err != nil { fmt.Println("Error writing to file; aborting transfer") return } if request.Udp { conn.Write([]byte("get-ack")) } hasher.Write(buffer[:read]) totalRead += read } if totalRead == length { fmt.Println("Transfer complete") realHash := hex.EncodeToString(hasher.Sum([]byte{})) if request.VerifyMode && (len(realHash) == 0 || len(hash) == 0) { fmt.Println("Checksum calculation failed") } else if request.VerifyMode { if realHash == hash { fmt.Printf("Checksum OK") } else { fmt.Println("Checksum failed; file is corrupt") fmt.Println("Expected: ", hash) fmt.Println("Actual: ", realHash) } } } else { fmt.Println("Connection closed before transfer completed. File contents are likely incomplete.") } }
func ReadFileHandler(parameters string, connection io.ReadWriter) { args := strings.Split(parameters, " ") var verify bool flagSet := flag.NewFlagSet("", flag.ContinueOnError) flagSet.BoolVar(&verify, "v", false, "Verify") flagSet.Parse(args[1:]) fileName := args[0] log.Printf("Request for file '%s'", fileName) file, err := os.Open(fileName) if err != nil { common.WriteError(connection, err) return } stat, err := file.Stat() if err != nil { common.WriteError(connection, err) file.Close() return } hash, err := common.GetHash(file) if err != nil { log.Println("Hash calculation failed") file.Close() return } lengthParameters := fmt.Sprintf("%d", stat.Size()) if verify { lengthParameters = fmt.Sprintf("%s %s", lengthParameters, hash) } common.WriteMessage("length", lengthParameters, connection) buffer := make([]byte, 1024) for { // Read into buffer len, err := file.Read(buffer) // EOF? if err == io.EOF { log.Println("Transfer completed") break } // Some other error if err != nil { log.Println("Error reading file; abandoning transfer") break } // Write to socket _, err = connection.Write(buffer[:len]) if err != nil { log.Println("Failed to write data to socket; abandoning transfer") } } file.Close() }
func putFile(conn *bufio.ReadWriter, file *os.File, source string, conntype int) { // Send the command err := common.WriteMessage("put", source, conn) if err != nil { fmt.Println("Error writing command:", err) return } // Read the status response command, value, err := common.ReadMessage(conn.Reader) if err != nil { fmt.Println("Error reading status:", err) return } if command == "ok" { fmt.Printf("Status OK, starting transfer of %d bytes\n", source) buffer := make([]byte, 1024) if err != nil { fmt.Println("Client file error:", file) return } if conntype == 0 { for { n, err := file.Read(buffer) if err == io.EOF { fmt.Println("Transfer complete") break } bytes := []byte(buffer) _, err = conn.Write(bytes[0:n]) } } else if conntype == 1 { for { file := context.file buffer := make([]byte, 1024) // Read into buffer len, err := file.Read(buffer) if len > 0 { // Write to socket bytes := []byte(buffer) _, err = conn.Write(bytes[0:n]) if err != nil { log.Println("Failed to write data to socket; abandoning transfer") } } // EOF? if err == io.EOF { log.Println("Transfer completed") break } // Some other error if err != nil { log.Println("Error reading file; abandoning transfer") return } for { if message != "put-ack" { log.Println("Protocol error: expected get-ack") continue } break } } } command, value, err := common.ReadMessage(conn.Reader) if err != nil { fmt.Println("Error reading status:", err) return } if command == "error" { fmt.Println("Server sent error:", value) return } } else if command == "error" { fmt.Println("Server sent error:", value) return } else { fmt.Printf("Unexpected message type '%s'\n", command) return } }