From: Ariel Miculas <amiculas@cisco.com>
To: rust-for-linux@vger.kernel.org
Cc: Miguel Ojeda <ojeda@kernel.org>
Subject: [PATCH 30/80] rust: serde: add `no_fp_fmt_parse` support
Date: Fri, 9 Jun 2023 09:30:28 +0300 [thread overview]
Message-ID: <20230609063118.24852-31-amiculas@cisco.com> (raw)
In-Reply-To: <20230609063118.24852-1-amiculas@cisco.com>
From: Miguel Ojeda <ojeda@kernel.org>
We do not have formatting for floating point in the kernel,
thus simple compile out all that.
Probably we should name it differently, more similar to `integer128`.
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
rust/serde/de/ignored_any.rs | 1 +
rust/serde/de/impls.rs | 2 ++
rust/serde/de/mod.rs | 16 ++++++++++++++--
rust/serde/de/value.rs | 2 ++
rust/serde/private/ser.rs | 4 ++++
rust/serde/ser/fmt.rs | 8 ++++++--
rust/serde/ser/impls.rs | 2 ++
rust/serde/ser/mod.rs | 2 ++
8 files changed, 33 insertions(+), 4 deletions(-)
diff --git a/rust/serde/de/ignored_any.rs b/rust/serde/de/ignored_any.rs
index 9ed438e79795..7b65792e77c0 100644
--- a/rust/serde/de/ignored_any.rs
+++ b/rust/serde/de/ignored_any.rs
@@ -152,6 +152,7 @@ fn visit_u128<E>(self, x: u128) -> Result<Self::Value, E> {
}
}
+ #[cfg(not(no_fp_fmt_parse))]
#[inline]
fn visit_f64<E>(self, x: f64) -> Result<Self::Value, E> {
let _ = x;
diff --git a/rust/serde/de/impls.rs b/rust/serde/de/impls.rs
index a2e2c4856df3..002bbf74d65b 100644
--- a/rust/serde/de/impls.rs
+++ b/rust/serde/de/impls.rs
@@ -350,6 +350,7 @@ fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
uint_to_self!(u32:visit_u32 u64:visit_u64);
}
+#[cfg(not(no_fp_fmt_parse))]
impl_deserialize_num! {
f32, deserialize_f32
num_self!(f32:visit_f32);
@@ -358,6 +359,7 @@ fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
num_as_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
}
+#[cfg(not(no_fp_fmt_parse))]
impl_deserialize_num! {
f64, deserialize_f64
num_self!(f64:visit_f64);
diff --git a/rust/serde/de/mod.rs b/rust/serde/de/mod.rs
index ca29ec610bfb..017964f0d0d0 100644
--- a/rust/serde/de/mod.rs
+++ b/rust/serde/de/mod.rs
@@ -344,6 +344,7 @@ pub enum Unexpected<'a> {
/// The input contained a floating point `f32` or `f64` that was not
/// expected.
+ #[cfg(not(no_fp_fmt_parse))]
Float(f64),
/// The input contained a `char` that was not expected.
@@ -400,6 +401,7 @@ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
Bool(b) => write!(formatter, "boolean `{}`", b),
Unsigned(i) => write!(formatter, "integer `{}`", i),
Signed(i) => write!(formatter, "integer `{}`", i),
+ #[cfg(not(no_fp_fmt_parse))]
Float(f) => write!(formatter, "floating point `{}`", f),
Char(c) => write!(formatter, "character `{}`", c),
Str(s) => write!(formatter, "string {:?}", s),
@@ -996,12 +998,20 @@ fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value, Self::Error>
/// Hint that the `Deserialize` type is expecting a `f32` value.
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
- V: Visitor<'de>;
+ V: Visitor<'de>
+ {
+ let _ = visitor;
+ Err(Error::custom("f32 is not supported"))
+ }
/// Hint that the `Deserialize` type is expecting a `f64` value.
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
- V: Visitor<'de>;
+ V: Visitor<'de>
+ {
+ let _ = visitor;
+ Err(Error::custom("f64 is not supported"))
+ }
/// Hint that the `Deserialize` type is expecting a `char` value.
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
@@ -1446,6 +1456,7 @@ fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
/// The default implementation forwards to [`visit_f64`].
///
/// [`visit_f64`]: #method.visit_f64
+ #[cfg(not(no_fp_fmt_parse))]
fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E>
where
E: Error,
@@ -1456,6 +1467,7 @@ fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E>
/// The input contains an `f64`.
///
/// The default implementation fails with a type error.
+ #[cfg(not(no_fp_fmt_parse))]
fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
where
E: Error,
diff --git a/rust/serde/de/value.rs b/rust/serde/de/value.rs
index 5d88862159b8..d847b8ec071c 100644
--- a/rust/serde/de/value.rs
+++ b/rust/serde/de/value.rs
@@ -298,7 +298,9 @@ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
primitive_deserializer!(u16, "a `u16`.", U16Deserializer, visit_u16);
primitive_deserializer!(u64, "a `u64`.", U64Deserializer, visit_u64);
primitive_deserializer!(usize, "a `usize`.", UsizeDeserializer, visit_u64 as u64);
+#[cfg(not(no_fp_fmt_parse))]
primitive_deserializer!(f32, "an `f32`.", F32Deserializer, visit_f32);
+#[cfg(not(no_fp_fmt_parse))]
primitive_deserializer!(f64, "an `f64`.", F64Deserializer, visit_f64);
primitive_deserializer!(char, "a `char`.", CharDeserializer, visit_char);
diff --git a/rust/serde/private/ser.rs b/rust/serde/private/ser.rs
index 528e8c125a39..fc9e7e6d7426 100644
--- a/rust/serde/private/ser.rs
+++ b/rust/serde/private/ser.rs
@@ -46,6 +46,7 @@ struct TaggedSerializer<S> {
enum Unsupported {
Boolean,
Integer,
+ #[cfg(not(no_fp_fmt_parse))]
Float,
Char,
String,
@@ -64,6 +65,7 @@ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
match *self {
Unsupported::Boolean => formatter.write_str("a boolean"),
Unsupported::Integer => formatter.write_str("an integer"),
+ #[cfg(not(no_fp_fmt_parse))]
Unsupported::Float => formatter.write_str("a float"),
Unsupported::Char => formatter.write_str("a char"),
Unsupported::String => formatter.write_str("a string"),
@@ -150,10 +152,12 @@ fn serialize_u64(self, _: u64) -> Result<Self::Ok, Self::Error> {
Err(self.bad_type(Unsupported::Integer))
}
+ #[cfg(not(no_fp_fmt_parse))]
fn serialize_f32(self, _: f32) -> Result<Self::Ok, Self::Error> {
Err(self.bad_type(Unsupported::Float))
}
+ #[cfg(not(no_fp_fmt_parse))]
fn serialize_f64(self, _: f64) -> Result<Self::Ok, Self::Error> {
Err(self.bad_type(Unsupported::Float))
}
diff --git a/rust/serde/ser/fmt.rs b/rust/serde/ser/fmt.rs
index e7e09a1bfe94..94c3054fe36b 100644
--- a/rust/serde/ser/fmt.rs
+++ b/rust/serde/ser/fmt.rs
@@ -55,13 +55,17 @@ impl<'a, 'b> Serializer for &'a mut fmt::Formatter<'b> {
serialize_u16: u16,
serialize_u32: u32,
serialize_u64: u64,
- serialize_f32: f32,
- serialize_f64: f64,
serialize_char: char,
serialize_str: &str,
serialize_unit_struct: &'static str,
}
+ #[cfg(not(no_fp_fmt_parse))]
+ fmt_primitives! {
+ serialize_f32: f32,
+ serialize_f64: f64,
+ }
+
serde_if_integer128! {
fmt_primitives! {
serialize_i128: i128,
diff --git a/rust/serde/ser/impls.rs b/rust/serde/ser/impls.rs
index a79326e5c558..639e480e252d 100644
--- a/rust/serde/ser/impls.rs
+++ b/rust/serde/ser/impls.rs
@@ -29,7 +29,9 @@ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
primitive_impl!(u16, serialize_u16);
primitive_impl!(u32, serialize_u32);
primitive_impl!(u64, serialize_u64);
+#[cfg(not(no_fp_fmt_parse))]
primitive_impl!(f32, serialize_f32);
+#[cfg(not(no_fp_fmt_parse))]
primitive_impl!(f64, serialize_f64);
primitive_impl!(char, serialize_char);
diff --git a/rust/serde/ser/mod.rs b/rust/serde/ser/mod.rs
index 5c45426e802e..13ea792c58ef 100644
--- a/rust/serde/ser/mod.rs
+++ b/rust/serde/ser/mod.rs
@@ -644,6 +644,7 @@ fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
/// }
/// }
/// ```
+ #[cfg(not(no_fp_fmt_parse))]
fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error>;
/// Serialize an `f64` value.
@@ -662,6 +663,7 @@ fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
/// }
/// }
/// ```
+ #[cfg(not(no_fp_fmt_parse))]
fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error>;
/// Serialize a character.
--
2.40.1
next prev parent reply other threads:[~2023-06-09 6:54 UTC|newest]
Thread overview: 134+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-09 6:29 [RFC PATCH 00/80] Rust PuzzleFS filesystem driver Ariel Miculas
2023-06-09 6:29 ` [PATCH 01/80] rust: add definitions for ref-counted inodes and dentries Ariel Miculas
2023-06-09 6:30 ` [PATCH 02/80] rust: add ability to register a file system Ariel Miculas
2023-06-09 9:23 ` Miguel Ojeda
2023-06-09 6:30 ` [PATCH 03/80] rust: define fs context Ariel Miculas
2023-06-09 6:30 ` [PATCH 04/80] rust: add support for file system parameters Ariel Miculas
2023-06-09 6:30 ` [PATCH 05/80] rust: kernel: add libraries required by the filesystem abstractions Ariel Miculas
2023-06-09 9:46 ` Miguel Ojeda
2023-06-09 6:30 ` [PATCH 06/80] rust: allow fs driver to initialise new superblocks Ariel Miculas
2023-06-09 6:30 ` [PATCH 07/80] rust: add `module_fs` macro Ariel Miculas
2023-06-09 6:30 ` [PATCH 08/80] WIP: rust: allow fs to be populated Ariel Miculas
2023-06-09 6:30 ` [PATCH 09/80] rust: kernel: backport the delay module from the rust branch Ariel Miculas
2023-06-09 9:29 ` Miguel Ojeda
2023-06-09 6:30 ` [PATCH 10/80] rust: kernel: add container_of macro Ariel Miculas
2023-06-09 6:30 ` [PATCH 11/80] rust: kernel: add offset_of macro Ariel Miculas
2023-06-09 6:30 ` [PATCH 12/80] drop: Add crate::pr_warn declaration Ariel Miculas
2023-06-09 9:29 ` Miguel Ojeda
2023-06-09 10:46 ` Ariel Miculas (amiculas)
2023-06-09 6:30 ` [PATCH 13/80] rust: kernel: rename from_kernel_errno to from_errno Ariel Miculas
2023-06-09 9:56 ` Miguel Ojeda
2023-06-09 6:30 ` [PATCH 14/80] rust: kernel: Rename from_pointer to from_foreing and into_pointer to into_foreign Ariel Miculas
2023-06-09 9:57 ` Miguel Ojeda
2023-06-09 6:30 ` [PATCH 15/80] rust: kernel: add count_paren_items macro, needed by define_fs_params macro Ariel Miculas
2023-06-09 6:30 ` [PATCH 16/80] rust: helpers: add missing rust helper 'alloc_pages' Ariel Miculas
2023-06-09 9:57 ` Miguel Ojeda
2023-06-09 6:30 ` [PATCH 17/80] kernel: configs: add qemu-busybox-min.config Ariel Miculas
2023-06-09 9:39 ` Miguel Ojeda
2023-06-09 6:30 ` [PATCH 18/80] rust: kernel: format the rust code Ariel Miculas
2023-06-09 9:21 ` Miguel Ojeda
2023-06-09 6:30 ` [PATCH 19/80] samples: puzzlefs: add initial puzzlefs sample, copied from rust_fs.rs Ariel Miculas
2023-06-09 6:30 ` [PATCH 20/80] kernel: configs: enable rust samples in rust.config Ariel Miculas
2023-06-09 9:25 ` Miguel Ojeda
2023-06-09 6:30 ` [PATCH 22/80] rust: proc-macro2: add SPDX License Identifiers Ariel Miculas
2023-06-09 6:30 ` [PATCH 23/80] rust: proc-macro2: remove `unicode_ident` dependency Ariel Miculas
2023-06-09 6:30 ` [PATCH 24/80] rust: quote: import crate Ariel Miculas
2023-06-09 6:30 ` [PATCH 25/80] rust: quote: add SPDX License Identifiers Ariel Miculas
2023-06-09 6:30 ` [PATCH 27/80] rust: syn: " Ariel Miculas
2023-06-09 6:30 ` [PATCH 28/80] rust: syn: remove `unicode-ident` dependency Ariel Miculas
2023-06-09 6:30 ` Ariel Miculas [this message]
2023-06-09 6:30 ` [PATCH 31/80] rust: serde: add SPDX License Identifiers Ariel Miculas
2023-06-10 0:19 ` Kent Overstreet
2023-06-10 6:43 ` Greg KH
2023-06-10 13:18 ` Kent Overstreet
2023-06-10 15:28 ` Greg KH
2023-06-10 0:25 ` Kent Overstreet
2023-06-10 9:04 ` Andreas Hindborg (Samsung)
2023-06-10 13:20 ` Kent Overstreet
2023-06-12 8:56 ` Ariel Miculas
2023-06-10 9:33 ` Miguel Ojeda
2023-06-12 11:58 ` Ariel Miculas
2023-06-15 15:05 ` Ariel Miculas
2023-06-17 16:04 ` Kent Overstreet
2023-06-09 6:30 ` [PATCH 33/80] rust: serde_derive: " Ariel Miculas
2023-06-09 6:30 ` [PATCH 34/80] rust: Kbuild: enable `proc-macro2`, `quote`, `syn`, `serde` and `serde_derive` Ariel Miculas
2023-06-09 6:30 ` [PATCH 35/80] rust: test `serde` support Ariel Miculas
2023-06-09 6:30 ` [PATCH 36/80] Add SAMPLE_RUST_SERDE in rust.config Ariel Miculas
2023-06-09 6:30 ` [PATCH 37/80] rust: kernel: fix compile errors after rebase to rust-next Ariel Miculas
2023-06-09 9:38 ` Miguel Ojeda
2023-06-09 6:30 ` [PATCH 39/80] rust: serde_cbor: add SPDX License Identifiers Ariel Miculas
2023-06-09 6:30 ` [PATCH 40/80] rust: serde_cbor: add no_fp_fmt_parse support Ariel Miculas
2023-06-09 6:30 ` [PATCH 41/80] rust: Kbuild: enable serde_cbor Ariel Miculas
2023-06-09 10:21 ` Miguel Ojeda
2023-06-09 6:30 ` [PATCH 42/80] samples: rust: add cbor serialize/deserialize example Ariel Miculas
2023-06-09 6:30 ` [PATCH 43/80] rust: serde_cbor: add support for serde_cbor's from_slice method by using a custom alloc_kernel feature Ariel Miculas
2023-06-09 9:55 ` Miguel Ojeda
2023-06-09 6:30 ` [PATCH 44/80] rust: serde: add support for deserializing Vec with kernel_alloc feature Ariel Miculas
2023-06-09 10:10 ` Miguel Ojeda
2023-06-09 6:30 ` [PATCH 45/80] rust: file: Replace UnsafeCell with Opaque for File Ariel Miculas
2023-06-09 6:30 ` [PATCH 46/80] rust: kernel: implement fmt::Debug for CString Ariel Miculas
2023-06-09 6:30 ` [PATCH 47/80] samples: puzzlefs: rename RustFs to PuzzleFs Ariel Miculas
2023-06-09 6:30 ` [PATCH 48/80] samples: puzzlefs: add basic deserializing support for the puzzlefs metadata Ariel Miculas
2023-06-09 6:30 ` [PATCH 49/80] rust: file: present the filesystem context to the open function Ariel Miculas
2023-06-09 6:30 ` [PATCH 50/80] rust: kernel: add an abstraction over vfsmount to allow cloning a new private mount Ariel Miculas
2023-06-09 6:30 ` [PATCH 51/80] rust: file: add from_path, from_path_in_root_mnt and read_with_offset methods to File Ariel Miculas
2023-06-09 6:30 ` [PATCH 52/80] samples: puzzlefs: pass the Vfsmount structure from open to read and return the contents of the data file inside /home/puzzlefs_oci Ariel Miculas
2023-06-09 6:30 ` [PATCH 53/80] rust: file: move from_path, from_path_in_root_mnt and read_with_offset methods to a RegularFile newtype Ariel Miculas
2023-06-09 6:30 ` [PATCH 54/80] rust: file: ensure RegularFile can only create regular files Ariel Miculas
2023-06-09 6:30 ` [PATCH 55/80] rust: file: add get_pos method to RegularFile Ariel Miculas
2023-06-09 6:30 ` [PATCH 56/80] rust: file: add methods read_to_end, get_file_size and update_pos " Ariel Miculas
2023-06-09 6:30 ` [PATCH 57/80] rust: file: define a minimal Read trait and implement it for RegularFile Ariel Miculas
2023-06-09 6:30 ` [PATCH 58/80] samples: puzzlefs: add cbor_get_array_size method Ariel Miculas
2023-06-09 6:30 ` [PATCH 59/80] samples: puzzlefs: add KernelError to WireFormatError and implement From conversion Ariel Miculas
2023-06-09 6:30 ` [PATCH 60/80] samples: puzzlefs: implement new for MetadataBlob Ariel Miculas
2023-06-09 6:30 ` [PATCH 61/80] samples: puzzlefs: build puzzlefs into the kernel, thus avoiding the need to export rust symbols Ariel Miculas
2023-06-09 6:31 ` [PATCH 62/80] rust: alloc: add try_clone for Vec<T> Ariel Miculas
2023-06-09 6:31 ` [PATCH 63/80] rust: alloc: add from_iter_fallible " Ariel Miculas
2023-06-09 10:06 ` Miguel Ojeda
2023-06-09 6:31 ` [PATCH 64/80] samples: puzzlefs: implement to_errno and from_errno for WireFormatError Ariel Miculas
2023-06-09 6:31 ` [PATCH 65/80] samples: puzzlefs: add TryReserveError (and from conversion) to WireFormatError Ariel Miculas
2023-06-09 6:31 ` [PATCH 66/80] samples: puzzlefs: add higher level inode related functionality Ariel Miculas
2023-06-09 6:31 ` [PATCH 67/80] samples: puzzlefs: populate the directory entries with the inodes from the puzzlefs metadata file Ariel Miculas
2023-06-09 6:31 ` [PATCH 68/80] rust: hex: import crate Ariel Miculas
2023-06-09 6:31 ` [PATCH 69/80] rust: hex: add SPDX license identifiers Ariel Miculas
2023-06-09 6:31 ` [PATCH 70/80] rust: Kbuild: enable `hex` Ariel Miculas
2023-06-09 6:31 ` [PATCH 71/80] rust: hex: implement FromHex trait and hex::decode using a custom kernel_alloc feature Ariel Miculas
2023-06-09 6:31 ` [PATCH 72/80] rust: hex: add encode_hex_iter and encode_hex_upper_iter methods Ariel Miculas
2023-06-09 6:31 ` [PATCH 73/80] rust: puzzlefs: add HexError to WireFormatError and implement the From conversion Ariel Miculas
2023-06-09 6:31 ` [PATCH 74/80] rust: puzzlefs: display the error value for WireFormatError::KernelError Ariel Miculas
2023-06-09 6:31 ` [PATCH 75/80] samples: puzzlefs: add Rootfs and Digest structs to types.rs Ariel Miculas
2023-06-09 6:31 ` [PATCH 76/80] samples: puzzlefs: implement the conversion from WireFormatError to kernel::error::Error Ariel Miculas
2023-06-09 6:31 ` [PATCH 77/80] rust: puzzlefs: read the puzzlefs image manifest instead of an individual metadata layer Ariel Miculas
2023-06-09 6:31 ` [PATCH 78/80] rust: puzzlefs: rename PuzzleFs to PuzzleFsModule to avoid confusion with the PuzzleFS struct Ariel Miculas
2023-06-09 6:31 ` [PATCH 79/80] rust: puzzlefs: add support for reading files Ariel Miculas
2023-06-09 6:31 ` [PATCH 80/80] rust: puzzlefs: add oci_root_dir and image_manifest filesystem parameters Ariel Miculas
2023-06-09 10:26 ` [RFC PATCH 00/80] Rust PuzzleFS filesystem driver Miguel Ojeda
2023-06-09 10:36 ` Christian Brauner
2023-06-09 11:42 ` Miguel Ojeda
[not found] ` <CH0PR11MB529981313ED5A1F815350E41CD51A@CH0PR11MB5299.namprd11.prod.outlook.com>
2023-06-09 11:45 ` Christian Brauner
2023-06-09 12:03 ` Ariel Miculas (amiculas)
2023-06-09 12:56 ` Gao Xiang
2023-06-09 12:07 ` Miguel Ojeda
2023-06-09 12:11 ` Ariel Miculas (amiculas)
2023-06-09 12:21 ` Greg KH
2023-06-09 13:05 ` Alice Ryhl
2023-06-09 12:20 ` Colin Walters
2023-06-09 12:42 ` Christian Brauner
2023-06-09 17:28 ` Serge Hallyn
2023-06-09 13:45 ` Ariel Miculas (amiculas)
2023-06-09 17:10 ` Trilok Soni
2023-06-09 17:16 ` Ariel Miculas (amiculas)
2023-06-09 17:41 ` Miguel Ojeda
2023-06-09 18:49 ` James Bottomley
2023-06-09 19:08 ` Miguel Ojeda
2023-06-09 19:11 ` Ariel Miculas
2023-06-09 20:01 ` James Bottomley
2023-06-10 9:34 ` Miguel Ojeda
2023-06-09 18:43 ` James Bottomley
2023-06-09 18:59 ` Ariel Miculas (amiculas)
2023-06-09 19:20 ` Ariel Miculas
2023-06-09 19:45 ` Trilok Soni
2023-06-09 19:53 ` Alice Ryhl
2023-06-09 23:52 ` Kent Overstreet
2023-06-10 9:40 ` Miguel Ojeda
2023-06-10 0:09 ` Kent Overstreet
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230609063118.24852-31-amiculas@cisco.com \
--to=amiculas@cisco.com \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).