From: "Mike Frysinger" <vapier@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/pax-utils:master commit in: /
Date: Thu, 25 Jan 2024 02:53:56 +0000 (UTC) [thread overview]
Message-ID: <1706151161.5243cb017a7847f53caaa7c89b8e7f3abf1e5e40.vapier@gentoo> (raw)
commit: 5243cb017a7847f53caaa7c89b8e7f3abf1e5e40
Author: Mike Frysinger <vapier <AT> gentoo <DOT> org>
AuthorDate: Thu Jan 25 02:52:41 2024 +0000
Commit: Mike Frysinger <vapier <AT> gentoo <DOT> org>
CommitDate: Thu Jan 25 02:52:41 2024 +0000
URL: https://gitweb.gentoo.org/proj/pax-utils.git/commit/?id=5243cb01
unify usage() output across all the tools
The scanelf --help output is the best & most flexible, so move that
to common code so the rest of the tools can benefit from it.
Signed-off-by: Mike Frysinger <vapier <AT> gentoo.org>
dumpelf.c | 20 +++++++-------------
paxinc.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
paxinc.h | 11 +++++++++++
pspax.c | 21 +++++++--------------
scanelf.c | 45 +++++++--------------------------------------
scanmacho.c | 24 ++++++++----------------
6 files changed, 90 insertions(+), 81 deletions(-)
diff --git a/dumpelf.c b/dumpelf.c
index c8f27e4..5b18326 100644
--- a/dumpelf.c
+++ b/dumpelf.c
@@ -507,7 +507,6 @@ static void dump_dyn(const elfobj *elf, const void *dyn_void, size_t dyn_cnt)
/* usage / invocation handling functions */
#define PARSE_FLAGS "vhV"
-#define a_argument required_argument
static struct option const long_opts[] = {
{"verbose", no_argument, NULL, 'v'},
{"help", no_argument, NULL, 'h'},
@@ -524,18 +523,13 @@ static const char * const opts_help[] = {
/* display usage and exit */
static void usage(int status)
{
- size_t i;
- printf("* Dump internal ELF structure\n\n"
- "Usage: %s <file1> [file2 fileN ...]\n\n", argv0);
- printf("Options:\n");
- for (i = 0; long_opts[i].name; ++i)
- if (long_opts[i].has_arg == no_argument)
- printf(" -%c, --%-13s* %s\n", long_opts[i].val,
- long_opts[i].name, opts_help[i]);
- else
- printf(" -%c, --%-6s <arg> * %s\n", long_opts[i].val,
- long_opts[i].name, opts_help[i]);
- exit(status);
+ pax_usage(
+ "Dump internal ELF structure",
+ "<file1> [file2 fileN ...]",
+ PARSE_FLAGS,
+ long_opts,
+ opts_help,
+ status);
}
/* parse command line arguments and perform needed actions */
diff --git a/paxinc.c b/paxinc.c
index 589d7ae..ff4ab85 100644
--- a/paxinc.c
+++ b/paxinc.c
@@ -198,3 +198,53 @@ const char *root_rel_path(const char *path)
return path;
}
+
+void pax_usage(
+ const char *header,
+ const char *args,
+ const char *parse_flags,
+ const struct option long_opts[],
+ const char * const opts_help[],
+ int status)
+{
+ const char a_arg[] = "<arg>";
+ size_t a_arg_len = strlen(a_arg) + 2;
+ size_t i;
+ int optlen;
+
+ printf("* %s\n\n"
+ "Usage: %s [options] %s\n\n", header, argv0, args);
+ printf("Options: -[%s]\n", parse_flags);
+
+ /* Prescan the --long opt length to auto-align. */
+ optlen = 0;
+ for (i = 0; long_opts[i].name; ++i) {
+ int l = strlen(long_opts[i].name);
+ if (long_opts[i].has_arg == a_argument)
+ l += a_arg_len;
+ optlen = max(l, optlen);
+ }
+ /* Use some reasonable min width. */
+ optlen = max(20, optlen);
+
+ for (i = 0; long_opts[i].name; ++i) {
+ /* First output the short flag if it has one. */
+ if (long_opts[i].val > '~')
+ printf(" ");
+ else
+ printf(" -%c, ", long_opts[i].val);
+
+ /* Then the long flag. */
+ if (long_opts[i].has_arg == no_argument)
+ printf("--%-*s", optlen, long_opts[i].name);
+ else
+ printf("--%s %s %*s", long_opts[i].name, a_arg,
+ (int)(optlen - strlen(long_opts[i].name) - a_arg_len), "");
+
+ /* Finally the help text. */
+ printf("* %s\n", opts_help[i]);
+ }
+
+ printf("\nFor more information, see the %s(1) manpage.\n", argv0);
+ exit(status);
+}
diff --git a/paxinc.h b/paxinc.h
index d25cf57..c8fcf71 100644
--- a/paxinc.h
+++ b/paxinc.h
@@ -124,6 +124,17 @@ void color_init(bool disable);
/* constant pointer to a constant buffer ... each program needs to set this */
extern const char argv0[];
+/* Display usage and exit. */
+extern void pax_usage(
+ const char *header,
+ const char *args,
+ const char *parse_flags,
+ const struct option long_opts[],
+ const char * const opts_help[],
+ int status);
+
+#define a_argument required_argument
+
/* we need the space before the last comma or we trigger a bug in gcc-2 :( */
#define warn(fmt, args...) \
fprintf(stderr, "%s%s%s: " fmt "\n", RED, argv0, NORM , ## args)
diff --git a/pspax.c b/pspax.c
index 1cfd72f..4cd09b6 100644
--- a/pspax.c
+++ b/pspax.c
@@ -448,7 +448,6 @@ static void pspax(const char *find_name)
/* usage / invocation handling functions */
#define PARSE_FLAGS "aeip:u:g:nwWvCBhV"
-#define a_argument required_argument
static struct option const long_opts[] = {
{"all", no_argument, NULL, 'a'},
{"header", no_argument, NULL, 'e'},
@@ -488,19 +487,13 @@ static const char * const opts_help[] = {
/* display usage and exit */
static void usage(int status)
{
- int i;
- printf("* List ELF/PaX information about running processes\n\n"
- "Usage: %s [options]\n\n", argv0);
- fputs("Options:\n", stdout);
- for (i = 0; long_opts[i].name; ++i)
- printf(" -%c, --%-12s* %s\n", long_opts[i].val,
- long_opts[i].name, opts_help[i]);
-#ifdef MANLYPAGE
- for (i = 0; long_opts[i].name; ++i)
- printf(".TP\n\\fB\\-%c, \\-\\-%s\\fR\n%s\n", long_opts[i].val,
- long_opts[i].name, opts_help[i]);
-#endif
- exit(status);
+ pax_usage(
+ "List ELF/PaX information about running processes",
+ "",
+ PARSE_FLAGS,
+ long_opts,
+ opts_help,
+ status);
}
/* parse command line arguments and perform needed actions */
diff --git a/scanelf.c b/scanelf.c
index 1a6043e..140208b 100644
--- a/scanelf.c
+++ b/scanelf.c
@@ -1828,7 +1828,6 @@ static void scanelf_envpath(void)
/* usage / invocation handling functions */ /* Free Flags: c d j u w G H J K P Q U W */
#define PARSE_FLAGS "plRmyAXz:xetrnLibSs:k:gN:TaqvF:f:o:E:M:DIYO:ZCBhV"
-#define a_argument required_argument
static struct option const long_opts[] = {
{"path", no_argument, NULL, 'p'},
{"ldpath", no_argument, NULL, 'l'},
@@ -1924,43 +1923,13 @@ static const char * const opts_help[] = {
/* display usage and exit */
static void usage(int status)
{
- const char a_arg[] = "<arg>";
- size_t a_arg_len = strlen(a_arg) + 2;
- size_t i;
- int optlen;
- printf("* Scan ELF binaries for stuff\n\n"
- "Usage: %s [options] <dir1/file1> [dir2 dirN file2 fileN ...]\n\n", argv0);
- printf("Options: -[%s]\n", PARSE_FLAGS);
-
- /* prescan the --long opt length to auto-align */
- optlen = 0;
- for (i = 0; long_opts[i].name; ++i) {
- int l = strlen(long_opts[i].name);
- if (long_opts[i].has_arg == a_argument)
- l += a_arg_len;
- optlen = max(l, optlen);
- }
-
- for (i = 0; long_opts[i].name; ++i) {
- /* first output the short flag if it has one */
- if (long_opts[i].val > '~')
- printf(" ");
- else
- printf(" -%c, ", long_opts[i].val);
-
- /* then the long flag */
- if (long_opts[i].has_arg == no_argument)
- printf("--%-*s", optlen, long_opts[i].name);
- else
- printf("--%s %s %*s", long_opts[i].name, a_arg,
- (int)(optlen - strlen(long_opts[i].name) - a_arg_len), "");
-
- /* finally the help text */
- printf("* %s\n", opts_help[i]);
- }
-
- puts("\nFor more information, see the scanelf(1) manpage");
- exit(status);
+ pax_usage(
+ "Scan ELF binaries for stuff",
+ "<dir1/file1> [dir2 dirN file2 fileN ...]",
+ PARSE_FLAGS,
+ long_opts,
+ opts_help,
+ status);
}
/* parse command line arguments and perform needed actions */
diff --git a/scanmacho.c b/scanmacho.c
index f0351ff..d33a440 100644
--- a/scanmacho.c
+++ b/scanmacho.c
@@ -573,7 +573,6 @@ static void scanmacho_envpath(void)
/* usage / invocation handling functions */ /* Free Flags: c d e j k l s t u w x z G H I J K L P Q T W X Y */
#define PARSE_FLAGS "pRmyArnibSUN:gE:M:DO:ZaqvF:f:o:CBhV"
-#define a_argument required_argument
static struct option const long_opts[] = {
{"path", no_argument, NULL, 'p'},
{"recursive", no_argument, NULL, 'R'},
@@ -621,7 +620,7 @@ static const char * const opts_help[] = {
"Find a specified library",
"Use strncmp to match libraries. (use with -N)",
"Print only Mach-O files matching mach_header\n"
- " MH_OBJECT,MH_EXECUTE ... (ELF: etype)",
+ " MH_OBJECT,MH_EXECUTE ... (ELF: etype)",
"Print only Mach-O files matching numeric bits",
"Print Endianness",
"Print only Mach-O files matching octal permissions",
@@ -642,20 +641,13 @@ static const char * const opts_help[] = {
/* display usage and exit */
static void usage(int status)
{
- unsigned long i;
- printf("* Scan Mach-O binaries for stuff\n\n"
- "Usage: %s [options] <dir1/file1> [dir2 dirN file2 fileN ...]\n\n", argv0);
- printf("Options: -[%s]\n", PARSE_FLAGS);
- for (i = 0; long_opts[i].name; ++i)
- if (long_opts[i].has_arg == no_argument)
- printf(" -%c, --%-14s* %s\n", long_opts[i].val,
- long_opts[i].name, opts_help[i]);
- else
- printf(" -%c, --%-7s <arg> * %s\n", long_opts[i].val,
- long_opts[i].name, opts_help[i]);
-
- puts("\nFor more information, see the scanmacho(1) manpage");
- exit(status);
+ pax_usage(
+ "Scan Mach-O binaries for stuff",
+ "<dir1/file1> [dir2 dirN file2 fileN ...]",
+ PARSE_FLAGS,
+ long_opts,
+ opts_help,
+ status);
}
/* parse command line arguments and perform needed actions */
next reply other threads:[~2024-01-25 2:54 UTC|newest]
Thread overview: 253+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-01-25 2:53 Mike Frysinger [this message]
-- strict thread matches above, loose matches on Subject: below --
2024-09-22 4:33 [gentoo-commits] proj/pax-utils:master commit in: / Sam James
2024-09-22 4:30 Sam James
2024-08-09 10:06 Sam James
2024-08-09 10:06 Sam James
2024-08-09 10:06 Sam James
2024-08-09 10:06 Sam James
2024-08-09 10:06 Sam James
2024-08-09 10:06 Sam James
2024-08-09 10:02 Sam James
2024-07-22 21:07 Mike Gilbert
2024-07-22 20:08 Mike Gilbert
2024-01-25 6:52 Mike Frysinger
2024-01-25 5:57 Mike Frysinger
2024-01-25 5:57 Mike Frysinger
2024-01-25 5:36 Mike Frysinger
2024-01-25 5:21 Mike Frysinger
2024-01-25 5:06 Mike Frysinger
2024-01-25 5:06 Mike Frysinger
2024-01-25 4:44 Mike Frysinger
2024-01-25 2:53 Mike Frysinger
2024-01-25 2:53 Mike Frysinger
2024-01-25 2:14 Mike Frysinger
2024-01-24 22:53 Mike Frysinger
2024-01-24 22:15 Mike Frysinger
2024-01-24 15:44 Mike Frysinger
2024-01-16 5:13 Mike Frysinger
2024-01-16 5:13 Mike Frysinger
2024-01-10 8:05 Mike Frysinger
2024-01-10 8:02 Mike Frysinger
2024-01-10 8:02 Mike Frysinger
2024-01-10 7:58 Mike Frysinger
2024-01-02 18:03 Mike Frysinger
2024-01-02 18:03 Mike Frysinger
2024-01-02 18:03 Mike Frysinger
2024-01-02 18:03 Mike Frysinger
2024-01-02 16:28 Mike Frysinger
2024-01-01 15:43 Mike Frysinger
2024-01-01 15:43 Mike Frysinger
2023-12-22 5:31 Mike Frysinger
2023-12-22 5:31 Mike Frysinger
2023-12-22 5:31 Mike Frysinger
2023-12-22 2:31 Mike Frysinger
2023-12-22 2:31 Mike Frysinger
2023-12-22 2:31 Mike Frysinger
2023-12-14 21:28 Mike Frysinger
2023-12-14 21:28 Mike Frysinger
2023-12-14 19:57 Mike Frysinger
2023-11-23 13:31 Sam James
2023-02-13 5:26 Sam James
2023-02-13 5:26 Sam James
2023-01-29 5:56 Sam James
2023-01-29 5:56 Sam James
2023-01-29 5:56 Sam James
2023-01-29 3:41 Sam James
2023-01-29 3:36 Sam James
2023-01-29 3:36 Sam James
2023-01-26 21:46 Sam James
2023-01-06 7:15 Sam James
2022-09-28 7:42 Mike Frysinger
2022-09-28 7:42 Mike Frysinger
2022-09-28 7:42 Mike Frysinger
2022-09-28 7:42 Mike Frysinger
2022-09-28 7:42 Mike Frysinger
2022-09-28 7:42 Mike Frysinger
2022-09-28 7:42 Mike Frysinger
2022-09-21 8:28 Mike Frysinger
2022-09-21 8:26 Mike Frysinger
2022-09-21 8:20 Mike Frysinger
2022-07-31 4:56 Sam James
2022-07-12 6:33 Sam James
2022-07-12 6:33 Sam James
2022-04-25 1:20 WANG Xuerui
2022-03-24 15:42 Sam James
2022-03-09 8:01 Mike Frysinger
2022-02-07 7:18 Fabian Groffen
2022-01-23 2:47 Mike Frysinger
2021-12-24 1:45 Sam James
2021-12-17 5:19 Mike Frysinger
2021-10-17 5:15 Mike Frysinger
2021-10-05 1:05 Mike Frysinger
2021-10-04 22:05 Mike Frysinger
2021-09-20 4:51 Sam James
2021-07-22 21:31 Sergei Trofimovich
2021-07-22 21:16 Sergei Trofimovich
2021-07-02 22:04 Sergei Trofimovich
2021-06-10 7:07 Sergei Trofimovich
2021-06-10 7:02 Sergei Trofimovich
2021-04-19 4:58 Mike Frysinger
2021-04-18 18:29 Mike Frysinger
2021-04-17 5:39 Mike Frysinger
2021-04-17 5:39 Mike Frysinger
2021-04-17 0:38 Mike Frysinger
2021-04-16 19:26 Mike Frysinger
2021-04-16 19:26 Mike Frysinger
2021-04-16 19:26 Mike Frysinger
2021-04-16 19:03 Mike Frysinger
2021-04-16 19:03 Mike Frysinger
2021-04-16 15:08 Mike Frysinger
2021-04-16 15:08 Mike Frysinger
2021-04-16 15:08 Mike Frysinger
2021-04-16 3:41 Mike Frysinger
2021-04-16 3:39 Mike Frysinger
2021-04-16 3:39 Mike Frysinger
2021-04-16 1:56 Mike Frysinger
2021-04-16 1:56 Mike Frysinger
2021-04-16 0:48 Mike Frysinger
2021-04-16 0:48 Mike Frysinger
2021-02-26 11:51 Sergei Trofimovich
2021-02-04 18:51 Sergei Trofimovich
2021-02-03 20:41 Sergei Trofimovich
2021-02-03 20:17 Sergei Trofimovich
2021-02-03 19:46 Sergei Trofimovich
2021-01-01 14:08 Fabian Groffen
2021-01-01 14:08 Fabian Groffen
2020-12-20 19:53 Sergei Trofimovich
2020-10-05 17:46 Sergei Trofimovich
2020-08-14 22:17 Sergei Trofimovich
2020-04-13 10:41 Sergei Trofimovich
2020-04-06 18:00 Sergei Trofimovich
2020-03-26 19:27 Mike Frysinger
2020-03-26 17:09 Mike Frysinger
2020-03-26 17:09 Mike Frysinger
2020-03-19 0:00 Sergei Trofimovich
2020-03-18 23:39 Sergei Trofimovich
2020-02-16 10:57 Sergei Trofimovich
2020-02-16 10:50 Sergei Trofimovich
2020-02-16 10:48 Sergei Trofimovich
2020-02-16 10:17 Sergei Trofimovich
2019-01-14 22:53 Sergei Trofimovich
2018-11-19 22:20 Sergei Trofimovich
2018-06-07 14:09 Mike Frysinger
2018-06-07 14:09 Mike Frysinger
2018-06-07 14:09 Mike Frysinger
2018-06-07 14:09 Mike Frysinger
2018-06-07 14:09 Mike Frysinger
2018-06-07 14:09 Mike Frysinger
2018-06-07 14:09 Mike Frysinger
2018-06-07 14:09 Mike Frysinger
2018-06-07 14:09 Mike Frysinger
2018-06-07 4:44 Mike Frysinger
2018-06-07 4:44 Mike Frysinger
2018-06-07 4:44 Mike Frysinger
2018-02-24 10:16 Sergei Trofimovich
2017-09-18 9:27 Fabian Groffen
2017-09-18 9:27 Fabian Groffen
2017-09-18 7:06 Fabian Groffen
2017-03-14 7:19 Mike Frysinger
2017-02-16 21:24 Mike Frysinger
2017-02-16 21:24 Mike Frysinger
2017-02-16 21:24 Mike Frysinger
2017-02-11 7:06 Mike Frysinger
2017-02-01 23:08 Mike Frysinger
2017-02-01 23:08 Mike Frysinger
2017-02-01 23:08 Mike Frysinger
2017-01-24 20:39 Mike Frysinger
2017-01-24 20:39 Mike Frysinger
2017-01-24 6:50 Mike Frysinger
2017-01-24 6:50 Mike Frysinger
2017-01-24 6:50 Mike Frysinger
2017-01-24 6:50 Mike Frysinger
2017-01-22 17:59 Mike Frysinger
2017-01-22 17:59 Mike Frysinger
2017-01-22 17:59 Mike Frysinger
2017-01-22 17:59 Mike Frysinger
2017-01-22 17:59 Mike Frysinger
2017-01-22 17:59 Mike Frysinger
2017-01-22 17:59 Mike Frysinger
2017-01-22 17:59 Mike Frysinger
2017-01-22 17:59 Mike Frysinger
2016-11-27 3:43 Mike Frysinger
2016-11-15 4:02 Mike Frysinger
2016-11-15 4:02 Mike Frysinger
2016-11-14 14:57 Mike Frysinger
2016-11-12 7:15 Mike Frysinger
2016-11-12 7:15 Mike Frysinger
2016-11-12 7:15 Mike Frysinger
2016-11-12 7:15 Mike Frysinger
2016-11-12 7:15 Mike Frysinger
2016-11-12 7:15 Mike Frysinger
2016-11-08 20:47 Mike Gilbert
2016-06-20 17:46 Mike Frysinger
2016-06-20 4:03 Mike Frysinger
2016-06-20 4:03 Mike Frysinger
2016-06-20 3:22 Mike Frysinger
2016-06-20 3:22 Mike Frysinger
2016-06-20 3:08 Mike Frysinger
2016-06-20 3:08 Mike Frysinger
2016-06-20 3:08 Mike Frysinger
2016-06-20 3:08 Mike Frysinger
2016-06-20 3:08 Mike Frysinger
2016-06-20 3:08 Mike Frysinger
2016-06-20 3:08 Mike Frysinger
2016-06-20 3:08 Mike Frysinger
2016-06-20 3:08 Mike Frysinger
2016-06-20 3:08 Mike Frysinger
2016-06-20 3:08 Mike Frysinger
2016-05-31 22:27 Mike Frysinger
2016-03-03 21:15 Mike Frysinger
2016-02-10 19:41 Mike Frysinger
2016-02-10 18:54 Mike Frysinger
2016-01-28 22:42 Mike Frysinger
2016-01-03 22:23 Mike Frysinger
2016-01-03 22:23 Mike Frysinger
2016-01-03 22:01 Mike Frysinger
2016-01-02 15:26 Mike Frysinger
2016-01-02 3:52 Mike Frysinger
2015-12-19 19:41 Mike Frysinger
2015-12-17 3:24 Mike Frysinger
2015-12-17 3:24 Mike Frysinger
2015-12-17 3:24 Mike Frysinger
2015-12-17 3:24 Mike Frysinger
2015-12-12 22:45 Mike Frysinger
2015-12-12 22:45 Mike Frysinger
2015-12-12 22:45 Mike Frysinger
2015-12-12 22:45 Mike Frysinger
2015-12-12 22:45 Mike Frysinger
2015-12-12 22:45 Mike Frysinger
2015-11-26 8:43 Mike Frysinger
2015-10-26 4:35 Mike Frysinger
2015-10-08 20:31 Mike Frysinger
2015-09-19 6:27 Mike Frysinger
2015-09-19 6:27 Mike Frysinger
2015-09-12 4:17 Mike Frysinger
2015-08-28 0:33 Mike Frysinger
2015-08-26 6:29 Mike Frysinger
2015-08-24 21:22 Mike Frysinger
2015-08-24 21:22 Mike Frysinger
2015-08-24 21:22 Mike Frysinger
2015-08-20 14:39 Mike Frysinger
2015-08-20 14:39 Mike Frysinger
2015-08-20 14:39 Mike Frysinger
2015-08-20 14:33 Mike Frysinger
2015-08-20 14:33 Mike Frysinger
2015-08-20 13:32 Mike Frysinger
2015-08-18 15:56 Mike Frysinger
2015-08-18 15:35 Mike Frysinger
2015-08-18 15:35 Mike Frysinger
2015-08-18 14:39 Mike Frysinger
2015-08-18 14:38 Mike Frysinger
2015-07-13 9:14 Mike Frysinger
2015-07-13 9:14 Mike Frysinger
2015-07-13 9:14 Mike Frysinger
2015-05-24 3:22 Mike Frysinger
2015-03-29 20:07 Mike Frysinger
2015-03-29 20:07 Mike Frysinger
2015-03-29 20:07 Mike Frysinger
2015-03-10 5:31 Mike Frysinger
2015-03-10 5:31 Mike Frysinger
2015-03-10 4:19 Mike Frysinger
2015-03-10 3:36 Mike Frysinger
2015-03-06 11:52 Mike Frysinger
2015-03-04 22:35 Mike Frysinger
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=1706151161.5243cb017a7847f53caaa7c89b8e7f3abf1e5e40.vapier@gentoo \
--to=vapier@gentoo.org \
--cc=gentoo-commits@lists.gentoo.org \
--cc=gentoo-dev@lists.gentoo.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