// netstring -- netstring format serialization library // Copyright (C) 2015-2024 Sergey Matveev // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, version 3 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . package main import ( "flag" "fmt" "io" "os" "strconv" "go.cypherpunks.ru/netstring/v2" ) func usage() { fmt.Fprintf(os.Stderr, "ns -- Work with netstring encoded files\n\n") fmt.Fprintf(os.Stderr, "Usage: %s list FILE\n", os.Args[0]) fmt.Fprintf(os.Stderr, " %s read FILE CHUNK > data\n", os.Args[0]) fmt.Fprintf(os.Stderr, " %s write FILE ... > data\n", os.Args[0]) fmt.Fprintf(os.Stderr, "FILE can be \"-\" for reading from stdin\n") os.Exit(1) } func fileRead(path string) io.Reader { if path == "-" { return os.Stdin } fd, err := os.Open(path) if err != nil { panic(err) } return fd } func main() { flag.Usage = usage flag.Parse() if len(os.Args) < 3 { usage() } switch os.Args[1] { case "list": r := netstring.NewReader(fileRead(os.Args[2])) for i := 0; ; i++ { size, err := r.Next() if err == io.EOF { break } if err != nil { panic(err) } fmt.Printf("%d\t%d\n", i, size) r.Discard() } case "read": if len(os.Args) != 4 { usage() } chunk, err := strconv.Atoi(os.Args[3]) if err != nil { panic(err) } r := netstring.NewReader(fileRead(os.Args[2])) for i := 0; i < chunk; i++ { _, err = r.Next() if err != nil { panic(err) } r.Discard() } _, err = r.Next() if err != nil { panic(err) } if _, err = io.Copy(os.Stdout, r); err != nil { panic(err) } case "write": w := netstring.NewWriter(os.Stdout) for i, fn := range os.Args[2:] { fd, err := os.Open(fn) if err != nil { panic(err) } fi, err := fd.Stat() if err != nil { panic(err) } size := uint64(fi.Size()) if _, err = w.WriteSize(size); err != nil { panic(err) } if _, err = io.Copy(w, fd); err != nil { panic(err) } fmt.Fprintf(os.Stderr, "%d\t%d\t%s\n", i, size, fn) } } }