]> 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-cronexpr
 nncp-daemon
 nncp-exec
 nncp-file
index ac24b2a98764ee79838b36561fb46d44791bcf2c..81ee9bafd465a0b5d15044c3406fc035b5d431f6 100644 (file)
@@ -28,6 +28,10 @@ calls: [
         xx: rx
         addr: lan
     },
+    {
+        cron: "*/5 * * * * * *"
+        when-tx-exists: true
+    },
 ]
 @end verbatim
 
@@ -46,122 +50,7 @@ It contains the following fields (only @emph{cron} is required):
 @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
@@ -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.
 
+@item when-tx-exists
+Call only if packets for sending exists.
+
 @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.
 
+@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
 
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}.
 
+@item
+@option{when-tx-exists} опция вызова в конфигурационном файле позволяет
+делать вызов только если имеются исходящие сообщения. Совмещённая с cron
+выражением содержащим секунды, это можно использовать как возможность
+вызова только при появлении исходящих пакетов.
+
+@item
+@command{nncp-cronexpr} команда позволяет проверить корректность и
+ожидаемый результат от указанного cron выражения.
+
 @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.
 
+@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
index b846f49bc4ace307aadfaf62075f6425e2f65747..0ced51bae4e6684f590768786ec0f008b1a66871 100644 (file)
@@ -1,7 +1,7 @@
 # $FreeBSD: $
 
 PORTNAME=      nncp
-DISTVERSION=   5.5.1
+DISTVERSION=   5.7.0
 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-cronexpr
 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
+       WhenTxExists   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"`
+       WhenTxExists   *bool   `json:"when-tx-exists,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.WhenTxExists != nil {
+                       call.WhenTxExists = *callCfg.WhenTxExists
+               }
                if callCfg.AutoToss != nil {
                        call.AutoToss = *callCfg.AutoToss
                }
index 826033c334526166c530c1c8330226dac055080c..f7ab13c23299cc301608920776df84f417266042 100644 (file)
@@ -134,6 +134,25 @@ func main() {
                                                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 {
index 93f3749df41be8180fc10f9c4261c76dce389666..798f31cdb534f0e893ba495211df0611c3d136b5 100644 (file)
@@ -210,6 +210,7 @@ func main() {
     #   #     txrate: 20
     #   #     xx: rx
     #   #     addr: lan
+    #   #     when-tx-exists: 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))
+       }
+}