From: Sergey Matveev Date: Sun, 28 Sep 2025 08:40:42 +0000 (+0300) Subject: Ability to read configuration from file descriptor X-Git-Tag: v8.13.0^2~3 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=547f6228b20fa70046124d6124243f7927c595e4;p=nncp.git Ability to read configuration from file descriptor --- diff --git a/doc/cmd/index.texi b/doc/cmd/index.texi index fa2b38e..984a3bc 100644 --- a/doc/cmd/index.texi +++ b/doc/cmd/index.texi @@ -8,8 +8,10 @@ Nearly all commands have the following common options: @vindex NNCPCFG @item -cfg Path to configuration file. May be overridden by @env{$NNCPCFG} - environment variable. If file file is an encrypted @ref{EBlob, - eblob}, then ask for passphrase to decrypt it first. + environment variable. If file file is an encrypted @ref{EBlob, eblob}, + then ask for passphrase to decrypt it first. + If it equals to @code{FD:x}, then read configration file from opened + file descriptor @code{x}. @item -debug Print debug messages. Normally this option should not be used. @item -minsize diff --git a/doc/news.ru.texi b/doc/news.ru.texi index de3e026..5db31b5 100644 --- a/doc/news.ru.texi +++ b/doc/news.ru.texi @@ -1,6 +1,16 @@ @node Новости @section Новости +@node Релиз 8.13.0 +@subsection Релиз 8.13.0 +@itemize + +@item +Возможно передавать конфигурационный факт через открытый файловый +дескриптор (@env{$NNCPCFG=FD:0} например для чтения из stdin). + +@end itemize + @node Релиз 8.12.1 @subsection Релиз 8.12.1 @itemize diff --git a/doc/news.texi b/doc/news.texi index 61a1191..20f274e 100644 --- a/doc/news.texi +++ b/doc/news.texi @@ -4,6 +4,16 @@ See also this page @ref{Новости, in russian}. +@node Release 8_13_0 +@section Release 8.13.0 +@itemize + +@item +Ability to pass configuration file through opened file descriptor +(@env{$NNCPCFG=FD:0} for example to read it from stdin). + +@end itemize + @node Release 8_12_1 @section Release 8.12.1 @itemize diff --git a/src/ctx.go b/src/ctx.go index 680d940..8de89a0 100644 --- a/src/ctx.go +++ b/src/ctx.go @@ -18,6 +18,7 @@ package nncp import ( "errors" "fmt" + "io" "io/fs" "os" "path/filepath" @@ -27,6 +28,8 @@ import ( "syscall" ) +const FdPrefix = "FD:" + type Ctx struct { Self *NodeOur SelfId *NodeId @@ -95,6 +98,21 @@ func (ctx *Ctx) ensureRxDir(nodeId *NodeId) error { return err } +func openPossibleFd(pth, name string) (*os.File, error) { + if !strings.HasPrefix(pth, FdPrefix) { + return nil, nil + } + ptr, err := strconv.ParseUint(strings.TrimPrefix(pth, FdPrefix), 10, 64) + if err != nil { + return nil, err + } + fd := os.NewFile(uintptr(ptr), name) + if fd == nil { + err = fmt.Errorf("can not open: %s: %s", name, pth) + } + return fd, err +} + func CtxFromCmdline( cfgPath, spoolPath, logPath string, quiet, showPrgrs, omitPrgrs, debug bool, @@ -106,25 +124,41 @@ func CtxFromCmdline( if showPrgrs && omitPrgrs { return nil, errors.New("simultaneous -progress and -noprogress") } - fi, err := os.Stat(cfgPath) - if err != nil { - return nil, err - } var cfg *CfgJSON - if fi.IsDir() { - cfg, err = DirToCfg(cfgPath) - if err != nil { - return nil, err + if fd, err := openPossibleFd(cfgPath, CfgPathEnv); err == nil { + if fd == nil { + fi, err := os.Stat(cfgPath) + if err != nil { + return nil, err + } + if fi.IsDir() { + cfg, err = DirToCfg(cfgPath) + if err != nil { + return nil, err + } + } else { + cfgRaw, err := os.ReadFile(cfgPath) + if err != nil { + return nil, err + } + cfg, err = CfgParse(cfgRaw) + if err != nil { + return nil, err + } + } + } else { + cfgRaw, err := io.ReadAll(fd) + fd.Close() + if err != nil { + return nil, err + } + cfg, err = CfgParse(cfgRaw) + if err != nil { + return nil, err + } } } else { - cfgRaw, err := os.ReadFile(cfgPath) - if err != nil { - return nil, err - } - cfg, err = CfgParse(cfgRaw) - if err != nil { - return nil, err - } + return nil, err } ctx, err := Cfg2Ctx(cfg) if err != nil { @@ -146,17 +180,12 @@ func CtxFromCmdline( } else { ctx.LogPath = logPath } - if strings.HasPrefix(ctx.LogPath, LogFdPrefix) { - ptr, err := strconv.ParseUint( - strings.TrimPrefix(ctx.LogPath, LogFdPrefix), 10, 64, - ) - if err != nil { - return nil, err - } - LogFd = os.NewFile(uintptr(ptr), CfgLogEnv) - if LogFd == nil { - return nil, errors.New("can not open:" + ctx.LogPath) + if fd, err := openPossibleFd(ctx.LogPath, CfgLogEnv); err == nil { + if fd != nil { + LogFd = fd } + } else { + return nil, err } if showPrgrs { ctx.ShowPrgrs = true diff --git a/src/log.go b/src/log.go index 94309a6..201fb19 100644 --- a/src/log.go +++ b/src/log.go @@ -26,8 +26,6 @@ import ( "golang.org/x/sys/unix" ) -const LogFdPrefix = "FD:" - var ( LogFd *os.File LogFdLock sync.Mutex diff --git a/src/nncp.go b/src/nncp.go index b5e917a..653f2e1 100644 --- a/src/nncp.go +++ b/src/nncp.go @@ -39,7 +39,7 @@ along with this program. If not, see .` ) var ( - Version string = "8.12.1" + Version string = "8.13.0" Base32Codec *base32.Encoding = base32.StdEncoding.WithPadding(base32.NoPadding) )