+++ /dev/null
-[submodule "src/cypherpunks.ru/nncp/vendor/github.com/davecgh/go-xdr"]
- path = src/cypherpunks.ru/nncp/vendor/github.com/davecgh/go-xdr
- url = https://github.com/davecgh/go-xdr.git
-[submodule "src/cypherpunks.ru/nncp/vendor/github.com/dustin/go-humanize"]
- path = src/cypherpunks.ru/nncp/vendor/github.com/dustin/go-humanize
- url = https://github.com/dustin/go-humanize.git
-[submodule "src/cypherpunks.ru/nncp/vendor/github.com/flynn/noise"]
- path = src/cypherpunks.ru/nncp/vendor/github.com/flynn/noise
- url = https://github.com/flynn/noise.git
-[submodule "src/cypherpunks.ru/nncp/vendor/gopkg.in/check.v1"]
- path = src/cypherpunks.ru/nncp/vendor/gopkg.in/check.v1
- url = https://github.com/go-check/check.git
- branch = v1
-[submodule "src/cypherpunks.ru/nncp/vendor/gopkg.in/yaml.v2"]
- path = src/cypherpunks.ru/nncp/vendor/gopkg.in/yaml.v2
- url = https://github.com/go-yaml/yaml.git
- branch = v2
-[submodule "src/cypherpunks.ru/nncp/vendor/golang.org/x/crypto"]
- path = src/cypherpunks.ru/nncp/vendor/golang.org/x/crypto
- url = https://go.googlesource.com/crypto
-[submodule "src/cypherpunks.ru/nncp/vendor/golang.org/x/sys"]
- path = src/cypherpunks.ru/nncp/vendor/golang.org/x/sys
- url = https://go.googlesource.com/sys
-[submodule "src/cypherpunks.ru/nncp/vendor/golang.org/x/net"]
- path = src/cypherpunks.ru/nncp/vendor/golang.org/x/net
- url = https://go.googlesource.com/net
-[submodule "src/cypherpunks.ru/nncp/vendor/github.com/gorhill/cronexpr"]
- path = src/cypherpunks.ru/nncp/vendor/github.com/gorhill/cronexpr
- url = https://github.com/gorhill/cronexpr.git
-[submodule "src/cypherpunks.ru/nncp/vendor/cypherpunks.ru/balloon"]
- path = src/cypherpunks.ru/nncp/vendor/cypherpunks.ru/balloon
- url = git://git.cypherpunks.ru/balloon.git
+++ /dev/null
-VERSION != cat VERSION
-GO ?= go
-
-GO_MOD_EXISTS != $(GO) help mod >/dev/null 2>&1 || echo no
-
-.if ${GO_MOD_EXISTS} == "no"
-BUILDMOD ?=
-GOPATH ?= $(PWD)
-.else
-BUILDMOD ?= -mod=vendor
-GOPATH ?= $(PWD)/gopath
-.endif
-
-include common.mk
+++ /dev/null
-VERSION = $(shell cat VERSION)
-GO ?= go
-
-GO_MOD_EXISTS = $(shell $(GO) help mod >/dev/null 2>&1 || echo no)
-
-ifeq ($(GO_MOD_EXISTS), no)
-BUILDMOD ?=
-GOPATH ?= $(PWD)
-else
-BUILDMOD ?= -mod=vendor
-GOPATH ?= $(PWD)/gopath
-endif
-
-include common.mk
--- /dev/null
+GOPATH != pwd
+VERSION != cat VERSION
+
+GO ?= go
+PREFIX ?= /usr/local
+
+SENDMAIL ?= /usr/sbin/sendmail
+CFGPATH ?= $(PREFIX)/etc/nncp.hjson
+SPOOLPATH ?= /var/spool/nncp
+LOGPATH ?= /var/spool/nncp/log
+
+BINDIR = $(DESTDIR)$(PREFIX)/bin
+INFODIR = $(DESTDIR)$(PREFIX)/info
+DOCDIR = $(DESTDIR)$(PREFIX)/share/doc/nncp
+
+MOD = go.cypherpunks.ru/nncp/v5
+
+LDFLAGS = \
+ -X $(MOD).Version=$(VERSION) \
+ -X $(MOD).DefaultCfgPath=$(CFGPATH) \
+ -X $(MOD).DefaultSendmailPath=$(SENDMAIL) \
+ -X $(MOD).DefaultSpoolPath=$(SPOOLPATH) \
+ -X $(MOD).DefaultLogPath=$(LOGPATH)
+
+ALL = \
+ $(BIN)/nncp-bundle \
+ $(BIN)/nncp-call \
+ $(BIN)/nncp-caller \
+ $(BIN)/nncp-cfgenc \
+ $(BIN)/nncp-cfgmin \
+ $(BIN)/nncp-cfgnew \
+ $(BIN)/nncp-check \
+ $(BIN)/nncp-daemon \
+ $(BIN)/nncp-exec \
+ $(BIN)/nncp-file \
+ $(BIN)/nncp-freq \
+ $(BIN)/nncp-log \
+ $(BIN)/nncp-pkt \
+ $(BIN)/nncp-reass \
+ $(BIN)/nncp-rm \
+ $(BIN)/nncp-stat \
+ $(BIN)/nncp-toss \
+ $(BIN)/nncp-xfer
+
+SRC := $(PWD)/src
+BIN := $(PWD)/bin
+
+all: $(ALL)
+
+$(ALL):
+ mkdir -p $(BIN)
+ cd $(SRC) ; GOPATH=$(GOPATH) $(GO) build -ldflags "$(LDFLAGS)" \
+ $(MOD)/cmd/$$(basename $@)
+ mv $(SRC)/$$(basename $@) $(BIN)
+
+test:
+ cd $(SRC) ; GOPATH=$(GOPATH) $(GO) test -failfast $(MOD)/...
+
+clean:
+ rm -rf $(BIN)
+
+.PHONY: doc
+
+doc:
+ $(MAKE) -C doc
+
+install: all doc
+ mkdir -p $(BINDIR)
+ cp -f $(ALL) $(BINDIR)
+ for e in $(ALL) ; do chmod 755 $(BINDIR)/$$(basename $$e) ; done
+ mkdir -p $(INFODIR)
+ cp -f doc/nncp.info $(INFODIR)
+ chmod 644 $(INFODIR)/nncp.info
+ mkdir -p $(DOCDIR)
+ cp -f -L AUTHORS NEWS NEWS.RU README README.RU THANKS $(DOCDIR)
+ chmod 644 $(DOCDIR)/*
+
+install-strip: install
+ for e in $(ALL) ; do strip $(BINDIR)/$$(basename $$e) ; done
NNCP is copylefted free software: see the file COPYING for copying
conditions. It should work on all POSIX-compatible systems. Easy
-integration with existing SMTP servers. Single YAML configuration file.
+integration with existing SMTP servers. Single Hjson configuration file.
Home page: http://www.nncpgo.org/
NNCP это свободное программное обеспечением: условия распространения
находятся в файле COPYING. Оно должно работать на всех POSIX-совместимых
системах. Лёгкая интеграция с существующими SMTP серверами. Единственный
-конфигурационный YAML файл.
+конфигурационный Hjson файл.
Домашняя страница: http://www.nncpgo.org/
+++ /dev/null
-PREFIX ?= /usr/local
-
-SENDMAIL ?= /usr/sbin/sendmail
-CFGPATH ?= $(PREFIX)/etc/nncp.yaml
-SPOOLPATH ?= /var/spool/nncp
-LOGPATH ?= /var/spool/nncp/log
-
-BINDIR = $(DESTDIR)$(PREFIX)/bin
-INFODIR = $(DESTDIR)$(PREFIX)/info
-DOCDIR = $(DESTDIR)$(PREFIX)/share/doc/nncp
-
-LDFLAGS = \
- -X cypherpunks.ru/nncp.Version=$(VERSION) \
- -X cypherpunks.ru/nncp.DefaultCfgPath=$(CFGPATH) \
- -X cypherpunks.ru/nncp.DefaultSendmailPath=$(SENDMAIL) \
- -X cypherpunks.ru/nncp.DefaultSpoolPath=$(SPOOLPATH) \
- -X cypherpunks.ru/nncp.DefaultLogPath=$(LOGPATH)
-
-ALL = \
- nncp-bundle \
- nncp-call \
- nncp-caller \
- nncp-cfgenc \
- nncp-cfgmin \
- nncp-cfgnew \
- nncp-check \
- nncp-daemon \
- nncp-exec \
- nncp-file \
- nncp-freq \
- nncp-log \
- nncp-pkt \
- nncp-reass \
- nncp-rm \
- nncp-stat \
- nncp-toss \
- nncp-xfer
-
-SRC := $(PWD)/src/cypherpunks.ru/nncp
-BIN := $(PWD)/bin
-
-all: $(ALL)
-
-$(BIN):
- mkdir -p $(BIN)
-
-$(ALL): $(BIN)
- cd $(SRC) ; GOPATH=$(GOPATH) $(GO) build $(BUILDMOD) -ldflags "$(LDFLAGS)" cypherpunks.ru/nncp/cmd/$@
- mv $(SRC)/$@ $(BIN)
-
-test:
- cd $(SRC) ; GOPATH=$(GOPATH) $(GO) test $(BUILDMOD) -failfast cypherpunks.ru/nncp/...
-
-clean:
- rm -rf bin
-
-.PHONY: doc
-
-doc:
- $(MAKE) -C doc
-
-install: all doc
- mkdir -p $(BINDIR)
- (cd bin ; cp -f $(ALL) $(BINDIR))
- for e in $(ALL) ; do chmod 755 $(BINDIR)/$$e ; done
- mkdir -p $(INFODIR)
- cp -f doc/nncp.info $(INFODIR)
- chmod 644 $(INFODIR)/nncp.info
- mkdir -p $(DOCDIR)
- cp -f -L AUTHORS NEWS NEWS.RU README README.RU THANKS $(DOCDIR)
- chmod 644 $(DOCDIR)/*
-
-install-strip: install
- for e in $(ALL) ; do strip $(BINDIR)/$$e ; done
nncp.html: *.texi sp.utxt pedro.txt
rm -f nncp.html/*.html
$(MAKEINFO) --html \
+ --set-customization-variable EXTRA_HEAD='<link rev="made" href="mailto:stargrave+webmaster@nncpgo.org">' \
--set-customization-variable CSS_LINES='$(CSS)' \
--set-customization-variable SHOW_TITLE=0 \
--set-customization-variable USE_ACCESSKEY=0 \
NNCP это @url{https://www.gnu.org/philosophy/pragmatic.ru.html,
копилефт} @url{https://www.gnu.org/philosophy/free-sw.ru.html, свободное
программное обеспечение}: лицензировано под условиями
-@url{https://www.gnu.org/licenses/gpl-3.0.ru.html, GNU GPLv3+}. Оно
+@url{https://www.gnu.org/licenses/gpl-3.0.ru.html, GNU GPLv3}. Оно
должно работать на всех @url{https://ru.wikipedia.org/wiki/POSIX,
POSIX}-совместимых системах. Лёгкая @ref{Integration, интеграция} с
существующими @url{https://ru.wikipedia.org/wiki/SMTP, SMTP} серверами.
-Единственный конфигурационный @url{http://yaml.org/, YAML} файл.
+Единственный конфигурационный @url{https://hjson.org/, Hjson} файл.
Зачем создавать ещё одно решение с принципом сохранить-и-переслать когда
уже существуют UUCP, FTN и даже SMTP? Посмотрите @ref{Сравнение, сравнение}!
NNCP is @url{https://www.gnu.org/philosophy/pragmatic.html, copylefted}
@url{https://www.gnu.org/philosophy/free-sw.html, free software}
-licenced under @url{https://www.gnu.org/licenses/gpl-3.0.html, GNU GPLv3+}.
+licenced under @url{https://www.gnu.org/licenses/gpl-3.0.html, GNU GPLv3}.
It should work on all @url{https://en.wikipedia.org/wiki/POSIX,
POSIX}-compatible systems. Easy @ref{Integration, integration} with existing
@url{https://en.wikipedia.org/wiki/SMTP, SMTP} servers. Single
-@url{http://yaml.org/, YAML} configuration file.
+@url{https://hjson.org/, Hjson} configuration file.
Why create yet another store-and-forward solution when UUCP, FTN and
even SMTP exists? Look in @ref{Comparison, comparison} section!
--- /dev/null
+@node Build-instructions
+@section Build instructions
+
+Make sure that Go is installed. For example to install it from packages:
+
+@table @asis
+@item FreeBSD
+ @verb{|pkg install go|}
+@item Debian, Ubuntu
+ @verb{|apt install golang|}
+@end table
+
+@verbatim
+$ [fetch|wget] http://www.nncpgo.org/download/nncp-5.0.0.tar.xz
+$ [fetch|wget] http://www.nncpgo.org/download/nncp-5.0.0.tar.xz.sig
+$ gpg --verify nncp-5.0.0.tar.xz.sig nncp-5.0.0.tar.xz
+$ xz --decompress --stdout nncp-5.0.0.tar.xz | tar xf -
+$ make -C nncp-5.0.0 all
+@end verbatim
+
+There is @command{install} make-target respecting @env{DESTDIR}. It will
+install binaries and info-documentation:
+
+@verbatim
+# make -C nncp-5.0.0 install PREFIX=/usr/local
+@end verbatim
@item They do not require intermediate storage before recording on
either CD-ROM or tape drive.
@verbatim
-% nncp-bundle -tx SOMENODE | cdrecord -tao - # record directly to CD
-% nncp-bundle -tx SOMENODE | dd of=/dev/sa0 bs=10240 # record directly to tape
+$ nncp-bundle -tx SOMENODE | cdrecord -tao - # record directly to CD
+$ nncp-bundle -tx SOMENODE | dd of=/dev/sa0 bs=10240 # record directly to tape
-% dd if=/dev/cd0 bs=2048 | nncp-bundle -rx # read directly from CD
-% dd if=/dev/sa0 bs=10240 | nncp-bundle -rx # read directly from tape
+$ dd if=/dev/cd0 bs=2048 | nncp-bundle -rx # read directly from CD
+$ dd if=/dev/sa0 bs=10240 | nncp-bundle -rx # read directly from tape
@end verbatim
@item They do not require filesystem existence to deal with, simplifying
filesystems. No @command{mount}/@command{umount}, @command{zpool
import}/@command{zpool export} and struggling with file permissions.
@verbatim
-% nncp-bundle -tx SOMENODE | dd of=/dev/da0 bs=1M # record directly to
+$ nncp-bundle -tx SOMENODE | dd of=/dev/da0 bs=1M # record directly to
# hard/flash drive
-% dd if=/dev/da0 bs=1M | nncp-bundle -rx # read directly from drive
+$ dd if=/dev/da0 bs=1M | nncp-bundle -rx # read directly from drive
@end verbatim
@item This is the fastest way to record outbound packets for offline
Example list of call structures:
@verbatim
-calls:
- -
- cron: "*/1 * * * MON-FRI"
- onlinedeadline: 3600
- nice: PRIORITY+10
- -
- cron: "30 * * * SAT,SUN"
- onlinedeadline: 1800
- maxonlinetime: 1750
- nice: NORMAL
- rxrate: 10
- txrate: 20
- -
- cron: "0 * * * SAT,SUN"
- xx: rx
- addr: lan
+calls: [
+ {
+ cron: "*/1 * * * MON-FRI"
+ onlinedeadline: 3600
+ nice: PRIORITY+10
+ },
+ {
+ cron: "30 * * * SAT,SUN"
+ onlinedeadline: 1800
+ maxonlinetime: 1750
+ nice: NORMAL
+ rxrate: 10
+ txrate: 20
+ },
+ {
+ cron: "0 * * * SAT,SUN"
+ xx: rx
+ addr: lan
+ },
+]
@end verbatim
tells that on work days of the week call that node every minute,
@node Configuration
@unnumbered Configuration file
-Example YAML configuration file:
+Example @url{https://hjson.org/, Hjson} configuration file:
@verbatim
-spool: /var/spool/nncp
-log: /var/spool/nncp/log
-notify:
- file:
- from: nncp@localhost
- to: user+file@example.com
- freq:
- from: nncp@localhost
- to: user+freq@example.com
-self:
- id: TIJQL...2NGIA
- exchpub: CYVGQ...PSEWQ
- exchprv: 65PUY...MPZ3Q
- signpub: 2NMVC...CMH5Q
- signprv: 555JD...RGD6Y
- noiseprv: D62XU...NKYPA
- noisepub: KIBKK...ESM7Q
-neigh:
- self:
+{
+ spool: /var/spool/nncp
+ log: /var/spool/nncp/log
+ umask: "022"
+
+ notify: {
+ file: {
+ from: nncp@localhost
+ to: user+file@example.com
+ }
+ freq: {
+ from: nncp@localhost
+ to: user+freq@example.com
+ }
+ }
+
+ self: {
id: TIJQL...2NGIA
exchpub: CYVGQ...PSEWQ
+ exchprv: 65PUY...MPZ3Q
signpub: 2NMVC...CMH5Q
+ signprv: 555JD...RGD6Y
+ noiseprv: D62XU...NKYPA
noisepub: KIBKK...ESM7Q
- exec:
- sendmail: [/usr/sbin/sendmail]
- alice:
- id: XJZBK...65IJQ
- exchpub: MJACJ...FAI6A
- signpub: T4AFC...N2FRQ
- noisepub: UBM5K...VI42A
- exec:
- flag: ["/usr/bin/touch", "-t"]
- incoming: /home/alice/incoming
- onlinedeadline: 1800
- maxonlinetime: 3600
- addrs:
- lan: "[fe80::1234%igb0]:5400"
- internet: alice.com:3389
- calls:
- -
- cron: "*/2 * * * *"
- bob:
- id: 2IZNP...UYGYA
- exchpub: WFLMZ...B7NHA
- signpub: GTGXG...IE3OA
- exec:
- sendmail: [/usr/sbin/sendmail]
- warcer: [/path/to/warcer.sh]
- wgeter: [/path/to/wgeter.sh]
- freq: /home/bob/pub
- freqchunked: 1024
- freqminsize: 2048
- via: [alice]
- rxrate: 10
- txrate: 20
+ }
+
+ neigh: {
+ self: {
+ id: TIJQL...2NGIA
+ exchpub: CYVGQ...PSEWQ
+ signpub: 2NMVC...CMH5Q
+ noisepub: KIBKK...ESM7Q
+ exec: {sendmail: ["/usr/sbin/sendmail"]}
+ }
+ alice: {
+ id: "XJZBK...65IJQ"
+ exchpub: MJACJ...FAI6A
+ signpub: T4AFC...N2FRQ
+ noisepub: UBM5K...VI42A
+ exec: {flag: ["/usr/bin/touch", "-t"]}
+ incoming: "/home/alice/incoming"
+ onlinedeadline: 1800
+ maxonlinetime: 3600
+ addrs: {
+ lan: "[fe80::1234%igb0]:5400"
+ internet: alice.com:3389
+ proxied: "|ssh remote.host nncp-daemon -inetd"
+ }
+ calls: [
+ {
+ cron: "*/2 * * * *"
+ },
+ ]
+ }
+ bob: {
+ id: 2IZNP...UYGYA
+ exchpub: WFLMZ...B7NHA
+ signpub: GTGXG...IE3OA
+ exec: {
+ sendmail: ["/usr/sbin/sendmail"]
+ warcer: ["/path/to/warcer.sh"]
+ wgeter: ["/path/to/wgeter.sh"]
+ }
+ freq: "/home/bob/pub"
+ freqchunked: 1024
+ freqminsize: 2048
+ via: ["alice"]
+ rxrate: 10
+ txrate: 20
+ }
+ }
+}
@end verbatim
@strong{spool} field contains an absolute path to @ref{Spool, spool}
directory. @strong{log} field contains an absolute path to @ref{Log,
log} file.
+Non-empty optional @strong{umask} will force all invoked commands to
+override their umask to specified octal mask. Useful for using with
+@ref{Shared spool, shared spool directories}.
+
@anchor{CfgNotify}
@strong{notify} section contains notification settings for successfully
tossed file and freq packets. Corresponding @strong{from} and
command, will execute:
@verbatim
-echo hello world |
- NNCP_SELF=OURNODE \
- NNCP_SENDER=REMOTE \
- NNCP_NICE=64 \
- /usr/sbin/sendmail -t ARG0 ARG1 ARG2
+NNCP_SELF=OURNODE \
+NNCP_SENDER=REMOTE \
+NNCP_NICE=64 \
+/usr/sbin/sendmail -t ARG0 ARG1 ARG2
@end verbatim
+feeding @verb{|hello world\n|} to that started @command{sendmail}
+process.
+
@anchor{CfgIncoming}
@item incoming
Full path to directory where all file uploads will be saved. May be
@anchor{CfgAddrs}
@item addrs
Dictionary containing known network addresses of the node. Each key is
-human-readable name of the link/address. Values are @verb{|addr:port|}
-pairs pointing to @ref{nncp-daemon}'s listening instance. May be omitted
-if either no direct connection exists, or @ref{nncp-call} is used with
+human-readable name of the address. For direct TCP connections use
+@verb{|host:port|} format, pointing to @ref{nncp-daemon}'s listening
+instance. Also you can pipe connection through the external command
+using @verb{#|some command#} format. @code{/bin/sh -c "some command"}
+will start and its stdin/stdout used as a connection. May be omitted if
+either no direct connection exists, or @ref{nncp-call} is used with
forced address specifying.
@anchor{CfgXxRate}
@ref{nncp-caller} won't be used to call that node.
@end table
+
+@menu
+* Shared spool directory: Shared spool.
+@end menu
+
+@node Shared spool
+@section Shared spool directory
+
+If you want to share single spool directory with multiple grouped Unix
+users, then you can @command{setgid} it and assure that umask is group
+friendly. For convenience you can set @option{umask} globally for
+invoked NNCP commands in the configuration file. For example:
+
+@verbatim
+$ chgrp nncp /usr/local/etc/nncp.hjson /var/spool/nncp
+$ chmod g+r /usr/local/etc/nncp.hjson
+$ chmod g+rwxs /var/spool/nncp
+$ echo 'umask: "007"' >> /usr/local/etc/nncp.hjson
+@end verbatim
@section nncp-bundle
@verbatim
-% nncp-bundle [options] -tx [-delete] NODE [NODE ...] > ...
-% nncp-bundle [options] -rx -delete [-dryrun] [NODE ...] < ...
-% nncp-bundle [options] -rx [-check] [-dryrun] [NODE ...] < ...
+$ nncp-bundle [options] -tx [-delete] NODE [NODE ...] > ...
+$ nncp-bundle [options] -rx -delete [-dryrun] [NODE ...] < ...
+$ nncp-bundle [options] -rx [-check] [-dryrun] [NODE ...] < ...
@end verbatim
With @option{-tx} option, this command creates @ref{Bundles, bundle} of
spool if everything is good. So it is advisable to recheck your streams:
@verbatim
-% nncp-bundle -tx ALICE BOB WHATEVER | cdrecord -tao -
-% dd if=/dev/cd0 bs=2048 | nncp-bundle -rx -delete
+$ nncp-bundle -tx ALICE BOB WHATEVER | cdrecord -tao -
+$ dd if=/dev/cd0 bs=2048 | nncp-bundle -rx -delete
@end verbatim
@option{-dryrun} option prevents any writes to the spool. This is
@section nncp-call
@verbatim
-% nncp-call [options]
+$ nncp-call [options]
[-onlinedeadline INT]
[-maxonlinetime INT]
[-rx|-tx]
You can specify what packets your want to download, by specifying
@option{-pkts} option with comma-separated list of packets identifiers.
+Each @option{NODE} can contain several uniquely identified
+@option{ADDR}esses in @ref{CfgAddrs, configuration} file. If you do
+not specify the exact one, then all will be tried until the first
+success. Optionally you can force @option{FORCEADDR} address usage,
+instead of addresses taken from configuration file. You can specify both
+@verb{|host:port|} and @verb{#|some command#} formats.
+
+Pay attention that this command runs integrity check for each completely
+received packet in the background. This can be time consuming.
+Connection could be lost during that check and remote node won't be
+notified that file is done. But after successful integrity check that
+file is renamed from @file{.part} one and when you rerun
+@command{nncp-call} again, remote node will receive completion
+notification.
+
@node nncp-caller
@section nncp-caller
@verbatim
-% nncp-caller [options] [NODE ...]
+$ nncp-caller [options] [NODE ...]
@end verbatim
Croned daemon that calls remote nodes from time to time, according to
Otherwise all nodes with specified @emph{calls} configuration
field will be called.
-@option{-onlinedeadline} overrides @ref{CfgOnlineDeadline,
-@emph{onlinedeadline}} configuration option.
-
-Each @option{NODE} can contain several uniquely identified
-@option{ADDR}esses in @ref{CfgAddrs, configuration} file. If you do
-not specify the exact one, then all will be tried until the first
-success. Optionally you can force @option{FORCEADDR} address usage,
-instead of addresses taken from configuration file.
-
-Pay attention that this command runs integrity check for each completely
-received packet in the background. This can be time consuming.
-Connection could be lost during that check and remote node won't be
-notified that file is done. But after successful integrity check that
-file is renamed from @file{.part} one and when you rerun
-@command{nncp-call} again, remote node will receive completion
-notification.
+Look @ref{nncp-call} for more information.
@node nncp-cfgenc
@section nncp-cfgenc
@verbatim
-% nncp-cfgmin [options] [-s INT] [-t INT] [-p INT] cfg.yaml > cfg.yaml.eblob
-% nncp-cfgmin [options] -d cfg.yaml.eblob > cfg.yaml
+$ nncp-cfgmin [options] [-s INT] [-t INT] [-p INT] cfg.hjson > cfg.hjson.eblob
+$ nncp-cfgmin [options] -d cfg.hjson.eblob > cfg.hjson
@end verbatim
-This command allows you to encrypt provided @file{cfg.yaml} file with
+This command allows you to encrypt provided @file{cfg.hjson} file with
the passphrase, producing @ref{EBlob, eblob}, to safely keep your
configuration file with private keys. This utility was written for users
who do not want (or can not) to use either @url{https://gnupg.org/,
@option{-dump} options parses @file{eblob} and prints parameters used
during its creation. For example:
@verbatim
-% nncp-cfgenc -dump /usr/local/etc/nncp.yaml.eblob
+$ nncp-cfgenc -dump /usr/local/etc/nncp.hjson.eblob
Strengthening function: Balloon with BLAKE2b-256
Memory space cost: 1048576 bytes
Number of rounds: 16
@section nncp-cfgmin
@verbatim
-% nncp-cfgmin [options] > stripped.yaml
+$ nncp-cfgmin [options] > stripped.hjson
@end verbatim
Print out stripped configuration version: only path to @ref{Spool,
@section nncp-cfgnew
@verbatim
-% nncp-cfgnew [options] > new.yaml
+$ nncp-cfgnew [options] [-nocomments] > new.hjson
@end verbatim
Generate new node configuration: private keys, example configuration
file and print it to stdout. You must use this command when you setup
-the new node.
+the new node. @option{-nocomments} will create configuration file
+without descriptive huge comments -- useful for advanced users.
Pay attention that private keys generation consumes an entropy from your
operating system.
@section nncp-check
@verbatim
-% nncp-check [options]
+$ nncp-check [options]
@end verbatim
Perform @ref{Spool, spool} directory integrity check. Read all files
@section nncp-daemon
@verbatim
-% nncp-daemon [options] [-maxconn INT] [-bind ADDR] [-inetd]
+$ nncp-daemon [options] [-maxconn INT] [-bind ADDR] [-inetd]
@end verbatim
Start listening TCP daemon, wait for incoming connections and run
@section nncp-exec
@verbatim
-% nncp-exec [options] NODE HANDLE [ARG0 ARG1 ...]
+$ nncp-exec [options] NODE HANDLE [ARG0 ARG1 ...]
@end verbatim
Send execution command to @option{NODE} for specified @option{HANDLE}.
node:
@verbatim
-exec:
+exec: {
sendmail: [/usr/sbin/sendmail, "-t"]
appender: ["/bin/sh", "-c", "cat >> /append"]
+}
@end verbatim
then executing @verb{|echo My message | nncp-exec -replynice 123 REMOTE
@section nncp-file
@verbatim
-% nncp-file [options] [-chunked INT] SRC NODE:[DST]
+$ nncp-file [options] [-chunked INT] SRC NODE:[DST]
@end verbatim
Send @file{SRC} file to remote @option{NODE}. @file{DST} specifies
@section nncp-freq
@verbatim
-% nncp-freq [options] NODE:SRC [DST]
+$ nncp-freq [options] NODE:SRC [DST]
@end verbatim
Send file request to @option{NODE}, asking it to send its @file{SRC}
@section nncp-log
@verbatim
-% nncp-log [options]
+$ nncp-log [options]
@end verbatim
Parse @ref{Log, log} file and print out its records in human-readable form.
@section nncp-pkt
@verbatim
-% nncp-pkt [options] < pkt
-% nncp-pkt [options] [-decompress] -dump < pkt > payload
-% nncp-pkt -overheads
+$ nncp-pkt [options] < pkt
+$ nncp-pkt [options] [-decompress] -dump < pkt > payload
+$ nncp-pkt -overheads
@end verbatim
Low level packet parser. Normally it should not be used, but can help in
And with the @option{-dump} option it will give you the actual payload
(the whole file, mail message, and so on). @option{-decompress} option
-tries to zlib-decompress the data from plain packet (useful for mail
+tries to zstd-decompress the data from plain packet (useful for mail
packets).
@option{-overheads} options print encrypted, plain and size header overheads.
@section nncp-reass
@verbatim
-% nncp-reass [options] [-dryrun] [-keep] [-dump] [-stdout] FILE.nncp.meta
-% nncp-reass [options] [-dryrun] [-keep] {-all | -node NODE}
+$ nncp-reass [options] [-dryrun] [-keep] [-dump] [-stdout] FILE.nncp.meta
+$ nncp-reass [options] [-dryrun] [-keep] {-all | -node NODE}
@end verbatim
Reassemble @ref{Chunked, chunked file} after @ref{nncp-toss, tossing}.
@section nncp-rm
@verbatim
-% nncp-rm [options] -tmp
-% nncp-rm [options] -lock
-% nncp-rm [options] -node NODE -part
-% nncp-rm [options] -node NODE -seen
-% nncp-rm [options] -node NODE [-rx] [-tx]
-% nncp-rm [options] -node NODE -pkt PKT
+$ nncp-rm [options] -tmp
+$ nncp-rm [options] -lock
+$ nncp-rm [options] -node NODE -part
+$ nncp-rm [options] -node NODE -seen
+$ nncp-rm [options] -node NODE [-rx] [-tx]
+$ nncp-rm [options] -node NODE -pkt PKT
@end verbatim
This command is aimed to delete various files from your spool directory:
@section nncp-stat
@verbatim
-% nncp-stat [options] [-node NODE]
+$ nncp-stat [options] [-node NODE]
@end verbatim
Print current @ref{Spool, spool} statistics about unsent and unprocessed
@section nncp-toss
@verbatim
-% nncp-toss [options]
+$ nncp-toss [options]
[-node NODE]
[-dryrun]
[-cycle INT]
@section nncp-xfer
@verbatim
-% nncp-xfer [options] [-node NODE] [-mkdir] [-keep] [-rx|-tx] DIR
+$ nncp-xfer [options] [-node NODE] [-mkdir] [-keep] [-rx|-tx] DIR
@end verbatim
Search for directory in @file{DIR} containing inbound packets for us and
@item Шифрование пакетов @tab Нет @tab Нет @tab @strong{Да} @tab Нет
@item Приватность метаданных @tab Нет @tab Нет @tab @strong{Да} @tab Нет
@item Проверка целостности пакетов @tab Нет @tab Нет @tab @strong{Да} @tab Нет
-@item Ð\94Ñ\80Ñ\83желÑ\8eбноÑ\81Ñ\82Ñ\8c к Ñ\84лоппинеÑ\82Ñ\83 @tab Ð\9dеÑ\82 @tab Ð\9dеÑ\82 @tab @strong{Да} @tab Нет
+@item Ð\94Ñ\80Ñ\83желÑ\8eбноÑ\81Ñ\82Ñ\8c к Ñ\84лоппинеÑ\82Ñ\83 @tab Ð\9dеÑ\82 @tab ЧаÑ\81Ñ\82иÑ\87но @tab @strong{Да} @tab Нет
@end multitable
того, из коробки не предоставляется никакого шифрования и сильной
аутентификации.
- NNCP требует редактирование единственного YAML @ref{Configuration,
+ NNCP требует редактирование единственного Hjson @ref{Configuration,
конфигурационного файла}.
@item Передача новостей
@item Packets encryption @tab No @tab No @tab @strong{Yes} @tab No
@item Metadata privacy @tab No @tab No @tab @strong{Yes} @tab No
@item Packets integrity check @tab No @tab No @tab @strong{Yes} @tab No
-@item Sneakernet friendliness @tab No @tab No @tab @strong{Yes} @tab No
+@item Sneakernet friendliness @tab No @tab Partially @tab @strong{Yes} @tab No
@end multitable
like GoldEd, not an ordinary email client. Moreover, there is no
out-of-box encryption and strong authentication involved.
- NNCP requires editing of single YAML @ref{Configuration,
+ NNCP requires editing of single Hjson @ref{Configuration,
configuration file}.
@item News transmission
@multitable @columnfractions .50 .50
@headitem Library @tab Licence
-@item @code{cypherpunks.ru/balloon} @tab GNU LGPLv3+
@item @code{github.com/davecgh/go-xdr} @tab ISC
@item @code{github.com/dustin/go-humanize} @tab MIT
@item @code{github.com/flynn/noise} @tab BSD 3-Clause
-@item @code{github.com/go-check/check} @tab BSD 2-Clause
-@item @code{github.com/go-yaml/yaml} @tab Apache License 2.0 and MIT
@item @code{github.com/gorhill/cronexpr} @tab GNU GPLv3
+@item @code{github.com/hjson/hjson-go} @tab MIT
+@item @code{github.com/klauspost/compress} @tab BSD 3-Clause
+@item @code{go.cypherpunks.ru/balloon} @tab GNU LGPLv3
@item @code{golang.org/x/crypto} @tab BSD 3-Clause
@item @code{golang.org/x/net} @tab BSD 3-Clause
@item @code{golang.org/x/sys} @tab BSD 3-Clause
@multitable {XXXXX} {XXXX-XX-XX} {XXXX KiB} {link sign} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
@headitem Version @tab Date @tab Size @tab Tarball @tab SHA256 checksum
+@item @ref{Release 4.1, 4.1} @tab 2019-05-01 @tab 1227 KiB
+@tab @url{download/nncp-4.1.tar.xz, link} @url{download/nncp-4.1.tar.xz.sig, sign}
+@tab @code{29AEC53D EC914906 D7C47194 0955A32E 2BF470E6 9B8E09D3 AF3B62D8 CC8E541E}
+
@item @ref{Release 4.0, 4.0} @tab 2019-04-28 @tab 1227 KiB
@tab @url{download/nncp-4.0.tar.xz, link} @url{download/nncp-4.0.tar.xz.sig, sign}
@tab @code{EAFA6272 22E355FC EB772A90 FC6DEA8E AE1F1695 3F48A4A3 57ADA0B4 FF918452}
--- /dev/null
+#!/bin/sh -ex
+
+tmp=$(mktemp)
+
+cleanup()
+{
+ rm -f $tmp
+}
+trap cleanup HUP PIPE INT QUIT TERM EXIT
+
+read revs
+cd $HOME/git/$1.git
+git bundle create $tmp $revs
+nncp-file -nice $NNCP_NICE $tmp $NNCP_SENDER:$1-$(date '+%Y%M%d%H%m%S').bundle
@quotation
Permission is granted to copy, distribute and/or modify this document
-under the terms of the GNU Free Documentation License, Version 1.3
-or any later version published by the Free Software Foundation;
+under the terms of the GNU Free Documentation License, Version 1.3;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled "Copying conditions".
@end quotation
@itemize
@item @url{https://www.freshports.org/net/nncp/, FreeBSD ports}
+@item @url{https://github.com/DragonFlyBSD/DPorts/tree/master/net/nncp, DragonFly BSD ports}
@item @url{https://github.com/void-linux/void-packages/blob/master/srcpkgs/nncp/template, Void Linux}
@end itemize
NNCP should run on any POSIX-compatible operating system.
NNCP is written on @url{https://golang.org/, Go} programming language
-and you have to install Go compiler (1.10+ version is highly
-recommended). @emph{Make} (BSD and GNU ones are fine) is recommended for
-convenient building. @url{https://www.gnu.org/software/texinfo/,
-Texinfo} is used for building documentation.
+and you have to install Go compiler 1.10+ version. @command{Make} (BSD
+and GNU versions are fine) is recommended for convenient building.
+@url{https://www.gnu.org/software/texinfo/, Texinfo} is used for
+building documentation (although tarballs already include it).
In general you must get @ref{Tarballs, the tarball}, check its
@ref{Integrity, integrity and authenticity} and run @command{make}.
-Look for general and @ref{Platform-specific, platform-specific}
-installation instructions.
+Look for general and platform-specific @ref{Build-instructions, build
+instructions}.
@menu
* Prepared tarballs: Tarballs.
* Tarballs integrity check: Integrity.
-* Platform-specific instructions: Platform-specific.
+* Build instructions: Build-instructions.
* Development source code: Sources.
@end menu
@include download.texi
@include integrity.texi
-@include platforms.texi
+@include building.texi
@include sources.texi
After installing @command{rss2email}, create configuration file:
@verbatim
-% r2e new rss-robot@address.com
+$ r2e new rss-robot@address.com
@end verbatim
and add feeds you want to retrieve:
@verbatim
-% r2e add https://git.cypherpunks.ru/cgit.cgi/nncp.git/atom/?h=master
+$ r2e add https://git.cypherpunks.ru/cgit.cgi/nncp.git/atom/?h=master
@end verbatim
and run the process:
@verbatim
-% r2e run
+$ r2e run
@end verbatim
@node WARCs
Simple HTML web page can be downloaded very easily for sending and
viewing it offline after:
@verbatim
-% wget http://www.example.com/page.html
+$ wget http://www.example.com/page.html
@end verbatim
But most web pages contain links to images, CSS and JavaScript files,
documents parsing and understanding page dependencies. You can download
the whole page with dependencies the following way:
@verbatim
-% wget \
+$ wget \
--page-requisites \
--convert-links \
--adjust-extension \
necessary to view @file{page.html} web page. You can create single file
compressed tarball with that directory and send it to remote node:
@verbatim
-% tar cf - www.example.com | xz -9 |
- nncp-file - remote.node:www.example.com-page.tar.xz
+$ tar cf - www.example.com | zstd |
+ nncp-file - remote.node:www.example.com-page.tar.zst
@end verbatim
But there are multi-paged articles, there are the whole interesting
sites you want to get in a single package. You can mirror the whole web
site by utilizing @command{wget}'s recursive feature:
@verbatim
-% wget \
+$ wget \
--recursive \
--timestamping \
-l inf \
@strong{WARC}. Fortunately again, @command{wget} supports it as an
output format.
@verbatim
-% wget \
+$ wget \
--warc-file www.example_com-$(date '+%Y%M%d%H%m%S') \
--no-warc-compression \
--no-warc-keep-log \
That command will create uncompressed @file{www.example_com-XXX.warc}
web archive. By default, WARCs are compressed using
@url{https://en.wikipedia.org/wiki/Gzip, gzip}, but, in example above,
-we have disabled it to compress with stronger @command{xz}, before
-sending via @command{nncp-file}.
+we have disabled it to compress with stronger and faster
+@url{https://en.wikipedia.org/wiki/Zstd, zstd}, before sending via
+@command{nncp-file}.
There are plenty of software acting like HTTP proxy for your browser,
allowing to view that WARC files. However you can extract files from
that archive using @url{https://pypi.python.org/pypi/Warcat, warcat}
utility, producing usual directory hierarchy:
@verbatim
-% python3 -m warcat extract \
+$ python3 -m warcat extract \
www.example_com-XXX.warc \
--output-dir www.example.com-XXX \
--progress
@url{http://aria2.github.io/manual/en/html/aria2c.html#files, input file}
with the jobs you want to download:
@verbatim
-% cat jobs
+$ cat jobs
http://www.nncpgo.org/download/nncp-0.11.tar.xz
out=nncp.txz
http://www.nncpgo.org/download/nncp-0.11.tar.xz.sig
out=nncp.txz.sig
-% aria2c \
+$ aria2c \
--on-download-complete aria2-downloaded.sh \
--input-file jobs
@end verbatim
easily solved with @ref{CfgExec, exec} handles.
@verbatim
-exec:
+exec: {
warcer: ["/bin/sh", "/path/to/warcer.sh"]
wgeter: ["/bin/sh", "/path/to/wgeter.sh"]
aria2c: [
"--on-download-complete", "aria2-downloaded.sh",
"--on-bt-download-complete", "aria2-downloaded.sh"
]
+}
@end verbatim
@file{warcer.sh} contents:
BitTorrents:
@verbatim
-% echo http://www.nncpgo.org/Postfix.html |
+$ echo http://www.nncpgo.org/Postfix.html |
nncp-exec remote.node warcer postfix-whole-page
-% echo http://www.nncpgo.org/Postfix.html |
+$ echo http://www.nncpgo.org/Postfix.html |
nncp-exec remote.node wgeter postfix-html-page
-% echo \
+$ echo \
http://www.nncpgo.org/download/nncp-0.11.tar.xz
http://www.nncpgo.org/download/nncp-0.11.tar.xz.sig |
nncp-exec remote.node aria2c
Use it to create bundles containing all required blobs/trees/commits and tags:
@verbatim
-% git bundle create repo-initial.bundle master --tags --branches
-% git tag -f last-bundle
-% nncp-file repo-initial.bundle remote.node:repo-$(date % '+%Y%M%d%H%m%S').bundle
+$ git bundle create repo-initial.bundle master --tags --branches
+$ git tag -f last-bundle
+$ nncp-file repo-initial.bundle remote.node:repo-$(date % '+%Y%M%d%H%m%S').bundle
@end verbatim
Do usual working with the Git: commit, add, branch, checkout, etc. When
you decide to queue your changes for sending, create diff-ed bundle and
transfer them:
@verbatim
-% git bundle create repo-$(date '+%Y%M%d%H%m%S').bundle last-bundle..master
+$ git bundle create repo-$(date '+%Y%M%d%H%m%S').bundle last-bundle..master
or maybe
-% git bundle create repo-$(date '+%Y%M%d').bundle --since=10.days master
+$ git bundle create repo-$(date '+%Y%M%d').bundle --since=10.days master
@end verbatim
Received bundle on remote machine acts like usual remote:
@verbatim
-% git clone -b master repo-XXX.bundle
+$ git clone -b master repo-XXX.bundle
@end verbatim
overwrite @file{repo.bundle} file with newer bundles you retrieve and
fetch all required branches and commits:
@verbatim
-% git pull # assuming that origin remote points to repo.bundle
-% git fetch repo.bundle master:localRef
-% git ls-remote repo.bundle
+$ git pull # assuming that origin remote points to repo.bundle
+$ git fetch repo.bundle master:localRef
+$ git ls-remote repo.bundle
@end verbatim
Bundles are also useful when cloning huge repositories (like Linux has).
bundle, you can add an ordinary @file{git://} remote and fetch the
difference.
+Also you can find the following exec-handler useful:
+@verbatiminclude git-bundler.sh
+And it allows you to request for bundles like that:
+@code{echo some-old-commit..master | nncp-exec REMOTE bundler REPONAME}.
+
@node Multimedia
@section Integration with multimedia streaming
When you multimedia becomes an ordinary file, you can transfer it easily.
@verbatim
-% youtube-dl \
+$ youtube-dl \
--exec 'nncp-file {} remote.node:' \
'https://www.youtube.com/watch?list=PLd2Cw8x5CytxPAEBwzilrhQUHt_UN10FJ'
@end verbatim
@item
@verbatim
-% gpg --keyserver hkp://keys.gnupg.net/ --recv-keys 0x2B25868E75A1A953
-% gpg --auto-key-locate dane --locate-keys releases at nncpgo dot org
-% gpg --auto-key-locate wkd --locate-keys releases at nncpgo dot org
+$ gpg --auto-key-locate dane --locate-keys releases at nncpgo dot org
+$ gpg --auto-key-locate wkd --locate-keys releases at nncpgo dot org
@end verbatim
@item
Then you could verify tarballs signature:
@verbatim
-% gpg --verify nncp-3.1.tar.xz.sig nncp-3.1.tar.xz
+$ gpg --verify nncp-5.0.0.tar.xz.sig nncp-5.0.0.tar.xz
@end verbatim
@node Новости
@section Новости
+@node Релиз 5.0.0
+@subsection Релиз 5.0.0
+@itemize
+
+@item
+@strong{Несовместимое} изменение формата конфигурационного файла:
+YAML заменён на Hjson, из-за его гораздо большей простоты, без
+заметного потеря функционала и удобства.
+
+@item
+@strong{Несовместимое} изменение формата простых пакетов. Работа со
+старыми версиями не поддерживается. @code{zlib} сжатие заменено на
+@code{Zstandard}, так как оно значительно быстрее и эффективнее, не
+смотря на то, что версия библиотеки ещё не проверена временем.
+
+@item
+Возможность соединяться с удалёнными нодами не только по TCP, но и через
+pipe вызов сторонней команды.
+
+@item
+@command{nncp-cfgnew} генерирует конфигурационный файл с множеством
+комментариев. Можно использовать @option{-nocomments} опцию для старого
+поведения.
+
+@item
+Дубликаты имён файлов имеют суффикс @file{.CTR}, вместо @file{CTR},
+чтобы избежать возможных коллизий с @file{.nncp.chunkCTR}.
+
+@item
+Возможность переопределить umask процесса через опцию конфигурационного
+файла.
+
+@item
+По умолчанию файлы и директории создаются с 666/777 правами доступа,
+позволяя управлять ими @command{umask}-ом.
+
+@item
+Обновлены зависимости.
+
+@item
+Полное использование go модулей для управления зависимостями
+(используется @code{go.cypherpunks.ru/nncp/v5} namespace).
+
+@item
+Отмена автоматического использования более новых версий GNU GPL
+(лицензия проекта GNU GPLv3-только).
+
+@end itemize
+
@node Релиз 4.1
@subsection Релиз 4.1
@itemize
-@item
-Восстановлена работоспособность на GNU/Linux системах и Go версии 1.10.
+@item Восстановлена работоспособность на GNU/Linux системах и Go версии 1.10.
@end itemize
@node Релиз 4.0
@subsection Релиз 4.0
@itemize
+
@item
@strong{Несовместимое} изменение формата зашифрованных и eblob пакетов:
используется AEAD режим шифрования с 128 КиБ блоками, так как раньше
@command{nncp-toss} не проверял MAC зашифрованного пакета прежде чем
отсылать дешифрованные данные внешней команде. Старые версии не
поддерживаются.
+
@item
Проверка доступного места перед копированием во время работы
@command{nncp-xfer}, @command{nncp-daemon}, @command{nncp-call(er)}.
+
@item
@command{nncp-call} имеет возможность только показывать список пакетов
на удалённой машине, без их передачи.
+
@item
@command{nncp-call} имеет возможность передавать только чётко указанные пакеты.
+
@item
Восстановлена работоспособность @option{xxrate} настройки в
@option{calls} секции конфигурационного файла.
+
@item
Зависимые библиотеки обновлены.
+
@item
Небольшие исправления ошибок.
+
@item
Начало использования @code{go.mod} подсистемы.
+
@end itemize
@node Релиз 3.4
@subsection Релиз 3.4
@itemize
-@item
-@command{nncp-daemon} может быть запущен как @command{inetd}-служба.
+@item @command{nncp-daemon} может быть запущен как @command{inetd}-служба.
@end itemize
@node Релиз 3.3
@subsection Релиз 3.3
@itemize
+
@item
@command{nncp-daemon}, @command{nncp-call}, @command{nncp-caller}
проверяют существование @file{.seen} файла и расценивают его как то, что
файл уже был скачан. Возможно передача данных была осуществлена
сторонним способом и удалённая сторона должна быть оповещена об этом.
+
@item
Если более высокоприоритетный пакет попадает в спул, то
@command{nncp-daemon} добавит его в очередь отправки первым, прерывая
низкоприоритетные передачи.
+
@item
К средствам связанным с online-соединениями (@command{nncp-daemon},
@command{nncp-call}, @command{nncp-caller}) добавлен простой
ограничитель скорости.
+
@item
Возможность задания приоритета символьными обозначениями:
@verb{|NORMAL|}, @verb{|BULK+10|}, @verb{|PRIORITY-5|}, итд.
+
@item
Изменены значения приоритетов по-умолчанию:
для @command{nncp-exec} с 64 на 96,
для @command{nncp-freq} с 64 на 160,
для @command{nncp-file} с 196 на 224.
+
@end itemize
@node Релиз 3.2
@node Релиз 3.0
@subsection Релиз 3.0
@itemize
+
@item
@strong{Несовместимое} изменение формата простых пакетов. Работа со
старыми версиями не поддерживается.
+
@item
Добавлена возможность удалённого исполнения команд, путём
конфигурирования @option{exec} опции конфигурационного файла и
@option{exec}. @verb{|sendmail: [...]|} нужно заменить на @verb{|exec:
sendmail: [...]|}.
@end itemize
+
@item
Возможность переопределить @option{via} опцию конфигурации для целевого
узла через @option{-via} опцию командной строки для следующих команд:
@command{nncp-file}, @command{nncp-freq}, @command{nncp-exec}.
+
@item
Chunked файлы, меньшего размера чем указанный chunk, отправляются просто
в виде одного файла.
+
@item
Exec команды вызываются с дополнительными переменными окружения
@env{NNCP_NICE} и @env{NNCP_SELF}.
+
@item
Отправляемые файлы в ответ на запрос имеют приоритет указанный в запросе.
Указать их желаемый приоритет во время вызова @command{nncp-freq} можно
аргументом @option{-replynice}.
+
@item
Команде @command{nncp-toss} можно сказать не обрабатывать определённые
типы пакетов, за счёт опций @option{-nofile}, @option{-nofreq},
@option{-noexec}, @option{-notrns}.
+
@item
По-умолчанию @command{nncp-file} команда для
@option{-minsize}/@option{-chunked} опций использует
@option{FreqMinSize}/@option{FreqChunked} из конфигурационного файла.
Это можно отключить указав нулевое значение.
+
@end itemize
@node Релиз 2.0
@subsection Релиз 2.0
@itemize
+
@item
@strong{Несовместимое} изменение формата зашифрованных и eblob пакетов.
Работа со старыми версиями не поддерживается.
+
@item
Алгоритм шифрования Twofish заменён на ChaCha20. Он намного быстрее.
Одним криптографическим примитивом меньше.
+
@item
HKDF-BLAKE2b-256 KDF алгоритм заменён на BLAKE2Xb XOF. Ещё одним
криптографическим примитивом меньше (предполагая, что BLAKE2X
практически идентичен BLAKE2).
+
@end itemize
@node Релиз 1.0
@subsection Релиз 1.0
@itemize
+
@item
@strong{Несовместимое} изменение формата зашифрованных пакетов. Работа
со старыми версиями не поддерживается.
+
@item
@command{nncp-bundle} команда может создавать потоки зашифрованных
пакетов или потреблять их. Это полезно когда речь идёт о stdin/stdout
методах передачи (например запись на CD-ROM без создания промежуточного
подготовленного ISO образа или работа с ленточными накопителями).
+
@item
@command{nncp-toss} команда может создавать @file{.seen} файлы,
предотвращая приём дублированных пакетов.
+
@item
В команде @command{nncp-call} разрешается иметь только одного
обработчика контрольной суммы в фоне. Это полезно когда тысячи маленьких
входящих пакетов могут создать много горутин.
+
@item
Возможность переопределить путь до spool директории и файла журнала
через аргумент командной строки или переменную окружения.
+
@item
@command{nncp-rm} команда может удалять все исходящие/входящие,
@file{.seen}, @file{.part}, @file{.lock} и временные файлы.
+
@end itemize
@node Релиз 0.12
@subsection Релиз 0.12
@itemize
-@item
-Команда sendmail вызывается с @env{NNCP_SENDER} переменной окружения.
+@item Команда sendmail вызывается с @env{NNCP_SENDER} переменной окружения.
@end itemize
@node Релиз 0.11
@subsection Релиз 0.11
@itemize
-@item
-Вывод команды @command{nncp-stat} отсортирован по имени ноды.
+@item Вывод команды @command{nncp-stat} отсортирован по имени ноды.
@end itemize
@node Релиз 0.10
@node Релиз 0.7
@subsection Релиз 0.7
@itemize
+
@item
Возможность предоставлять данные для @command{nncp-file} через
стандартный ввод, используя временный зашифрованный файл для этого.
а @command{nncp-mincfg} в @command{nncp-cfgmin}, для того чтобы они
имели общий префикс и были сгруппированы для удобства.
-@item Появилась команда @command{nncp-cfgenc}, позволяющая
+@item
+Появилась команда @command{nncp-cfgenc}, позволяющая
шифровать/дешифровать конфигурационный файл, чтобы безопасно его хранить
без использования OpenPGP или других подобных инструментов.
@item
Обновлены зависимые криптографические библиотеки.
+
@end itemize
@node Релиз 0.6
@node Релиз 0.5
@subsection Релиз 0.5
@itemize
-@item Тривиальное небольшое исправление в значениях приоритетов
-по-умолчанию в @command{nncp-file} и @command{nncp-freq} командах.
+@item
+Тривиальное небольшое исправление в значениях приоритетов по-умолчанию в
+@command{nncp-file} и @command{nncp-freq} командах.
@end itemize
@node Релиз 0.4
@subsection Релиз 0.4
@itemize
-@item Небольшое исправление в @command{nncp-call}, @command{nncp-caller},
+
+@item
+Небольшое исправление в @command{nncp-call}, @command{nncp-caller},
@command{nncp-daemon}: иногда они могли падать с segmentation fault
ошибкой (данные не терялись).
-@item @command{nncp-newnode} переименована в @command{nncp-newcfg} --
+
+@item
+@command{nncp-newnode} переименована в @command{nncp-newcfg} --
это короче и удобнее для использования.
-@item Появилась команда @command{nncp-mincfg}: вспомогательная утилита
+
+@item
+Появилась команда @command{nncp-mincfg}: вспомогательная утилита
позволяющая создать минималистичный урезанный конфигурационный файл без
приватных ключей, что полезно во время использования @command{nncp-xfer}.
+
@end itemize
@node Релиз 0.3
@subsection Релиз 0.3
-Исправлена совместимость с Go 1.6.
+@itemize
+@item Исправлена совместимость с Go 1.6.
+@end itemize
@node Релиз 0.2
@subsection Релиз 0.2
@itemize
-@item @strong{Несовместимое} изменение формата пакета (магическое число
-тоже изменено): поле размера пакета шифруется и не посылается в открытом
-виде.
-@item @option{-minsize} опция даёт возможность автоматически дополнять
+
+@item
+@strong{Несовместимое} изменение формата пакета (магическое число тоже
+изменено): поле размера пакета шифруется и не посылается в открытом виде.
+
+@item
+@option{-minsize} опция даёт возможность автоматически дополнять
исходящие пакеты до указанного минимального размера.
-@item @command{nncp-daemon} и
-@command{nncp-call}/@command{nncp-caller} всегда в фоне проверяют появление
-исходящих @emph{tx} пакетов пока подключены. Удалённая сторона сразу же
-оповещается об этом.
-@item @option{-onlinedeadline} опция даёт возможность выставления
-timeout-а на неактивность в online соединении, когда оно должно быть
-отключено. Она может быть использована для сохранения соединения на
-долгое время.
-@item @option{-maxonlinetime} опция даёт возможность указания
-максимального возможного времени жизни соединения.
-@item Появилась @command{nncp-caller} команда: клиент TCP-демона
-работающий по cron-у.
-@item @command{nncp-pkt} команда может разжимать данные.
+
+@item
+@command{nncp-daemon} и @command{nncp-call}/@command{nncp-caller} всегда
+в фоне проверяют появление исходящих @emph{tx} пакетов пока подключены.
+Удалённая сторона сразу же оповещается об этом.
+
+@item
+@option{-onlinedeadline} опция даёт возможность выставления timeout-а на
+неактивность в online соединении, когда оно должно быть отключено. Она
+может быть использована для сохранения соединения на долгое время.
+
+@item
+@option{-maxonlinetime} опция даёт возможность указания максимального
+возможного времени жизни соединения.
+
+@item
+Появилась @command{nncp-caller} команда: клиент TCP-демона работающий по
+cron-у.
+
+@item
+@command{nncp-pkt} команда может разжимать данные.
+
@end itemize
See also this page @ref{Новости, on russian}.
+@node Release 5.0.0
+@section Release 5.0.0
+@itemize
+
+@item
+@strong{Incompatible} configuration file format change: YAML is
+replaced with Hjson, due to its simplicity, without noticeable lack
+of either functionality or convenience.
+
+@item
+@strong{Incompatible} plain packet format changes. Older versions are
+not supported. @code{zlib} compression is replaced with
+@code{Zstandard}, due to its speed and efficiency, despite library
+version is not mature enough.
+
+@item
+Ability to call remote nodes via pipe call of external command, not only
+through TCP.
+
+@item
+@command{nncp-cfgnew} generates configuration file with many
+comments. @option{-nocomments} option can be used for an old
+behaviour.
+
+@item
+Duplicate filenames have @file{.CTR} suffix, instead of @file{CTR}, to
+avoid possible collisions with @file{.nncp.chunkCTR}.
+
+@item
+Ability to override process umask through configuration file option.
+
+@item
+Files and directories are created with 666/777 permissions by default,
+allowing control with @command{umask}.
+
+@item
+Updated dependencies.
+
+@item
+Full usage of go modules for dependencies management
+(@code{go.cypherpunks.ru/nncp/v5} namespace is used).
+
+@item
+Forbid any later GNU GPL version autousage
+(project's licence now is GNU GPLv3-only).
+
+@end itemize
+
@node Release 4.1
@section Release 4.1
@itemize
-@item
-Workability on GNU/Linux systems and Go 1.10 is fixed.
+@item Workability on GNU/Linux systems and Go 1.10 is fixed.
@end itemize
@node Release 4.0
@section Release 4.0
@itemize
+
@item
@strong{Incompatible} encrypted and eblob packet format change: AEAD
encryption mode with 128 KiB blocks is used now, because previously
@command{nncp-toss} did not verify encrypted packet's MAC before feeding
decrypted data to external command. Older versions are not supported.
+
@item
Available free space checking before copying in @command{nncp-xfer},
@command{nncp-daemon}, @command{nncp-call(er)}.
+
@item
@command{nncp-call} has ability only to list packets on remote node,
without their transmission.
+
@item
@command{nncp-call} has ability to transfer only specified packets.
+
@item
Workability of @option{xxrate} preference in @option{calls}
configuration file section.
+
@item
Dependant libraries are updated.
+
@item
Minor bugfixes.
+
@item
Begin using of @code{go.mod} subsystem.
+
@end itemize
@node Release 3.4
@section Release 3.4
@itemize
-@item
-@command{nncp-daemon} can be run as @command{inetd}-service.
+@item @command{nncp-daemon} can be run as @command{inetd}-service.
@end itemize
@node Release 3.3
@section Release 3.3
@itemize
+
@item
@command{nncp-daemon}, @command{nncp-call}, @command{nncp-caller} check
if @file{.seen} exists and treat it like file was already downloaded.
Possibly it was transferred out-of-bound and remote side needs to be
notifier about that.
+
@item
If higher priority packet is spooled, then @command{nncp-daemon} will
queue its sending first, interrupting lower priority transmissions.
+
@item
Simple packet rate limiter added to online-related tools
(@command{nncp-daemon}, @command{nncp-call}, @command{nncp-caller}).
+
@item
Ability to specify niceness with symbolic notation:
@verb{|NORMAL|}, @verb{|BULK+10|}, @verb{|PRIORITY-5|}, etc.
+
@item
Changed default niceness levels:
for @command{nncp-exec} from 64 to 96,
for @command{nncp-freq} from 64 to 160,
for @command{nncp-file} from 196 to 224.
+
@end itemize
@node Release 3.2
@node Release 3.0
@section Release 3.0
@itemize
+
@item
@strong{Incompatible} plain packet format changes. Older versions are
not supported.
+
@item
Ability to queue remote command execution, by configuring @option{exec}
option in configuration file and using @command{nncp-exec} command:
@option{exec}. @verb{|sendmail: [...]|} must be replaced with
@verb{|exec: sendmail: [...]|}.
@end itemize
+
@item
Ability to override @option{via} configuration option for destination
node via @option{-via} command line option for following commands:
@command{nncp-file}, @command{nncp-freq}, @command{nncp-exec}.
+
@item
Chunked files, having size less than specified chunk size, will be sent
as an ordinary single file.
+
@item
Exec commands are invoked with additional @env{NNCP_NICE} and
@env{NNCP_SELF} environment variables.
+
@item
Files, that are sent as a reply to freq, have niceness level taken from
the freq packet. You can set desired niceness during @command{nncp-freq}
invocation using @option{-replynice} option.
+
@item
@command{nncp-toss} command can ignore specified packet types during
processing: @option{-nofile}, @option{-nofreq}, @option{-noexec},
@option{-notrns}.
+
@item
@command{nncp-file} command uses
@option{FreqMinSize}/@option{FreqChunked} configuration file options
for @option{-minsize}/@option{-chunked} by default. You can turn this
off by specifying zero value.
+
@end itemize
@node Release 2.0
@section Release 2.0
@itemize
+
@item
@strong{Incompatible} encrypted/eblob packet format changes. Older
versions are not supported.
+
@item
Twofish encryption algorithm is replaced with ChaCha20. It is much more
faster. One cryptographic primitive less.
+
@item
HKDF-BLAKE2b-256 KDF algorithm is replaced with BLAKE2Xb XOF. Yet
another cryptographic primitive less (assuming that BLAKE2X is nearly
identical to BLAKE2).
+
@end itemize
@node Release 1.0
@section Release 1.0
@itemize
+
@item
@strong{Incompatible} encrypted packet format changes. Older versions
are not supported.
+
@item
@command{nncp-bundle} command can either create stream of encrypted
packets, or digest it. It is useful when dealing with stdin/stdout based
transmission methods (like writing to CD-ROM without intermediate
prepared ISO image and working with tape drives).
+
@item
@command{nncp-toss} is able to create @file{.seen} files preventing
duplicate packets receiving.
+
@item
Single background checksum verifier worker is allowed in
@command{nncp-call}. This is helpful when thousands of small inbound
packets could create many goroutines.
+
@item
Ability to override path to spool directory and logfile through either
command line argument, or environment variable.
+
@item
@command{nncp-rm} is able to delete outbound/inbound, @file{.seen},
@file{.part}, @file{.lock} and temporary files.
+
@end itemize
@node Release 0.12
@section Release 0.12
@itemize
-@item
-Sendmail command is called with @env{NNCP_SENDER} environment variable.
+@item Sendmail command is called with @env{NNCP_SENDER} environment variable.
@end itemize
@node Release 0.11
@section Release 0.11
@itemize
-@item
-@command{nncp-stat}'s command output is sorted by node name.
+@item @command{nncp-stat}'s command output is sorted by node name.
@end itemize
@node Release 0.10
@node Release 0.7
@section Release 0.7
@itemize
+
@item
Ability to feed @command{nncp-file} from stdin, that uses an encrypted
temporary file for that.
@item
Cryptographic libraries (dependencies) are updated.
+
@end itemize
@node Release 0.6
@node Release 0.5
@section Release 0.5
@itemize
-@item Trivial small fix in default niceness level of @command{nncp-file}
+@item
+Trivial small fix in default niceness level of @command{nncp-file}
and @command{nncp-freq} commands.
@end itemize
@node Release 0.4
@section Release 0.4
@itemize
-@item Small fix in @command{nncp-call}, @command{nncp-caller},
+
+@item
+Small fix in @command{nncp-call}, @command{nncp-caller},
@command{nncp-daemon}: they can segmentation fail sometimes (no data is
lost).
-@item @command{nncp-newnode} renamed to @command{nncp-newcfg} -- it is
-shorter and more convenient to use.
-@item @command{nncp-mincfg} command appeared: helper allowing to create
-minimalistic stripped down configuration file without private keys,
-that is useful during @command{nncp-xfer} usage.
+
+@item
+@command{nncp-newnode} renamed to @command{nncp-newcfg} -- it is shorter
+and more convenient to use.
+
+@item
+@command{nncp-mincfg} command appeared: helper allowing to create
+minimalistic stripped down configuration file without private keys, that
+is useful during @command{nncp-xfer} usage.
+
@end itemize
@node Release 0.3
@section Release 0.3
-Fixed compatibility with Go 1.6.
+@itemize
+@item Fixed compatibility with Go 1.6.
+@end itemize
@node Release 0.2
@section Release 0.2
@itemize
-@item @strong{Incompatible} packet's format change (magic number is
-changed too): size field is encrypted and is not send in plaintext
-anymore.
-@item @option{-minsize} option gives ability to automatically pad
-outgoing packets to specified minimal size.
-@item @command{nncp-daemon} and
-@command{nncp-call}/@command{nncp-caller} always check new @emph{tx}
-packets appearance in the background while connected. Remote side is
-immediately notified.
-@item @option{-onlinedeadline} option gives ability to configure timeout
-of inactivity of online connection, when it could be disconnected. It
-could be used to keep connection alive for a long time.
-@item @option{-maxonlinetime} option gives ability to set maximal
-allowable online connection aliveness time.
-@item @command{nncp-caller} command appeared: cron-ed TCP daemon caller.
-@item @command{nncp-pkt} command can decompress the data.
+
+@item
+@strong{Incompatible} packet's format change (magic number is changed
+too): size field is encrypted and is not send in plaintext anymore.
+
+@item
+@option{-minsize} option gives ability to automatically pad outgoing
+packets to specified minimal size.
+
+@item
+@command{nncp-daemon} and @command{nncp-call}/@command{nncp-caller}
+always check new @emph{tx} packets appearance in the background while
+connected. Remote side is immediately notified.
+
+@item
+@option{-onlinedeadline} option gives ability to configure timeout of
+inactivity of online connection, when it could be disconnected. It could
+be used to keep connection alive for a long time.
+
+@item
+@option{-maxonlinetime} option gives ability to set maximal allowable
+online connection aliveness time.
+
+@item
+@command{nncp-caller} command appeared: cron-ed TCP daemon caller.
+
+@item
+@command{nncp-pkt} command can decompress the data.
+
@end itemize
@headitem @tab XDR type @tab Value
@item Magic number @tab
8-byte, fixed length opaque data @tab
- @verb{|N N C P P 0x00 0x00 0x02|}
+ @verb{|N N C P P 0x00 0x00 0x03|}
@item Payload type @tab
unsigned integer @tab
0 (file), 1 (freq), 2 (exec), 3 (transition)
@itemize
@item File contents
@item Destination path for freq
-@item @url{http://zlib.net/, zlib} compressed exec body
+@item @url{https://facebook.github.io/zstd/, Zstandard} compressed exec body
@item Whole encrypted packet we need to relay on
@end itemize
+++ /dev/null
-@node Platform-specific
-@section Platform-specific instructions
-
-@node General
-@subsection General installation instructions
-
-Look @ref{Integrity, here} for finding public keys for tarball authentication.
-
-@verbatim
-% wget http://www.nncpgo.org/download/nncp-3.1.tar.xz
-% wget http://www.nncpgo.org/download/nncp-3.1.tar.xz.sig
-% gpg --verify nncp-3.1.tar.xz.sig nncp-3.1.tar.xz
-% xz -d nncp-3.1.tar.xz
-% tar xf nncp-3.1.tar
-% make -C nncp-3.1 all
-@end verbatim
-
-There is @command{install} target respecting @env{DESTDIR}. It will
-install binaries and info-documentation.
-
-@node Ubuntu
-@subsection Ubuntu installation instructions
-
-Look @ref{Integrity, here} for finding public keys for tarball authentication.
-
-@table @asis
-@item Ubuntu 16.04
-
-@verbatim
-# apt install golang
-@end verbatim
-
-follow @ref{General, general} installation instructions
-
-@verbatim
-# make -C nncp-3.1 install PREFIX=/usr
-@end verbatim
-
-@item Ubuntu 14.04
-
-@verbatim
-# apt-get install golang-1.6
-% wget http://www.nncpgo.org/download/nncp-3.1.tar.xz
-% wget http://www.nncpgo.org/download/nncp-3.1.tar.xz.sig
-% gpg --verify nncp-3.1.tar.xz.sig nncp-3.1.tar.xz
-% tar xf nncp-3.1.tar.xz
-% PATH=/usr/lib/go-1.6/bin:$PATH make -C nncp-3.1 all
-# make -C nncp-3.1 install PREFIX=/usr
-@end verbatim
-
-@end table
libraries source code. Because of that, it is recommended for porters
to use @ref{Tarballs, tarballs} instead.
-You can obtain it by cloning @url{http://git-scm.com/, Git}
-@url{https://git.cypherpunks.ru/cgit.cgi/nncp.git/log/, repository}
-and fetching dependent libraries source code as git submodules:
-
@verbatim
-% git clone git://git.cypherpunks.ru/nncp.git nncp
-% cd nncp
-% git checkout develop
-% git submodule update --init
+$ git clone git://git.cypherpunks.ru/nncp.git
+$ cd nncp
+$ git checkout develop
@end verbatim
Also there is mirror of dependent libraries for safety if their native
@item @code{github.com/davecgh/go-xdr} @tab @url{git://git.cypherpunks.ru/go-xdr.git}
@item @code{github.com/dustin/go-humanize} @tab @url{git://git.cypherpunks.ru/go-humanize.git}
@item @code{github.com/flynn/noise} @tab @url{git://git.cypherpunks.ru/noise.git}
+@item @code{github.com/google/go-cmp} @tab @url{git://git.cypherpunks.ru/go-cmp.git}
@item @code{github.com/gorhill/cronexpr} @tab @url{git://git.cypherpunks.ru/cronexpr.git}
+@item @code{github.com/hjson/hjson-go} @tab @url{git://git.cypherpunks.ru/hjson-go.git}
+@item @code{github.com/klauspost/compress} @tab @url{git://git.cypherpunks.ru/compress.git}
@item @code{golang.org/x/crypto} @tab @url{git://git.cypherpunks.ru/crypto.git}
@item @code{golang.org/x/net} @tab @url{git://git.cypherpunks.ru/net.git}
@item @code{golang.org/x/sys} @tab @url{git://git.cypherpunks.ru/sys.git}
@item @code{gopkg.in/check.v1} @tab @url{git://git.cypherpunks.ru/check.git}
-@item @code{gopkg.in/yaml.v2} @tab @url{git://git.cypherpunks.ru/yaml.git}
@end multitable
ноутбук подключён?
Одна из возможностей это войти на сервер и сделать что-то типа
-@command{postqueue -f}, но по-умолчанию у вас есть только несколько дней
+@command{postqueue -f}, но по умолчанию у вас есть только несколько дней
на это, плюс отправитель будет получать уведомления о том, что его
сообщение всё ещё не доставлено. Кроме того, вы должны использовать
безопасный канал связи (SSH, VPN, итд).
Команды:
@verbatim
-% nncp-file file_i_want_to_send bob:
-% nncp-file another_file bob:movie.avi
+$ nncp-file file_i_want_to_send bob:
+$ nncp-file another_file bob:movie.avi
@end verbatim
добавят в очередь отправки два файла для узла @emph{bob}.
опцию:
@verbatim
-% nncp-file -nice FLASH myfile node:dst
-% nncp-xfer -nice PRIORITY /mnt/shared
-% nncp-call -nice NORMAL bob
+$ nncp-file -nice FLASH myfile node:dst
+$ nncp-xfer -nice PRIORITY /mnt/shared
+$ nncp-call -nice NORMAL bob
[...]
@end verbatim
Вы также можете использовать CD-ROM и ленточные накопители:
@verbatim
-% nncp-bundle -tx bob | cdrecord -tao -
-% nncp-bundle -tx bob | dd of=/dev/sa0 bs=10240
+$ nncp-bundle -tx bob | cdrecord -tao -
+$ nncp-bundle -tx bob | dd of=/dev/sa0 bs=10240
@end verbatim
@node UsecaseNoLinkRU
запустите @ref{nncp-xfer}:
@verbatim
-% nncp-xfer -node bob /media/usbstick
+$ nncp-xfer -node bob /media/usbstick
@end verbatim
чтобы скопировать все исходящие пакеты относящиеся к @emph{bob}.
@option{-node} опцию, чтобы скопировать все доступные исходящие пакеты.
@verbatim
-% nncp-xfer /media/usbstick
+$ nncp-xfer /media/usbstick
@end verbatim
Размонтируйте и передайте накопитель Бобу и Алисе. Когда они вставят
накопитель в свои компьютеры, то выполнят точно такую же команду:
@verbatim
-% nncp-xfer /media/usbstick
+$ nncp-xfer /media/usbstick
@end verbatim
чтобы найти все пакеты относящиеся к их узлу и локально скопируют для
зашифрованных пакетов}, которые вы можете принять.
@verbatim
-% nncp-bundle -tx alice bob eve ... | команда для отправки широковещательной рассылки
-% команда для приёма широковещательной рассылки | nncp-bundle -rx
+$ nncp-bundle -tx alice bob eve ... | команда для отправки широковещательной рассылки
+$ команда для приёма широковещательной рассылки | nncp-bundle -rx
@end verbatim
Встроенная возможность определять дубляжи пакетов позволит вам
транспорт с свойством совершенной прямой секретности.
@verbatim
-% nncp-daemon -bind [::]:5400
+$ nncp-daemon -bind [::]:5400
@end verbatim
запустит TCP демон, который будет слушать входящие соединения на всех
интерфейсах.
@verbatim
-% nncp-call bob
+$ nncp-call bob
@end verbatim
попытается подключиться к известному TCP-адресу узла @emph{bob} (взятого
из конфигурационного файла), послать все связанные с ним исходящие
NNCP из коробки поддерживает ретрансляцию пакетов.
@verbatim
-neigh:
- bob:
+neigh: {
+ bob: {
[...]
- addrs:
- lan: [fe80::5400%igb0]:5400
+ addrs: {
+ lan: "[fe80::5400%igb0]:5400"
+ }
+ }
bob-airgap:
[...]
- via: [bob]
+ via: ["bob"]
+ }
+}
@end verbatim
Такой @ref{Configuration, конфигурационный файл} говорит что у нас есть
звонков} для @ref{nncp-caller} команды, используемой при online связи.
@verbatim
-neigh:
+neigh: {
[...]
- some-node:
+ some-node: {
[...]
- addrs:
+ addrs: {
lan: "[fe80::be5f:f4ff:fedd:2752%igb0]:5400"
wan: "some-node.com:5400"
- calls:
- -
+ }
+ calls: [
+ {
cron: "*/1 * * * *"
addr: lan
nice: MAX
onlinedeadline: 3600
- -
+ },
+ {
cron: "*/10 * * * *"
addr: wan
nice: PRIORITY
xx: rx
- -
+ },
+ {
cron: "*/1 0-7 * * *"
addr: wan
nice: BULK
onlinedeadline: 3600
maxonlinetime: 3600
+ },
+ ]
+ }
+}
@end verbatim
The command:
@verbatim
-% nncp-file file_i_want_to_send bob:
-% nncp-file another_file bob:movie.avi
+$ nncp-file file_i_want_to_send bob:
+$ nncp-file another_file bob:movie.avi
@end verbatim
will queue two files for sending to @emph{bob} node. Fire and forget!
later than the other ones. Nearly all commands has corresponding option:
@verbatim
-% nncp-file -nice FLASH myfile node:dst
-% nncp-xfer -nice PRIORITY /mnt/shared
-% nncp-call -nice NORMAL bob
+$ nncp-file -nice FLASH myfile node:dst
+$ nncp-xfer -nice PRIORITY /mnt/shared
+$ nncp-call -nice NORMAL bob
[...]
@end verbatim
You can also use CD-ROM and tape drives:
@verbatim
-% nncp-bundle -tx bob | cdrecord -tao -
-% nncp-bundle -tx bob | dd of=/dev/sa0 bs=10240
+$ nncp-bundle -tx bob | cdrecord -tao -
+$ nncp-bundle -tx bob | dd of=/dev/sa0 bs=10240
@end verbatim
@node UsecaseNoLink
device (SD is preferable!), mount it and run @ref{nncp-xfer}:
@verbatim
-% nncp-xfer -node bob /media/usbstick
+$ nncp-xfer -node bob /media/usbstick
@end verbatim
to copy all outbound packets related to @emph{bob}. Use @option{-mkdir}
outgoing packets.
@verbatim
-% nncp-xfer /media/usbstick
+$ nncp-xfer /media/usbstick
@end verbatim
Unmount it and transfer storage to Bob and Alice. When they will insert
it in their computers, they will use exactly the same command:
@verbatim
-% nncp-xfer /media/usbstick
+$ nncp-xfer /media/usbstick
@end verbatim
to find all packets related to their node and copy them locally for
a sequence of @ref{Encrypted, encrypted packets} you can catch on.
@verbatim
-% nncp-bundle -tx alice bob eve ... | command to send broadcast
-% command to receive broadcast | nncp-bundle -rx
+$ nncp-bundle -tx alice bob eve ... | command to send broadcast
+$ command to receive broadcast | nncp-bundle -rx
@end verbatim
With built-in packet duplicates detection ability, you can retransmit
property.
@verbatim
-% nncp-daemon -bind [::]:5400
+$ nncp-daemon -bind [::]:5400
@end verbatim
will start TCP daemon listening on all interfaces for incoming
connections.
@verbatim
-% nncp-call bob
+$ nncp-call bob
@end verbatim
will try to connect to @emph{bob}'s node known TCP addresses (taken from
configuration file) and send all related outbound packets and retrieve
NNCP supports packets relying (transitioning) out-of-box.
@verbatim
-neigh:
- bob:
+neigh: {
+ bob: {
[...]
- addrs:
- lan: [fe80::5400%igb0]:5400
+ addrs: {
+ lan: "[fe80::5400%igb0]:5400"
+ }
+ }
bob-airgap:
[...]
- via: [bob]
+ via: ["bob"]
+ }
+}
@end verbatim
That @ref{Configuration, configuration file} tells that we have got two
communications.
@verbatim
-neigh:
+neigh: {
[...]
- some-node:
+ some-node: {
[...]
- addrs:
+ addrs: {
lan: "[fe80::be5f:f4ff:fedd:2752%igb0]:5400"
wan: "some-node.com:5400"
- calls:
- -
+ }
+ calls: [
+ {
cron: "*/1 * * * *"
addr: lan
nice: MAX
onlinedeadline: 3600
- -
+ },
+ {
cron: "*/10 * * * *"
addr: wan
nice: PRIORITY
xx: rx
- -
+ },
+ {
cron: "*/1 0-7 * * *"
addr: wan
nice: BULK
onlinedeadline: 3600
maxonlinetime: 3600
+ },
+ ]
+ }
+}
@end verbatim
--no-warc-compression \
--no-warc-keep-log \
$cmdline || :
-xz -9 "$name".warc
-nncp-file -nice $NNCP_NICE "$name".warc.xz $NNCP_SENDER:
+zstd --rm "$name".warc
+nncp-file -nice $NNCP_NICE "$name".warc.zst $NNCP_SENDER:
rm -r $tmp
tmp=$(mktemp)
wget --output-document=$tmp $cmdline
-xz -9 $tmp
-nncp-file -nice $NNCP_NICE $tmp.xz $NNCP_SENDER:$name.xz
-rm $tmp.xz
+zstd --rm $tmp
+nncp-file -nice $NNCP_NICE $tmp.zst $NNCP_SENDER:$name.zst
+rm $tmp.zst
release=$1
[ -n "$release" ]
-vendor=src/cypherpunks.ru/nncp/vendor
-
git clone . $tmp/nncp-$release
-repos="
- cypherpunks.ru/balloon
- github.com/davecgh/go-xdr
- github.com/dustin/go-humanize
- github.com/flynn/noise
- github.com/gorhill/cronexpr
- golang.org/x/crypto
- golang.org/x/net
- golang.org/x/sys
- gopkg.in/check.v1
- gopkg.in/yaml.v2
+cd $tmp/nncp-$release
+git checkout v$release
+rm -fr .git
+
+mod_name=go.cypherpunks.ru/nncp/v5
+mv src src.orig
+mkdir -p src/$mod_name
+mv src.orig/* src/$mod_name
+rmdir src.orig
+
+mods="
+github.com/davecgh/go-xdr
+github.com/dustin/go-humanize
+github.com/flynn/noise
+github.com/gorhill/cronexpr
+github.com/hjson/hjson-go
+github.com/klauspost/compress
+go.cypherpunks.ru/balloon
+golang.org/x/crypto
+golang.org/x/net
+golang.org/x/sys
"
-for repo in $repos; do
- git clone $vendor/$repo $tmp/nncp-$release/$vendor/$repo
+for mod in $mods; do
+ mod_path=$(sed -n "s# // indirect## ; s#^ \($mod\) \(.*\)\$#\1@\2#p" src/$mod_name/go.mod)
+ [ -n "$mod_path" ]
+ mkdir -p src/$mod
+ ( cd $GOPATH/pkg/mod/$mod_path ; tar cf - --exclude ".git*" * ) | tar xfC - src/$mod
+ chmod -R +w src/$mod
done
-cd $tmp/nncp-$release
-git checkout $release
-git submodule update --init
cat > $tmp/includes <<EOF
golang.org/x/crypto/AUTHORS
golang.org/x/crypto/blake2b
golang.org/x/crypto/blake2s
+golang.org/x/crypto/chacha20
golang.org/x/crypto/chacha20poly1305
golang.org/x/crypto/CONTRIBUTORS
golang.org/x/crypto/curve25519
golang.org/x/crypto/ed25519
golang.org/x/crypto/go.mod
golang.org/x/crypto/go.sum
-golang.org/x/crypto/internal/chacha20
golang.org/x/crypto/internal/subtle
golang.org/x/crypto/LICENSE
golang.org/x/crypto/nacl
golang.org/x/sys/README.md
golang.org/x/sys/unix
EOF
-tar cfCI - $vendor $tmp/includes | tar xfC - $tmp
-rm -fr $vendor/golang.org
-mv $tmp/golang.org $vendor
-rm $tmp/includes
+tar cfCI - src $tmp/includes | tar xfC - $tmp
+rm -fr src/golang.org $tmp/includes
+mv $tmp/golang.org src
+
+cat > $tmp/includes <<EOF
+compress/compressible.go
+compress/fse
+compress/huff0
+compress/LICENSE
+compress/README.md
+compress/zstd
+EOF
+cat > $tmp/excludes <<EOF
+*testdata*
+*_test.go
+snappy.go
+EOF
+tar cfCIX - src/github.com/klauspost $tmp/includes $tmp/excludes | tar xfC - $tmp
+rm -fr src/github.com/klauspost/compress $tmp/includes $tmp/excludes
+mv $tmp/compress src/github.com/klauspost
find src -name .travis.yml -delete
-rm -fr $vendor/github.com/davecgh/go-xdr/xdr
-rm $vendor/github.com/gorhill/cronexpr/APLv2
+rm -fr src/github.com/davecgh/go-xdr/xdr
+rm -r src/github.com/flynn/noise/vector*
+rm src/github.com/hjson/hjson-go/build_release.sh
+rm src/github.com/gorhill/cronexpr/APLv2
rm -fr ports
rm makedist.sh
You can obtain releases source code prepared tarballs on
@url{http://www.nncpgo.org/}.
EOF
+perl -i -ne 'print unless /include pedro/' doc/index.texi doc/about.ru.texi
make -C doc
-./supplementary_files.sh
-rm -r doc/.well-known doc/nncp.html/.well-known supplementary_files.sh
-find . -name .git | xargs rm -fr
-find . -name .gitignore -delete
-rm .gitmodules
+########################################################################
+# Supplementary files autogeneration
+########################################################################
+texi=`mktemp`
+
+cat > $texi <<EOF
+\input texinfo
+@documentencoding UTF-8
+@settitle NEWS
+
+@node News
+@unnumbered News
+
+`sed -n '5,$p' < doc/news.texi`
+
+@bye
+EOF
+makeinfo --plaintext -o NEWS $texi
+
+cat > $texi <<EOF
+\input texinfo
+@documentencoding UTF-8
+@settitle NEWS.RU
+
+@node Новости
+@unnumbered Новости
+
+`sed -n '3,$p' < doc/news.ru.texi | sed 's/^@subsection/@section/'`
+
+@bye
+EOF
+makeinfo --plaintext -o NEWS.RU $texi
+
+rm -f $texi
+
+texi=$(TMPDIR=doc mktemp)
+cat > $texi <<EOF
+\input texinfo
+@documentencoding UTF-8
+@settitle INSTALL
+
+@include install.texi
+
+@bye
+EOF
+makeinfo --plaintext -o INSTALL $texi
+rm -f $texi
+
+texi=`mktemp`
+
+cat > $texi <<EOF
+\input texinfo
+@documentencoding UTF-8
+@settitle THANKS
+
+`cat doc/thanks.texi`
+
+@bye
+EOF
+makeinfo --plaintext -o THANKS $texi
+rm -f $texi
+
+########################################################################
+
+mv doc/.well-known/openpgpkey/hu/i4cdqgcarfjdjnba6y4jnf498asg8c6p.asc PUBKEY.asc
+rm -r doc/.gitignore doc/.well-known doc/nncp.html/.well-known
+
+find . -type d -exec chmod 755 {} \;
+find . -type f -exec chmod 644 {} \;
+find . -type f -name "*.sh" -exec chmod 755 {} \;
cd ..
tar cvf nncp-"$release".tar --uid=0 --gid=0 --numeric-owner nncp-"$release"
# $FreeBSD: head/net/nncp/Makefile 484628 2018-11-10 18:12:57Z bapt $
PORTNAME= nncp
-DISTVERSION= 4.0
+DISTVERSION= 5.0.0
PORTREVISION= 1
CATEGORIES= net
MASTER_SITES= http://www.nncpgo.org/download/
MAINTAINER= stargrave@stargrave.org
COMMENT= Utilities for secure store-and-forward files, mail, command exchanging
-LICENSE= GPLv3+
+LICENSE= GPLv3
LICENSE_FILE= ${WRKSRC}/COPYING
BUILD_DEPENDS= go:lang/go
USES= tar:xz
-MAKEFILE= BSDmakefile
USE_RC_SUBR= nncp-caller nncp-daemon nncp-toss
INSTALL_TARGET= install-strip
#
# nncp_caller_enable (bool): Set to NO by default.
# Set it to YES to enable nncp-caller.
-# nncp_caller_config (path): Set to %%PREFIX%%/etc/nncp.yaml by default.
+# nncp_caller_config (path): Set to %%PREFIX%%/etc/nncp.hjson by default.
. /etc/rc.subr
load_rc_config $name
: ${nncp_caller_enable:="NO"}
-: ${nncp_caller_config="%%PREFIX%%/etc/nncp.yaml"}
+: ${nncp_caller_config="%%PREFIX%%/etc/nncp.hjson"}
command=%%PREFIX%%/bin/nncp-caller
command_args="-quiet -cfg $nncp_caller_config &"
#
# nncp_daemon_enable (bool): Set to NO by default.
# Set it to YES to enable nncp-daemon.
-# nncp_daemon_config (path): Set to %%PREFIX%%/etc/nncp.yaml by default.
+# nncp_daemon_config (path): Set to %%PREFIX%%/etc/nncp.hjson by default.
# nncp_daemon_bind (string): Address:port to bind to
# Default is "[::]:5400".
load_rc_config $name
: ${nncp_daemon_enable:="NO"}
-: ${nncp_daemon_config="%%PREFIX%%/etc/nncp.yaml"}
+: ${nncp_daemon_config="%%PREFIX%%/etc/nncp.hjson"}
: ${nncp_daemon_bind="[::]:5400"}
command=%%PREFIX%%/bin/nncp-daemon
#
# nncp_toss_enable (bool): Set to NO by default.
# Set it to YES to enable nncp-toss.
-# nncp_toss_config (path): Set to %%PREFIX%%/etc/nncp.yaml by default.
+# nncp_toss_config (path): Set to %%PREFIX%%/etc/nncp.hjson by default.
# nncp_toss_cycle (int): Repeat tossing after that number of seconds.
# Default is "60".
load_rc_config $name
: ${nncp_toss_enable:="NO"}
-: ${nncp_toss_config="%%PREFIX%%/etc/nncp.yaml"}
+: ${nncp_toss_config="%%PREFIX%%/etc/nncp.hjson"}
: ${nncp_toss_cycle="60"}
command=%%PREFIX%%/bin/nncp-toss
[ "$2" = "POST-DEINSTALL" ] || exit 0
-if [ -e %%PREFIX%%/etc/nncp.yaml ]; then
- echo "%%PREFIX%%/etc/nncp.yaml with your private keys is not removed!"
+if [ -e %%PREFIX%%/etc/nncp.hjson ]; then
+ echo "%%PREFIX%%/etc/nncp.hjson with your private keys is not removed!"
fi
exec rmdir /var/spool/nncp
- Generate NNCP configuration file using the command:
# umask 077
- # nncp-cfgnew > %%PREFIX%%/etc/nncp.yaml
+ # nncp-cfgnew > %%PREFIX%%/etc/nncp.hjson
======================================================================
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
for _, addr := range addrs {
sds := SDS{"node": node.Id, "addr": addr}
ctx.LogD("call", sds, "dialing")
- conn, err := net.Dial("tcp", addr)
+ var conn ConnDeadlined
+ var err error
+ if addr[0] == '|' {
+ conn, err = NewPipeConn(addr[1:])
+ } else {
+ conn, err = net.Dial("tcp", addr)
+ }
if err != nil {
ctx.LogD("call", SdsAdd(sds, SDS{"err": err}), "dialing")
continue
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
import (
"bytes"
+ "encoding/json"
"errors"
"log"
"os"
"path"
+ "strconv"
"github.com/gorhill/cronexpr"
+ "github.com/hjson/hjson-go"
"golang.org/x/crypto/ed25519"
"golang.org/x/crypto/ssh/terminal"
- "gopkg.in/yaml.v2"
)
const (
)
var (
- DefaultCfgPath string = "/usr/local/etc/nncp.yaml"
+ DefaultCfgPath string = "/usr/local/etc/nncp.hjson"
DefaultSendmailPath string = "/usr/sbin/sendmail"
DefaultSpoolPath string = "/var/spool/nncp"
DefaultLogPath string = "/var/spool/nncp/log"
)
-type NodeYAML struct {
- Id string
- ExchPub string
- SignPub string
- NoisePub *string `yaml:"noisepub,omitempty"`
- Exec map[string][]string `yaml:"exec,omitempty"`
- Incoming *string `yaml:"incoming,omitempty"`
- Freq *string `yaml:"freq,omitempty"`
- FreqChunked *uint64 `yaml:"freqchunked,omitempty"`
- FreqMinSize *uint64 `yaml:"freqminsize,omitempty"`
- Via []string `yaml:"via,omitempty"`
- Calls []CallYAML `yaml:"calls,omitempty"`
-
- Addrs map[string]string `yaml:"addrs,omitempty"`
-
- RxRate *int `yaml:"rxrate,omitempty"`
- TxRate *int `yaml:"txrate,omitempty"`
- OnlineDeadline *uint `yaml:"onlinedeadline,omitempty"`
- MaxOnlineTime *uint `yaml:"maxonlinetime,omitempty"`
+type NodeJSON struct {
+ Id string `json:"id"`
+ ExchPub string `json:"exchpub"`
+ SignPub string `json:"signpub"`
+ NoisePub *string `json:"noisepub,omitempty"`
+ Exec map[string][]string `json:"exec,omitempty"`
+ Incoming *string `json:"incoming,omitempty"`
+ Freq *string `json:"freq,omitempty"`
+ FreqChunked *uint64 `json:"freqchunked,omitempty"`
+ FreqMinSize *uint64 `json:"freqminsize,omitempty"`
+ Via []string `json:"via,omitempty"`
+ Calls []CallJSON `json:"calls,omitempty"`
+
+ Addrs map[string]string `json:"addrs,omitempty"`
+
+ RxRate *int `json:"rxrate,omitempty"`
+ TxRate *int `json:"txrate,omitempty"`
+ OnlineDeadline *uint `json:"onlinedeadline,omitempty"`
+ MaxOnlineTime *uint `json:"maxonlinetime,omitempty"`
}
-type CallYAML struct {
+type CallJSON struct {
Cron string
- Nice *string `yaml:"nice,omitempty"`
- Xx string `yaml:"xx,omitempty"`
- RxRate *int `yaml:"rxrate,omitempty"`
- TxRate *int `yaml:"txrate,omitempty"`
- Addr *string `yaml:"addr,omitempty"`
- OnlineDeadline *uint `yaml:"onlinedeadline,omitempty"`
- MaxOnlineTime *uint `yaml:"maxonlinetime,omitempty"`
+ Nice *string `json:"nice,omitempty"`
+ Xx *string `json:"xx,omitempty"`
+ RxRate *int `json:"rxrate,omitempty"`
+ TxRate *int `json:"txrate,omitempty"`
+ Addr *string `json:"addr,omitempty"`
+ OnlineDeadline *uint `json:"onlinedeadline,omitempty"`
+ MaxOnlineTime *uint `json:"maxonlinetime,omitempty"`
}
-type NodeOurYAML struct {
- Id string
- ExchPub string
- ExchPrv string
- SignPub string
- SignPrv string
- NoisePrv string
- NoisePub string
+type NodeOurJSON struct {
+ Id string `json:"id"`
+ ExchPub string `json:"exchpub"`
+ ExchPrv string `json:"exchprv"`
+ SignPub string `json:"signpub"`
+ SignPrv string `json:"signprv"`
+ NoisePrv string `json:"noiseprv"`
+ NoisePub string `json:"noisepub"`
}
-type FromToYAML struct {
+type FromToJSON struct {
From string
To string
}
-type NotifyYAML struct {
- File *FromToYAML `yaml:"file,omitempty"`
- Freq *FromToYAML `yaml:"freq,omitempty"`
+type NotifyJSON struct {
+ File *FromToJSON `json:"file,omitempty"`
+ Freq *FromToJSON `json:"freq,omitempty"`
}
-type CfgYAML struct {
- Self *NodeOurYAML `yaml:"self,omitempty"`
- Neigh map[string]NodeYAML
+type CfgJSON struct {
+ Spool string `json:"spool"`
+ Log string `json:"log"`
+ Umask string `json:"umask",omitempty`
- Spool string
- Log string
- Notify *NotifyYAML `yaml:"notify,omitempty"`
+ Notify *NotifyJSON `json:"notify,omitempty"`
+
+ Self *NodeOurJSON `json:"self"`
+ Neigh map[string]NodeJSON `json:"neigh"`
}
-func NewNode(name string, yml NodeYAML) (*Node, error) {
+func NewNode(name string, yml NodeJSON) (*Node, error) {
nodeId, err := NodeIdFromString(yml.Id)
if err != nil {
return nil, err
}
var xx TRxTx
- switch callYml.Xx {
- case "rx":
- xx = TRx
- case "tx":
- xx = TTx
- case "":
- default:
- return nil, errors.New("xx field must be either \"rx\" or \"tx\"")
+ if callYml.Xx != nil {
+ switch *callYml.Xx {
+ case "rx":
+ xx = TRx
+ case "tx":
+ xx = TTx
+ default:
+ return nil, errors.New("xx field must be either \"rx\" or \"tx\"")
+ }
}
rxRate := defRxRate
return &node, nil
}
-func NewNodeOur(yml *NodeOurYAML) (*NodeOur, error) {
+func NewNodeOur(yml *NodeOurJSON) (*NodeOur, error) {
id, err := NodeIdFromString(yml.Id)
if err != nil {
return nil, err
return &node, nil
}
-func (nodeOur *NodeOur) ToYAML() string {
- yml := NodeOurYAML{
- Id: nodeOur.Id.String(),
- ExchPub: ToBase32(nodeOur.ExchPub[:]),
- ExchPrv: ToBase32(nodeOur.ExchPrv[:]),
- SignPub: ToBase32(nodeOur.SignPub[:]),
- SignPrv: ToBase32(nodeOur.SignPrv[:]),
- NoisePub: ToBase32(nodeOur.NoisePub[:]),
- NoisePrv: ToBase32(nodeOur.NoisePrv[:]),
- }
- raw, err := yaml.Marshal(&yml)
- if err != nil {
- panic(err)
- }
- return string(raw)
-}
-
func CfgParse(data []byte) (*Ctx, error) {
var err error
if bytes.Compare(data[:8], MagicNNCPBv3[:]) == 0 {
return nil, err
}
}
- var cfgYAML CfgYAML
- if err = yaml.Unmarshal(data, &cfgYAML); err != nil {
+ var cfgGeneral map[string]interface{}
+ if err = hjson.Unmarshal(data, &cfgGeneral); err != nil {
return nil, err
}
- if _, exists := cfgYAML.Neigh["self"]; !exists {
+ marshaled, err := json.Marshal(cfgGeneral)
+ if err != nil {
+ return nil, err
+ }
+ var cfgJSON CfgJSON
+ if err = json.Unmarshal(marshaled, &cfgJSON); err != nil {
+ return nil, err
+ }
+ if _, exists := cfgJSON.Neigh["self"]; !exists {
return nil, errors.New("self neighbour missing")
}
var self *NodeOur
- if cfgYAML.Self != nil {
- self, err = NewNodeOur(cfgYAML.Self)
+ if cfgJSON.Self != nil {
+ self, err = NewNodeOur(cfgJSON.Self)
if err != nil {
return nil, err
}
}
- spoolPath := path.Clean(cfgYAML.Spool)
+ spoolPath := path.Clean(cfgJSON.Spool)
if !path.IsAbs(spoolPath) {
return nil, errors.New("Spool path must be absolute")
}
- logPath := path.Clean(cfgYAML.Log)
+ logPath := path.Clean(cfgJSON.Log)
if !path.IsAbs(logPath) {
return nil, errors.New("Log path must be absolute")
}
+ var umaskForce *int
+ if cfgJSON.Umask != "" {
+ r, err := strconv.ParseUint(cfgJSON.Umask, 8, 16)
+ if err != nil {
+ return nil, err
+ }
+ rInt := int(r)
+ umaskForce = &rInt
+ }
ctx := Ctx{
- Spool: spoolPath,
- LogPath: logPath,
- Self: self,
- Neigh: make(map[NodeId]*Node, len(cfgYAML.Neigh)),
- Alias: make(map[string]*NodeId),
- }
- if cfgYAML.Notify != nil {
- if cfgYAML.Notify.File != nil {
- ctx.NotifyFile = cfgYAML.Notify.File
+ Spool: spoolPath,
+ LogPath: logPath,
+ UmaskForce: umaskForce,
+ Self: self,
+ Neigh: make(map[NodeId]*Node, len(cfgJSON.Neigh)),
+ Alias: make(map[string]*NodeId),
+ }
+ if cfgJSON.Notify != nil {
+ if cfgJSON.Notify.File != nil {
+ ctx.NotifyFile = cfgJSON.Notify.File
}
- if cfgYAML.Notify.Freq != nil {
- ctx.NotifyFreq = cfgYAML.Notify.Freq
+ if cfgJSON.Notify.Freq != nil {
+ ctx.NotifyFreq = cfgJSON.Notify.Freq
}
}
vias := make(map[NodeId][]string)
- for name, neighYAML := range cfgYAML.Neigh {
- neigh, err := NewNode(name, neighYAML)
+ for name, neighJSON := range cfgJSON.Neigh {
+ neigh, err := NewNode(name, neighJSON)
if err != nil {
return nil, err
}
return nil, errors.New("Node names conflict")
}
ctx.Alias[name] = neigh.Id
- vias[*neigh.Id] = neighYAML.Via
+ vias[*neigh.Id] = neighJSON.Via
}
ctx.SelfId = ctx.Alias["self"]
for neighId, viasRaw := range vias {
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
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
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
"strconv"
"strings"
- "cypherpunks.ru/nncp"
"github.com/davecgh/go-xdr/xdr2"
+ "go.cypherpunks.ru/nncp/v5"
"golang.org/x/crypto/blake2b"
)
nodeIds[*node.Id] = struct{}{}
}
+ ctx.Umask()
+
sds := nncp.SDS{}
if *doTx {
sds["xx"] = string(nncp.TTx)
log.Fatalln("Error during syncing:", err)
}
tmp.Close()
- if err = os.MkdirAll(selfPath, os.FileMode(0700)); err != nil {
+ if err = os.MkdirAll(selfPath, os.FileMode(0777)); err != nil {
log.Fatalln("Error during mkdir:", err)
}
if err = os.Rename(tmp.Name(), dstPath); err != nil {
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
"os"
"strings"
- "cypherpunks.ru/nncp"
+ "go.cypherpunks.ru/nncp/v5"
)
func usage() {
}
}
+ ctx.Umask()
if !ctx.CallNode(
node,
addrs,
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
"sync"
"time"
- "cypherpunks.ru/nncp"
+ "go.cypherpunks.ru/nncp/v5"
)
func usage() {
if ctx.Self == nil {
log.Fatalln("Config lacks private keys")
}
+ ctx.Umask()
var nodes []*nncp.Node
if flag.NArg() > 0 {
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
"log"
"os"
- "cypherpunks.ru/nncp"
"github.com/davecgh/go-xdr/xdr2"
+ "go.cypherpunks.ru/nncp/v5"
"golang.org/x/crypto/blake2b"
"golang.org/x/crypto/ssh/terminal"
)
func usage() {
fmt.Fprintf(os.Stderr, nncp.UsageHeader())
fmt.Fprintf(os.Stderr, "nncp-cfgenc -- encrypt/decrypt configuration file\n\n")
- fmt.Fprintf(os.Stderr, "Usage: %s [options] cfg.yaml > cfg.yaml.eblob\n", os.Args[0])
- fmt.Fprintf(os.Stderr, " %s [options] -d cfg.yaml.eblob > cfg.yaml\n", os.Args[0])
- fmt.Fprintf(os.Stderr, " %s [options] -dump cfg.yaml.eblob\n", os.Args[0])
+ fmt.Fprintf(os.Stderr, "Usage: %s [options] cfg.hjson > cfg.hjson.eblob\n", os.Args[0])
+ fmt.Fprintf(os.Stderr, " %s [options] -d cfg.hjson.eblob > cfg.hjson\n", os.Args[0])
+ fmt.Fprintf(os.Stderr, " %s [options] -dump cfg.hjson.eblob\n", os.Args[0])
fmt.Fprintln(os.Stderr, "Options:")
flag.PrintDefaults()
}
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
"log"
"os"
- "cypherpunks.ru/nncp"
- "gopkg.in/yaml.v2"
+ "github.com/hjson/hjson-go"
+ "go.cypherpunks.ru/nncp/v5"
)
func usage() {
log.Fatalln("Error during initialization:", err)
}
- cfg := nncp.CfgYAML{
+ cfg := nncp.CfgJSON{
Spool: ctx.Spool,
Log: ctx.LogPath,
- Neigh: make(map[string]nncp.NodeYAML),
+ Neigh: make(map[string]nncp.NodeJSON),
}
for _, node := range ctx.Neigh {
var noisePub *string
np := nncp.ToBase32(node.NoisePub[:])
noisePub = &np
}
- cfg.Neigh[node.Name] = nncp.NodeYAML{
+ cfg.Neigh[node.Name] = nncp.NodeJSON{
Id: node.Id.String(),
ExchPub: nncp.ToBase32(node.ExchPub[:]),
SignPub: nncp.ToBase32(node.SignPub[:]),
NoisePub: noisePub,
}
}
- raw, err := yaml.Marshal(&cfg)
+ raw, err := hjson.Marshal(&cfg)
if err != nil {
panic(err)
}
--- /dev/null
+/*
+NNCP -- Node to Node copy, utilities for store-and-forward data exchange
+Copyright (C) 2016-2019 Sergey Matveev <stargrave@stargrave.org>
+
+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 <http://www.gnu.org/licenses/>.
+*/
+
+// Generate new NNCP node keys and configuration file
+package main
+
+import (
+ "flag"
+ "fmt"
+ "os"
+
+ "go.cypherpunks.ru/nncp/v5"
+)
+
+func usage() {
+ fmt.Fprintf(os.Stderr, nncp.UsageHeader())
+ fmt.Fprintln(os.Stderr, "nncp-cfgnew -- generate new configuration and keys\nOptions:")
+ flag.PrintDefaults()
+}
+
+func main() {
+ var (
+ noComments = flag.Bool("nocomments", false, "Do not include descriptive comments")
+ version = flag.Bool("version", false, "Print version information")
+ warranty = flag.Bool("warranty", false, "Print warranty information")
+ )
+ flag.Usage = usage
+ flag.Parse()
+ if *warranty {
+ fmt.Println(nncp.Warranty)
+ return
+ }
+ if *version {
+ fmt.Println(nncp.VersionGet())
+ return
+ }
+ nodeOur, err := nncp.NewNodeGenerate()
+ if err != nil {
+ panic(err)
+ }
+ var cfgRaw string
+ if *noComments {
+ cfgRaw = fmt.Sprintf(`{
+ spool: %s
+ log: %s
+
+ self: {
+ # DO NOT show anyone your private keys!!!
+ id: %s
+ exchpub: %s
+ exchprv: %s
+ signpub: %s
+ signprv: %s
+ noiseprv: %s
+ noisepub: %s
+ }
+
+ neigh: {
+ self: {
+ id: %s
+ exchpub: %s
+ signpub: %s
+ noisepub: %s
+ exec: {sendmail: ["%s"]}
+ }
+ }
+}`,
+ nncp.DefaultSpoolPath,
+ nncp.DefaultLogPath,
+ nodeOur.Id.String(),
+ nncp.ToBase32(nodeOur.ExchPub[:]),
+ nncp.ToBase32(nodeOur.ExchPrv[:]),
+ nncp.ToBase32(nodeOur.SignPub[:]),
+ nncp.ToBase32(nodeOur.SignPrv[:]),
+ nncp.ToBase32(nodeOur.NoisePub[:]),
+ nncp.ToBase32(nodeOur.NoisePrv[:]),
+ nodeOur.Id.String(),
+ nncp.ToBase32(nodeOur.ExchPub[:]),
+ nncp.ToBase32(nodeOur.SignPub[:]),
+ nncp.ToBase32(nodeOur.NoisePub[:]),
+ nncp.DefaultSendmailPath,
+ )
+ } else {
+ cfgRaw = fmt.Sprintf(`{
+ # Path to encrypted packets spool directory
+ spool: %s
+ # Path to log file
+ log: %s
+ # Enforce specified umask usage
+ # umask: "022"
+
+ # Enable notification email sending
+ # notify: {
+ # file: {
+ # from: nncp@localhost
+ # to: user+file@example.com
+ # }
+ # freq: {
+ # from: nncp@localhost
+ # to: user+freq@example.com
+ # }
+ # }
+
+ self: {
+ # DO NOT show anyone your private keys!!!
+ id: %s
+ exchpub: %s
+ exchprv: %s
+ signpub: %s
+ signprv: %s
+ noiseprv: %s
+ noisepub: %s
+ }
+
+ neigh: {
+ self: {
+ # You should give public keys below to your neighbours
+ id: %s
+ exchpub: %s
+ signpub: %s
+ noisepub: %s
+
+ exec: {
+ # Default self's sendmail command is used for email notifications sending
+ sendmail: ["%s"]
+ }
+ }
+
+ # Example neighbour, most of fields are optional
+ # alice: {
+ # id: XJZBK...65IJQ
+ # exchpub: MJACJ...FAI6A
+ # signpub: T4AFC...N2FRQ
+ # noisepub: UBM5K...VI42A
+ #
+ # # He is allowed to send email
+ # exec: {sendmail: ["/usr/sbin/sendmail"]}
+ #
+ # # Allow incoming files saving in that directory
+ # incoming: "/home/alice/incoming"
+ #
+ # # Transitional nodes path
+ # via: ["bob", "eve"]
+ #
+ # # Inactivity timeout when session with remote peer should be terminated
+ # onlinedeadline: 1800
+ #
+ # # Maximal online session lifetime
+ # maxonlinetime: 3600
+ #
+ # # Allow freqing from that directory
+ # freq: "/home/bob/pub"
+ # # Send freqed files with chunks
+ # freqchunked: 1024
+ # # Send freqed files with minumal chunk size
+ # freqminsize: 2048
+ #
+ # # Set maximal packets per second receive and transmit rates
+ # rxrate: 10
+ # txrate: 20
+ #
+ # # Address aliases
+ # addrs: {
+ # lan: "[fe80::1234%%igb0]:5400"
+ # internet: alice.com:3389
+ # }
+ #
+ # # Calls configuration
+ # calls: [
+ # {
+ # cron: "*/2 * * * *"
+ # onlinedeadline: 1800
+ # maxonlinetime: 1750
+ # nice: PRIORITY+10
+ # rxrate: 10
+ # txrate: 20
+ # xx: rx
+ # addr: lan
+ # },
+ # ]
+ # }
+ }
+}`,
+ nncp.DefaultSpoolPath,
+ nncp.DefaultLogPath,
+ nodeOur.Id.String(),
+ nncp.ToBase32(nodeOur.ExchPub[:]),
+ nncp.ToBase32(nodeOur.ExchPrv[:]),
+ nncp.ToBase32(nodeOur.SignPub[:]),
+ nncp.ToBase32(nodeOur.SignPrv[:]),
+ nncp.ToBase32(nodeOur.NoisePub[:]),
+ nncp.ToBase32(nodeOur.NoisePrv[:]),
+ nodeOur.Id.String(),
+ nncp.ToBase32(nodeOur.ExchPub[:]),
+ nncp.ToBase32(nodeOur.SignPub[:]),
+ nncp.ToBase32(nodeOur.NoisePub[:]),
+ nncp.DefaultSendmailPath,
+ )
+ }
+ if _, err = nncp.CfgParse([]byte(cfgRaw)); err != nil {
+ panic(err)
+ }
+ fmt.Println(cfgRaw)
+}
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
"log"
"os"
- "cypherpunks.ru/nncp"
+ "go.cypherpunks.ru/nncp/v5"
)
func usage() {
if err != nil {
log.Fatalln("Error during initialization:", err)
}
+ ctx.Umask()
var nodeOnly *nncp.Node
if *nodeRaw != "" {
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
"strconv"
"time"
- "cypherpunks.ru/nncp"
+ "go.cypherpunks.ru/nncp/v5"
"golang.org/x/net/netutil"
)
w *os.File
}
-func (ic *InetdConn) Read(p []byte) (n int, err error) {
- return ic.r.Read(p)
+func (c InetdConn) Read(p []byte) (n int, err error) {
+ return c.r.Read(p)
}
-func (ic *InetdConn) Write(p []byte) (n int, err error) {
- return ic.w.Write(p)
+func (c InetdConn) Write(p []byte) (n int, err error) {
+ return c.w.Write(p)
}
-func (ic *InetdConn) SetReadDeadline(t time.Time) error {
- return ic.r.SetReadDeadline(t)
+func (c InetdConn) SetReadDeadline(t time.Time) error {
+ return c.r.SetReadDeadline(t)
}
-func (ic *InetdConn) SetWriteDeadline(t time.Time) error {
- return ic.w.SetWriteDeadline(t)
+func (c InetdConn) SetWriteDeadline(t time.Time) error {
+ return c.w.SetWriteDeadline(t)
+}
+
+func (c InetdConn) Close() error {
+ return c.w.Close()
}
func performSP(ctx *nncp.Ctx, conn nncp.ConnDeadlined, nice uint8) {
if ctx.Self == nil {
log.Fatalln("Config lacks private keys")
}
+ ctx.Umask()
if *inetd {
os.Stderr.Close()
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
"bufio"
"flag"
"fmt"
- "io/ioutil"
"log"
"os"
- "cypherpunks.ru/nncp"
+ "go.cypherpunks.ru/nncp/v5"
)
func usage() {
}
nncp.ViaOverride(*viaOverride, ctx, node)
-
- body, err := ioutil.ReadAll(bufio.NewReader(os.Stdin))
- if err != nil {
- log.Fatalln("Can not read body from stdin:", err)
- }
+ ctx.Umask()
if err = ctx.TxExec(
node,
replyNice,
flag.Args()[1],
flag.Args()[2:],
- body,
+ bufio.NewReader(os.Stdin),
int64(*minSize)*1024,
); err != nil {
log.Fatalln(err)
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
"os"
"strings"
- "cypherpunks.ru/nncp"
+ "go.cypherpunks.ru/nncp/v5"
)
func usage() {
}
nncp.ViaOverride(*viaOverride, ctx, node)
+ ctx.Umask()
var minSize int64
if *argMinSize < 0 {
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
"strconv"
"strings"
- "cypherpunks.ru/nncp"
+ "go.cypherpunks.ru/nncp/v5"
)
func usage() {
}
nncp.ViaOverride(*viaOverride, ctx, node)
+ ctx.Umask()
var dst string
if flag.NArg() == 2 {
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
"log"
"os"
- "cypherpunks.ru/nncp"
+ "go.cypherpunks.ru/nncp/v5"
)
func usage() {
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
import (
"bufio"
"bytes"
- "compress/zlib"
"flag"
"fmt"
"io"
"log"
"os"
- "cypherpunks.ru/nncp"
"github.com/davecgh/go-xdr/xdr2"
+ "github.com/klauspost/compress/zstd"
+ "go.cypherpunks.ru/nncp/v5"
)
func usage() {
var (
overheads = flag.Bool("overheads", false, "Print packet overheads")
dump = flag.Bool("dump", false, "Write decrypted/parsed payload to stdout")
- decompress = flag.Bool("decompress", false, "Try to zlib decompress dumped data")
+ decompress = flag.Bool("decompress", false, "Try to zstd decompress dumped data")
cfgPath = flag.String("cfg", nncp.DefaultCfgPath, "Path to configuration file")
version = flag.Bool("version", false, "Print version information")
warranty = flag.Bool("warranty", false, "Print warranty information")
}
var pkt nncp.Pkt
_, err = xdr.Unmarshal(bytes.NewReader(beginning), &pkt)
- if err == nil && pkt.Magic == nncp.MagicNNCPPv2 {
+ if err == nil && pkt.Magic == nncp.MagicNNCPPv3 {
if *dump {
bufW := bufio.NewWriter(os.Stdout)
var r io.Reader
r = bufio.NewReader(os.Stdin)
if *decompress {
- decompressor, err := zlib.NewReader(r)
+ decompressor, err := zstd.NewReader(r)
if err != nil {
log.Fatalln(err)
}
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
"fmt"
"hash"
"io"
- "io/ioutil"
"log"
"os"
"path/filepath"
"strconv"
"strings"
- "cypherpunks.ru/nncp"
"github.com/davecgh/go-xdr/xdr2"
"github.com/dustin/go-humanize"
+ "go.cypherpunks.ru/nncp/v5"
"golang.org/x/crypto/blake2b"
)
dst = os.Stdout
sds = nncp.SDS{"path": path}
} else {
- tmp, err = ioutil.TempFile(mainDir, "nncp-reass")
+ tmp, err = nncp.TempFile(mainDir, "reass")
if err != nil {
log.Fatalln(err)
}
}
log.Fatalln(err)
}
- dstPath = dstPathOrig + strconv.Itoa(dstPathCtr)
+ dstPath = dstPathOrig + "." + strconv.Itoa(dstPathCtr)
dstPathCtr++
}
if err = os.Rename(tmp.Name(), dstPath); err != nil {
os.Exit(1)
}
+ ctx.Umask()
+
if flag.NArg() > 0 {
if process(ctx, flag.Arg(0), *keep, *dryRun, *stdout, *dumpMeta) {
return
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
"path/filepath"
"strings"
- "cypherpunks.ru/nncp"
+ "go.cypherpunks.ru/nncp/v5"
)
func usage() {
if err != nil {
log.Fatalln("Error during initialization:", err)
}
+ ctx.Umask()
if *doTmp {
err = filepath.Walk(filepath.Join(ctx.Spool, "tmp"), func(path string, info os.FileInfo, err error) error {
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
"os"
"sort"
- "cypherpunks.ru/nncp"
"github.com/dustin/go-humanize"
+ "go.cypherpunks.ru/nncp/v5"
)
func usage() {
}
sort.Strings(nodeNames)
+ ctx.Umask()
var node *nncp.Node
for _, nodeName := range nodeNames {
node = nodeNameToNode[nodeName]
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
"os"
"time"
- "cypherpunks.ru/nncp"
+ "go.cypherpunks.ru/nncp/v5"
)
func usage() {
}
}
+ ctx.Umask()
+
Cycle:
isBad := false
for nodeId, node := range ctx.Neigh {
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
"flag"
"fmt"
"io"
- "io/ioutil"
"log"
"os"
"path/filepath"
"strconv"
- "cypherpunks.ru/nncp"
"github.com/davecgh/go-xdr/xdr2"
+ "go.cypherpunks.ru/nncp/v5"
)
func usage() {
}
}
+ ctx.Umask()
selfPath := filepath.Join(flag.Arg(0), ctx.SelfId.String())
isBad := false
var dir *os.File
ctx.UnlockDir(dirLock)
continue
}
- if err = os.Mkdir(nodePath, os.FileMode(0700)); err != nil {
+ if err = os.Mkdir(nodePath, os.FileMode(0777)); err != nil {
ctx.UnlockDir(dirLock)
ctx.LogE("nncp-xfer", nncp.SdsAdd(sds, nncp.SDS{"err": err}), "mkdir")
isBad = true
_, err = os.Stat(dstPath)
if err != nil {
if os.IsNotExist(err) {
- if err = os.Mkdir(dstPath, os.FileMode(0700)); err != nil {
+ if err = os.Mkdir(dstPath, os.FileMode(0777)); err != nil {
ctx.UnlockDir(dirLock)
ctx.LogE("nncp-xfer", nncp.SdsAdd(sds, nncp.SDS{"err": err}), "mkdir")
isBad = true
job.Fd.Close()
continue
}
- tmp, err := ioutil.TempFile(dstPath, "nncp-xfer")
+ tmp, err := nncp.TempFile(dstPath, "xfer")
if err != nil {
ctx.LogE("nncp-xfer", nncp.SdsAdd(sds, nncp.SDS{"err": err}), "mktemp")
job.Fd.Close()
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
"path/filepath"
"golang.org/x/sys/unix"
+ "syscall"
)
type Ctx struct {
Spool string
LogPath string
+ UmaskForce *int
Quiet bool
Debug bool
- NotifyFile *FromToYAML
- NotifyFreq *FromToYAML
+ NotifyFile *FromToJSON
+ NotifyFreq *FromToJSON
}
func (ctx *Ctx) FindNode(id string) (*Node, error) {
func (ctx *Ctx) ensureRxDir(nodeId *NodeId) error {
dirPath := filepath.Join(ctx.Spool, nodeId.String(), string(TRx))
- if err := os.MkdirAll(dirPath, os.FileMode(0700)); err != nil {
+ if err := os.MkdirAll(dirPath, os.FileMode(0777)); err != nil {
ctx.LogE("dir-ensure", SDS{"dir": dirPath, "err": err}, "")
return err
}
}
return int64(s.Bavail)*int64(s.Bsize) > want
}
+
+func (ctx *Ctx) Umask() {
+ if ctx.UmaskForce != nil {
+ syscall.Umask(*ctx.UmaskForce)
+ }
+}
+++ /dev/null
-/*
-NNCP -- Node to Node copy, utilities for store-and-forward data exchange
-Copyright (C) 2016-2019 Sergey Matveev <stargrave@stargrave.org>
-
-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.
-
-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 <http://www.gnu.org/licenses/>.
-*/
-
-// Generate new NNCP node keys and configuration file
-package main
-
-import (
- "flag"
- "fmt"
- "os"
-
- "cypherpunks.ru/nncp"
- "gopkg.in/yaml.v2"
-)
-
-func usage() {
- fmt.Fprintf(os.Stderr, nncp.UsageHeader())
- fmt.Fprintln(os.Stderr, "nncp-cfgnew -- generate new configuration and keys\nOptions:")
- flag.PrintDefaults()
-}
-
-func main() {
- var (
- version = flag.Bool("version", false, "Print version information")
- warranty = flag.Bool("warranty", false, "Print warranty information")
- )
- flag.Usage = usage
- flag.Parse()
- if *warranty {
- fmt.Println(nncp.Warranty)
- return
- }
- if *version {
- fmt.Println(nncp.VersionGet())
- return
- }
- nodeOur, err := nncp.NewNodeGenerate()
- if err != nil {
- panic(err)
- }
- noisePub := nncp.ToBase32(nodeOur.NoisePub[:])
- cfg := nncp.CfgYAML{
- Self: &nncp.NodeOurYAML{
- Id: nodeOur.Id.String(),
- ExchPub: nncp.ToBase32(nodeOur.ExchPub[:]),
- ExchPrv: nncp.ToBase32(nodeOur.ExchPrv[:]),
- SignPub: nncp.ToBase32(nodeOur.SignPub[:]),
- SignPrv: nncp.ToBase32(nodeOur.SignPrv[:]),
- NoisePub: nncp.ToBase32(nodeOur.NoisePub[:]),
- NoisePrv: nncp.ToBase32(nodeOur.NoisePrv[:]),
- },
- Neigh: map[string]nncp.NodeYAML{
- "self": nncp.NodeYAML{
- Id: nodeOur.Id.String(),
- ExchPub: nncp.ToBase32(nodeOur.ExchPub[:]),
- SignPub: nncp.ToBase32(nodeOur.SignPub[:]),
- NoisePub: &noisePub,
- Exec: map[string][]string{
- "sendmail": []string{nncp.DefaultSendmailPath},
- },
- },
- },
- Spool: nncp.DefaultSpoolPath,
- Log: nncp.DefaultLogPath,
- }
- raw, err := yaml.Marshal(&cfg)
- if err != nil {
- panic(err)
- }
- fmt.Print(string(raw))
-}
+++ /dev/null
-module cypherpunks.ru/nncp
-
-require (
- cypherpunks.ru/balloon v0.0.0-20190427214838-0e07700b0279
- github.com/davecgh/go-xdr v0.0.0-20161123171359-e6a2ba005892
- github.com/dustin/go-humanize v1.0.0
- github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6
- github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75
- golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734
- golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6
- golang.org/x/sys v0.0.0-20190426135247-a129542de9ae
- gopkg.in/yaml.v2 v2.2.2
-)
-
-replace cypherpunks.ru/balloon => git.cypherpunks.ru/balloon.git v0.0.0-20190427214838-0e07700b0279
+++ /dev/null
-git.cypherpunks.ru/balloon.git v0.0.0-20190427214838-0e07700b0279 h1:UtJj64EdBav9c3gXvDzuVhfKv0dSOUu/8rA709WRyBg=
-git.cypherpunks.ru/balloon.git v0.0.0-20190427214838-0e07700b0279/go.mod h1:MMNkZjNnjCkWMS+luQsSoSp6CCzhQiowH2uvfy5KgG8=
-github.com/davecgh/go-xdr v0.0.0-20161123171359-e6a2ba005892 h1:qg9VbHo1TlL0KDM0vYvBG9EY0X0Yku5WYIPoFWt8f6o=
-github.com/davecgh/go-xdr v0.0.0-20161123171359-e6a2ba005892/go.mod h1:CTDl0pzVzE5DEzZhPfvhY/9sPFMQIxaJ9VAMs9AagrE=
-github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
-github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
-github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6 h1:u/UEqS66A5ckRmS4yNpjmVH56sVtS/RfclBAYocb4as=
-github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6/go.mod h1:1i71OnUq3iUe1ma7Lr6yG6/rjvM3emb6yoL7xLFzcVQ=
-github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75 h1:f0n1xnMSmBLzVfsMMvriDyA75NB/oBgILX2GcHXIQzY=
-github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734 h1:p/H982KKEjUnLJkM3tt/LemDnOc1GiZL5FCVlORJ5zo=
-golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6 h1:FP8hkuE6yUEaJnK7O2eTuejKWwW+Rhfj80dQ2JcKxCU=
-golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190426135247-a129542de9ae h1:mQLHiymj/JXKnnjc62tb7nD5pZLs940/sXJu+Xp3DBA=
-golang.org/x/sys v0.0.0-20190426135247-a129542de9ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
-gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+++ /dev/null
-Subproject commit 0e07700b027907d44e0060fc3f75c4590478452b
+++ /dev/null
-Subproject commit e6a2ba005892b6a5b27cb5352f64c2e96942dd28
+++ /dev/null
-Subproject commit 9f541cc9db5d55bce703bd99987c9d5cb8eea45e
+++ /dev/null
-Subproject commit 2492fe189ae688d7edbeae0fd575de2f1c5fec8e
+++ /dev/null
-Subproject commit 88b0669f7d75f171bd612b874e52b95c190218df
+++ /dev/null
-Subproject commit a29dc8fdc73485234dbef99ebedb95d2eced08de
+++ /dev/null
-Subproject commit 4829fb13d2c62012c17688fa7f629f371014946d
+++ /dev/null
-Subproject commit a129542de9ae0895210abff9c95d67a1f33cb93d
+++ /dev/null
-Subproject commit 788fd78401277ebd861206a03c884797c6ec5541
+++ /dev/null
-Subproject commit 7b8349ac747c6a24702b762d2c4fd9266cf4f1d6
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
"crypto/rand"
"hash"
- "cypherpunks.ru/balloon"
"github.com/davecgh/go-xdr/xdr2"
+ "go.cypherpunks.ru/balloon"
"golang.org/x/crypto/blake2b"
"golang.org/x/crypto/chacha20poly1305"
)
--- /dev/null
+module go.cypherpunks.ru/nncp/v5
+
+require (
+ github.com/davecgh/go-xdr v0.0.0-20161123171359-e6a2ba005892
+ github.com/dustin/go-humanize v1.0.0
+ github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6
+ github.com/google/go-cmp v0.3.1 // indirect
+ github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75
+ github.com/hjson/hjson-go v3.0.1+incompatible
+ github.com/klauspost/compress v1.9.2
+ github.com/kr/pretty v0.1.0 // indirect
+ go.cypherpunks.ru/balloon v1.1.0
+ golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708
+ golang.org/x/net v0.0.0-20191112182307-2180aed22343
+ golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056
+ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
+)
--- /dev/null
+github.com/davecgh/go-xdr v0.0.0-20161123171359-e6a2ba005892 h1:qg9VbHo1TlL0KDM0vYvBG9EY0X0Yku5WYIPoFWt8f6o=
+github.com/davecgh/go-xdr v0.0.0-20161123171359-e6a2ba005892/go.mod h1:CTDl0pzVzE5DEzZhPfvhY/9sPFMQIxaJ9VAMs9AagrE=
+github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
+github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
+github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6 h1:u/UEqS66A5ckRmS4yNpjmVH56sVtS/RfclBAYocb4as=
+github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6/go.mod h1:1i71OnUq3iUe1ma7Lr6yG6/rjvM3emb6yoL7xLFzcVQ=
+github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75 h1:f0n1xnMSmBLzVfsMMvriDyA75NB/oBgILX2GcHXIQzY=
+github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA=
+github.com/hjson/hjson-go v3.0.1+incompatible h1:JwOXblcMiBbiWue7iPkoFK9oXSnW8n+qXh/0Fio6TCo=
+github.com/hjson/hjson-go v3.0.1+incompatible/go.mod h1:qsetwF8NlsTsOTwZTApNlTCerV+b2GjYRRcIk4JMFio=
+github.com/klauspost/compress v1.9.2 h1:LfVyl+ZlLlLDeQ/d2AqfGIIH4qEDu0Ed2S5GyhCWIWY=
+github.com/klauspost/compress v1.9.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
+github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+go.cypherpunks.ru/balloon v1.1.0 h1:tKwBeS1xrZYS/vn87Hm/4EvgNeHKyU1uC099aPRa2JQ=
+go.cypherpunks.ru/balloon v1.1.0/go.mod h1:k4s4ozrIrhpBjj78Z7LX8ZHxMQ+XE7DZUWl8gP2ojCo=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708 h1:pXVtWnwHkrWD9ru3sDxY/qFK/bfc0egRovX91EjWjf4=
+golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20191112182307-2180aed22343 h1:00ohfJ4K98s3m6BGUoBd8nyfp4Yl0GoIKvw5abItTjI=
+golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056 h1:dHtDnRWQtSx0Hjq9kvKFpBh9uPPKfQN70NZZmvssGwk=
+golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
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
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
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
dirLock, err := os.OpenFile(
lockPath,
os.O_CREATE|os.O_WRONLY,
- os.FileMode(0600),
+ os.FileMode(0666),
)
if err != nil {
ctx.LogE("lockdir", SDS{"path": lockPath, "err": err}, "")
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
fdLock, err := os.OpenFile(
ctx.LogPath+".lock",
os.O_CREATE|os.O_WRONLY,
- os.FileMode(0600),
+ os.FileMode(0666),
)
if err != nil {
fmt.Fprintln(os.Stderr, "Can not open lock for log:", err)
fd, err := os.OpenFile(
ctx.LogPath,
os.O_CREATE|os.O_WRONLY|os.O_APPEND,
- os.FileMode(0600),
+ os.FileMode(0666),
)
if err != nil {
fmt.Fprintln(os.Stderr, "Can not open log:", err)
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
const (
Warranty = `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
)
var (
- Version string
+ Version string = "UNKNOWN"
)
func VersionGet() string {
func UsageHeader() string {
return VersionGet() + `
Copyright (C) 2016-2019 Sergey Matveev
-License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
+License GPLv3: GNU GPL version 3 <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
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
--- /dev/null
+/*
+NNCP -- Node to Node copy, utilities for store-and-forward data exchange
+Copyright (C) 2016-2019 Sergey Matveev <stargrave@stargrave.org>
+
+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 <http://www.gnu.org/licenses/>.
+*/
+
+package nncp
+
+import (
+ "os"
+ "os/exec"
+ "time"
+)
+
+type PipeConn struct {
+ cmd *exec.Cmd
+ r *os.File
+ w *os.File
+}
+
+func NewPipeConn(command string) (ConnDeadlined, error) {
+ cmd := exec.Command("/bin/sh", "-c", command)
+ stdinR, stdinW, err := os.Pipe()
+ if err != nil {
+ return nil, err
+ }
+ cmd.Stdin = stdinR
+ stdoutR, stdoutW, err := os.Pipe()
+ if err != nil {
+ return nil, err
+ }
+ cmd.Stdout = stdoutW
+ err = cmd.Start()
+ if err != nil {
+ return nil, err
+ }
+ return &PipeConn{cmd, stdoutR, stdinW}, nil
+}
+
+func (c PipeConn) Read(p []byte) (n int, err error) {
+ return c.r.Read(p)
+}
+
+func (c PipeConn) Write(p []byte) (n int, err error) {
+ return c.w.Write(p)
+}
+
+func (c PipeConn) SetReadDeadline(t time.Time) error {
+ return c.r.SetReadDeadline(t)
+}
+
+func (c PipeConn) SetWriteDeadline(t time.Time) error {
+ return c.w.SetWriteDeadline(t)
+}
+
+func (c PipeConn) Close() (err error) {
+ err = c.w.Close()
+ go c.cmd.Wait()
+ time.AfterFunc(time.Duration(10*time.Second), func() { c.cmd.Process.Kill() })
+ return
+}
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
)
var (
- MagicNNCPPv2 [8]byte = [8]byte{'N', 'N', 'C', 'P', 'P', 0, 0, 2}
+ MagicNNCPPv3 [8]byte = [8]byte{'N', 'N', 'C', 'P', 'P', 0, 0, 3}
MagicNNCPEv4 [8]byte = [8]byte{'N', 'N', 'C', 'P', 'E', 0, 0, 4}
BadMagic error = errors.New("Unknown magic number")
BadPktType error = errors.New("Unknown packet type")
return nil, errors.New("Too long path")
}
pkt := Pkt{
- Magic: MagicNNCPPv2,
+ Magic: MagicNNCPPv3,
Type: typ,
Nice: nice,
PathLen: uint8(len(path)),
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
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
}
type ConnDeadlined interface {
- io.ReadWriter
+ io.ReadWriteCloser
SetReadDeadline(t time.Time) error
SetWriteDeadline(t time.Time) error
}
fd, err := os.OpenFile(
filePath+PartSuffix,
os.O_RDWR|os.O_CREATE,
- os.FileMode(0600),
+ os.FileMode(0666),
)
if err != nil {
state.Ctx.LogE("sp-file", SdsAdd(sdsp, SDS{"err": err}), "")
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
"bufio"
"hash"
"io"
- "io/ioutil"
"os"
"path/filepath"
+ "strconv"
+ "time"
"golang.org/x/crypto/blake2b"
)
+func TempFile(dir, prefix string) (*os.File, error) {
+ // Assume that probability of suffix collision is negligible
+ suffix := strconv.FormatInt(time.Now().UnixNano()+int64(os.Getpid()), 16)
+ name := filepath.Join(dir, "nncp"+prefix+suffix)
+ return os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, os.FileMode(0666))
+}
+
func (ctx *Ctx) NewTmpFile() (*os.File, error) {
jobsPath := filepath.Join(ctx.Spool, "tmp")
var err error
- if err = os.MkdirAll(jobsPath, os.FileMode(0700)); err != nil {
+ if err = os.MkdirAll(jobsPath, os.FileMode(0777)); err != nil {
return nil, err
}
- fd, err := ioutil.TempFile(jobsPath, "")
+ fd, err := TempFile(jobsPath, "")
if err == nil {
ctx.LogD("tmp", SDS{"src": fd.Name()}, "created")
}
func (tmp *TmpFileWHash) Commit(dir string) error {
var err error
- if err = os.MkdirAll(dir, os.FileMode(0700)); err != nil {
+ if err = os.MkdirAll(dir, os.FileMode(0777)); err != nil {
return err
}
if err = tmp.W.Flush(); err != nil {
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
import (
"bufio"
"bytes"
- "compress/zlib"
"fmt"
"io"
"io/ioutil"
"github.com/davecgh/go-xdr/xdr2"
"github.com/dustin/go-humanize"
+ "github.com/klauspost/compress/zstd"
"golang.org/x/crypto/blake2b"
"golang.org/x/crypto/poly1305"
)
SeenSuffix = ".seen"
)
-func newNotification(fromTo *FromToYAML, subject string) io.Reader {
+func newNotification(fromTo *FromToJSON, subject string) io.Reader {
return strings.NewReader(fmt.Sprintf(
"From: %s\nTo: %s\nSubject: %s\n",
fromTo.From,
dryRun, doSeen, noFile, noFreq, noExec, noTrns bool,
) bool {
isBad := false
+ decompressor, err := zstd.NewReader(nil)
+ if err != nil {
+ panic(err)
+ }
+ defer decompressor.Close()
for job := range ctx.Jobs(nodeId, TRx) {
pktName := filepath.Base(job.Fd.Name())
sds := SDS{"node": job.PktEnc.Sender, "pkt": pktName}
"type": "exec",
"dst": strings.Join(append([]string{handle}, args...), " "),
})
- decompressor, err := zlib.NewReader(pipeR)
- if err != nil {
- log.Fatalln(err)
- }
sender := ctx.Neigh[*job.PktEnc.Sender]
cmdline, exists := sender.Exec[handle]
if !exists || len(cmdline) == 0 {
isBad = true
goto Closing
}
+ if err = decompressor.Reset(pipeR); err != nil {
+ log.Fatalln(err)
+ }
if !dryRun {
cmd := exec.Command(
cmdline[0],
goto Closing
}
dir := filepath.Join(*incoming, path.Dir(dst))
- if err = os.MkdirAll(dir, os.FileMode(0700)); err != nil {
+ if err = os.MkdirAll(dir, os.FileMode(0777)); err != nil {
ctx.LogE("rx", SdsAdd(sds, SDS{"err": err}), "mkdir")
isBad = true
goto Closing
}
if !dryRun {
- tmp, err := ioutil.TempFile(dir, "nncp-file")
+ tmp, err := TempFile(dir, "file")
if err != nil {
ctx.LogE("rx", SdsAdd(sds, SDS{"err": err}), "mktemp")
isBad = true
isBad = true
goto Closing
}
- dstPath = dstPathOrig + strconv.Itoa(dstPathCtr)
+ dstPath = dstPathOrig + "." + strconv.Itoa(dstPathCtr)
dstPathCtr++
}
if err = os.Rename(tmp.Name(), dstPath); err != nil {
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
"os"
"path/filepath"
"strconv"
+ "strings"
"testing"
"testing/quick"
replyNice,
handle,
[]string{"arg0", "arg1"},
- []byte("BODY\n"),
+ strings.NewReader("BODY\n"),
1<<15,
); err != nil {
t.Error(err)
expected := make(map[string]struct{})
expected["samefile"] = struct{}{}
for i := 0; i < files-1; i++ {
- expected["samefile"+strconv.Itoa(i)] = struct{}{}
+ expected["samefile."+strconv.Itoa(i)] = struct{}{}
}
for _, filename := range dirFiles(incomingPath) {
if _, exists := expected[filename]; !exists {
os.MkdirAll(txPath, os.FileMode(0700))
for _, data := range datum {
pktTrans := Pkt{
- Magic: MagicNNCPPv2,
+ Magic: MagicNNCPPv3,
Type: PktTypeTrns,
PathLen: blake2b.Size256,
Path: new([MaxPathSize]byte),
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
import (
"bufio"
"bytes"
- "compress/zlib"
"crypto/rand"
"errors"
"hash"
"strings"
"github.com/davecgh/go-xdr/xdr2"
+ "github.com/klauspost/compress/zstd"
"golang.org/x/crypto/blake2b"
"golang.org/x/crypto/chacha20poly1305"
)
nice, replyNice uint8,
handle string,
args []string,
- body []byte,
+ in io.Reader,
minSize int64,
) error {
path := make([][]byte, 0, 1+len(args))
return err
}
var compressed bytes.Buffer
- compressor, err := zlib.NewWriterLevel(&compressed, zlib.BestCompression)
+ compressor, err := zstd.NewWriter(
+ &compressed,
+ zstd.WithEncoderLevel(zstd.SpeedDefault),
+ )
if err != nil {
return err
}
- if _, err = io.Copy(compressor, bytes.NewReader(body)); err != nil {
+ _, err = io.Copy(compressor, in)
+ compressor.Close()
+ if err != nil {
return err
}
- compressor.Close()
size := int64(compressed.Len())
_, err = ctx.Tx(node, pkt, nice, size, minSize, &compressed)
sds := SDS{
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
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
+++ /dev/null
-#!/bin/sh
-
-texi=`mktemp`
-
-cat > $texi <<EOF
-\input texinfo
-@documentencoding UTF-8
-@settitle NEWS
-
-@node News
-@unnumbered News
-
-`sed -n '5,$p' < doc/news.texi`
-
-@bye
-EOF
-makeinfo --plaintext -o NEWS $texi
-
-cat > $texi <<EOF
-\input texinfo
-@documentencoding UTF-8
-@settitle NEWS.RU
-
-@node Новости
-@unnumbered Новости
-
-`sed -n '3,$p' < doc/news.ru.texi | sed 's/^@subsection/@section/'`
-
-@bye
-EOF
-makeinfo --plaintext -o NEWS.RU $texi
-
-rm -f $texi
-
-texi=$(TMPDIR=doc mktemp)
-cat > $texi <<EOF
-\input texinfo
-@documentencoding UTF-8
-@settitle INSTALL
-
-@include install.texi
-
-@bye
-EOF
-makeinfo --plaintext -o INSTALL $texi
-rm -f $texi
-
-texi=`mktemp`
-
-cat > $texi <<EOF
-\input texinfo
-@documentencoding UTF-8
-@settitle THANKS
-
-`cat doc/thanks.texi`
-
-@bye
-EOF
-makeinfo --plaintext -o THANKS $texi
-rm -f $texi