Re-enable the web-based PR submission mechanism.
This code relies on the netpbm port being installed ; this is already a dependency of the textproc/docproj port. This comes courtesy of a collaboration with Eric Anderson <anderson@centtech.com> who submitted both the idea and the vast majority of the code to implement it; thank you very much, Eric - this is a great Christmas present to us and our user community.
This commit is contained in:
parent
0613439948
commit
555cb01e5a
Notes:
svn2git
2020-12-08 03:00:23 +00:00
svn path=/www/; revision=19185
41 changed files with 260 additions and 29 deletions
|
@ -1,4 +1,4 @@
|
|||
# $FreeBSD: www/en/cgi/Makefile,v 1.18 2001/10/29 10:14:31 murray Exp $
|
||||
# $FreeBSD: www/en/cgi/Makefile,v 1.19 2002/11/09 05:23:14 bmah Exp $
|
||||
|
||||
.if exists(../Makefile.conf)
|
||||
.include "../Makefile.conf"
|
||||
|
@ -11,7 +11,7 @@ DATA= ftp.mirrors
|
|||
DATA+= cvsweb.conf cvsweb.conf-freebsd cvsweb.conf-netbsd cvsweb.conf-openbsd
|
||||
CGI= ftp.cgi gallery.cgi mirror.cgi cgi-lib.pl cgi-style.pl
|
||||
CGI+= search.cgi cvsweb.cgi query-pr.cgi query-pr-summary.cgi
|
||||
# CGI+= dosendpr.cgi
|
||||
CGI+= dosendpr.cgi sendpr-code.cgi
|
||||
CGI+= freebsd.def html.pl reg.cgi missing_handler.cgi
|
||||
CGI+= ports.cgi pds.cgi man.cgi url.cgi getmsg.cgi mid.cgi
|
||||
CGI+= mailindex.cgi
|
||||
|
|
82
en/cgi/confirm-code.cgi
Executable file
82
en/cgi/confirm-code.cgi
Executable file
|
@ -0,0 +1,82 @@
|
|||
#!/usr/bin/perl -T
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
# Copyright (c) 2003 Eric Anderson
|
||||
|
||||
use DB_File;
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
use strict;
|
||||
|
||||
$ENV{"PATH"} = "/bin:/usr/bin";
|
||||
$ENV{"TMPDIR"} = "/tmp";
|
||||
|
||||
my($fd, $db_obj, %db_hash, $currenttime, $randomcode, $pngbindata, $randompick, $pnmlist, $i);
|
||||
my($expiretime, $pnmcat, $pnmtopng, $pnmdatadir, $dbpath);
|
||||
|
||||
############################################
|
||||
# generate 8 charactor code from A-Z0-9 (no o,O,0)
|
||||
my @availchars = qw(A B C D E F G H I J K L M N P Q R S T U V W X Y Z
|
||||
1 2 3 4 5 6 7 8 9);
|
||||
|
||||
$pnmcat = "/usr/local/bin/pnmcat";
|
||||
$pnmtopng = "/usr/local/bin/pnmtopng";
|
||||
$pnmdatadir = "../gifs/";
|
||||
$dbpath = "/tmp/sendpr-code.db";
|
||||
$expiretime = 900; # seconds until code expires
|
||||
############################################
|
||||
|
||||
$currenttime = time();
|
||||
|
||||
# DB stuff here
|
||||
$db_obj = tie(%db_hash, 'DB_File', $dbpath, O_CREAT|O_RDWR, 0644)
|
||||
or die "dbcreate $dbpath $!";
|
||||
$fd = $db_obj->fd;
|
||||
open(DB_FH, "+<&=$fd") or die "fdopen $!";
|
||||
|
||||
unless (flock (DB_FH, LOCK_EX | LOCK_NB)) {
|
||||
unless (flock (DB_FH, LOCK_EX)) { die "flock: $!" }
|
||||
}
|
||||
|
||||
&gencode;
|
||||
|
||||
while ($db_hash{$randomcode}) {
|
||||
# it already exists so:
|
||||
# we check age (over x seconds old?)
|
||||
# if it is, override with new date
|
||||
# if not, generate a new code
|
||||
if ( ($currenttime - $expiretime) <= $db_hash{$randomcode}) {
|
||||
&gencode;
|
||||
} else {
|
||||
delete $db_hash{"$randomcode"};
|
||||
}
|
||||
}
|
||||
|
||||
$db_hash{$randomcode} = $currenttime;
|
||||
|
||||
$db_obj->sync(); # to flush
|
||||
flock(DB_FH, LOCK_UN);
|
||||
undef $db_obj; # removing the last reference to the DB
|
||||
# closes it. Closing DB_FH is implicit.
|
||||
untie %db_hash;
|
||||
|
||||
$/ = "";
|
||||
|
||||
open(BUILDPNG, "$pnmcat -lr $pnmlist | $pnmtopng 2>/dev/null |");
|
||||
$pngbindata = <BUILDPNG>;
|
||||
print "Content-type: image/png\n\n";
|
||||
print "$pngbindata";
|
||||
close(BUILDPNG);
|
||||
|
||||
############################################
|
||||
sub gencode {
|
||||
srand( time() ^ ($$ + ($$ << 15)) );
|
||||
|
||||
for ($i = 0; $i < 8; $i++) {
|
||||
$randompick = $availchars[int(rand(@availchars))];
|
||||
$randomcode .= "$randompick";
|
||||
$pnmlist .= "$pnmdatadir$randompick\.pnm ";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -8,17 +8,22 @@
|
|||
# GNU General Public License Version 2.
|
||||
# (http://www.gnu.ai.mit.edu/copyleft/gpl.html)
|
||||
#
|
||||
# $FreeBSD: www/en/cgi/dosendpr.cgi,v 1.12 2003/05/15 12:08:05 ceri Exp $
|
||||
# $FreeBSD: www/en/cgi/dosendpr.cgi,v 1.13 2003/09/04 15:16:15 ceri Exp $
|
||||
|
||||
require "html.pl";
|
||||
|
||||
use Socket;
|
||||
use DB_File;
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
|
||||
my $blackhole = "dnsbl.njabl.org";
|
||||
my $openproxyip = "127.0.0.9";
|
||||
my $blackhole_err = 0;
|
||||
my $openproxy;
|
||||
|
||||
my $expiretime = 900;
|
||||
$dbpath = "/tmp/sendpr-code.db";
|
||||
|
||||
# Environment variables to stuff in the PR header.
|
||||
my @ENV_captures = qw/ REMOTE_HOST
|
||||
REMOTE_ADDR
|
||||
|
@ -102,21 +107,52 @@ if (!$submitprog) { &prerror("submit program problem"); }
|
|||
&html_body ($gnsprepbody);
|
||||
|
||||
# Verify the data ...
|
||||
if (!$cgi_data{'email'} || !$cgi_data{'originator'} ||
|
||||
!$cgi_data{'synopsis'}) {
|
||||
if ($gnsprepbad && -e $gnsprepbad )
|
||||
{ print `cat $gnsprepbad`; }
|
||||
else {
|
||||
print "<h1>Bad Data</h1>\nYou need to specify at least your ",
|
||||
"electronic mail address, your name and a synopsis of the ",
|
||||
"of the problem.\n Please return to the form and add the ",
|
||||
"missing information. Thank you.\n";
|
||||
}
|
||||
&html_end();
|
||||
|
||||
exit(1);
|
||||
$db_obj = tie(%db_hash, 'DB_File', $dbpath, O_CREAT|O_RDWR, 0644)
|
||||
or die "dbcreate $dbpath $!";
|
||||
$fd = $db_obj->fd;
|
||||
open(DB_FH, "+<&=$fd") or die "fdopen $!";
|
||||
|
||||
unless (flock (DB_FH, LOCK_EX | LOCK_NB)) {
|
||||
unless (flock (DB_FH, LOCK_EX)) { die "flock: $!" }
|
||||
}
|
||||
|
||||
$codeentered = $cgi_data{'code-confirm'};
|
||||
$currenttime = time();
|
||||
if (defined($codeentered) && $codeentered && $db_hash{$codeentered} &&
|
||||
(($currenttime - $expiretime) <= $db_hash{$codeentered})) {
|
||||
if (!$cgi_data{'email'} || !$cgi_data{'originator'} ||
|
||||
!$cgi_data{'synopsis'}) {
|
||||
if ($gnsprepbad && -e $gnsprepbad )
|
||||
{ print `cat $gnsprepbad`; }
|
||||
else {
|
||||
print "<h1>Bad Data</h1>\nYou need to specify at least your ",
|
||||
"electronic mail address, your name and a synopsis of the ",
|
||||
"of the problem.\n Please return to the form and add the ",
|
||||
"missing information. Thank you.\n";
|
||||
}
|
||||
&html_end();
|
||||
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
print "<h1>Incorrect safety code</h1>\nYou need to enter the correct ",
|
||||
"code from the image displayed. Please return to the form and enter the ",
|
||||
"code exactly as shown. Thank you.\n";
|
||||
|
||||
&html_end();
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
delete $db_hash{"$codeentered"};
|
||||
$db_obj->sync(); # to flush
|
||||
flock(DB_FH, LOCK_UN);
|
||||
undef $db_obj; # removing the last reference to the DB
|
||||
# closes it. Closing DB_FH is implicit.
|
||||
untie %db_hash;
|
||||
|
||||
|
||||
$openproxy = isopenproxy($ENV{'REMOTE_ADDR'}, $blackhole, $openproxyip);
|
||||
if (defined $openproxy) {
|
||||
if ($openproxy) {
|
||||
|
@ -134,7 +170,7 @@ $pr = "To: $gnemail\n" .
|
|||
if ($blackhole_err) {
|
||||
$pr .= "X-REMOTE_ADDR-Is-Open-Proxy: Maybe\n";
|
||||
}
|
||||
$pr .= "X-Send-Pr-Version: www-1.0\n\n" .
|
||||
$pr .= "X-Send-Pr-Version: www-2.0\n\n" .
|
||||
">Submitter-Id:\t$cgi_data{'submitterid'}\n" .
|
||||
">Originator:\t$cgi_data{'originator'}\n" .
|
||||
">Organization:\t$cgi_data{'organization'}\n" .
|
||||
|
|
82
en/cgi/sendpr-code.cgi
Executable file
82
en/cgi/sendpr-code.cgi
Executable file
|
@ -0,0 +1,82 @@
|
|||
#!/usr/bin/perl -T
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
# Copyright (c) 2003 Eric Anderson
|
||||
|
||||
use DB_File;
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
use strict;
|
||||
|
||||
$ENV{"PATH"} = "/bin:/usr/bin";
|
||||
$ENV{"TMPDIR"} = "/tmp";
|
||||
|
||||
my($fd, $db_obj, %db_hash, $currenttime, $randomcode, $pngbindata, $randompick, $pnmlist, $i);
|
||||
my($expiretime, $pnmcat, $pnmtopng, $pnmdatadir, $dbpath);
|
||||
|
||||
############################################
|
||||
# generate 8 charactor code from A-Z0-9 (no o,O,0)
|
||||
my @availchars = qw(A B C D E F G H I J K L M N P Q R S T U V W X Y Z
|
||||
1 2 3 4 5 6 7 8 9);
|
||||
|
||||
$pnmcat = "/usr/local/bin/pnmcat";
|
||||
$pnmtopng = "/usr/local/bin/pnmtopng";
|
||||
$pnmdatadir = "../gifs/";
|
||||
$dbpath = "/tmp/sendpr-code.db";
|
||||
$expiretime = 900; # seconds until code expires
|
||||
############################################
|
||||
|
||||
$currenttime = time();
|
||||
|
||||
# DB stuff here
|
||||
$db_obj = tie(%db_hash, 'DB_File', $dbpath, O_CREAT|O_RDWR, 0644)
|
||||
or die "dbcreate $dbpath $!";
|
||||
$fd = $db_obj->fd;
|
||||
open(DB_FH, "+<&=$fd") or die "fdopen $!";
|
||||
|
||||
unless (flock (DB_FH, LOCK_EX | LOCK_NB)) {
|
||||
unless (flock (DB_FH, LOCK_EX)) { die "flock: $!" }
|
||||
}
|
||||
|
||||
&gencode;
|
||||
|
||||
while ($db_hash{$randomcode}) {
|
||||
# it already exists so:
|
||||
# we check age (over x seconds old?)
|
||||
# if it is, override with new date
|
||||
# if not, generate a new code
|
||||
if ( ($currenttime - $expiretime) <= $db_hash{$randomcode}) {
|
||||
&gencode;
|
||||
} else {
|
||||
delete $db_hash{"$randomcode"};
|
||||
}
|
||||
}
|
||||
|
||||
$db_hash{$randomcode} = $currenttime;
|
||||
|
||||
$db_obj->sync(); # to flush
|
||||
flock(DB_FH, LOCK_UN);
|
||||
undef $db_obj; # removing the last reference to the DB
|
||||
# closes it. Closing DB_FH is implicit.
|
||||
untie %db_hash;
|
||||
|
||||
$/ = "";
|
||||
|
||||
open(BUILDPNG, "$pnmcat -lr $pnmlist | $pnmtopng 2>/dev/null |");
|
||||
$pngbindata = <BUILDPNG>;
|
||||
print "Content-type: image/png\n\n";
|
||||
print "$pngbindata";
|
||||
close(BUILDPNG);
|
||||
|
||||
############################################
|
||||
sub gencode {
|
||||
srand( time() ^ ($$ + ($$ << 15)) );
|
||||
|
||||
for ($i = 0; $i < 8; $i++) {
|
||||
$randompick = $availchars[int(rand(@availchars))];
|
||||
$randomcode .= "$randompick";
|
||||
$pnmlist .= "$pnmdatadir$randompick\.pnm ";
|
||||
}
|
||||
}
|
||||
|
||||
|
BIN
en/gifs/1.pnm
Normal file
BIN
en/gifs/1.pnm
Normal file
Binary file not shown.
BIN
en/gifs/2.pnm
Normal file
BIN
en/gifs/2.pnm
Normal file
Binary file not shown.
BIN
en/gifs/3.pnm
Normal file
BIN
en/gifs/3.pnm
Normal file
Binary file not shown.
BIN
en/gifs/4.pnm
Normal file
BIN
en/gifs/4.pnm
Normal file
Binary file not shown.
BIN
en/gifs/5.pnm
Normal file
BIN
en/gifs/5.pnm
Normal file
Binary file not shown.
BIN
en/gifs/6.pnm
Normal file
BIN
en/gifs/6.pnm
Normal file
Binary file not shown.
BIN
en/gifs/7.pnm
Normal file
BIN
en/gifs/7.pnm
Normal file
Binary file not shown.
BIN
en/gifs/8.pnm
Normal file
BIN
en/gifs/8.pnm
Normal file
Binary file not shown.
BIN
en/gifs/9.pnm
Normal file
BIN
en/gifs/9.pnm
Normal file
Binary file not shown.
BIN
en/gifs/A.pnm
Normal file
BIN
en/gifs/A.pnm
Normal file
Binary file not shown.
BIN
en/gifs/B.pnm
Normal file
BIN
en/gifs/B.pnm
Normal file
Binary file not shown.
BIN
en/gifs/C.pnm
Normal file
BIN
en/gifs/C.pnm
Normal file
Binary file not shown.
BIN
en/gifs/D.pnm
Normal file
BIN
en/gifs/D.pnm
Normal file
Binary file not shown.
BIN
en/gifs/E.pnm
Normal file
BIN
en/gifs/E.pnm
Normal file
Binary file not shown.
BIN
en/gifs/F.pnm
Normal file
BIN
en/gifs/F.pnm
Normal file
Binary file not shown.
BIN
en/gifs/G.pnm
Normal file
BIN
en/gifs/G.pnm
Normal file
Binary file not shown.
BIN
en/gifs/H.pnm
Normal file
BIN
en/gifs/H.pnm
Normal file
Binary file not shown.
BIN
en/gifs/I.pnm
Normal file
BIN
en/gifs/I.pnm
Normal file
Binary file not shown.
BIN
en/gifs/J.pnm
Normal file
BIN
en/gifs/J.pnm
Normal file
Binary file not shown.
BIN
en/gifs/K.pnm
Normal file
BIN
en/gifs/K.pnm
Normal file
Binary file not shown.
BIN
en/gifs/L.pnm
Normal file
BIN
en/gifs/L.pnm
Normal file
Binary file not shown.
BIN
en/gifs/M.pnm
Normal file
BIN
en/gifs/M.pnm
Normal file
Binary file not shown.
|
@ -1,4 +1,4 @@
|
|||
# $FreeBSD: www/en/gifs/Makefile,v 1.45 2003/04/06 20:57:08 ceri Exp $
|
||||
# $FreeBSD: www/en/gifs/Makefile,v 1.46 2003/06/24 13:27:54 phantom Exp $
|
||||
|
||||
.if exists(../Makefile.conf)
|
||||
.include "../Makefile.conf"
|
||||
|
@ -62,5 +62,9 @@ DATA+= not_planned.png not_started.png project_goal.png project_plan.png
|
|||
DATA+= resources_and_links.png status_board.png blocked.png c99.jpg
|
||||
DATA+= fbsdcng-english.png fbsdcng-japanese.png
|
||||
DATA+= abs_bsd_cov.gif fbsd-ososfypc.jpg
|
||||
DATA+= 1.pnm 2.pnm 3.pnm 4.pnm 5.pnm 6.pnm 7.pnm 8.pnm 9.pnm
|
||||
DATA+= A.pnm B.pnm C.pnm D.pnm E.pnm F.pnm G.pnm H.pnm I.pnm J.pnm
|
||||
DATA+= K.pnm L.pnm M.pnm N.pnm P.pnm Q.pnm R.pnm S.pnm T.pnm U.pnm
|
||||
DATA+= V.pnm W.pnm X.pnm Y.pnm Z.pnm
|
||||
|
||||
.include "${WEB_PREFIX}/share/mk/web.site.mk"
|
||||
|
|
BIN
en/gifs/N.pnm
Normal file
BIN
en/gifs/N.pnm
Normal file
Binary file not shown.
BIN
en/gifs/P.pnm
Normal file
BIN
en/gifs/P.pnm
Normal file
Binary file not shown.
BIN
en/gifs/Q.pnm
Normal file
BIN
en/gifs/Q.pnm
Normal file
Binary file not shown.
BIN
en/gifs/R.pnm
Normal file
BIN
en/gifs/R.pnm
Normal file
Binary file not shown.
BIN
en/gifs/S.pnm
Normal file
BIN
en/gifs/S.pnm
Normal file
Binary file not shown.
BIN
en/gifs/T.pnm
Normal file
BIN
en/gifs/T.pnm
Normal file
Binary file not shown.
BIN
en/gifs/U.pnm
Normal file
BIN
en/gifs/U.pnm
Normal file
Binary file not shown.
BIN
en/gifs/V.pnm
Normal file
BIN
en/gifs/V.pnm
Normal file
Binary file not shown.
BIN
en/gifs/W.pnm
Normal file
BIN
en/gifs/W.pnm
Normal file
Binary file not shown.
BIN
en/gifs/X.pnm
Normal file
BIN
en/gifs/X.pnm
Normal file
Binary file not shown.
BIN
en/gifs/Y.pnm
Normal file
BIN
en/gifs/Y.pnm
Normal file
Binary file not shown.
BIN
en/gifs/Z.pnm
Normal file
BIN
en/gifs/Z.pnm
Normal file
Binary file not shown.
|
@ -1,10 +1,11 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" [
|
||||
<!ENTITY date "$FreeBSD: www/en/send-pr.sgml,v 1.30 2003/01/01 20:58:16 ceri Exp $">
|
||||
<!ENTITY date "$FreeBSD: www/en/send-pr.sgml,v 1.31 2003/09/11 21:10:08 ceri Exp $">
|
||||
<!ENTITY title "Submit a FreeBSD problem report">
|
||||
<!ENTITY copyright "This gnats pr-submission mechanism Copyright © 1996
|
||||
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.">
|
||||
<!ENTITY footer '<address>&author;<br>&date;</address>'>
|
||||
<!ENTITY % includes SYSTEM "includes.sgml"> %includes;
|
||||
<!ENTITY bugbusters "bugbusters@FreeBSD.org">
|
||||
]>
|
||||
|
||||
<html>
|
||||
|
@ -14,7 +15,6 @@
|
|||
|
||||
<img src="gifs/bug.jpg" alt="Bugs" align="right" border="0" width="200" height="233">
|
||||
|
||||
<!-- The web interface is disabled for the time being.
|
||||
<p>Thank you for taking the time to let us know about a problem with
|
||||
FreeBSD. Please fill out the form as completely as possible. Make sure
|
||||
you fill in the "Environment" field as requested with the output from
|
||||
|
@ -26,7 +26,7 @@
|
|||
|
||||
<form action="http://www.FreeBSD.org/cgi/dosendpr.cgi" method="post">
|
||||
<input type="hidden" name="gndb" value="freebsd" >
|
||||
<input type="hidden" name="submitterid" value="net" >
|
||||
<input type="hidden" name="submitterid" value="current-users" >
|
||||
<input type="hidden" name="confidential" value="no" >
|
||||
|
||||
<b>Your Electronic Mail Address</b>: <br>
|
||||
|
@ -96,6 +96,13 @@
|
|||
<b>Fix to the problem if known</b>: <br>
|
||||
<textarea name="fix" rows="6" cols="72"></textarea><br>
|
||||
|
||||
<b>Finally, please enter the code from the image below to prove
|
||||
you're not a robot</b>: <br>
|
||||
<img src="http://www.FreeBSD.org/cgi/sendpr-code.cgi"
|
||||
alt="Random text; if you cannot see the image, please email &bugbusters;"
|
||||
border="0" width="100" height="35">
|
||||
<input type="text" name="code-confirm" size="8"><br>
|
||||
|
||||
<input type="submit" value="Submit Problem Report" >
|
||||
<input type="reset" value="Reset" >
|
||||
</form>
|
||||
|
@ -103,15 +110,6 @@
|
|||
<p><b>Note</b>: copy/paste will destroy TABs and spacing, and this web
|
||||
form should not be used to submit code as plain text.</p>
|
||||
|
||||
end comment for disabled PR interface -->
|
||||
|
||||
<!-- When re-enabling the web PR interface, delete the next 2 paragraphs -->
|
||||
<p>The web-based bug interface is currently disabled.</p>
|
||||
|
||||
<p>If you have access to a FreeBSD system, you can use the
|
||||
<a href="http://www.FreeBSD.org/cgi/man.cgi?send-pr">send-pr(1)</a>
|
||||
program to submit a bug report.</p>
|
||||
|
||||
&footer;
|
||||
</body>
|
||||
</html>
|
||||
|
|
29
tools/buildpnms.sh
Executable file
29
tools/buildpnms.sh
Executable file
|
@ -0,0 +1,29 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
# Shell script to generate the .pnm files required for the send-pr
|
||||
# mechanism. This is not used by the build process, as it requires
|
||||
# X libraries for the gozer program; rather they are generated and
|
||||
# committed into www/en/gifs/
|
||||
|
||||
GOZER=/usr/X11R6/bin/gozer
|
||||
PNGTOPNM=/usr/local/bin/pngtopnm
|
||||
VERBOSE=/usr/bin/false
|
||||
|
||||
# Generate 8 character code from A-Z0-9 (no o,O,0)
|
||||
availchars="A B C D E F G H I J K L M N P Q R S T U V W X Y Z 1 2 3 4 5 6 7 8 9"
|
||||
|
||||
for char in ${availchars}
|
||||
do
|
||||
${VERBOSE} Making ${char}.png...
|
||||
${GOZER} -x 2 -t ${char} -f "#990000" -b "#ffffff" ${char}.png
|
||||
${VERBOSE} DONE
|
||||
${VERBOSE} Converting ${char}.pnm to ${char}.png...
|
||||
${PNGTOPNM} ${char}.png > ${char}.pnm
|
||||
${VERBOSE} DONE
|
||||
${VERBOSE} Removing ${char}.png...
|
||||
rm ${char}.png
|
||||
${VERBOSE} DONE
|
||||
done
|
||||
|
Loading…
Reference in a new issue