linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] drm/i915: Fix comments mentioning typo in IS_ENABLED()
@ 2020-06-05 14:19 Kees Cook
  2020-06-05 14:40 ` [Intel-gfx] " Chris Wilson
  2020-06-05 18:24 ` [PATCH] checkpatch: Add test for possible misuse of IS_ENABLED() without CONFIG_ Joe Perches
  0 siblings, 2 replies; 7+ messages in thread
From: Kees Cook @ 2020-06-05 14:19 UTC (permalink / raw)
  To: David Airlie, Daniel Vetter
  Cc: Jani Nikula, Chris Wilson, Joe Perches, dri-devel, intel-gfx,
	linux-kernel

This has no code changes, but the typo is clearly getting copy/pasted,
so better to avoid this now and fix the typo. IS_ENABLED() takes full
names, and must have the "CONFIG_" prefix.

Reported-by: Joe Perches <joe@perches.com>
Link: https://lore.kernel.org/lkml/b08611018fdb6d88757c6008a5c02fa0e07b32fb.camel@perches.com
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/dma-buf/selftests.h                          | 2 +-
 drivers/gpu/drm/i915/selftests/i915_live_selftests.h | 2 +-
 drivers/gpu/drm/i915/selftests/i915_mock_selftests.h | 2 +-
 drivers/gpu/drm/i915/selftests/i915_perf_selftests.h | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/dma-buf/selftests.h b/drivers/dma-buf/selftests.h
index 55918ef9adab..bc8cea67bf1e 100644
--- a/drivers/dma-buf/selftests.h
+++ b/drivers/dma-buf/selftests.h
@@ -5,7 +5,7 @@
  * a module parameter. It must be unique and legal for a C identifier.
  *
  * The function should be of type int function(void). It may be conditionally
- * compiled using #if IS_ENABLED(DRM_I915_SELFTEST).
+ * compiled using #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST).
  *
  * Tests are executed in order by igt/dmabuf_selftest
  */
diff --git a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
index 5dd5d81646c4..e42ea9c6703b 100644
--- a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
+++ b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
@@ -11,7 +11,7 @@
  * a module parameter. It must be unique and legal for a C identifier.
  *
  * The function should be of type int function(void). It may be conditionally
- * compiled using #if IS_ENABLED(DRM_I915_SELFTEST).
+ * compiled using #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST).
  *
  * Tests are executed in order by igt/drv_selftest
  */
diff --git a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
index 6a2be7d0dd95..4be044198af9 100644
--- a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
+++ b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
@@ -11,7 +11,7 @@
  * a module parameter. It must be unique and legal for a C identifier.
  *
  * The function should be of type int function(void). It may be conditionally
- * compiled using #if IS_ENABLED(DRM_I915_SELFTEST).
+ * compiled using #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST).
  *
  * Tests are executed in order by igt/drv_selftest
  */
diff --git a/drivers/gpu/drm/i915/selftests/i915_perf_selftests.h b/drivers/gpu/drm/i915/selftests/i915_perf_selftests.h
index d8da142985eb..c2389f8a257d 100644
--- a/drivers/gpu/drm/i915/selftests/i915_perf_selftests.h
+++ b/drivers/gpu/drm/i915/selftests/i915_perf_selftests.h
@@ -11,7 +11,7 @@
  * a module parameter. It must be unique and legal for a C identifier.
  *
  * The function should be of type int function(void). It may be conditionally
- * compiled using #if IS_ENABLED(DRM_I915_SELFTEST).
+ * compiled using #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST).
  *
  * Tests are executed in order by igt/i915_selftest
  */
-- 
2.25.1


-- 
Kees Cook

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [Intel-gfx] [PATCH] drm/i915: Fix comments mentioning typo in IS_ENABLED()
  2020-06-05 14:19 [PATCH] drm/i915: Fix comments mentioning typo in IS_ENABLED() Kees Cook
@ 2020-06-05 14:40 ` Chris Wilson
  2020-06-05 18:24 ` [PATCH] checkpatch: Add test for possible misuse of IS_ENABLED() without CONFIG_ Joe Perches
  1 sibling, 0 replies; 7+ messages in thread
From: Chris Wilson @ 2020-06-05 14:40 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Kees Cook
  Cc: intel-gfx, linux-kernel, dri-devel, Joe Perches

