]> Cypherpunks.ru repositories - nncp.git/commitdiff
On demand calling
authorSergey Matveev <stargrave@stargrave.org>
Sat, 23 Jan 2021 14:57:25 +0000 (17:57 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Sat, 23 Jan 2021 14:57:25 +0000 (17:57 +0300)
13 files changed:
bin/cmd.list
doc/call.texi
doc/cmds.texi
doc/cronexpr.texi [new file with mode: 0644]
doc/news.ru.texi
doc/news.texi
ports/nncp/Makefile
ports/nncp/pkg-plist
src/call.go
src/cfg.go
src/cmd/nncp-caller/main.go
src/cmd/nncp-cfgnew/main.go
src/cmd/nncp-cronexpr/main.go [new file with mode: 0644]

index 6c4cf7227f382926528a513a604e57fd489bc221..7797d4f7a678cbd9909645ec47dff7dacde90391 100644 (file)
@@ -5,6 +5,7 @@ nncp-cfgenc
 nncp-cfgmin
 nncp-cfgnew
 nncp-check
 nncp-cfgmin
 nncp-cfgnew
 nncp-check
+nncp-cronexpr
 nncp-daemon
 nncp-exec
 nncp-file
 nncp-daemon
 nncp-exec
 nncp-file
index ac24b2a98764ee79838b36561fb46d44791bcf2c..81ee9bafd465a0b5d15044c3406fc035b5d431f6 100644 (file)
@@ -28,6 +28,10 @@ calls: [
         xx: rx
         addr: lan
     },
         xx: rx
         addr: lan
     },
+    {
+        cron: "*/5 * * * * * *"
+        when-tx-exists: true
+    },
 ]
 @end verbatim
 
 ]
 @end verbatim
 
@@ -46,122 +50,7 @@ It contains the following fields (only @emph{cron} is required):
 @table @emph
 
 @item cron
 @table @emph
 
 @item cron
