1 // NNCP -- Node to Node copy, utilities for store-and-forward data exchange
2 // Copyright (C) 2016-2024 Sergey Matveev <stargrave@stargrave.org>
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, version 3 of the License.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program. If not, see <http://www.gnu.org/licenses/>.
33 Neigh map[NodeId]*Node
34 Alias map[string]*NodeId
36 AreaId2Area map[AreaId]*Area
37 AreaName2Id map[string]*AreaId
46 NotifyFile *FromToJSON
47 NotifyFreq *FromToJSON
48 NotifyExec map[string]*FromToJSON
51 MCDTxIfis map[string]int
53 YggdrasilAliases map[string]string
56 func (ctx *Ctx) FindNode(id string) (*Node, error) {
57 nodeId, known := ctx.Alias[id]
59 return ctx.Neigh[*nodeId], nil
61 nodeId, err := NodeIdFromString(id)
65 node, known := ctx.Neigh[*nodeId]
67 return nil, errors.New("Unknown node")
72 func ensureDir(dirs ...string) error {
73 p := filepath.Join(dirs...)
79 return fmt.Errorf("%s: is not a directory", p)
81 if !errors.Is(err, fs.ErrNotExist) {
84 return os.MkdirAll(p, os.FileMode(0777))
87 func (ctx *Ctx) ensureRxDir(nodeId *NodeId) error {
88 dirPath := filepath.Join(ctx.Spool, nodeId.String(), string(TRx))
89 err := ensureDir(dirPath)
91 ctx.LogE("dir-ensure-mkdir", LEs{{"Dir", dirPath}}, err, func(les LEs) string {
92 return fmt.Sprintf("Ensuring directory %s existence", dirPath)
99 cfgPath, spoolPath, logPath string,
100 quiet, showPrgrs, omitPrgrs, debug bool,
102 env := os.Getenv(CfgPathEnv)
106 if showPrgrs && omitPrgrs {
107 return nil, errors.New("simultaneous -progress and -noprogress")
109 fi, err := os.Stat(cfgPath)
115 cfg, err = DirToCfg(cfgPath)
120 cfgRaw, err := os.ReadFile(cfgPath)
124 cfg, err = CfgParse(cfgRaw)
129 ctx, err := Cfg2Ctx(cfg)
134 env = os.Getenv(CfgSpoolEnv)
139 ctx.Spool = spoolPath
142 env = os.Getenv(CfgLogEnv)
147 ctx.LogPath = logPath
149 if strings.HasPrefix(ctx.LogPath, LogFdPrefix) {
150 ptr, err := strconv.ParseUint(
151 strings.TrimPrefix(ctx.LogPath, LogFdPrefix), 10, 64,
156 LogFd = os.NewFile(uintptr(ptr), CfgLogEnv)
158 return nil, errors.New("can not open:" + ctx.LogPath)
164 if quiet || omitPrgrs {
165 ctx.ShowPrgrs = false
172 func (ctx *Ctx) Umask() {
173 if ctx.UmaskForce != nil {
174 syscall.Umask(*ctx.UmaskForce)