X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=src%2Fcypherpunks.ru%2Fnncp%2Fcmd%2Fnncp-xfer%2Fmain.go;h=2072a3cc956280ba6e318c21c2a51363bcaac2ce;hb=dd92823db3d72fb21a4c712a7fb052dce16443dd;hp=9c2b5e211efd96eaaa8acd1fbed765e3bcb41403;hpb=acd587140f52e9c25aae0359b2e8209c05dfa1f7;p=nncp.git diff --git a/src/cypherpunks.ru/nncp/cmd/nncp-xfer/main.go b/src/cypherpunks.ru/nncp/cmd/nncp-xfer/main.go index 9c2b5e2..2072a3c 100644 --- a/src/cypherpunks.ru/nncp/cmd/nncp-xfer/main.go +++ b/src/cypherpunks.ru/nncp/cmd/nncp-xfer/main.go @@ -1,11 +1,10 @@ /* NNCP -- Node to Node copy, utilities for store-and-forward data exchange -Copyright (C) 2016-2017 Sergey Matveev +Copyright (C) 2016-2019 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, either version 3 of the License, or -(at your option) any later version. +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 @@ -16,7 +15,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -// Copy NNCP inbound and outbounds packets +// Exchange NNCP inbound and outbounds packets with external directory. package main import ( @@ -36,24 +35,26 @@ import ( func usage() { fmt.Fprintf(os.Stderr, nncp.UsageHeader()) - fmt.Fprintln(os.Stderr, "nncp-xfer -- copy inbound and outbounds packets\n") + fmt.Fprintf(os.Stderr, "nncp-xfer -- copy inbound and outbounds packets\n\n") fmt.Fprintf(os.Stderr, "Usage: %s [options] DIR\nOptions:\n", os.Args[0]) flag.PrintDefaults() } func main() { var ( - cfgPath = flag.String("cfg", nncp.DefaultCfgPath, "Path to configuration file") - nodeRaw = flag.String("node", "", "Process only that node") - niceRaw = flag.Int("nice", 255, "Minimal required niceness") - rxOnly = flag.Bool("rx", false, "Only receive packets") - txOnly = flag.Bool("tx", false, "Only transfer packets") - force = flag.Bool("force", false, "Force outbound directories creation") - keep = flag.Bool("keep", false, "Do not delete transferred packets") - quiet = flag.Bool("quiet", false, "Print only errors") - debug = flag.Bool("debug", false, "Print debug messages") - version = flag.Bool("version", false, "Print version information") - warranty = flag.Bool("warranty", false, "Print warranty information") + cfgPath = flag.String("cfg", nncp.DefaultCfgPath, "Path to configuration file") + nodeRaw = flag.String("node", "", "Process only that node") + niceRaw = flag.String("nice", nncp.NicenessFmt(255), "Minimal required niceness") + rxOnly = flag.Bool("rx", false, "Only receive packets") + txOnly = flag.Bool("tx", false, "Only transfer packets") + mkdir = flag.Bool("mkdir", false, "Create necessary outbound directories") + keep = flag.Bool("keep", false, "Do not delete transferred packets") + spoolPath = flag.String("spool", "", "Override path to spool") + logPath = flag.String("log", "", "Override path to logfile") + quiet = flag.Bool("quiet", false, "Print only errors") + debug = flag.Bool("debug", false, "Print debug messages") + version = flag.Bool("version", false, "Print version information") + warranty = flag.Bool("warranty", false, "Print warranty information") ) flag.Usage = usage flag.Parse() @@ -69,24 +70,18 @@ func main() { usage() os.Exit(1) } - if *niceRaw < 1 || *niceRaw > 255 { - log.Fatalln("-nice must be between 1 and 255") + nice, err := nncp.NicenessParse(*niceRaw) + if err != nil { + log.Fatalln(err) } - nice := uint8(*niceRaw) if *rxOnly && *txOnly { log.Fatalln("-rx and -tx can not be set simultaneously") } - cfgRaw, err := ioutil.ReadFile(nncp.CfgPathFromEnv(cfgPath)) - if err != nil { - log.Fatalln("Can not read config:", err) - } - ctx, err := nncp.CfgParse(cfgRaw) + ctx, err := nncp.CtxFromCmdline(*cfgPath, *spoolPath, *logPath, *quiet, *debug) if err != nil { - log.Fatalln("Can not parse config:", err) + log.Fatalln("Error during initialization:", err) } - ctx.Quiet = *quiet - ctx.Debug = *debug var nodeOnly *nncp.Node if *nodeRaw != "" { @@ -96,7 +91,7 @@ func main() { } } - selfPath := filepath.Join(flag.Arg(0), ctx.Self.Id.String()) + selfPath := filepath.Join(flag.Arg(0), ctx.SelfId.String()) isBad := false var dir *os.File var fis []os.FileInfo @@ -166,6 +161,7 @@ func main() { } filename := filepath.Join(dir.Name(), fiInt.Name()) sds["file"] = filename + delete(sds, "size") fd, err := os.Open(filename) if err != nil { ctx.LogE("nncp-xfer", nncp.SdsAdd(sds, nncp.SDS{"err": err}), "open") @@ -174,7 +170,7 @@ func main() { } var pktEnc nncp.PktEnc _, err = xdr.Unmarshal(fd, &pktEnc) - if err != nil || pktEnc.Magic != nncp.MagicNNCPEv1 { + if err != nil || pktEnc.Magic != nncp.MagicNNCPEv4 { ctx.LogD("nncp-xfer", sds, "is not a packet") fd.Close() continue @@ -184,13 +180,18 @@ func main() { fd.Close() continue } + sds["size"] = strconv.FormatInt(fiInt.Size(), 10) + if !ctx.IsEnoughSpace(fiInt.Size()) { + ctx.LogE("nncp-xfer", sds, "is not enough space") + fd.Close() + continue + } fd.Seek(0, 0) tmp, err := ctx.NewTmpFileWHash() if err != nil { log.Fatalln(err) } - copied, err := io.Copy(tmp.W, bufio.NewReader(fd)) - if err != nil { + if _, err = io.CopyN(tmp.W, bufio.NewReader(fd), fiInt.Size()); err != nil { ctx.LogE("nncp-xfer", nncp.SdsAdd(sds, nncp.SDS{"err": err}), "copy") isBad = true fd.Close() @@ -205,9 +206,7 @@ func main() { )); err != nil { log.Fatalln(err) } - ctx.LogI("nncp-xfer", nncp.SdsAdd(sds, nncp.SDS{ - "size": strconv.FormatInt(copied, 10), - }), "") + ctx.LogI("nncp-xfer", sds, "") if !*keep { if err = os.Remove(filename); err != nil { ctx.LogE("nncp-xfer", nncp.SdsAdd(sds, nncp.SDS{"err": err}), "remove") @@ -241,7 +240,7 @@ Tx: if err != nil { if os.IsNotExist(err) { ctx.LogD("nncp-xfer", sds, "does not exist") - if !*force { + if !*mkdir { ctx.UnlockDir(dirLock) continue } @@ -258,7 +257,7 @@ Tx: continue } } - dstPath := filepath.Join(nodePath, ctx.Self.Id.String()) + dstPath := filepath.Join(nodePath, ctx.SelfId.String()) sds["dir"] = dstPath _, err = os.Stat(dstPath) if err != nil { @@ -285,6 +284,16 @@ Tx: job.Fd.Close() continue } + if _, err = os.Stat(filepath.Join(dstPath, pktName)); err == nil || !os.IsNotExist(err) { + ctx.LogD("nncp-xfer", sds, "already exists") + job.Fd.Close() + continue + } + if _, err = os.Stat(filepath.Join(dstPath, pktName+nncp.SeenSuffix)); err == nil || !os.IsNotExist(err) { + ctx.LogD("nncp-xfer", sds, "already exists") + job.Fd.Close() + continue + } tmp, err := ioutil.TempFile(dstPath, "nncp-xfer") if err != nil { ctx.LogE("nncp-xfer", nncp.SdsAdd(sds, nncp.SDS{"err": err}), "mktemp") @@ -303,19 +312,25 @@ Tx: isBad = true continue } - err = bufW.Flush() - tmp.Sync() - tmp.Close() - if err != nil { - ctx.LogE("nncp-xfer", nncp.SdsAdd(sds, nncp.SDS{"err": err}), "copy") + if err = bufW.Flush(); err != nil { + tmp.Close() + ctx.LogE("nncp-xfer", nncp.SdsAdd(sds, nncp.SDS{"err": err}), "flush") + isBad = true + continue + } + if err = tmp.Sync(); err != nil { + tmp.Close() + ctx.LogE("nncp-xfer", nncp.SdsAdd(sds, nncp.SDS{"err": err}), "sync") isBad = true continue } + tmp.Close() if err = os.Rename(tmp.Name(), filepath.Join(dstPath, pktName)); err != nil { ctx.LogE("nncp-xfer", nncp.SdsAdd(sds, nncp.SDS{"err": err}), "rename") isBad = true continue } + os.Remove(filepath.Join(dstPath, pktName+".part")) delete(sds, "tmp") ctx.LogI("nncp-xfer", nncp.SdsAdd(sds, nncp.SDS{ "size": strconv.FormatInt(copied, 10),