Quoting Kees Cook (2020-06-05 15:19:53)
> This has no code changes, but the typo is clearly getting copy/pasted,
> so better to avoid this now and fix the typo. IS_ENABLED() takes full
> names, and must have the "CONFIG_" prefix.
> 
> Reported-by: Joe Perches <joe@perches.com>
> Link: https://lore.kernel.org/lkml/b08611018fdb6d88757c6008a5c02fa0e07b32fb.camel@perches.com
> Signed-off-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
-Chris

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH] checkpatch: Add test for possible misuse of IS_ENABLED() without CONFIG_
  2020-06-05 14:19 [PATCH] drm/i915: Fix comments mentioning typo in IS_ENABLED() Kees Cook
  2020-06-05 14:40 ` [Intel-gfx] " Chris Wilson
@ 2020-06-05 18:24 ` Joe Perches
  2020-06-05 18:48   ` Kees Cook
  2020-06-06  0:32   ` Andrew Morton
  1 sibling, 2 replies; 7+ messages in thread
From: Joe Perches @ 2020-06-05 18:24 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Kees Cook, linux-kernel

IS_ENABLED is almost always used with CONFIG_<FOO> defines.

Add a test to verify that the #define being tested starts with CONFIG_.

Signed-off-by: Joe Perches <joe@perches.com>
---
 scripts/checkpatch.pl | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 5f00df2c3f59..83be88b16166 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -6480,6 +6480,12 @@ sub process {
 			}
 		}
 