-This is copy-pasted documentation from
-@code{github.com/gorhill/cronexpr} library used there.
-
-@multitable @columnfractions .2 .1 .2 .5
-@headitem Field name @tab Mandatory? @tab Allowed values @tab Allowed special characters
-
-@item Seconds @tab No @tab 0-59 @tab @verb{|* / , -|}
-@item Minutes @tab Yes @tab 0-59 @tab @verb{|* / , -|}
-@item Hours @tab Yes @tab 0-23 @tab @verb{|* / , -|}
-@item Day of month @tab Yes @tab 1-31 @tab @verb{|* / , - L W|}
-@item Month @tab Yes @tab 1-12 or JAN-DEC @tab @verb{|* / , -|}
-@item Day of week @tab Yes @tab 0-6 or SUN-SAT @tab @verb{|* / , - L #|}
-@item Year @tab No @tab 1970–2099 @tab @verb{|* / , -|}
-
-@end multitable
-
-@table @asis
-
-@item Asterisk (@verb{|*|})
-
-The asterisk indicates that the cron expression matches for all values
-of the field. E.g., using an asterisk in the 4th field (month) indicates
-every month.
-
-@item Slash (@verb{|/|})
-
-Slashes describe increments of ranges. For example @verb{|3-59/15|} in
-the minute field indicate the third minute of the hour and every 15
-minutes thereafter. The form @verb{|*/...|} is equivalent to the form
-"first-last/...", that is, an increment over the largest possible range
-of the field.
-
-@item Comma (@verb{|,|})
-
-Commas are used to separate items of a list. For example, using
-@verb{|MON,WED,FRI|} in the 5th field (day of week) means Mondays,
-Wednesdays and Fridays.
-
-@item Hyphen (@verb{|-|})
-
-Hyphens define ranges. For example, 2000-2010 indicates every year
-between 2000 and 2010 AD, inclusive.
-
-@item L
-
-@verb{|L|} stands for "last". When used in the day-of-week field, it
-allows you to specify constructs such as "the last Friday" (@verb{|5L|})
-of a given month. In the day-of-month field, it specifies the last day
-of the month.
-
-@item W
-
-The @verb{|W|} character is allowed for the day-of-month field. This
-character is used to specify the business day (Monday-Friday) nearest
-the given day. As an example, if you were to specify @verb{|15W|} as the
-value for the day-of-month field, the meaning is: "the nearest business
-day to the 15th of the month."
-
-So, if the 15th is a Saturday, the trigger fires on Friday the 14th. If
-the 15th is a Sunday, the trigger fires on Monday the 16th. If the 15th
-is a Tuesday, then it fires on Tuesday the 15th. However if you specify
-@verb{|1W|} as the value for day-of-month, and the 1st is a Saturday,
-the trigger fires on Monday the 3rd, as it does not 'jump' over the
-boundary of a month's days.
-
-The @verb{|W|} character can be specified only when the day-of-month is
-a single day, not a range or list of days.
-
-The @verb{|W|} character can also be combined with @verb{|L|}, i.e.
-@verb{|LW|} to mean "the last business day of the month."
-
-@item Hash (@verb{|#|})
-
-@verb{|#|} is allowed for the day-of-week field, and must be followed by
-a number between one and five. It allows you to specify constructs such
-as "the second Friday" of a given month.
-
-@end table
-
-Predefined cron expressions:
-
-@multitable @columnfractions .1 .75 .15
-@headitem Entry @tab Description @tab Equivalent to
-@item @verb{|@annually|} @tab
-    Run once a year at midnight in the morning of January 1 @tab
-    @verb{|0 0 0 1 1 * *|}
-@item @verb{|@yearly|} @tab
-    Run once a year at midnight in the morning of January 1 @tab
-    @verb{|0 0 0 1 1 * *|}
-@item @verb{|@monthly|} @tab
-    Run once a month at midnight in the morning of the first of the month @tab
-    @verb{|0 0 0 1 * * *|}
-@item @verb{|@weekly|} @tab
-    Run once a week at midnight in the morning of Sunday @tab
-    @verb{|0 0 0 * * 0 *|}
-@item @verb{|@daily|} @tab
-    Run once a day at midnight @tab
-    @verb{|0 0 0 * * * *|}
-@item @verb{|@hourly|} @tab
-    Run once an hour at the beginning of the hour @tab
-    @verb{|0 0 * * * * *|}
-@end multitable
-
-@itemize
-@item
-If only six fields are present, a @verb{|0|} second field is prepended,
-that is, @verb{|* * * * * 2013|} internally become
-@verb{|0 * * * * * 2013|}.
-@item
-If only five fields are present, a @verb{|0|} second field is prepended
-and a wildcard year field is appended, that is, @verb{|* * * * Mon|}
-internally become @verb{|0 * * * * Mon *|}.
-@item
-Domain for day-of-week field is [0-7] instead of [0-6], 7 being Sunday
-(like 0). This to comply with @url{https://linux.die.net/man/5/crontab}.
-@end itemize
+@include cronexpr.texi
 
 @item nice
 Optional. Use that @ref{Niceness, niceness} during the call (255 is used
 
 @item nice
 Optional. Use that @ref{Niceness, niceness} during the call (255 is used
@@ -193,4 +82,7 @@ Optionally enable auto tossing: run tosser on node's spool every second
 during the call. You can control either are @file{.seen} files must be
 created, or skip any kind of packet processing.
 
 during the call. You can control either are @file{.seen} files must be
 created, or skip any kind of packet processing.
 
+@item when-tx-exists
+Call only if packets for sending exists.
+
 @end table
 @end table
index ae7bd52824db6b5346220341612a1bfa223719ee..e7e21ea9bdbe1c44a4561c0949a4b748bf9165a8 100644 (file)
@@ -238,6 +238,16 @@ that has Base32-encoded filenames and compare it with recalculated
 BLAKE2b hash output of their contents. That supplementary command is
 not used often in practice, if ever.
 
 BLAKE2b hash output of their contents. That supplementary command is
 not used often in practice, if ever.
 
+@node nncp-cronexpr
+@section nncp-cronexpr
+
+@example
+$ nncp-cronexpr -num 12 "*/1 * * * * SAT,SUN 2021"
+@end example
+
+Check validity of specified @ref{CronExpr, cron expression} and print 12
+next time entities.
+
 @node nncp-daemon
 @section nncp-daemon
 
 @node nncp-daemon
 @section nncp-daemon
 
diff --git a/doc/cronexpr.texi b/doc/cronexpr.texi
new file mode 100644 (file)
index 0000000..3331b12
--- /dev/null
@@ -0,0 +1,117 @@
+@anchor{CronExpr}
+This is copy-pasted documentation from
+@code{github.com/gorhill/cronexpr} library used there.
+
+@multitable @columnfractions .2 .1 .2 .5
+@headitem Field name @tab Mandatory? @tab Allowed values @tab Allowed special characters
+
+@item Seconds @tab No @tab 0-59 @tab @verb{|* / , -|}
+@item Minutes @tab Yes @tab 0-59 @tab @verb{|* / , -|}
+@item Hours @tab Yes @tab 0-23 @tab @verb{|* / , -|}
+@item Day of month @tab Yes @tab 1-31 @tab @verb{|* / , - L W|}
+@item Month @tab Yes @tab 1-12 or JAN-DEC @tab @verb{|* / , -|}
+@item Day of week @tab Yes @tab 0-6 or SUN-SAT @tab @verb{|* / , - L #|}
+@item Year @tab No @tab 1970–2099 @tab @verb{|* / , -|}
+
+@end multitable
+
+@table @asis
+
+@item Asterisk (@verb{|*|})
+
+The asterisk indicates that the cron expression matches for all values
+of the field. E.g., using an asterisk in the 4th field (month) indicates
+every month.
+
+@item Slash (@verb{|/|})
+
+Slashes describe increments of ranges. For example @verb{|3-59/15|} in
+the minute field indicate the third minute of the hour and every 15
+minutes thereafter. The form @verb{|*/...|} is equivalent to the form
+"first-last/...", that is, an increment over the largest possible range
+of the field.
+
+@item Comma (@verb{|,|})
+
+Commas are used to separate items of a list. For example, using
+@verb{|MON,WED,FRI|} in the 5th field (day of week) means Mondays,
+Wednesdays and Fridays.
+
+@item Hyphen (@verb{|-|})
+
+Hyphens define ranges. For example, 2000-2010 indicates every year
+between 2000 and 2010 AD, inclusive.
+
+@item L
+
+@verb{|L|} stands for "last". When used in the day-of-week field, it
+allows you to specify constructs such as "the last Friday" (@verb{|5L|})
+of a given month. In the day-of-month field, it specifies the last day
+of the month.
+
+@item W
+
+The @verb{|W|} character is allowed for the day-of-month field. This
+character is used to specify the business day (Monday-Friday) nearest
+the given day. As an example, if you were to specify @verb{|15W|} as the
+value for the day-of-month field, the meaning is: "the nearest business
+day to the 15th of the month."
+
+So, if the 15th is a Saturday, the trigger fires on Friday the 14th. If
+the 15th is a Sunday, the trigger fires on Monday the 16th. If the 15th
+is a Tuesday, then it fires on Tuesday the 15th. However if you specify
+@verb{|1W|} as the value for day-of-month, and the 1st is a Saturday,
+the trigger fires on Monday the 3rd, as it does not 'jump' over the
+boundary of a month's days.
+
+The @verb{|W|} character can be specified only when the day-of-month is
+a single day, not a range or list of days.
+
+The @verb{|W|} character can also be combined with @verb{|L|}, i.e.
+@verb{|LW|} to mean "the last business day of the month."
+
+@item Hash (@verb{|#|})
+
+@verb{|#|} is allowed for the day-of-week field, and must be followed by
+a number between one and five. It allows you to specify constructs such
+as "the second Friday" of a given month.
+
+@end table
+
+Predefined cron expressions:
+
+@multitable @columnfractions .1 .75 .15
+@headitem Entry @tab Description @tab Equivalent to
+@item @verb{|@annually|} @tab
+    Run once a year at midnight in the morning of January 1 @tab
+    @verb{|0 0 0 1 1 * *|}
+@item @verb{|@yearly|} @tab
+    Run once a year at midnight in the morning of January 1 @tab
+    @verb{|0 0 0 1 1 * *|}
+@item @verb{|@monthly|} @tab
+    Run once a month at midnight in the morning of the first of the month @tab
+    @verb{|0 0 0 1 * * *|}
+@item @verb{|@weekly|} @tab
+    Run once a week at midnight in the morning of Sunday @tab
+    @verb{|0 0 0 * * 0 *|}
+@item @verb{|@daily|} @tab
+    Run once a day at midnight @tab
+    @verb{|0 0 0 * * * *|}
+@item @verb{|@hourly|} @tab
+    Run once an hour at the beginning of the hour @tab
+    @verb{|0 0 * * * * *|}
+@end multitable
+
+@itemize
+@item
+If only six fields are present, a @verb{|0|} second field is prepended,
+that is, @verb{|* * * * * 2013|} internally become
+@verb{|0 * * * * * 2013|}.
+@item
+If only five fields are present, a @verb{|0|} second field is prepended
+and a wildcard year field is appended, that is, @verb{|* * * * Mon|}
+internally become @verb{|0 * * * * Mon *|}.
+@item
+Domain for day-of-week field is [0-7] instead of [0-6], 7 being Sunday
+(like 0). This to comply with @url{https://linux.die.net/man/5/crontab}.
+@end itemize
index 1a65a501f71ffea8ec1e024cc4ea59e6a15db25e..6c42a2a85d2747f1f23c56c8fed91f4a55c2fba9 100644 (file)
@@ -9,6 +9,16 @@
 Работоспособность @option{-autotoss*} опции с @option{-inetd} режимом
 @command{nncp-daemon}.
 
 Работоспособность @option{-autotoss*} опции с @option{-inetd} режимом
 @command{nncp-daemon}.
 
+@item
+@option{when-tx-exists} опция вызова в конфигурационном файле позволяет
+делать вызов только если имеются исходящие сообщения. Совмещённая с cron
+выражением содержащим секунды, это можно использовать как возможность
+вызова только при появлении исходящих пакетов.
+
+@item
+@command{nncp-cronexpr} команда позволяет проверить корректность и
+ожидаемый результат от указанного cron выражения.
+
 @end itemize
 
 @node Релиз 5.6.0
 @end itemize
 
 @node Релиз 5.6.0
index 1bd2f44e15f0c776a25ed8f6b66f36c284826f83..ebd48da449fe46b728fd9aa419e1d732b05124ce 100644 (file)
@@ -11,6 +11,15 @@ See also this page @ref{Новости, on russian}.
 @option{-autotoss*} option workability with @command{nncp-daemon}'s
 @option{-inetd} mode.
 
 @option{-autotoss*} option workability with @command{nncp-daemon}'s
 @option{-inetd} mode.
 
+@item
+Call's @option{when-tx-exists} allows to make a call only when outbound
+packets exists. Combined with seconds-aware cron expression that can be
+used as some kind of auto dialler.
+
+@item
+@command{nncp-cronexpr} command allows you to check validity and
+expectations of specified cron expression.
+
 @end itemize
 
 @node Release 5.6.0
 @end itemize
 
 @node Release 5.6.0
index b846f49bc4ace307aadfaf62075f6425e2f65747..0ced51bae4e6684f590768786ec0f008b1a66871 100644 (file)
@@ -1,7 +1,7 @@
 # $FreeBSD: $
 
 PORTNAME=      nncp
 # $FreeBSD: $
 
 PORTNAME=      nncp
-DISTVERSION=   5.5.1
+DISTVERSION=   5.7.0
 CATEGORIES=    net
 MASTER_SITES=  http://www.nncpgo.org/download/
 
 CATEGORIES=    net
 MASTER_SITES=  http://www.nncpgo.org/download/
 
index e7d9c876e74c18da5ac47065104d46008ab2de58..4a584028612e2fc58654072ac010f4328e2710f5 100644 (file)
@@ -5,6 +5,7 @@ bin/nncp-cfgenc
 bin/nncp-cfgmin
 bin/nncp-cfgnew
 bin/nncp-check
 bin/nncp-cfgmin
 bin/nncp-cfgnew
 bin/nncp-check
+bin/nncp-cronexpr
 bin/nncp-daemon
 bin/nncp-exec
 bin/nncp-file
 bin/nncp-daemon
 bin/nncp-exec
 bin/nncp-file
index 87fb5aeef9a76769163ee6f78be87790c39e6404..1635b3042c77036b697421b601e821dc8dcaf176 100644 (file)
@@ -33,6 +33,7 @@ type Call struct {
        Addr           *string
        OnlineDeadline time.Duration
        MaxOnlineTime  time.Duration
        Addr           *string
        OnlineDeadline time.Duration
        MaxOnlineTime  time.Duration
+       WhenTxExists   bool
 
        AutoToss       bool
        AutoTossDoSeen bool
 
        AutoToss       bool
        AutoTossDoSeen bool
index a72d371c141fecd588e8762fa2a758ece1ed18bd..946243396b7403c99aa499e22fd870a123516365 100644 (file)
@@ -81,6 +81,7 @@ type CallJSON struct {
        Addr           *string `json:"addr,omitempty"`
        OnlineDeadline *uint   `json:"onlinedeadline,omitempty"`
        MaxOnlineTime  *uint   `json:"maxonlinetime,omitempty"`
        Addr           *string `json:"addr,omitempty"`
        OnlineDeadline *uint   `json:"onlinedeadline,omitempty"`
        MaxOnlineTime  *uint   `json:"maxonlinetime,omitempty"`
+       WhenTxExists   *bool   `json:"when-tx-exists,omitempty"`
 
        AutoToss       *bool `json:"autotoss,omitempty"`
        AutoTossDoSeen *bool `json:"autotoss-doseen,omitempty"`
 
        AutoToss       *bool `json:"autotoss,omitempty"`
        AutoTossDoSeen *bool `json:"autotoss-doseen,omitempty"`
@@ -280,6 +281,9 @@ func NewNode(name string, cfg NodeJSON) (*Node, error) {
                if callCfg.MaxOnlineTime != nil {
                        call.MaxOnlineTime = time.Duration(*callCfg.MaxOnlineTime) * time.Second
                }
                if callCfg.MaxOnlineTime != nil {
                        call.MaxOnlineTime = time.Duration(*callCfg.MaxOnlineTime) * time.Second
                }
+               if callCfg.WhenTxExists != nil {
+                       call.WhenTxExists = *callCfg.WhenTxExists
+               }
                if callCfg.AutoToss != nil {
                        call.AutoToss = *callCfg.AutoToss
                }
                if callCfg.AutoToss != nil {
                        call.AutoToss = *callCfg.AutoToss
                }
index 826033c334526166c530c1c8330226dac055080c..f7ab13c23299cc301608920776df84f417266042 100644 (file)
@@ -134,6 +134,25 @@ func main() {
                                                node.Busy = true
                                                node.Unlock()
 
                                                node.Busy = true
                                                node.Unlock()
 
+                                               if call.WhenTxExists && call.Xx != "TRx" {
+                                                       ctx.LogD("caller", sds, "checking tx existence")
+                                                       txExists := false
+                                                       for job := range ctx.Jobs(node.Id, nncp.TTx) {
+                                                               job.Fd.Close()
+                                                               if job.PktEnc.Nice > call.Nice {
+                                                                       continue
+                                                               }
+                                                               txExists = true
+                                                       }
+                                                       if !txExists {
+                                                               ctx.LogD("caller", sds, "no tx")
+                                                               node.Lock()
+                                                               node.Busy = false
+                                                               node.Unlock()
+                                                               continue
+                                                       }
+                                               }
+
                                                var autoTossFinish chan struct{}
                                                var autoTossBadCode chan bool
                                                if call.AutoToss {
                                                var autoTossFinish chan struct{}
                                                var autoTossBadCode chan bool
                                                if call.AutoToss {
index 93f3749df41be8180fc10f9c4261c76dce389666..798f31cdb534f0e893ba495211df0611c3d136b5 100644 (file)
@@ -210,6 +210,7 @@ func main() {
     #   #     txrate: 20
     #   #     xx: rx
     #   #     addr: lan
     #   #     txrate: 20
     #   #     xx: rx
     #   #     addr: lan
+    #   #     when-tx-exists: true
     #   #
     #   #     autotoss: false
     #   #     autotoss-doseen: true
     #   #
     #   #     autotoss: false
     #   #     autotoss-doseen: true
diff --git a/src/cmd/nncp-cronexpr/main.go b/src/cmd/nncp-cronexpr/main.go
new file mode 100644 (file)
index 0000000..c9b4010
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+NNCP -- Node to Node copy, utilities for store-and-forward data exchange
+Copyright (C) 2016-2021 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/>.
+*/
+
+// NNCP cron expression checker.
+package main
+
+import (
+       "flag"
+       "fmt"
+       "log"
+       "os"
+       "strings"
+       "time"
+
+       "github.com/gorhill/cronexpr"
+       "go.cypherpunks.ru/nncp/v5"
+)
+
+func usage() {
+       fmt.Fprintf(os.Stderr, nncp.UsageHeader())
+       fmt.Fprintf(os.Stderr, "nncp-cronexpr -- cron expression checker\n\n")
+       fmt.Fprintf(os.Stderr, "Usage: %s [-num XXX] CRON-EXPRESSION\n", os.Args[0])
+       flag.PrintDefaults()
+}
+
+func main() {
+       var (
+               num      = flag.Uint("num", 10, "Number of future entries to print")
+               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
+       }
+
+       expr, err := cronexpr.Parse(strings.Join(flag.Args(), " "))
+       if err != nil {
+               log.Fatalln(err)
+       }
+       now := time.Now()
+       fmt.Printf("Now:\t%s\n", now.UTC().Format(time.RFC3339Nano))
+       for n, t := range expr.NextN(now, *num) {
+               fmt.Printf("%d:\t%s\n", n, t.UTC().Format(time.RFC3339Nano))
+       }
+}