Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package ripcalc for openSUSE:Factory checked in at 2026-05-26 16:34:03 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ripcalc (Old) and /work/SRC/openSUSE:Factory/.ripcalc.new.2084 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ripcalc" Tue May 26 16:34:03 2026 rev:6 rq:1355098 version:0.3.1 Changes: -------- --- /work/SRC/openSUSE:Factory/ripcalc/ripcalc.changes 2026-01-22 15:17:09.621681801 +0100 +++ /work/SRC/openSUSE:Factory/.ripcalc.new.2084/ripcalc.changes 2026-05-26 16:34:08.072251557 +0200 @@ -1,0 +2,6 @@ +Sun May 24 11:31:31 UTC 2026 - Andreas Stieger <[email protected]> + +- Update to version 0.3.1: + * General performance improvements + +------------------------------------------------------------------- Old: ---- ripcalc-0.3.0.obscpio ripcalc-0.3.0.tar.xz New: ---- ripcalc-0.3.1.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ripcalc.spec ++++++ --- /var/tmp/diff_new_pack.CQgCbI/_old 2026-05-26 16:34:10.724361280 +0200 +++ /var/tmp/diff_new_pack.CQgCbI/_new 2026-05-26 16:34:10.724361280 +0200 @@ -18,7 +18,7 @@ Name: ripcalc -Version: 0.3.0 +Version: 0.3.1 Release: 0 Summary: Tool for network addresses License: GPL-3.0-or-later ++++++ _service ++++++ --- /var/tmp/diff_new_pack.CQgCbI/_old 2026-05-26 16:34:10.760362770 +0200 +++ /var/tmp/diff_new_pack.CQgCbI/_new 2026-05-26 16:34:10.764362935 +0200 @@ -5,7 +5,7 @@ <param name="changesgenerate">enable</param> <param name="filename">ripcalc</param> <param name="versionformat">@PARENT_TAG@</param> - <param name="revision">v0.3.0</param> + <param name="revision">v0.3.1</param> <param name="versionrewrite-pattern">v(.*)</param> <param name="versionrewrite-replacement">\1</param> </service> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.CQgCbI/_old 2026-05-26 16:34:10.784363762 +0200 +++ /var/tmp/diff_new_pack.CQgCbI/_new 2026-05-26 16:34:10.788363928 +0200 @@ -1,7 +1,7 @@ <servicedata> <service name="tar_scm"> <param name="url">https://gitlab.com/edneville/ripcalc.git</param> - <param name="changesrevision">ca9f34e2696999173ca495068c80474bb53d8547</param> + <param name="changesrevision">d206b49b3b1447102c9220fd3e2a66be8c68fcb9</param> </service> </servicedata> (No newline at EOF) ++++++ ripcalc-0.3.0.obscpio -> ripcalc-0.3.1.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ripcalc-0.3.0/Cargo.lock new/ripcalc-0.3.1/Cargo.lock --- old/ripcalc-0.3.0/Cargo.lock 2025-12-28 23:45:21.000000000 +0100 +++ new/ripcalc-0.3.1/Cargo.lock 2026-05-21 21:26:33.000000000 +0200 @@ -661,12 +661,9 @@ [[package]] name = "ipnetwork" -version = "0.20.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf466541e9d546596ee94f9f69590f89473455f88372423e0008fc1a7daf100e" -dependencies = [ - "serde", -] +checksum = "cf370abdafd54d13e54a620e8c3e1145f28e46cc9d704bc6d94414559df41763" [[package]] name = "iri-string" @@ -720,14 +717,15 @@ [[package]] name = "maxminddb" -version = "0.24.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6087e5d8ea14861bb7c7f573afbc7be3798d3ef0fae87ec4fd9a4de9a127c3c" +checksum = "faf6467428ad055b71e588bcedcbaf2ff605b3251deb0c52be4a04b674c546dd" dependencies = [ "ipnetwork", "log", "memchr", "serde", + "thiserror", ] [[package]] @@ -1013,7 +1011,7 @@ [[package]] name = "ripcalc" -version = "0.3.0" +version = "0.3.1" dependencies = [ "cdb", "chrono", @@ -1283,6 +1281,26 @@ ] [[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] name = "tinystr" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ripcalc-0.3.0/Cargo.toml new/ripcalc-0.3.1/Cargo.toml --- old/ripcalc-0.3.0/Cargo.toml 2025-12-28 23:45:21.000000000 +0100 +++ new/ripcalc-0.3.1/Cargo.toml 2026-05-21 21:26:33.000000000 +0200 @@ -1,7 +1,7 @@ [package] name = "ripcalc" description = "ripcalc, format and lookup IP addresses" -version = "0.3.0" +version = "0.3.1" authors = ["ed neville <[email protected]>"] edition = "2018" license = "GPL-3.0-or-later" @@ -24,4 +24,4 @@ reqwest = { version = "0.12", features = ["blocking"] } serde_json = "1" chrono = "0.4" -maxminddb = "0.24" +maxminddb = "0.28" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ripcalc-0.3.0/Makefile new/ripcalc-0.3.1/Makefile --- old/ripcalc-0.3.0/Makefile 2025-12-28 23:45:21.000000000 +0100 +++ new/ripcalc-0.3.1/Makefile 2026-05-21 21:26:33.000000000 +0200 @@ -76,6 +76,7 @@ $(RELEASE) 192.168.1.1 --format '%r\n' | grep 'RFC 1918' >/dev/null $(RELEASE) 127.0.0.1 --format '%r\n' | grep 'Used for loopback addresses to the local host.' >/dev/null printf "192.168.1.1 this should match\n192.168.1.10 so should this\n192.168.2.1 this should not\n" | $(RELEASE) --filter --inside 192.168.1.0/24 --format cidr | wc -l | grep -Fx 2 >/dev/null + printf "192.168.1.1 this should match\n192.168.1.10 so should this\n192.168.2.1 this should not\n" | $(RELEASE) --filter 192.168.1.0/24 --format cidr | wc -l | grep -Fx 2 >/dev/null printf "192.168.1.1 this should match\n192.168.1.10 so should this\n192.168.2.1 this should not\n" | $(RELEASE) --filter 192.168.1.0/24 --format cidr --outside | wc -l | grep -Fx 1 >/dev/null printf "this should match 192.168.1.1\nthis should match 192.168.1.20\nthis should not 192.168.10.1\n" | $(RELEASE) --filternum 4 --inside 192.168.1.0/24 --format cidr | wc -l | grep -Fx 2 >/dev/null printf "this should match 192.168.1.1\nthis should match 192.168.1.20\nthis should not 192.168.10.1\n" | $(RELEASE) --filternum 4 --outside 192.168.1.0/24 --format cidr | wc -l | grep -Fx 1 >/dev/null diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ripcalc-0.3.0/README.md new/ripcalc-0.3.1/README.md --- old/ripcalc-0.3.0/README.md 2025-12-28 23:45:21.000000000 +0100 +++ new/ripcalc-0.3.1/README.md 2026-05-21 21:26:33.000000000 +0200 @@ -281,6 +281,25 @@ cat /var/log/apache/access.log | ripcalc --filter --outside --cdb ipdb.cdb --format '%{ASNCC} %{line}\n' ``` +If you want to print certain IP ranges, perhaps for an email report or similar, the following could work: + +``` +#!/bin/sh + +A=`mktemp` +cat /var/log/apache2/access.log | ripcalc --filter --inside 192.168.0.0/16 >"$A" + +if [ -s "$A" ]; then + ( + printf "From: [email protected]\nTo: [email protected]\nSubject: 192.168.0.0/16 access\n\n" + cat "$A" + ) | /usr/sbin/sendmail [email protected] [email protected] +fi + +rm "$A" + +``` + # abuseipdb If `--abuseipdb [key]` is used then a successful lookup will populate `%{abuseipdb_var}` (where `var` is the lookup result data field) for use in a `--format` string. @@ -295,12 +314,11 @@ In normal context the following are returned: -mmcity: %{mmcity_city}, %{mmcity_continent}, %{mmcity_country}, %{mmcity_code}, %{mmcity_latitude}, %{mmcity_longitude} +mmcity: `%{mmcity_city}`, `%{mmcity_continent}`, `%{mmcity_country}`, `%{mmcity_code}`, `%{mmcity_latitude}`, `%{mmcity_longitude}` -mmcountry: %{mmcountry_continent}, %{mmcountry_country}, %{mmcountry_registered_country} +mmcountry: `%{mmcountry_continent}`, `%{mmcountry_country}`, `%{mmcountry_registered_country}` -mmasn: %{mmasn_autonomous_system_number}, %{mmasn_autonomous_system_organization -} +mmasn: `%{mmasn_autonomous_system_number}`, `%{mmasn_autonomous_system_organization}` Less information is returned in `--top` context: @@ -352,11 +370,11 @@ | /usr/sbin/sendmail -fme@example you@example ``` +All input can be read with `--consume` so a report can be produced. + # help ``` -ripcalc version 0.2.7 - Options: -4, --ipv4 treat inputs as ipv4 address -6, --ipv6 treat inputs as ipv6 address @@ -368,6 +386,7 @@ --cdb PATH cdb reference file --countseen count times an ip is seen -c, --csv PATH csv reference file + --consume read stdin until empty -d, --divide CIDR divide network into chunks --noexpand do not expand networks in list -e, --encapsulating @@ -403,7 +422,8 @@ --top show IP frequency like top --delay SECONDS top update delay in seconds --iterations NUMBER - top iterations + top iterations, use --consume to produce whole report + of stdin --noclear don't print clear screen codes --mmlang LANG the lang to use in results, defaults to en --mmasn PATH path to maxmind geoip asn file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ripcalc-0.3.0/changelog.md new/ripcalc-0.3.1/changelog.md --- old/ripcalc-0.3.0/changelog.md 2025-12-28 23:45:21.000000000 +0100 +++ new/ripcalc-0.3.1/changelog.md 2026-05-21 21:26:33.000000000 +0200 @@ -1,3 +1,8 @@ +0.3.1 + + * --filter should assume --inside unless told otherwise + * bumping maxmind to 0.28, Patch taken from Debian/Peter Michael Green + 0.3.0 * filter arguments to filter STDIN for address lines only diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ripcalc-0.3.0/ripcalc.1 new/ripcalc-0.3.1/ripcalc.1 --- old/ripcalc-0.3.0/ripcalc.1 2025-12-28 23:45:21.000000000 +0100 +++ new/ripcalc-0.3.1/ripcalc.1 2026-05-21 21:26:33.000000000 +0200 @@ -1,7 +1,7 @@ '\" t -.\" Automatically generated by Pandoc 3.1.11.1 +.\" Automatically generated by Pandoc 3.7.0.2 .\" -.TH "ripcalc" "1" "28 December 2025" "ripcalc 0.3.0" "User Manual" +.TH "ripcalc" "1" "21 May 2026" "ripcalc 0.3.1" "User Manual" .SH NAME ripcalc \- a tool for network addresses .SH SYNOPSIS @@ -11,7 +11,7 @@ .PP \f[B]ripcalc \-6/\-\-ipv6 ::1\f[R] .PP -\f[B]ripcalc \-f/\-\-format \[lq]%a/%c\[rq] 127.0.0.1\f[R] +\f[B]ripcalc \-f/\-\-format \(lq%a/%c\(rq 127.0.0.1\f[R] .PP \f[B]ripcalc \-m/\-\-mask 28 127.0.0.1\f[R] .PP @@ -22,7 +22,7 @@ .PP \f[B]ripcalc \-a/\-\-available\f[R] .PP -\f[B]ripcalc \[en]abuseipdb [KEY]\f[R] +\f[B]ripcalc \(enabuseipdb [KEY]\f[R] .PP \f[B]ripcalc \-s/\-\-file [\-] 127.0.0.1\f[R] .PP @@ -35,22 +35,22 @@ .PP \f[B]ripcalc \-d/\-\-divide [CIDR] 127.0.0.1/24\f[R] .PP -\f[B]ripcalc \[en]top [\-\-delay SECONDS] [\-\-interations NUMBER] -[\-\-noclear]\f[R] +\f[B]ripcalc \(entop [\-\-delay SECONDS] [\-\-interations NUMBER] +[\-\-noclear] [\-\-consume]\f[R] .PP -\f[B]ripcalc \[en]makecdb [PATH]\f[R] +\f[B]ripcalc \(enmakecdb [PATH]\f[R] .PP -\f[B]ripcalc \[en]makethymecdb [PATH] [\-\-data\-raw\-table PATH] +\f[B]ripcalc \(enmakethymecdb [PATH] [\-\-data\-raw\-table PATH] [\-\-ipv6\-raw\-table PATH] [\-\-data\-used\-autnums PATH]\f[R] .PP \f[B]ripcalc [\-\-mmasn PATH] [\-\-mmcountry PATH] [\-\-mmcity PATH]\f[R] .PP -\f[B]ripcalc \[en]networks [CIDR] 127.0.0.1/24\f[R] +\f[B]ripcalc \(ennetworks [CIDR] 127.0.0.1/24\f[R] .PP -\f[B]ripcalc \[en]filter [CIDR]\f[R] +\f[B]ripcalc \(enfilter [CIDR]\f[R] .PP -\f[B]ripcalc \[en]filternum [NUMBER] [CIDR]\f[R] +\f[B]ripcalc \(enfilternum [NUMBER] [CIDR]\f[R] .PP \f[B]ripcalc \-q/\-\-quiet\f[R] .PP @@ -100,6 +100,7 @@ If \f[CR]\-\-top\f[R] is given a frequency of IP addresses will be shown and updated every \f[CR]\-\-delay SECONDS\f[R] (defaults to 1). This can be used with \f[CR]\-\-cdb\f[R] and \f[CR]\-\-abuseipdb\f[R]. +\f[CR]\-\-consume\f[R] will read all stdin in for a report. .PP If \f[CR]\-\-quiet\f[R] is specified then parsing error messages will be suppressed. @@ -121,7 +122,7 @@ rfc1918,192.168.0.0/16,bob rfc1918,172.16.0.0/12,cliff rfc1918,10.0.0.0/8,mr nobody -$ ripcalc \-\-csv nets.csv \-i range \-\-format \[aq]%{owner}\[rs]n\[aq] 192.168.0.0 +$ ripcalc \-\-csv nets.csv \-i range \-\-format \(aq%{owner}\(rsn\(aq 192.168.0.0 bob .EE .PP @@ -134,7 +135,7 @@ 192.168.1.1/30 172.18.1.1/30 10.0.0.0/30 -$ ripcalc \-\-csv nets.csv \-i range \-\-format \[aq]%{range} %{owner}\[rs]n\[aq] \-s list +$ ripcalc \-\-csv nets.csv \-i range \-\-format \(aq%{range} %{owner}\(rsn\(aq \-s list 10.0.0.0/8 mr nobody 192.168.0.0/16 bob 172.16.0.0/12 cliff @@ -286,12 +287,12 @@ % T} T{ -\[rs]n +\(rsn T}@T{ Line break T} T{ -\[rs]t +\(rst T}@T{ Tab character T} @@ -304,7 +305,7 @@ network matched: .IP .EX -\-\-format \[aq]%{name}\[aq] +\-\-format \(aq%{name}\(aq .EE .SH inside/outside When \f[CR]\-\-inside\f[R] or \f[CR]\-\-outside\f[R] are given addresses @@ -343,12 +344,12 @@ encapsulates a list: .IP .EX -please ip route add blackhole \[ga]ripcalc \-e 192.168.56.10 192.168.57.1 192.168.44.47\[ga] +please ip route add blackhole \(garipcalc \-e 192.168.56.10 192.168.57.1 192.168.44.47\(ga .EE .PP Networks can be grouped, in a scenario where you have a list of unwanted traffic, you can turn this into a list of small networks to block, -supposing you don\[cq]t want to block anything that covers more than a +supposing you don\(cqt want to block anything that covers more than a /19: .IP .EX @@ -360,7 +361,7 @@ This can give an overview of which networks have most IP sources: .IP .EX -cat bad_traffic | ripcalc \-\-encapsulating \-\-group 19 \-\-format \[aq]%C %a/%c\[rs]n\[aq] | sort \-rn +cat bad_traffic | ripcalc \-\-encapsulating \-\-group 19 \-\-format \(aq%C %a/%c\(rsn\(aq | sort \-rn .EE .SH ipdb CDB files can be used for address lookup. @@ -379,4 +380,4 @@ Alternatively, if the argument does not start with http, it is treated as file to read instead of download. .SH AUTHORS -Ed Neville (ed\-ripcalc\[at]s5h.net). +Ed Neville (ed\-ripcalc\(ats5h.net). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ripcalc-0.3.0/ripcalc.md new/ripcalc-0.3.1/ripcalc.md --- old/ripcalc-0.3.0/ripcalc.md 2025-12-28 23:45:21.000000000 +0100 +++ new/ripcalc-0.3.1/ripcalc.md 2026-05-21 21:26:33.000000000 +0200 @@ -2,9 +2,9 @@ title: ripcalc section: 1 header: User Manual -footer: ripcalc 0.3.0 +footer: ripcalc 0.3.1 author: Ed Neville ([email protected]) -date: 28 December 2025 +date: 21 May 2026 --- # NAME @@ -41,7 +41,7 @@ **ripcalc -d/--divide [CIDR] 127.0.0.1/24** -**ripcalc --top [--delay SECONDS] [--interations NUMBER] [--noclear]** +**ripcalc --top [--delay SECONDS] [--interations NUMBER] [--noclear] [--consume]** **ripcalc --makecdb [PATH]** @@ -81,7 +81,7 @@ If **base** is a negative number, input addresses are treated as though the input is a signed integer in **base**. -If `--top` is given a frequency of IP addresses will be shown and updated every `--delay SECONDS` (defaults to 1). This can be used with `--cdb` and `--abuseipdb`. +If `--top` is given a frequency of IP addresses will be shown and updated every `--delay SECONDS` (defaults to 1). This can be used with `--cdb` and `--abuseipdb`. `--consume` will read all stdin in for a report. If `--quiet` is specified then parsing error messages will be suppressed. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ripcalc-0.3.0/src/lib.rs new/ripcalc-0.3.1/src/lib.rs --- old/ripcalc-0.3.0/src/lib.rs 2025-12-28 23:45:21.000000000 +0100 +++ new/ripcalc-0.3.1/src/lib.rs 2026-05-21 21:26:33.000000000 +0200 @@ -1378,6 +1378,18 @@ config.options.get(&opt).unwrap_or(&"false".to_string()) != "false" } +fn getnameforlang<'a>(names : &'a maxminddb::geoip2::Names, lang : &str) -> Option<&'a str> { + if lang == "de" { return names.german } + if lang == "en" { return names.english } + if lang == "es" { return names.spanish } + if lang == "fr" { return names.french } + if lang == "jp" { return names.japanese } + if lang == "pt-BR" { return names.brazilian_portuguese } + if lang == "ru" { return names.russian } + if lang == "zh-CN" { return names.simplified_chinese } + return None +} + pub fn geoip_city(config: &RefCell<Config>, ip: &Ip) -> Option<HashMap<String, String>> { let mut ret: HashMap<String, String> = HashMap::new(); if config.borrow().mmcity.is_none() { @@ -1399,65 +1411,37 @@ let f: IpAddr = ip.to_string().parse().unwrap(); - if let Ok(Some(city)) = reader.lookup::<Option<geoip2::City>>(f) { + if let Ok(Ok(Some(Some(city)))) = reader.lookup(f).map(|r| r.decode::<Option<geoip2::City>>()) { let config = config.borrow(); let default_lang = "en".to_string(); let lang = config.options.get("mmlang").unwrap_or(&default_lang); - city.city.as_ref()?; - city.city.as_ref().unwrap().names.as_ref()?; - - let c = city - .city - .as_ref() - .unwrap() - .names - .as_ref() - .unwrap() - .get(lang as &str); + let c = getnameforlang(&city.city.names,lang); if let Some(c) = c { ret.insert("city".to_string(), c.to_string()); } - city.continent.as_ref()?; - city.continent.as_ref().unwrap().names.as_ref()?; - let c = city - .continent - .as_ref() - .unwrap() - .names - .as_ref() - .unwrap() - .get(lang as &str); + let c = getnameforlang(&city.continent.names,lang); if let Some(c) = c { ret.insert("continent".to_string(), c.to_string()); } - city.country.as_ref()?; - city.country.as_ref().unwrap().names.as_ref()?; - let c = city - .country - .as_ref() - .unwrap() - .names - .as_ref() - .unwrap() - .get(lang as &str); + let c = getnameforlang(&city.continent.names,lang); if let Some(c) = c { ret.insert("country".to_string(), c.to_string()); } - let c = city.country.as_ref().unwrap().iso_code; + let c = city.country.iso_code; if let Some(c) = c { ret.insert("code".to_string(), c.to_string()); } - let c = city.location.as_ref().unwrap().latitude; + let c = city.location.latitude; if let Some(c) = c { ret.insert("latitude".to_string(), c.to_string()); } - let c = city.location.as_ref().unwrap().longitude; + let c = city.location.longitude; if let Some(c) = c { ret.insert("longitude".to_string(), c.to_string()); } @@ -1489,7 +1473,7 @@ let f: IpAddr = ip.to_string().parse().unwrap(); - if let Ok(Some(asn)) = reader.lookup::<Option<geoip2::Asn>>(f) { + if let Ok(Ok(Some(Some(asn)))) = reader.lookup(f).map(|r| r.decode::<Option<geoip2::Asn>>()) { asn.autonomous_system_number.as_ref()?; let c = asn.autonomous_system_number.as_ref().unwrap(); ret.insert("autonomous_system_number".to_string(), c.to_string()); @@ -1525,50 +1509,24 @@ let f: IpAddr = ip.to_string().parse().unwrap(); - if let Ok(Some(country)) = reader.lookup::<Option<geoip2::Country>>(f) { + if let Ok(Ok(Some(Some(country)))) = reader.lookup(f).map(|r| r.decode::<Option<geoip2::Country>>()) { let config = config.borrow(); let default_lang = "en".to_string(); let lang = config.options.get("mmlang").unwrap_or(&default_lang); - country.continent.as_ref()?; - country.continent.as_ref().unwrap().names.as_ref()?; - - let c = &country.continent.as_ref().unwrap().names; + let c = &country.continent.names; - if let Some(c) = c.as_ref().unwrap().get(lang as &str) { + if let Some(c) = getnameforlang(c,lang) { ret.insert("continent".to_string(), c.to_string()); } - country.country.as_ref()?; - country.country.as_ref().unwrap().names.as_ref()?; - let c = country - .country - .as_ref() - .unwrap() - .names - .as_ref() - .unwrap() - .get(lang as &str); + let c = getnameforlang(&country.country.names,lang); if let Some(c) = c { ret.insert("country".to_string(), c.to_string()); } - country.registered_country.as_ref()?; - country - .registered_country - .as_ref() - .unwrap() - .names - .as_ref()?; - let c = country - .registered_country - .as_ref() - .unwrap() - .names - .as_ref() - .unwrap() - .get(lang as &str); + let c = getnameforlang(&country.registered_country.names,lang); if let Some(c) = c { ret.insert("registered_country".to_string(), c.to_string()); } @@ -2175,3 +2133,27 @@ None } + +pub fn avg_count(totals: &[usize], num: usize) -> usize { + let total: usize = totals.iter().take(num).sum(); + let div = if totals.len() > num { + num + } else { + totals.len() + }; + if div == 0 { + 0 + } else { + total / div + } +} + +pub fn totals_line(totals: &[usize]) -> String { + format!( + "Total: {:4}/sec {:4}/min {:4}/5 min {:4}/15 min\n", + avg_count(totals, 1), + avg_count(totals, 60), + avg_count(totals, 300), + avg_count(totals, 900), + ) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ripcalc-0.3.0/src/main.rs new/ripcalc-0.3.1/src/main.rs --- old/ripcalc-0.3.0/src/main.rs 2025-12-28 23:45:21.000000000 +0100 +++ new/ripcalc-0.3.1/src/main.rs 2026-05-21 21:26:33.000000000 +0200 @@ -3,6 +3,8 @@ use regex::Regex; use ripcalc::*; use serde_json::Value; +use std::borrow::Borrow; +use std::borrow::BorrowMut; use std::cell::RefCell; use std::collections::HashMap; use std::fs; @@ -728,6 +730,8 @@ || matches.opt_present("filterany") || matches.opt_present("filternum") { + let inside = if inside.is_none() { Some(true) } else { inside }; + process_input_filter(&mut reader, ip_args, inside, config, matches, rows); std::process::exit(0); @@ -1096,6 +1100,7 @@ opts.optopt("", "cdb", "cdb reference file", "PATH"); opts.optflag("", "countseen", "count times an ip is seen"); opts.optopt("c", "csv", "csv reference file", "PATH"); + opts.optflag("", "consume", "read stdin until empty"); opts.optopt("d", "divide", "divide network into chunks", "CIDR"); opts.optflag("", "noexpand", "do not expand networks in list"); @@ -1165,7 +1170,12 @@ opts.optflag("", "top", "show IP frequency like top"); opts.optopt("", "delay", "top update delay in seconds", "SECONDS"); - opts.optopt("", "iterations", "top iterations ", "NUMBER"); + opts.optopt( + "", + "iterations", + "top iterations, use --consume to produce whole report of stdin", + "NUMBER", + ); opts.optflag("", "noclear", "don't print clear screen codes"); opts.optopt( @@ -1257,6 +1267,15 @@ let position = filter_pos(&config); loop { + if reader.fill_buf().unwrap().is_empty() { + let mut counter_lock = count_lock.lock().unwrap(); + counter_lock + .borrow_mut() + .options + .insert("consumed".to_string(), "true".to_string()); + sleep(100); + } + let mut m = String::new(); let _ = reader.read_line(&mut m); let found = line_filter(&config, position, &m, base); @@ -1297,8 +1316,20 @@ } }; + if config_option_true(&config.borrow(), "consume".to_string()) { + loop { + let config = count.lock().unwrap().clone(); + if !config_option_true(config.borrow(), "consumed".to_string()) { + sleep(100); + } else { + break; + } + } + } + let mut loops = 0; let clear_screen = !config_option_true(&config.borrow(), "noclear".to_string()); + let mut totals: Vec<usize> = vec![]; loop { if clear_screen { print!("\x1b\x5b\x48\x1b\x5b\x32\x4a"); @@ -1319,6 +1350,13 @@ total += i.1; } + totals.insert(0, total); + if totals.len() > 900 { + totals.pop(); + } + + print!("{}", totals_line(&totals)); + for i in v { let pct = (10.0 / total as f64) * (*i.1 as f64); let cidr = cidr_optional_mask(i.0); @@ -1398,15 +1436,15 @@ } } } - if c > 0 { + if c > 0 && c < 21 { println!(); } } if let Some(iterations) = iterations { + loops += 1; if loops >= iterations { return; } - loops += 1; } sleep(delay); } @@ -1789,6 +1827,13 @@ .insert("noclear".to_string(), "true".to_string()); } + if matches.opt_present("consume") { + config + .borrow_mut() + .options + .insert("consume".to_string(), "true".to_string()); + } + if let Some(iterations) = matches.opt_str("iterations") { match matches.opt_str("iterations").unwrap().trim().parse::<u32>() { Ok(_) => { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ripcalc-0.3.0/tests/funcs.rs new/ripcalc-0.3.1/tests/funcs.rs --- old/ripcalc-0.3.0/tests/funcs.rs 2025-12-28 23:45:21.000000000 +0100 +++ new/ripcalc-0.3.1/tests/funcs.rs 2026-05-21 21:26:33.000000000 +0200 @@ -1788,4 +1788,24 @@ }), ); } + + #[test] + fn test_avg_count() { + let mut totals: Vec<usize> = vec![]; + + assert_eq!(avg_count(&totals, 1), 0); + + totals.insert(0, 1); + assert_eq!(avg_count(&totals, 1), 1); + + for _ in 0..30 { + totals.insert(0, 1); + } + + for _ in 0..30 { + totals.insert(0, 3); + } + + assert_eq!(avg_count(&totals, 60), 2); + } } ++++++ ripcalc.obsinfo ++++++ --- /var/tmp/diff_new_pack.CQgCbI/_old 2026-05-26 16:34:10.916369224 +0200 +++ /var/tmp/diff_new_pack.CQgCbI/_new 2026-05-26 16:34:10.916369224 +0200 @@ -1,5 +1,5 @@ name: ripcalc -version: 0.3.0 -mtime: 1766961921 -commit: ca9f34e2696999173ca495068c80474bb53d8547 +version: 0.3.1 +mtime: 1779391593 +commit: d206b49b3b1447102c9220fd3e2a66be8c68fcb9 ++++++ vendor.tar.zst ++++++ /work/SRC/openSUSE:Factory/ripcalc/vendor.tar.zst /work/SRC/openSUSE:Factory/.ripcalc.new.2084/vendor.tar.zst differ: char 7, line 1
