From ce5b0763fb453cb6c0b8008178d1fb7d6bb712b3 Mon Sep 17 00:00:00 2001 From: Alexander Pevzner Date: Tue, 3 Dec 2024 12:26:03 +0300 Subject: [PATCH] Added alternative syntax for delays in the quirks. Delay (init-delay, request-delay etc) can now be specified using the following synax: init-delay = 15s This is more convenient, especially for delays bigger that a couple of seconds, that old syntax. Old syntax is also supported. See ipp-usb manual page for details. Tests and manual page are updated. --- ipp-usb.8 | 18 ++++++++++-------- ipp-usb.8.md | 21 +++++++++++++-------- quirks.go | 23 ++++++++++++++++++++--- quirks_test.go | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 19 deletions(-) diff --git a/ipp-usb.8 b/ipp-usb.8 index 89dfc12..015b91d 100644 --- a/ipp-usb.8 +++ b/ipp-usb.8 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "IPP\-USB" "8" "November 2024" "" "ipp-usb.8" +.TH "IPP\-USB" "8" "December 2024" "" "ipp-usb.8" .SH "NAME" \fBipp\-usb\fR \- Daemon for IPP over USB printer support .SH "DESCRIPTION" @@ -278,33 +278,35 @@ Some devices send buggy (malformed) IPP responses that violate IPP specification .IP "\(bu" 4 \fBdisable\-fax = true | false\fR .br -If \fBtrue\fR, the matching device's fax capability is ignored +If \fBtrue\fR, the matching device's fax capability is ignored\. .IP "\(bu" 4 \fBhttp\-XXX = YYY\fR .br -Set XXX header of the HTTP requests forwarded to device to YYY\. If YYY is empty string, XXX header is removed +Set XXX header of the HTTP requests forwarded to device to YYY\. If YYY is empty string, XXX header is removed\. .IP "\(bu" 4 \fBignore\-ipp\-status = true | false\fR .br If \fBtrue\fR, IPP status of IPP requests sent by the \fBipp\-usb\fR by itself will be ignored\. This quirk is useful, when device correctly handles IPP request but returned status is not reliable\. Affects only \fBipp\-usb\fR initialization\. .IP "\(bu" 4 -\fBinit\-delay = NNN\fR +\fBinit\-delay = DELAY\fR .br -Delay, in milliseconds, between device is opened and, optionally, reset, and the first request is sent to device +Delay, between device is opened and, optionally, reset, and the first request is sent to device\. .IP "\(bu" 4 \fBinit\-reset = none | soft | hard\fR .br How to reset device during initialization\. Default is \fBnone\fR .IP "\(bu" 4 -\fBrequest\-delay\fR = NNN +\fBrequest\-delay\fR = DELAY .br -Delay, in milliseconds, between subsequent requests +Delay, between subsequent requests\. .IP "\(bu" 4 \fBusb\-max\-interfaces = N\fR .br -Don't use more that N USB interfaces, even if more is available +Don't use more that N USB interfaces, even if more is available\. .IP "" 0 .P +The DELAY parameter can be specified either as an unsigned integer (in milliseconds) or as a sequence of decimal numbers with an optional fraction and a unit suffix, such as "300ms," "0\.5s," or "2m30s\." Valid time units are "ns," "us" (or "µs"), "ms," "s," "m," and "h\." +.P If you found out about your device that it needs a quirk to work properly or it does not work with \fBipp\-usb\fR at all, although it provides IPP\-over\-USB interface, please report the issue at https://github\.com/OpenPrinting/ipp\-usb\. It will let us to update our collection of quirks, so helping other owners of such a device\. .SH "FILES" .IP "\(bu" 4 diff --git a/ipp-usb.8.md b/ipp-usb.8.md index 00b1c67..a05db18 100644 --- a/ipp-usb.8.md +++ b/ipp-usb.8.md @@ -359,11 +359,11 @@ The following parameters are defined: as well) or `sanitize` them (fix IPP specs violations). * `disable-fax = true | false`
- If `true`, the matching device's fax capability is ignored + If `true`, the matching device's fax capability is ignored. * `http-XXX = YYY`
Set XXX header of the HTTP requests forwarded to device to YYY. - If YYY is empty string, XXX header is removed + If YYY is empty string, XXX header is removed. * `ignore-ipp-status = true | false`
If `true`, IPP status of IPP requests sent by the `ipp-usb` by @@ -371,18 +371,23 @@ The following parameters are defined: handles IPP request but returned status is not reliable. Affects only `ipp-usb` initialization. - * `init-delay = NNN`
- Delay, in milliseconds, between device is opened and, optionally, - reset, and the first request is sent to device + * `init-delay = DELAY `
+ Delay, between device is opened and, optionally, reset, and the + first request is sent to device. * `init-reset = none | soft | hard`
How to reset device during initialization. Default is `none` - * `request-delay` = NNN
- Delay, in milliseconds, between subsequent requests + * `request-delay` = DELAY
+ Delay, between subsequent requests. * `usb-max-interfaces = N`
- Don't use more that N USB interfaces, even if more is available + Don't use more that N USB interfaces, even if more is available. + +The DELAY parameter can be specified either as an unsigned integer (in +milliseconds) or as a sequence of decimal numbers with an optional +fraction and a unit suffix, such as "300ms," "0.5s," or "2m30s." Valid +time units are "ns," "us" (or "µs"), "ms," "s," "m," and "h." If you found out about your device that it needs a quirk to work properly or it does not work with `ipp-usb` at all, although it provides IPP-over-USB diff --git a/quirks.go b/quirks.go index cc6953c..d10fbe8 100644 --- a/quirks.go +++ b/quirks.go @@ -118,13 +118,30 @@ func (q *Quirk) parseUint() error { // parseDuration parses [Quirk.RawValue] as time.Duration. func (q *Quirk) parseDuration() error { + // Try to parse as uint. If OK, interpret it + // as a millisecond time. ms, err := strconv.ParseUint(q.RawValue, 10, 32) - if err != nil { + if err == nil { + q.Parsed = time.Millisecond * time.Duration(ms) + return nil + } + + // Try to use time.ParseDuration. + // + if strings.HasPrefix(q.RawValue, "+") || + strings.HasPrefix(q.RawValue, "-") { + // Note, time.ParseDuration allows signed duration, + // but we don't. return fmt.Errorf("%q: invalid duration", q.RawValue) } - q.Parsed = time.Millisecond * time.Duration(ms) - return nil + v, err := time.ParseDuration(q.RawValue) + if err == nil && v >= 0 { + q.Parsed = v + return nil + } + + return fmt.Errorf("%q: invalid duration", q.RawValue) } // parseQuirkBuggyIppRsp parses [Quirk.RawValue] as QuirkBuggyIppRsp. diff --git a/quirks_test.go b/quirks_test.go index f5734a6..a53c9c9 100644 --- a/quirks_test.go +++ b/quirks_test.go @@ -239,12 +239,44 @@ func TestQuirksParsers(t *testing.T) { value: time.Duration(0), }, + { + parser: (*Quirk).parseDuration, + input: "0s", + value: time.Duration(0), + }, + { parser: (*Quirk).parseDuration, input: "12345", value: 12345 * time.Millisecond, }, + { + parser: (*Quirk).parseDuration, + input: "1h2m3s", + value: time.Hour + + 2*time.Minute + + 3*time.Second, + }, + + { + parser: (*Quirk).parseDuration, + input: "0.5s", + value: time.Second / 2, + }, + + { + parser: (*Quirk).parseDuration, + input: "+0s", + err: `"+0s": invalid duration`, + }, + + { + parser: (*Quirk).parseDuration, + input: "-0s", + err: `"-0s": invalid duration`, + }, + { parser: (*Quirk).parseDuration, input: "hello",