From: Andreas Gruenbacher <agruenba@redhat.com>
To: Alexander Viro <viro@zeniv.linux.org.uk>,
"Theodore Ts'o" <tytso@mit.edu>,
Andreas Dilger <adilger.kernel@dilger.ca>,
"J. Bruce Fields" <bfields@fieldses.org>,
Jeff Layton <jlayton@poochiereds.net>,
Trond Myklebust <trond.myklebust@primarydata.com>,
Anna Schumaker <anna.schumaker@netapp.com>,
linux-ext4@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org,
linux-api@vger.kernel.org
Subject: [PATCH v9 43/43] richacl: uapi header split
Date: Mon, 5 Oct 2015 21:37:10 +0200 [thread overview]
Message-ID: <1444073830-21854-44-git-send-email-agruenba@redhat.com> (raw)
In-Reply-To: <1444073830-21854-1-git-send-email-agruenba@redhat.com>
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
include/linux/richacl.h | 119 +++++--------------------------------
include/linux/richacl_xattr.h | 17 +-----
include/uapi/linux/Kbuild | 2 +
include/uapi/linux/richacl.h | 111 ++++++++++++++++++++++++++++++++++
include/uapi/linux/richacl_xattr.h | 43 ++++++++++++++
5 files changed, 173 insertions(+), 119 deletions(-)
create mode 100644 include/uapi/linux/richacl.h
create mode 100644 include/uapi/linux/richacl_xattr.h
diff --git a/include/linux/richacl.h b/include/linux/richacl.h
index 5d2308a..f85c30a 100644
--- a/include/linux/richacl.h
+++ b/include/linux/richacl.h
@@ -17,9 +17,7 @@
#ifndef __RICHACL_H
#define __RICHACL_H
-#define RICHACE_OWNER_SPECIAL_ID 0
-#define RICHACE_GROUP_SPECIAL_ID 1
-#define RICHACE_EVERYONE_SPECIAL_ID 2
+#include <uapi/linux/richacl.h>
struct richace {
unsigned short e_type;
@@ -44,43 +42,12 @@ struct richacl {
struct richace a_entries[0];
};
-#define richacl_for_each_entry(_ace, _acl) \
- for (_ace = (_acl)->a_entries; \
- _ace != (_acl)->a_entries + (_acl)->a_count; \
- _ace++)
-
-#define richacl_for_each_entry_reverse(_ace, _acl) \
- for (_ace = (_acl)->a_entries + (_acl)->a_count - 1; \
- _ace != (_acl)->a_entries - 1; \
- _ace--)
-
-/* a_flags values */
-#define RICHACL_AUTO_INHERIT 0x01
-#define RICHACL_PROTECTED 0x02
-#define RICHACL_DEFAULTED 0x04
-#define RICHACL_WRITE_THROUGH 0x40
-#define RICHACL_MASKED 0x80
-
#define RICHACL_VALID_FLAGS ( \
- RICHACL_AUTO_INHERIT | \
- RICHACL_PROTECTED | \
- RICHACL_DEFAULTED | \
- RICHACL_WRITE_THROUGH | \
- RICHACL_MASKED)
-
-/* e_type values */
-#define RICHACE_ACCESS_ALLOWED_ACE_TYPE 0x0000
-#define RICHACE_ACCESS_DENIED_ACE_TYPE 0x0001
-
-/* e_flags bitflags */
-#define RICHACE_FILE_INHERIT_ACE 0x0001
-#define RICHACE_DIRECTORY_INHERIT_ACE 0x0002
-#define RICHACE_NO_PROPAGATE_INHERIT_ACE 0x0004
-#define RICHACE_INHERIT_ONLY_ACE 0x0008
-#define RICHACE_IDENTIFIER_GROUP 0x0040
-#define RICHACE_INHERITED_ACE 0x0080
-#define RICHACE_UNMAPPED_WHO 0x2000
-#define RICHACE_SPECIAL_WHO 0x4000
+ RICHACL_AUTO_INHERIT | \
+ RICHACL_PROTECTED | \
+ RICHACL_DEFAULTED | \
+ RICHACL_WRITE_THROUGH | \
+ RICHACL_MASKED)
#define RICHACE_VALID_FLAGS ( \
RICHACE_FILE_INHERIT_ACE | \
@@ -99,27 +66,6 @@ struct richacl {
RICHACE_INHERIT_ONLY_ACE | \
RICHACE_INHERITED_ACE )
-/* e_mask bitflags */
-#define RICHACE_READ_DATA 0x00000001
-#define RICHACE_LIST_DIRECTORY 0x00000001
-#define RICHACE_WRITE_DATA 0x00000002
-#define RICHACE_ADD_FILE 0x00000002
-#define RICHACE_APPEND_DATA 0x00000004
-#define RICHACE_ADD_SUBDIRECTORY 0x00000004
-#define RICHACE_READ_NAMED_ATTRS 0x00000008
-#define RICHACE_WRITE_NAMED_ATTRS 0x00000010
-#define RICHACE_EXECUTE 0x00000020
-#define RICHACE_DELETE_CHILD 0x00000040
-#define RICHACE_READ_ATTRIBUTES 0x00000080
-#define RICHACE_WRITE_ATTRIBUTES 0x00000100
-#define RICHACE_WRITE_RETENTION 0x00000200
-#define RICHACE_WRITE_RETENTION_HOLD 0x00000400
-#define RICHACE_DELETE 0x00010000
-#define RICHACE_READ_ACL 0x00020000
-#define RICHACE_WRITE_ACL 0x00040000
-#define RICHACE_WRITE_OWNER 0x00080000
-#define RICHACE_SYNCHRONIZE 0x00100000
-
/* Valid RICHACE_* flags for directories and non-directories */
#define RICHACE_VALID_MASK ( \
RICHACE_READ_DATA | RICHACE_LIST_DIRECTORY | \
@@ -139,49 +85,16 @@ struct richacl {
RICHACE_WRITE_OWNER | \
RICHACE_SYNCHRONIZE)
-/*
- * The POSIX permissions are supersets of the following NFSv4 permissions:
- *
- * - MAY_READ maps to READ_DATA or LIST_DIRECTORY, depending on the type
- * of the file system object.
- *
- * - MAY_WRITE maps to WRITE_DATA or RICHACE_APPEND_DATA for files, and to
- * ADD_FILE, RICHACE_ADD_SUBDIRECTORY, or RICHACE_DELETE_CHILD for directories.
- *
- * - MAY_EXECUTE maps to RICHACE_EXECUTE.
- *
- * (Some of these NFSv4 permissions have the same bit values.)
- */
-#define RICHACE_POSIX_MODE_READ ( \
- RICHACE_READ_DATA | \
- RICHACE_LIST_DIRECTORY)
-#define RICHACE_POSIX_MODE_WRITE ( \
- RICHACE_WRITE_DATA | \
- RICHACE_ADD_FILE | \
- RICHACE_APPEND_DATA | \
- RICHACE_ADD_SUBDIRECTORY | \
- RICHACE_DELETE_CHILD)
-#define RICHACE_POSIX_MODE_EXEC RICHACE_EXECUTE
-#define RICHACE_POSIX_MODE_ALL ( \
- RICHACE_POSIX_MODE_READ | \
- RICHACE_POSIX_MODE_WRITE | \
- RICHACE_POSIX_MODE_EXEC)
-/*
- * These permissions are always allowed
- * no matter what the acl says.
- */
-#define RICHACE_POSIX_ALWAYS_ALLOWED ( \
- RICHACE_SYNCHRONIZE | \
- RICHACE_READ_ATTRIBUTES | \
- RICHACE_READ_ACL)
-/*
- * The owner is implicitly granted
- * these permissions under POSIX.
- */
-#define RICHACE_POSIX_OWNER_ALLOWED ( \
- RICHACE_WRITE_ATTRIBUTES | \
- RICHACE_WRITE_OWNER | \
- RICHACE_WRITE_ACL)
+#define richacl_for_each_entry(_ace, _acl) \
+ for (_ace = (_acl)->a_entries; \
+ _ace != (_acl)->a_entries + (_acl)->a_count; \
+ _ace++)
+
+#define richacl_for_each_entry_reverse(_ace, _acl) \
+ for (_ace = (_acl)->a_entries + (_acl)->a_count - 1; \
+ _ace != (_acl)->a_entries - 1; \
+ _ace--)
+
/**
* richacl_get - grab another reference to a richacl handle
*/
diff --git a/include/linux/richacl_xattr.h b/include/linux/richacl_xattr.h
index dac4e32..4ba54bd 100644
--- a/include/linux/richacl_xattr.h
+++ b/include/linux/richacl_xattr.h
@@ -17,24 +17,9 @@
#ifndef __RICHACL_XATTR_H
#define __RICHACL_XATTR_H
+#include <uapi/linux/richacl_xattr.h>
#include <linux/richacl.h>
-struct richace_xattr {
- __le16 e_type;
- __le16 e_flags;
- __le32 e_mask;
- __le32 e_id;
-};
-
-struct richacl_xattr {
- unsigned char a_version;
- unsigned char a_flags;
- __le16 a_count;
- __le32 a_owner_mask;
- __le32 a_group_mask;
- __le32 a_other_mask;
-};
-
#define RICHACL_XATTR_VERSION 0
#define RICHACL_XATTR_MAX_COUNT \
((XATTR_SIZE_MAX - sizeof(struct richacl_xattr)) / \
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index f7b2db4..18ad070 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -348,6 +348,8 @@ header-y += reboot.h
header-y += reiserfs_fs.h
header-y += reiserfs_xattr.h
header-y += resource.h
+header-y += richacl.h
+header-y += richacl_xattr.h
header-y += rfkill.h
header-y += romfs_fs.h
header-y += rose.h
diff --git a/include/uapi/linux/richacl.h b/include/uapi/linux/richacl.h
new file mode 100644
index 0000000..6887f88
--- /dev/null
+++ b/include/uapi/linux/richacl.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2006, 2010 Novell, Inc.
+ * Copyright (C) 2015 Red Hat, Inc.
+ * Written by Andreas Gruenbacher <agruen@kernel.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; either version 2, or (at your option) any
+ * later version.
+ *
+ * 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.
+ */
+
+#ifndef __UAPI_RICHACL_H
+#define __UAPI_RICHACL_H
+
+/* a_flags values */
+#define RICHACL_AUTO_INHERIT 0x01
+#define RICHACL_PROTECTED 0x02
+#define RICHACL_DEFAULTED 0x04
+#define RICHACL_WRITE_THROUGH 0x40
+#define RICHACL_MASKED 0x80
+
+/* e_type values */
+#define RICHACE_ACCESS_ALLOWED_ACE_TYPE 0x0000
+#define RICHACE_ACCESS_DENIED_ACE_TYPE 0x0001
+
+/* e_flags bitflags */
+#define RICHACE_FILE_INHERIT_ACE 0x0001
+#define RICHACE_DIRECTORY_INHERIT_ACE 0x0002
+#define RICHACE_NO_PROPAGATE_INHERIT_ACE 0x0004
+#define RICHACE_INHERIT_ONLY_ACE 0x0008
+#define RICHACE_IDENTIFIER_GROUP 0x0040
+#define RICHACE_INHERITED_ACE 0x0080
+#define RICHACE_UNMAPPED_WHO 0x2000
+#define RICHACE_SPECIAL_WHO 0x4000
+
+/* e_mask bitflags */
+#define RICHACE_READ_DATA 0x00000001
+#define RICHACE_LIST_DIRECTORY 0x00000001
+#define RICHACE_WRITE_DATA 0x00000002
+#define RICHACE_ADD_FILE 0x00000002
+#define RICHACE_APPEND_DATA 0x00000004
+#define RICHACE_ADD_SUBDIRECTORY 0x00000004
+#define RICHACE_READ_NAMED_ATTRS 0x00000008
+#define RICHACE_WRITE_NAMED_ATTRS 0x00000010
+#define RICHACE_EXECUTE 0x00000020
+#define RICHACE_DELETE_CHILD 0x00000040
+#define RICHACE_READ_ATTRIBUTES 0x00000080
+#define RICHACE_WRITE_ATTRIBUTES 0x00000100
+#define RICHACE_WRITE_RETENTION 0x00000200
+#define RICHACE_WRITE_RETENTION_HOLD 0x00000400
+#define RICHACE_DELETE 0x00010000
+#define RICHACE_READ_ACL 0x00020000
+#define RICHACE_WRITE_ACL 0x00040000
+#define RICHACE_WRITE_OWNER 0x00080000
+#define RICHACE_SYNCHRONIZE 0x00100000
+
+/* e_id values */
+#define RICHACE_OWNER_SPECIAL_ID 0
+#define RICHACE_GROUP_SPECIAL_ID 1
+#define RICHACE_EVERYONE_SPECIAL_ID 2
+
+/*
+ * The POSIX permissions are supersets of the following richacl permissions:
+ *
+ * - MAY_READ maps to READ_DATA or LIST_DIRECTORY, depending on the type
+ * of the file system object.
+ *
+ * - MAY_WRITE maps to WRITE_DATA or RICHACE_APPEND_DATA for files, and to
+ * ADD_FILE, RICHACE_ADD_SUBDIRECTORY, or RICHACE_DELETE_CHILD for directories.
+ *
+ * - MAY_EXECUTE maps to RICHACE_EXECUTE.
+ *
+ * (Some of these richacl permissions have the same bit values.)
+ */
+#define RICHACE_POSIX_MODE_READ ( \
+ RICHACE_READ_DATA | \
+ RICHACE_LIST_DIRECTORY)
+#define RICHACE_POSIX_MODE_WRITE ( \
+ RICHACE_WRITE_DATA | \
+ RICHACE_ADD_FILE | \
+ RICHACE_APPEND_DATA | \
+ RICHACE_ADD_SUBDIRECTORY | \
+ RICHACE_DELETE_CHILD)
+#define RICHACE_POSIX_MODE_EXEC RICHACE_EXECUTE
+#define RICHACE_POSIX_MODE_ALL ( \
+ RICHACE_POSIX_MODE_READ | \
+ RICHACE_POSIX_MODE_WRITE | \
+ RICHACE_POSIX_MODE_EXEC)
+
+/*
+ * These permissions are always allowed no matter what the acl says.
+ */
+#define RICHACE_POSIX_ALWAYS_ALLOWED ( \
+ RICHACE_SYNCHRONIZE | \
+ RICHACE_READ_ATTRIBUTES | \
+ RICHACE_READ_ACL)
+
+/*
+ * The owner is implicitly granted these permissions under POSIX.
+ */
+#define RICHACE_POSIX_OWNER_ALLOWED ( \
+ RICHACE_WRITE_ATTRIBUTES | \
+ RICHACE_WRITE_OWNER | \
+ RICHACE_WRITE_ACL)
+
+#endif /* __UAPI_RICHACL_H */
diff --git a/include/uapi/linux/richacl_xattr.h b/include/uapi/linux/richacl_xattr.h
new file mode 100644
index 0000000..6f96bc0
--- /dev/null
+++ b/include/uapi/linux/richacl_xattr.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2006, 2010 Novell, Inc.
+ * Copyright (C) 2015 Red Hat, Inc.
+ * Written by Andreas Gruenbacher <agruen@kernel.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; either version 2, or (at your option) any
+ * later version.
+ *
+ * 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.
+ */
+
+#ifndef __UAPI_RICHACL_XATTR_H
+#define __UAPI_RICHACL_XATTR_H
+
+#include <linux/types.h>
+#include <linux/xattr.h>
+
+struct richace_xattr {
+ __le16 e_type;
+ __le16 e_flags;
+ __le32 e_mask;
+ __le32 e_id;
+};
+
+struct richacl_xattr {
+ unsigned char a_version;
+ unsigned char a_flags;
+ __le16 a_count;
+ __le32 a_owner_mask;
+ __le32 a_group_mask;
+ __le32 a_other_mask;
+};
+
+#define RICHACL_XATTR_MAX_COUNT \
+ ((XATTR_SIZE_MAX - sizeof(struct richacl_xattr)) / \
+ sizeof(struct richace_xattr))
+
+#endif /* __UAPI_RICHACL_XATTR_H */
--
2.5.0
next prev parent reply other threads:[~2015-10-05 19:41 UTC|newest]
Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-10-05 19:36 [PATCH v9 00/43] Richacls Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 01/43] vfs: Add IS_ACL() and IS_RICHACL() tests Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 02/43] vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 03/43] vfs: Add MAY_DELETE_SELF and MAY_DELETE_CHILD " Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 04/43] vfs: Make the inode passed to inode_change_ok non-const Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 05/43] vfs: Add permission flags for setting file attributes Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 06/43] richacl: In-memory representation and helper functions Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 07/43] richacl: Permission mapping functions Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 08/43] richacl: Compute maximum file masks from an acl Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 09/43] richacl: Permission check algorithm Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 10/43] vfs: Cache base_acl objects in inodes Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 11/43] vfs: Add get_richacl and set_richacl inode operations Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 12/43] vfs: Cache richacl in struct inode Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 13/43] richacl: Update the file masks in chmod() Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 14/43] richacl: Check if an acl is equivalent to a file mode Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 15/43] richacl: Create-time inheritance Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 16/43] richacl: Automatic Inheritance Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 17/43] richacl: xattr mapping functions Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 18/43] richacl: Add richacl xattr handler Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 19/43] vfs: Add richacl permission checking Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 20/43] ext4: Add richacl support Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 21/43] ext4: Add richacl feature flag Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 22/43] richacl: acl editing helper functions Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 23/43] richacl: Move everyone@ aces down the acl Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 24/43] richacl: Propagate everyone@ permissions to other aces Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 25/43] richacl: Set the owner permissions to the owner mask Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 26/43] richacl: Set the other permissions to the other mask Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 27/43] richacl: Isolate the owner and group classes Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 28/43] richacl: Apply the file masks to a richacl Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 29/43] richacl: Create richacl from mode values Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 30/43] nfsd: Keep list of acls to dispose of in compoundargs Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 31/43] nfsd: Use richacls as internal acl representation Andreas Gruenbacher
2015-10-05 19:36 ` [PATCH v9 32/43] nfsd: Add richacl support Andreas Gruenbacher
2015-10-05 19:37 ` [PATCH v9 33/43] nfsd: Add support for the v4.1 dacl attribute Andreas Gruenbacher
2015-10-05 19:37 ` [PATCH v9 34/43] nfsd: Add support for the MAY_CREATE_{FILE,DIR} permissions Andreas Gruenbacher
2015-10-05 19:37 ` [PATCH v9 35/43] richacl: Add support for unmapped identifiers Andreas Gruenbacher
2015-10-05 19:37 ` [PATCH v9 36/43] ext4: Don't allow unmapped identifiers in richacls Andreas Gruenbacher
2015-10-05 19:37 ` [PATCH v9 37/43] sunrpc: Allow to demand-allocate pages to encode into Andreas Gruenbacher
2015-10-05 19:37 ` [PATCH v9 38/43] sunrpc: Add xdr_init_encode_pages Andreas Gruenbacher
2015-10-05 19:37 ` [PATCH v9 39/43] nfs: Fix GETATTR bitmap verification Andreas Gruenbacher
2015-10-05 19:37 ` [PATCH v9 40/43] nfs: Remove unused xdr page offsets in getacl/setacl arguments Andreas Gruenbacher
2015-10-05 19:37 ` [PATCH v9 41/43] nfs: Add richacl support Andreas Gruenbacher
2015-10-05 19:37 ` [PATCH v9 42/43] nfs: Add support for the v4.1 dacl attribute Andreas Gruenbacher
2015-10-05 19:37 ` Andreas Gruenbacher [this message]
2015-10-06 9:07 ` [PATCH v9 00/43] Richacls Pavel Machek
2015-10-06 12:40 ` Andreas Gruenbacher
2015-10-07 7:33 ` James Morris
2015-10-07 13:21 ` Austin S Hemmelgarn
2015-10-07 13:46 ` Andreas Gruenbacher
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=1444073830-21854-44-git-send-email-agruenba@redhat.com \
--to=agruenba@redhat.com \
--cc=adilger.kernel@dilger.ca \
--cc=anna.schumaker@netapp.com \
--cc=bfields@fieldses.org \
--cc=jlayton@poochiereds.net \
--cc=linux-api@vger.kernel.org \
--cc=linux-ext4@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=trond.myklebust@primarydata.com \
--cc=tytso@mit.edu \
--cc=viro@zeniv.linux.org.uk \
/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).