From: Maximiliano Sandoval <m.sandoval@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [pbs-devel] [PATCH proxmox 01/10] adapt to rust 2024 match ergonomics
Date: Mon, 26 Jan 2026 16:13:38 +0100 [thread overview]
Message-ID: <20260126151349.627829-2-m.sandoval@proxmox.com> (raw)
In-Reply-To: <20260126151349.627829-1-m.sandoval@proxmox.com>
See
https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html
for more details.
Signed-off-by: Maximiliano Sandoval <m.sandoval@proxmox.com>
---
proxmox-acme-api/src/plugin_api_impl.rs | 4 +--
proxmox-acme-api/src/plugin_config.rs | 4 +--
proxmox-api-macro/src/api/method.rs | 8 +++---
proxmox-api-macro/src/api/structs.rs | 2 +-
proxmox-async/src/io/async_channel_writer.rs | 2 +-
proxmox-http/src/client/tls.rs | 30 ++++++++++----------
proxmox-http/src/rate_limited_stream.rs | 2 +-
proxmox-http/src/websocket/mod.rs | 2 +-
proxmox-network-api/src/config/lexer.rs | 4 +--
proxmox-notify/src/endpoints/smtp.rs | 2 +-
proxmox-router/src/cli/command.rs | 8 +++---
proxmox-router/src/permission.rs | 8 +++---
proxmox-router/src/stream/parsing.rs | 5 +---
proxmox-s3-client/src/object_key.rs | 4 +--
proxmox-schema/src/format.rs | 16 +++++------
proxmox-schema/src/schema.rs | 6 ++--
proxmox-upgrade-checks/src/lib.rs | 2 +-
17 files changed, 53 insertions(+), 56 deletions(-)
diff --git a/proxmox-acme-api/src/plugin_api_impl.rs b/proxmox-acme-api/src/plugin_api_impl.rs
index fe44aa2b..d0548e4b 100644
--- a/proxmox-acme-api/src/plugin_api_impl.rs
+++ b/proxmox-acme-api/src/plugin_api_impl.rs
@@ -83,7 +83,7 @@ pub fn update_plugin(
expected_digest.detect_modification(digest.as_ref())?;
match plugins.get_mut(&id) {
- Some((ty, ref mut entry)) => {
+ Some((ty, entry)) => {
if ty != "dns" {
bail!("cannot update plugin of type {:?}", ty);
}
@@ -150,7 +150,7 @@ fn modify_cfg_for_api(id: &str, ty: &str, data: &Value) -> PluginConfig {
// None of these should be able to fail unless the user changed the files by hand, in which
// case we leave the unmodified string in the Value for now. This will be handled with an error
// later.
- if let Some(Value::String(ref mut data)) = obj.get_mut("data") {
+ if let Some(Value::String(data)) = obj.get_mut("data") {
if let Ok(new) = proxmox_base64::url::decode_no_pad(&data) {
if let Ok(utf8) = String::from_utf8(new) {
*data = utf8;
diff --git a/proxmox-acme-api/src/plugin_config.rs b/proxmox-acme-api/src/plugin_config.rs
index c4685f2b..3295e15d 100644
--- a/proxmox-acme-api/src/plugin_config.rs
+++ b/proxmox-acme-api/src/plugin_config.rs
@@ -36,8 +36,8 @@ fn init() -> SectionConfig {
);
config.register_plugin(standalone_plugin);
- let dns_challenge_schema = match DnsPlugin::API_SCHEMA {
- Schema::AllOf(ref schema) => schema,
+ let dns_challenge_schema = match &DnsPlugin::API_SCHEMA {
+ Schema::AllOf(schema) => schema,
_ => unreachable!(),
};
let dns_challenge_plugin = SectionConfigPlugin::new(
diff --git a/proxmox-api-macro/src/api/method.rs b/proxmox-api-macro/src/api/method.rs
index 68969735..0fe2cf42 100644
--- a/proxmox-api-macro/src/api/method.rs
+++ b/proxmox-api-macro/src/api/method.rs
@@ -30,7 +30,7 @@ pub enum ReturnType {
impl ReturnType {
fn as_mut_schema(&mut self) -> Option<&mut Schema> {
match self {
- ReturnType::Explicit(ReturnSchema { ref mut schema, .. }) => Some(schema),
+ ReturnType::Explicit(ReturnSchema { schema, .. }) => Some(schema),
_ => None,
}
}
@@ -589,7 +589,7 @@ fn create_wrapper_function(
let body = match method_info.flavor {
MethodFlavor::Normal => {
quote! {
- if let ::serde_json::Value::Object(ref mut input_map) = &mut input_params {
+ if let ::serde_json::Value::Object(input_map) = &mut input_params {
#body
Ok(::serde_json::to_value(#func_name(#args) #await_keyword #question_mark)?)
} else {
@@ -599,7 +599,7 @@ fn create_wrapper_function(
}
MethodFlavor::Serializing => {
quote! {
- if let ::serde_json::Value::Object(ref mut input_map) = &mut input_params {
+ if let ::serde_json::Value::Object(input_map) = &mut input_params {
#body
let res = #func_name(#args) #await_keyword #question_mark;
let res: ::std::boxed::Box<dyn ::proxmox_router::SerializableReturn + Send> = ::std::boxed::Box::new(res);
@@ -616,7 +616,7 @@ fn create_wrapper_function(
quote! { ::proxmox_router::SyncStream }
};
quote! {
- if let ::serde_json::Value::Object(ref mut input_map) = &mut input_params {
+ if let ::serde_json::Value::Object(input_map) = &mut input_params {
#body
let res = #func_name(#args) #await_keyword #question_mark;
let res = #ty::from(res);
diff --git a/proxmox-api-macro/src/api/structs.rs b/proxmox-api-macro/src/api/structs.rs
index ee537ff0..c18b20b4 100644
--- a/proxmox-api-macro/src/api/structs.rs
+++ b/proxmox-api-macro/src/api/structs.rs
@@ -164,7 +164,7 @@ fn handle_regular_struct(
let mut all_of_schemas = TokenStream::new();
let mut to_remove = Vec::new();
- if let syn::Fields::Named(ref fields) = &stru.fields {
+ if let syn::Fields::Named(fields) = &stru.fields {
for field in &fields.named {
let attrs = serde::FieldAttrib::try_from(&field.attrs[..])?;
diff --git a/proxmox-async/src/io/async_channel_writer.rs b/proxmox-async/src/io/async_channel_writer.rs
index 9dd64cd5..d9de8e27 100644
--- a/proxmox-async/src/io/async_channel_writer.rs
+++ b/proxmox-async/src/io/async_channel_writer.rs
@@ -76,7 +76,7 @@ impl AsyncChannelWriter {
self.state = WriterState::Sending(future.boxed());
}
- WriterState::Sending(ref mut future) => match ready!(future.as_mut().poll(cx)) {
+ WriterState::Sending(future) => match ready!(future.as_mut().poll(cx)) {
Ok(sender) => {
self.sender = Some(sender);
self.state = WriterState::Ready;
diff --git a/proxmox-http/src/client/tls.rs b/proxmox-http/src/client/tls.rs
index 9eba154a..f330d8f6 100644
--- a/proxmox-http/src/client/tls.rs
+++ b/proxmox-http/src/client/tls.rs
@@ -24,9 +24,9 @@ impl<S: AsyncRead + AsyncWrite + Unpin> AsyncRead for MaybeTlsStream<S> {
buf: &mut ReadBuf,
) -> Poll<Result<(), io::Error>> {
match self.get_mut() {
- MaybeTlsStream::Normal(ref mut s) => Pin::new(s).poll_read(cx, buf),
- MaybeTlsStream::Proxied(ref mut s) => Pin::new(s).poll_read(cx, buf),
- MaybeTlsStream::Secured(ref mut s) => Pin::new(s).poll_read(cx, buf),
+ MaybeTlsStream::Normal(s) => Pin::new(s).poll_read(cx, buf),
+ MaybeTlsStream::Proxied(s) => Pin::new(s).poll_read(cx, buf),
+ MaybeTlsStream::Secured(s) => Pin::new(s).poll_read(cx, buf),
}
}
}
@@ -38,9 +38,9 @@ impl<S: AsyncRead + AsyncWrite + Unpin> AsyncWrite for MaybeTlsStream<S> {
buf: &[u8],
) -> Poll<Result<usize, io::Error>> {
match self.get_mut() {
- MaybeTlsStream::Normal(ref mut s) => Pin::new(s).poll_write(cx, buf),
- MaybeTlsStream::Proxied(ref mut s) => Pin::new(s).poll_write(cx, buf),
- MaybeTlsStream::Secured(ref mut s) => Pin::new(s).poll_write(cx, buf),
+ MaybeTlsStream::Normal(s) => Pin::new(s).poll_write(cx, buf),
+ MaybeTlsStream::Proxied(s) => Pin::new(s).poll_write(cx, buf),
+ MaybeTlsStream::Secured(s) => Pin::new(s).poll_write(cx, buf),
}
}
@@ -50,9 +50,9 @@ impl<S: AsyncRead + AsyncWrite + Unpin> AsyncWrite for MaybeTlsStream<S> {
bufs: &[io::IoSlice<'_>],
) -> Poll<Result<usize, io::Error>> {
match self.get_mut() {
- MaybeTlsStream::Normal(ref mut s) => Pin::new(s).poll_write_vectored(cx, bufs),
- MaybeTlsStream::Proxied(ref mut s) => Pin::new(s).poll_write_vectored(cx, bufs),
- MaybeTlsStream::Secured(ref mut s) => Pin::new(s).poll_write_vectored(cx, bufs),
+ MaybeTlsStream::Normal(s) => Pin::new(s).poll_write_vectored(cx, bufs),
+ MaybeTlsStream::Proxied(s) => Pin::new(s).poll_write_vectored(cx, bufs),
+ MaybeTlsStream::Secured(s) => Pin::new(s).poll_write_vectored(cx, bufs),
}
}
@@ -66,17 +66,17 @@ impl<S: AsyncRead + AsyncWrite + Unpin> AsyncWrite for MaybeTlsStream<S> {
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), io::Error>> {
match self.get_mut() {
- MaybeTlsStream::Normal(ref mut s) => Pin::new(s).poll_flush(cx),
- MaybeTlsStream::Proxied(ref mut s) => Pin::new(s).poll_flush(cx),
- MaybeTlsStream::Secured(ref mut s) => Pin::new(s).poll_flush(cx),
+ MaybeTlsStream::Normal(s) => Pin::new(s).poll_flush(cx),
+ MaybeTlsStream::Proxied(s) => Pin::new(s).poll_flush(cx),
+ MaybeTlsStream::Secured(s) => Pin::new(s).poll_flush(cx),
}
}
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), io::Error>> {
match self.get_mut() {
- MaybeTlsStream::Normal(ref mut s) => Pin::new(s).poll_shutdown(cx),
- MaybeTlsStream::Proxied(ref mut s) => Pin::new(s).poll_shutdown(cx),
- MaybeTlsStream::Secured(ref mut s) => Pin::new(s).poll_shutdown(cx),
+ MaybeTlsStream::Normal(s) => Pin::new(s).poll_shutdown(cx),
+ MaybeTlsStream::Proxied(s) => Pin::new(s).poll_shutdown(cx),
+ MaybeTlsStream::Secured(s) => Pin::new(s).poll_shutdown(cx),
}
}
}
diff --git a/proxmox-http/src/rate_limited_stream.rs b/proxmox-http/src/rate_limited_stream.rs
index 18ce864f..5fc5949a 100644
--- a/proxmox-http/src/rate_limited_stream.rs
+++ b/proxmox-http/src/rate_limited_stream.rs
@@ -177,7 +177,7 @@ fn register_traffic(limiter: &dyn ShareableRateLimit, count: usize) -> Option<Pi
fn delay_is_ready(delay: &mut Option<Pin<Box<Sleep>>>, ctx: &mut Context<'_>) -> bool {
match delay {
- Some(ref mut future) => future.as_mut().poll(ctx).is_ready(),
+ Some(future) => future.as_mut().poll(ctx).is_ready(),
None => true,
}
}
diff --git a/proxmox-http/src/websocket/mod.rs b/proxmox-http/src/websocket/mod.rs
index 5ce53651..88d25f44 100644
--- a/proxmox-http/src/websocket/mod.rs
+++ b/proxmox-http/src/websocket/mod.rs
@@ -550,7 +550,7 @@ impl<R: AsyncRead + Unpin + Send + 'static> AsyncRead for WebSocketReader<R> {
this.state = ReaderState::Receiving(future.boxed());
}
- ReaderState::Receiving(ref mut future) => match ready!(future.as_mut().poll(cx)) {
+ ReaderState::Receiving(future) => match ready!(future.as_mut().poll(cx)) {
Ok(ReadResult {
len,
reader,
diff --git a/proxmox-network-api/src/config/lexer.rs b/proxmox-network-api/src/config/lexer.rs
index bc0392cf..4729d462 100644
--- a/proxmox-network-api/src/config/lexer.rs
+++ b/proxmox-network-api/src/config/lexer.rs
@@ -121,8 +121,8 @@ impl<R: BufRead> Iterator for Lexer<R> {
self.cur_line = Some(Self::split_line(&line));
}
- match self.cur_line {
- Some(ref mut cur_line) => {
+ match &mut self.cur_line {
+ Some(cur_line) => {
if cur_line.is_empty() {
self.cur_line = None;
Some(Ok((Token::Newline, String::from("\n"))))
diff --git a/proxmox-notify/src/endpoints/smtp.rs b/proxmox-notify/src/endpoints/smtp.rs
index c888dee7..6785932f 100644
--- a/proxmox-notify/src/endpoints/smtp.rs
+++ b/proxmox-notify/src/endpoints/smtp.rs
@@ -254,7 +254,7 @@ impl Endpoint for SmtpEndpoint {
.map_err(|err| Error::NotifyFailed(self.name().into(), Box::new(err)))?
}
#[cfg(feature = "mail-forwarder")]
- Content::ForwardedMail { ref raw, .. } => {
+ Content::ForwardedMail { raw, .. } => {
build_forwarded_message(email_builder, self.name(), raw)?
}
};
diff --git a/proxmox-router/src/cli/command.rs b/proxmox-router/src/cli/command.rs
index 42de796d..3389dc50 100644
--- a/proxmox-router/src/cli/command.rs
+++ b/proxmox-router/src/cli/command.rs
@@ -337,10 +337,10 @@ pub async fn handle_command_future(
set_help_context(Some(def.clone()));
let result = match &*def {
- CommandLineInterface::Simple(ref cli_cmd) => {
+ CommandLineInterface::Simple(cli_cmd) => {
handle_simple_command_future(prefix, cli_cmd, args, rpcenv).await
}
- CommandLineInterface::Nested(ref map) => {
+ CommandLineInterface::Nested(map) => {
let mut prefix = prefix.to_string();
let cli_cmd = parse_nested_command(&mut prefix, map, &mut args)?;
handle_simple_command_future(&prefix, cli_cmd, args, rpcenv).await
@@ -366,10 +366,10 @@ pub fn handle_command(
set_help_context(Some(def.clone()));
let result = match &*def {
- CommandLineInterface::Simple(ref cli_cmd) => {
+ CommandLineInterface::Simple(cli_cmd) => {
handle_simple_command(prefix, cli_cmd, args, &mut rpcenv, run, [].into_iter())
}
- CommandLineInterface::Nested(ref map) => {
+ CommandLineInterface::Nested(map) => {
let mut prefix = prefix.to_string();
let cli_cmd = parse_nested_command(&mut prefix, map, &mut args)?;
handle_simple_command(&prefix, cli_cmd, args, &mut rpcenv, run, [].into_iter())
diff --git a/proxmox-router/src/permission.rs b/proxmox-router/src/permission.rs
index 3b20343c..e3be3387 100644
--- a/proxmox-router/src/permission.rs
+++ b/proxmox-router/src/permission.rs
@@ -38,9 +38,9 @@ impl fmt::Debug for Permission {
Permission::Superuser => f.write_str("Superuser"),
Permission::World => f.write_str("World"),
Permission::Anybody => f.write_str("Anybody"),
- Permission::User(ref userid) => write!(f, "User({userid})"),
+ Permission::User(userid) => write!(f, "User({userid})"),
Permission::UserParam(param_name) => write!(f, "UserParam({param_name})"),
- Permission::Group(ref group) => write!(f, "Group({group})"),
+ Permission::Group(group) => write!(f, "Group({group})"),
Permission::WithParam(param_name, subtest) => {
write!(f, "WithParam({param_name}, {subtest:?})")
}
@@ -122,12 +122,12 @@ fn check_api_permission_tail(
},
Permission::User(expected_userid) => match userid {
None => return false,
- Some(ref userid) => return userid == expected_userid,
+ Some(userid) => return &userid == expected_userid,
},
Permission::UserParam(param_name) => match (userid, param.get(¶m_name.to_string())) {
(None, _) => return false,
(_, None) => return false,
- (Some(ref userid), Some(ref expected)) => return userid == expected,
+ (Some(userid), Some(expected)) => return userid == expected,
},
Permission::Group(expected_group) => match userid {
None => return false,
diff --git a/proxmox-router/src/stream/parsing.rs b/proxmox-router/src/stream/parsing.rs
index ced59918..975d7c11 100644
--- a/proxmox-router/src/stream/parsing.rs
+++ b/proxmox-router/src/stream/parsing.rs
@@ -272,10 +272,7 @@ impl AsyncBufRead for BodyBufReader {
cx: &mut std::task::Context<'_>,
) -> Poll<io::Result<&[u8]>> {
use hyper::body::Body as HyperBody;
- let Self {
- ref mut reader,
- ref mut buf_at,
- } = Pin::into_inner(self);
+ let Self { reader, buf_at } = Pin::into_inner(self);
loop {
// If we currently have a buffer, use it:
if let Some((buf, at)) = buf_at {
diff --git a/proxmox-s3-client/src/object_key.rs b/proxmox-s3-client/src/object_key.rs
index 4c8d95b4..34189409 100644
--- a/proxmox-s3-client/src/object_key.rs
+++ b/proxmox-s3-client/src/object_key.rs
@@ -35,8 +35,8 @@ impl S3ObjectKey {
/// If the object key is already a full key, the prefix is ignored.
pub(crate) fn to_full_key(&self, prefix: &str) -> Self {
match self {
- Self::Full(ref key) => Self::Full(key.to_string()),
- Self::Relative(ref key) => {
+ Self::Full(key) => Self::Full(key.to_string()),
+ Self::Relative(key) => {
let prefix = prefix.strip_prefix("/").unwrap_or(prefix);
Self::Full(format!("{prefix}/{key}"))
}
diff --git a/proxmox-schema/src/format.rs b/proxmox-schema/src/format.rs
index 080b0268..c1e33a68 100644
--- a/proxmox-schema/src/format.rs
+++ b/proxmox-schema/src/format.rs
@@ -229,30 +229,30 @@ pub fn get_property_description(
let (descr, default, extra) = match schema {
Schema::Null => ("null", None, None),
- Schema::String(ref schema) => (
+ Schema::String(schema) => (
schema.description,
schema.default.map(|v| v.to_owned()),
None,
),
- Schema::Boolean(ref schema) => (
+ Schema::Boolean(schema) => (
schema.description,
schema.default.map(|v| v.to_string()),
None,
),
- Schema::Integer(ref schema) => (
+ Schema::Integer(schema) => (
schema.description,
schema.default.map(|v| v.to_string()),
None,
),
- Schema::Number(ref schema) => (
+ Schema::Number(schema) => (
schema.description,
schema.default.map(|v| v.to_string()),
None,
),
- Schema::Object(ref schema) => (schema.description, None, None),
- Schema::AllOf(ref schema) => (schema.description, None, None),
- Schema::OneOf(ref schema) => (schema.description, None, None),
- Schema::Array(ref schema) => (
+ Schema::Object(schema) => (schema.description, None, None),
+ Schema::AllOf(schema) => (schema.description, None, None),
+ Schema::OneOf(schema) => (schema.description, None, None),
+ Schema::Array(schema) => (
schema.description,
None,
Some(String::from("Can be specified more than once.")),
diff --git a/proxmox-schema/src/schema.rs b/proxmox-schema/src/schema.rs
index 40ede2f1..8413d40b 100644
--- a/proxmox-schema/src/schema.rs
+++ b/proxmox-schema/src/schema.rs
@@ -608,7 +608,7 @@ impl ArraySchema {
/// Verify JSON value using an `ArraySchema`.
pub fn verify_json(&self, data: &Value) -> Result<(), Error> {
let list = match data {
- Value::Array(ref list) => list,
+ Value::Array(list) => list,
Value::Object(_) => bail!("Expected array - got object."),
_ => bail!("Expected array - got scalar value."),
};
@@ -1091,7 +1091,7 @@ pub trait ObjectSchemaType: private::Sealed + Send + Sync {
/// Verify JSON value using an object schema.
fn verify_json(&self, data: &Value) -> Result<(), Error> {
let map = match data {
- Value::Object(ref map) => map,
+ Value::Object(map) => map,
Value::Array(_) => bail!("Expected object - got array."),
_ => bail!("Expected object - got scalar value."),
};
@@ -1285,7 +1285,7 @@ impl ObjectSchemaType for OneOfSchema {
fn verify_json(&self, data: &Value) -> Result<(), Error> {
let map = match data {
- Value::Object(ref map) => map,
+ Value::Object(map) => map,
Value::Array(_) => bail!("Expected object - got array."),
_ => bail!("Expected object - got scalar value."),
};
diff --git a/proxmox-upgrade-checks/src/lib.rs b/proxmox-upgrade-checks/src/lib.rs
index f9b66876..cfd85ff2 100644
--- a/proxmox-upgrade-checks/src/lib.rs
+++ b/proxmox-upgrade-checks/src/lib.rs
@@ -508,7 +508,7 @@ impl UpgradeChecker {
continue;
}
- if let Some((ref current_suite, ref current_location)) = found_suite {
+ if let Some((current_suite, current_location)) = found_suite {
let location = repo_file.path.clone().unwrap_or_default();
if suite != current_suite {
if mismatches.is_empty() {
--
2.47.3
_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel
next prev parent reply other threads:[~2026-01-26 15:14 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-26 15:13 [pbs-devel] [PATCH proxmox 00/10] Bump edition to 2024 Maximiliano Sandoval
2026-01-26 15:13 ` Maximiliano Sandoval [this message]
2026-01-26 15:13 ` [pbs-devel] [PATCH proxmox 02/10] rustfmt: Set style_edition to 2021 Maximiliano Sandoval
2026-01-26 15:13 ` [pbs-devel] [PATCH proxmox 03/10] cargo: set workspace edition to 2024 Maximiliano Sandoval
2026-01-26 15:13 ` [pbs-devel] [PATCH proxmox 04/10] cargo: run fmt Maximiliano Sandoval
2026-01-26 15:13 ` [pbs-devel] [PATCH proxmox 05/10] cargo: set resolver to 3 Maximiliano Sandoval
2026-01-26 15:13 ` [pbs-devel] [PATCH proxmox 06/10] cargo: run --fix Maximiliano Sandoval
2026-01-26 15:13 ` [pbs-devel] [PATCH proxmox 07/10] cargo: run fmt again Maximiliano Sandoval
2026-01-26 15:13 ` [pbs-devel] [PATCH proxmox 08/10] Remove rustfmt.toml and run cargo fmt Maximiliano Sandoval
2026-01-26 15:13 ` [pbs-devel] [PATCH proxmox 10/10] pve-api-types: specify rustfmt --edition 2024 Maximiliano Sandoval
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=20260126151349.627829-2-m.sandoval@proxmox.com \
--to=m.sandoval@proxmox.com \
--cc=pbs-devel@lists.proxmox.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.