+# check for IS_ENABLED() without CONFIG_<FOO> ($rawline for comments too)
+		if ($rawline =~ /\bIS_ENABLED\s*\(\s*(\w+)\s*\)/ && $1 !~ /^CONFIG_/) {
+			WARN("IS_ENABLED_CONFIG",
+			     "IS_ENABLED($1) is normally used as IS_ENABLED(CONFIG_$1)\n" . $herecurr);
+		}
+
 # check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
 		if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(CONFIG_[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) {
 			my $config = $1;



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] checkpatch: Add test for possible misuse of IS_ENABLED() without CONFIG_
  2020-06-05 18:24 ` [PATCH] checkpatch: Add test for possible misuse of IS_ENABLED() without CONFIG_ Joe Perches
@ 2020-06-05 18:48   ` Kees Cook
  2020-06-06  0:32   ` Andrew Morton
  1 sibling, 0 replies; 7+ messages in thread
From: Kees Cook @ 2020-06-05 18:48 UTC (permalink / raw)
  To: Joe Perches; +Cc: Andrew Morton, linux-kernel

On Fri, Jun 05, 2020 at 11:24:43AM -0700, Joe Perches wrote:
> IS_ENABLED is almost always used with CONFIG_<FOO> defines.
> 
> Add a test to verify that the #define being tested starts with CONFIG_.
> 
> Signed-off-by: Joe Perches <joe@perches.com>

Reviewed-by: Kees Cook <keescook@chromium.org>

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] checkpatch: Add test for possible misuse of IS_ENABLED() without CONFIG_
  2020-06-05 18:24 ` [PATCH] checkpatch: Add test for possible misuse of IS_ENABLED() without CONFIG_ Joe Perches
  2020-06-05 18:48   ` Kees Cook
@ 2020-06-06  0:32   ` Andrew Morton
  2020-06-06  1:58     ` Joe Perches
  1 sibling, 1 reply; 7+ messages in thread
From: Andrew Morton @ 2020-06-06  0:32 UTC (permalink / raw)
  To: Joe Perches; +Cc: Kees Cook, linux-kernel

On Fri, 05 Jun 2020 11:24:43 -0700 Joe Perches <joe@perches.com> wrote:

> IS_ENABLED is almost always used with CONFIG_<FOO> defines.
> 
> Add a test to verify that the #define being tested starts with CONFIG_.

Yay.

I wonder if there's a simple way of testing whether the CONFIG_ thing
can *ever* be enabled.  So detect if someone does

	if (IS_ENABLED(CONFIG_BLOCKK))


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] checkpatch: Add test for possible misuse of IS_ENABLED() without CONFIG_
  2020-06-06  0:32   ` Andrew Morton
@ 2020-06-06  1:58     ` Joe Perches
  2020-06-06  9:41       ` Joe Perches
  0 siblings, 1 reply; 7+ messages in thread
From: Joe Perches @ 2020-06-06  1:58 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Kees Cook, linux-kernel

On Fri, 2020-06-05 at 17:32 -0700, Andrew Morton wrote:
> On Fri, 05 Jun 2020 11:24:43 -0700 Joe Perches <joe@perches.com> wrote:
> 
> > IS_ENABLED is almost always used with CONFIG_<FOO> defines.
> > 
> > Add a test to verify that the #define being tested starts with CONFIG_.
> 
> Yay.
> 
> I wonder if there's a simple way of testing whether the CONFIG_ thing
> can *ever* be enabled.  So detect if someone does
> 
> 	if (IS_ENABLED(CONFIG_BLOCKK))

No, not really. There's no simple way to do that.
It's doable, but it's not at all simple.

I think it would require something similar to the
checkpatch seed_camelcase_includes function to look
for all current config symbols and verify whatever
CONFIG_<DEFINE> against that list.

$ git grep -P -oh "^\s*config\s+\w+" -- '*/Kconfig*' | \
  sed -r -e 's/^\s+//' -e 's/\s+/ /g' | \
  sort | uniq -cym

Right now that takes ~1.5 seconds with my laptop
against an uncached git tree, and ~0.25 seconds cached.

Without a git tree it takes 20+ seconds.

Anyway, maybe this.

It only does the time consuming lookup when
it finds a IS_ENABLED line.

---
 scripts/checkpatch.pl | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 101 insertions(+)

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 5f00df2c3f59..aabb01cf1e6c 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -47,6 +47,7 @@ my $gitroot = $ENV{'GIT_DIR'};
 $gitroot = ".git" if !defined($gitroot);
 my %debug;
 my %camelcase = ();
+my %Kconfig_syms = ();
 my %use_type = ();
 my @use = ();
 my %ignore_type = ();
@@ -911,6 +912,90 @@ sub is_SPDX_License_valid {
 	return 1;
 }
 
+sub seed_Kconfig_file {
+	my ($file) = @_;
+
+	return if (!(-f $file));
+
+	local $/;
+
+	open(my $Kconfig_file, '<', "$file")
+	    or warn "$P: Can't read '$file' $!\n";
+	my $text = <$Kconfig_file>;
+	close($Kconfig_file);
+
+	my @lines = split('\n', $text);
+
+	foreach my $line (@lines) {
+		next if ($line !~ /^\s*config\s+(\w+)/);
+		$Kconfig_syms{$1} = 1;
+	}
+}
+
+my $Kconfig_symbols_seeded = 0;
+sub seed_Kconfig_symbols {
+	return if ($Kconfig_symbols_seeded);
+
+	my $files;
+	my @Kconfig_files = ();
+	my $Kconfig_syms_cache = "";
+
+	$Kconfig_symbols_seeded = 1;
+
+	if (-e "$gitroot") {
+		my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`;
+		chomp $git_last_include_commit;
+		$Kconfig_syms_cache = ".checkpatch-Kconfig_syms.git.$git_last_include_commit";
+	} else {
+		my $last_mod_date = 0;
+		$files = `find $root/ -name "Kconfig*"`;
+		@Kconfig_files = split('\n', $files);
+		foreach my $file (@Kconfig_files) {
+			my $date = POSIX::strftime("%Y%m%d%H%M",
+						   localtime((stat $file)[9]));
+			$last_mod_date = $date if ($last_mod_date < $date);
+		}
+		$Kconfig_syms_cache = ".checkpatch-Kconfig_syms.date.$last_mod_date";
+	}
+
+	if ($Kconfig_syms_cache ne "" && -f $Kconfig_syms_cache) {
+		open(my $Kconfig_syms_file, '<', "$Kconfig_syms_cache")
+		    or warn "$P: Can't read '$Kconfig_syms_cache' $!\n";
+		while (<$Kconfig_syms_file>) {
+			chomp;
+			$Kconfig_syms{$_} = 1;
+		}
+		close($Kconfig_syms_file);
+
+		return;
+	}
+
+	if (-e "$gitroot") {
+		my @syms = `${git_command} grep -P -oh '^\\s*config\\s+\\w+' -- '*/Kconfig*'`;
+		s/^\s+// for @syms;
+		s/config\s+// for @syms;
+		s/\n$// for @syms;
+		@syms = sort(uniq(@syms));
+		foreach my $sym (@syms) {
+			$Kconfig_syms{$sym} = 1;
+		}
+	} else {
+		foreach my $file (@Kconfig_files) {
+			seed_Kconfig_file($file);
+		}
+	}
+
+	if ($Kconfig_syms_cache ne "") {
+		unlink glob ".checkpatch-Kconfig_syms.*";
+		open(my $Kconfig_syms_file, '>', "$Kconfig_syms_cache")
+		    or warn "$P: Can't write '$Kconfig_syms_cache' $!\n";
+		foreach (sort { lc($a) cmp lc($b) } keys(%Kconfig_syms)) {
+			print $Kconfig_syms_file ("$_\n");
+		}
+		close($Kconfig_syms_file);
+	}
+}
+
 my $camelcase_seeded = 0;
 sub seed_camelcase_includes {
 	return if ($camelcase_seeded);
@@ -6480,6 +6565,22 @@ sub process {
 			}
 		}
 
+# check for IS_ENABLED() used without CONFIG_<FOO> ($rawline for comment use)
+# or if the CONFIG_<FOO> symbol is not a known Kconfig entry
+		if ($rawline =~ /\bIS_ENABLED\s*\(\s*(\w+)\s*\)/) {
+			my $sym = $1;
+			seed_Kconfig_symbols();
+		        if ($sym !~ /^CONFIG_/) {
+				WARN("IS_ENABLED_CONFIG",
+				     "IS_ENABLED($sym) is normally used as IS_ENABLED(CONFIG_$1)\n" . $herecurr);
+			}
+			if (!exists($Kconfig_syms{$sym})) {
+				WARN("IS_ENABLED_CONFIG",
+				     "'$sym' is not a known Kconfig config entry in the current kernel sources\n" . $herecurr);
+
+			}
+		}
+
 # check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
 		if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(CONFIG_[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) {
 			my $config = $1;



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] checkpatch: Add test for possible misuse of IS_ENABLED() without CONFIG_
  2020-06-06  1:58     ` Joe Perches
@ 2020-06-06  9:41       ` Joe Perches
  0 siblings, 0 replies; 7+ messages in thread
From: Joe Perches @ 2020-06-06  9:41 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Kees Cook, linux-kernel

Might s well post one that works

Interdiff similar to:

 +		        if ($sym !~ /^CONFIG_/) {
 +				WARN("IS_ENABLED_CONFIG",
 +				     "IS_ENABLED($sym) is normally used as IS_ENABLED(CONFIG_$1)\n" . $herecurr);
++			} else {
++				$sym =~ s/^CONFIG_//;
 +			}
 +			if (!exists($Kconfig_syms{$sym})) {
 +				WARN("IS_ENABLED_CONFIG",
-+				     "'$sym' is not a known Kconfig config entry in the current kernel sources\n" . $herecurr);
-+
++				     "'config $sym' is not a known Kconfig config entry in the current kernel sources\n" . $herecurr);
 +			}
 +		}
 +
---
 scripts/checkpatch.pl | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 102 insertions(+)

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 5f00df2c3f59..02814c689676 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -47,6 +47,7 @@ my $gitroot = $ENV{'GIT_DIR'};
 $gitroot = ".git" if !defined($gitroot);
 my %debug;
 my %camelcase = ();
+my %Kconfig_syms = ();
 my %use_type = ();
 my @use = ();
 my %ignore_type = ();
@@ -911,6 +912,90 @@ sub is_SPDX_License_valid {
 	return 1;
 }
 
+sub seed_Kconfig_file {
+	my ($file) = @_;
+
+	return if (!(-f $file));
+
+	local $/;
+
+	open(my $Kconfig_file, '<', "$file")
+	    or warn "$P: Can't read '$file' $!\n";
+	my $text = <$Kconfig_file>;
+	close($Kconfig_file);
+
+	my @lines = split('\n', $text);
+
+	foreach my $line (@lines) {
+		next if ($line !~ /^\s*config\s+(\w+)/);
+		$Kconfig_syms{$1} = 1;
+	}
+}
+
+my $Kconfig_symbols_seeded = 0;
+sub seed_Kconfig_symbols {
+	return if ($Kconfig_symbols_seeded);
+
+	my $files;
+	my @Kconfig_files = ();
+	my $Kconfig_syms_cache = "";
+
+	$Kconfig_symbols_seeded = 1;
+
+	if (-e "$gitroot") {
+		my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`;
+		chomp $git_last_include_commit;
+		$Kconfig_syms_cache = ".checkpatch-Kconfig_syms.git.$git_last_include_commit";
+	} else {
+		my $last_mod_date = 0;
+		$files = `find $root/ -name "Kconfig*"`;
+		@Kconfig_files = split('\n', $files);
+		foreach my $file (@Kconfig_files) {
+			my $date = POSIX::strftime("%Y%m%d%H%M",
+						   localtime((stat $file)[9]));
+			$last_mod_date = $date if ($last_mod_date < $date);
+		}
+		$Kconfig_syms_cache = ".checkpatch-Kconfig_syms.date.$last_mod_date";
+	}
+
+	if ($Kconfig_syms_cache ne "" && -f $Kconfig_syms_cache) {
+		open(my $Kconfig_syms_file, '<', "$Kconfig_syms_cache")
+		    or warn "$P: Can't read '$Kconfig_syms_cache' $!\n";
+		while (<$Kconfig_syms_file>) {
+			chomp;
+			$Kconfig_syms{$_} = 1;
+		}
+		close($Kconfig_syms_file);
+
+		return;
+	}
+
+	if (-e "$gitroot") {
+		my @syms = `${git_command} grep -P -oh '^\\s*config\\s+\\w+' -- '*/Kconfig*'`;
+		s/^\s+// for @syms;
+		s/config\s+// for @syms;
+		s/\n$// for @syms;
+		@syms = sort(uniq(@syms));
+		foreach my $sym (@syms) {
+			$Kconfig_syms{$sym} = 1;
+		}
+	} else {
+		foreach my $file (@Kconfig_files) {
+			seed_Kconfig_file($file);
+		}
+	}
+
+	if ($Kconfig_syms_cache ne "") {
+		unlink glob ".checkpatch-Kconfig_syms.*";
+		open(my $Kconfig_syms_file, '>', "$Kconfig_syms_cache")
+		    or warn "$P: Can't write '$Kconfig_syms_cache' $!\n";
+		foreach (sort { lc($a) cmp lc($b) } keys(%Kconfig_syms)) {
+			print $Kconfig_syms_file ("$_\n");
+		}
+		close($Kconfig_syms_file);
+	}
+}
+
 my $camelcase_seeded = 0;
 sub seed_camelcase_includes {
 	return if ($camelcase_seeded);
@@ -6480,6 +6565,23 @@ sub process {
 			}
 		}
 
+# check for IS_ENABLED() used without CONFIG_<FOO> ($rawline for comment use)
+# or if the CONFIG_<FOO> symbol is not a known Kconfig entry
+		if ($rawline =~ /\bIS_ENABLED\s*\(\s*(\w+)\s*\)/) {
+			my $sym = $1;
+			seed_Kconfig_symbols();
+		        if ($sym !~ /^CONFIG_/) {
+				WARN("IS_ENABLED_CONFIG",
+				     "IS_ENABLED($sym) is normally used as IS_ENABLED(CONFIG_$1)\n" . $herecurr);
+			} else {
+				$sym =~ s/^CONFIG_//;
+			}
+			if (!exists($Kconfig_syms{$sym})) {
+				WARN("IS_ENABLED_CONFIG",
+				     "'config $sym' is not a known Kconfig config entry in the current kernel sources\n" . $herecurr);
+			}
+		}
+
 # check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
 		if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(CONFIG_[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) {
 			my $config = $1;



^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-06-06  9:41 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-05 14:19 [PATCH] drm/i915: Fix comments mentioning typo in IS_ENABLED() Kees Cook
2020-06-05 14:40 ` [Intel-gfx] " Chris Wilson
2020-06-05 18:24 ` [PATCH] checkpatch: Add test for possible misuse of IS_ENABLED() without CONFIG_ Joe Perches
2020-06-05 18:48   ` Kees Cook
2020-06-06  0:32   ` Andrew Morton
2020-06-06  1:58     ` Joe Perches
2020-06-06  9:41       ` Joe Perches

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).