Compare commits

..

1 Commits

Author SHA1 Message Date
(no author)
258dc9fead This commit was manufactured by cvs2svn to create branch 'src'.
git-svn-id: svn://10.0.0.236/branches/src@33658 18797224-902f-48f8-a5cc-f745e15eee43
1999-06-03 23:10:01 +00:00
229 changed files with 18627 additions and 31749 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 B

File diff suppressed because it is too large Load Diff

View File

@@ -1,404 +0,0 @@
This file contains only important changes made to Bugzilla. If you
are updating from an older verseion, make sure that you check this file!
For a more complete list of what has changed, use Bonsai
(http://cvs-mirror.mozilla.org/webtools/bonsai/cvsqueryform.cgi) to
query the CVS tree. For example,
http://cvs-mirror.mozilla.org/webtools/bonsai/cvsquery.cgi?module=all&branch=HEAD&branchtype=match&dir=mozilla%2Fwebtools%2Fbugzilla&file=&filetype=match&who=&whotype=match&sortby=Date&hours=2&date=week&mindate=&maxdate=&cvsroot=%2Fcvsroot
will tell you what has been changed in the last week.
10/12/99 The CHANGES file is now obsolete! There is a new file called
checksetup.pl. You should get in the habit of running that file every time
you update your installation of Bugzilla. That file will be constantly
updated to automatically update your installation to match any code changes.
If you're curious as to what is going on, changes are commented in that file,
at the end.
Many thanks to Holger Schurig <holgerschurig@nikocity.de> for writing this
script!
10/11/99 Restructured voting database to add a cached value in each
bug recording how many total votes that bug has. While I'm at it, I
removed the unused "area" field from the bugs database. It is
distressing to realize that the bugs table has reached the maximum
number of indices allowed by MySQL (16), which may make future
enhancements awkward.
You must feed the following to MySQL:
alter table bugs drop column area;
alter table bugs add column votes mediumint not null, add index (votes);
You then *must* delete the data/versioncache file when you make this
change, as it contains references to the "area" field. Deleting it is safe,
bugzilla will correctly regenerate it.
If you have been using the voting feature at all, then you will then
need to update the voting cache. You can do this by visiting the
sanitycheck.cgi page, and taking it up on its offer to rebuild the
votes stuff.
10/7/99 Added voting ability. You must run the new script
"makevotestable.sh". You must also feed the following to mysql:
alter table products add column votesperuser smallint not null;
9/15/99 Apparently, newer alphas of MySQL won't allow you to have
"when" as a column name. So, I have had to rename a column in the
bugs_activity table. You must feed the below to mysql or you won't
work at all.
alter table bugs_activity change column when bug_when datetime not null;
8/16/99 Added "OpenVMS" to the list of OS's. Feed this to mysql:
alter table bugs change column op_sys op_sys enum("All", "Windows 3.1", "Windows 95", "Windows 98", "Windows NT", "Mac System 7", "Mac System 7.5", "Mac System 7.6.1", "Mac System 8.0", "Mac System 8.5", "Mac System 8.6", "AIX", "BSDI", "HP-UX", "IRIX", "Linux", "FreeBSD", "OSF/1", "Solaris", "SunOS", "Neutrino", "OS/2", "BeOS", "OpenVMS", "other") not null;
6/22/99 Added an entry to the attachments table to record who the submitter
was. Nothing uses this yet, but it still should be recorded.
alter table attachments add column submitter_id mediumint not null;
You should also run this script to populate the new field:
#!/usr/bonsaitools/bin/perl -w
use diagnostics;
use strict;
require "globals.pl";
$|=1;
ConnectToDatabase();
SendSQL("select bug_id, attach_id from attachments order by bug_id");
my @list;
while (MoreSQLData()) {
my @row = FetchSQLData();
push(@list, \@row);
}
foreach my $ref (@list) {
my ($bug, $attach) = (@$ref);
SendSQL("select long_desc from bugs where bug_id = $bug");
my $comment = FetchOneColumn() . "Created an attachment (id=$attach)";
if ($comment =~ m@-* Additional Comments From ([^ ]*)[- 0-9/:]*\nCreated an attachment \(id=$attach\)@) {
print "Found $1\n";
SendSQL("select userid from profiles where login_name=" .
SqlQuote($1));
my $userid = FetchOneColumn();
if (defined $userid && $userid > 0) {
SendSQL("update attachments set submitter_id=$userid where attach_id = $attach");
}
} else {
print "Bug $bug can't find comment for attachment $attach\n";
}
}
6/14/99 Added "BeOS" to the list of OS's. Feed this to mysql:
alter table bugs change column op_sys op_sys enum("All", "Windows 3.1", "Windows 95", "Windows 98", "Windows NT", "Mac System 7", "Mac System 7.5", "Mac System 7.6.1", "Mac System 8.0", "Mac System 8.5", "Mac System 8.6", "AIX", "BSDI", "HP-UX", "IRIX", "Linux", "FreeBSD", "OSF/1", "Solaris", "SunOS", "Neutrino", "OS/2", "BeOS", "other") not null;
5/27/99 Added support for dependency information. You must run the new
"makedependenciestable.sh" script. You can turn off dependencies with the new
"usedependencies" param, but it defaults to being on. Also, read very
carefully the description for the new "webdotbase" param; you will almost
certainly need to tweak it.
5/24/99 Added "Mac System 8.6" and "Neutrino" to the list of OS's.
Feed this to mysql:
alter table bugs change column op_sys op_sys enum("All", "Windows 3.1", "Windows 95", "Windows 98", "Windows NT", "Mac System 7", "Mac System 7.5", "Mac System 7.6.1", "Mac System 8.0", "Mac System 8.5", "Mac System 8.6", "AIX", "BSDI", "HP-UX", "IRIX", "Linux", "FreeBSD", "OSF/1", "Solaris", "SunOS", "Neutrino", "OS/2", "other") not null;
5/12/99 Added a pref to control how much email you get. This needs a new
column in the profiles table, so feed the following to mysql:
alter table profiles add column emailnotification enum("ExcludeSelfChanges", "CConly", "All") not null default "ExcludeSelfChanges";
5/5/99 Added the ability to search by creation date. To make this perform
well, you ought to do the following:
alter table bugs change column creation_ts creation_ts datetime not null, add index (creation_ts);
4/30/99 Added a new severity, "blocker". To get this into your running
Bugzilla, do the following:
alter table bugs change column bug_severity bug_severity enum("blocker", "critical", "major", "normal", "minor", "trivial", "enhancement") not null;
4/22/99 There was a bug where the long descriptions of bugs had a variety of
newline characters at the end, depending on the operating system of the browser
that submitted the text. This bug has been fixed, so that no further changes
like that will happen. But to fix problems that have already crept into your
database, you can run the following perl script (which is slow and ugly, but
does work:)
#!/usr/bonsaitools/bin/perl -w
use diagnostics;
use strict;
require "globals.pl";
$|=1;
ConnectToDatabase();
SendSQL("select bug_id from bugs order by bug_id");
my @list;
while (MoreSQLData()) {
push(@list, FetchOneColumn());
}
foreach my $id (@list) {
if ($id % 50 == 0) {
print "\n$id ";
}
SendSQL("select long_desc from bugs where bug_id = $id");
my $comment = FetchOneColumn();
my $orig = $comment;
$comment =~ s/\r\n/\n/g; # Get rid of windows-style line endings.
$comment =~ s/\r/\n/g; # Get rid of mac-style line endings.
if ($comment ne $orig) {
SendSQL("update bugs set long_desc = " . SqlQuote($comment) .
" where bug_id = $id");
print ".";
} else {
print "-";
}
}
4/8/99 Added ability to store patches with bugs. This requires a new table
to store the data, so you will need to run the "makeattachmenttable.sh" script.
3/25/99 Unfortunately, the HTML::FromText CPAN module had too many bugs, and
so I had to roll my own. We no longer use the HTML::FromText CPAN module.
3/24/99 (This entry has been removed. It used to say that we required the
HTML::FromText CPAN module, but that's no longer true.)
3/22/99 Added the ability to query by fields which have changed within a date
range. To make this perform a bit better, we need a new index:
alter table bugs_activity add index (field);
3/10/99 Added 'groups' stuff, where we have different group bits that we can
put on a person or on a bug. Some of the group bits control access to bugzilla
features. And a person can't access a bug unless he has every group bit set
that is also set on the bug. See the comments in makegroupstable.sh for a bit
more info.
The 'maintainer' param is now used only as an email address for people to send
complaints to. The groups table is what is now used to determine permissions.
You will need to run the new script "makegroupstable.sh". And then you need to
feed the following lines to MySQL (replace XXX with the login name of the
maintainer, the person you wish to be all-powerful).
alter table bugs add column groupset bigint not null;
alter table profiles add column groupset bigint not null;
update profiles set groupset=0x7fffffffffffffff where login_name = XXX;
3/8/99 Added params to control how priorities are set in a new bug. You can
now choose whether to let submitters of new bugs choose a priority, or whether
they should just accept the default priority (which is now no longer hardcoded
to "P2", but is instead a param.) The default value of the params will cause
the same behavior as before.
3/3/99 Added a "disallownew" field to the products table. If non-zero, then
don't let people file new bugs against this product. (This is for when a
product is retired, but you want to keep the bug reports around for posterity.)
Feed this to MySQL:
alter table products add column disallownew tinyint not null;
2/8/99 Added FreeBSD to the list of OS's. Feed this to MySQL:
alter table bugs change column op_sys op_sys enum("All", "Windows 3.1", "Windows 95", "Windows 98", "Windows NT", "Mac System 7", "Mac System 7.5", "Mac System 7.6.1", "Mac System 8.0", "Mac System 8.5", "AIX", "BSDI", "HP-UX", "IRIX", "Linux", "FreeBSD", "OSF/1", "Solaris", "SunOS", "OS/2", "other") not null;
2/4/99 Added a new column "description" to the components table, and added
links to a new page which will use this to describe the components of a
given product. Feed this to MySQL:
alter table components add column description mediumtext not null;
2/3/99 Added a new column "initialqacontact" to the components table that gives
an initial QA contact field. It may be empty if you wish the initial qa
contact to be empty. If you're not using the QA contact field, you don't need
to add this column, but you might as well be safe and add it anyway:
alter table components add column initialqacontact tinytext not null;
2/2/99 Added a new column "milestoneurl" to the products table that gives a URL
which is to describe the currently defined milestones for a product. If you
don't use target milestone, you might be able to get away without adding this
column, but you might as well be safe and add it anyway:
alter table products add column milestoneurl tinytext not null;
1/29/99 Whoops; had a mispelled op_sys. It was "Mac System 7.1.6"; it should
be "Mac System 7.6.1". It turns out I had no bugs with this value set, so I
could just do the below simple command. If you have bugs with this value, you
may need to do something more complicated.
alter table bugs change column op_sys op_sys enum("All", "Windows 3.1", "Windows 95", "Windows 98", "Windows NT", "Mac System 7", "Mac System 7.5", "Mac System 7.6.1", "Mac System 8.0", "Mac System 8.5", "AIX", "BSDI", "HP-UX", "IRIX", "Linux", "OSF/1", "Solaris", "SunOS", "OS/2", "other") not null;
1/20/99 Added new fields: Target Milestone, QA Contact, and Status Whiteboard.
These fields are all optional in the UI; there are parameters to turn them on.
However, whether or not you use them, the fields need to be in the DB. There
is some code that needs them, even if you don't.
To update your DB to have these fields, send the following to MySQL:
alter table bugs add column target_milestone varchar(20) not null,
add column qa_contact mediumint not null,
add column status_whiteboard mediumtext not null,
add index (target_milestone), add index (qa_contact);
1/18/99 You can now query by CC. To make this perform reasonably, the CC table
needs some indices. The following MySQL does the necessary stuff:
alter table cc add index (bug_id), add index (who);
1/15/99 The op_sys field can now be queried by (and more easily tweaked).
To make this perform reasonably, it needs an index. The following MySQL
command will create the necessary index:
alter table bugs add index (op_sys);
12/2/98 The op_sys and rep_platform fields have been tweaked. op_sys
is now an enum, rather than having the legal values all hard-coded in
perl. rep_platform now no longer allows a value of "X-Windows".
Here's how I ported to the new world. This ought to work for you too.
Actually, it's probably overkill. I had a lot of illegal values for op_sys
in my tables, from importing bugs from strange places. If you haven't done
anything funky, then much of the below will be a no-op.
First, send the following commands to MySQL to make sure all your values for
rep_platform and op_sys are legal in the new world..
update bugs set rep_platform="Sun" where rep_platform="X-Windows" and op_sys like "Solaris%";
update bugs set rep_platform="SGI" where rep_platform="X-Windows" and op_sys = "IRIX";
update bugs set rep_platform="SGI" where rep_platform="X-Windows" and op_sys = "HP-UX";
update bugs set rep_platform="DEC" where rep_platform="X-Windows" and op_sys = "OSF/1";
update bugs set rep_platform="PC" where rep_platform="X-Windows" and op_sys = "Linux";
update bugs set rep_platform="other" where rep_platform="X-Windows";
update bugs set rep_platform="other" where rep_platform="";
update bugs set op_sys="Mac System 7" where op_sys="System 7";
update bugs set op_sys="Mac System 7.5" where op_sys="System 7.5";
update bugs set op_sys="Mac System 8.0" where op_sys="8.0";
update bugs set op_sys="OSF/1" where op_sys="Digital Unix 4.0";
update bugs set op_sys="IRIX" where op_sys like "IRIX %";
update bugs set op_sys="HP-UX" where op_sys like "HP-UX %";
update bugs set op_sys="Windows NT" where op_sys like "NT %";
update bugs set op_sys="OSF/1" where op_sys like "OSF/1 %";
update bugs set op_sys="Solaris" where op_sys like "Solaris %";
update bugs set op_sys="SunOS" where op_sys like "SunOS%";
update bugs set op_sys="other" where op_sys = "Motif";
update bugs set op_sys="other" where op_sys = "Other";
Next, send the following commands to make sure you now have only legal
entries in your table. If either of the queries do not come up empty, then
you have to do more stuff like the above.
select bug_id,op_sys,rep_platform from bugs where rep_platform not regexp "^(All|DEC|HP|Macintosh|PC|SGI|Sun|X-Windows|Other)$";
select bug_id,op_sys,rep_platform from bugs where op_sys not regexp "^(All|Windows 3.1|Windows 95|Windows 98|Windows NT|Mac System 7|Mac System 7.5|Mac System 7.1.6|Mac System 8.0|AIX|BSDI|HP-UX|IRIX|Linux|OSF/1|Solaris|SunOS|other)$";
Finally, once that's all clear, alter the table to make enforce the new legal
entries:
alter table bugs change column op_sys op_sys enum("All", "Windows 3.1", "Windows 95", "Windows 98", "Windows NT", "Mac System 7", "Mac System 7.5", "Mac System 7.1.6", "Mac System 8.0", "AIX", "BSDI", "HP-UX", "IRIX", "Linux", "OSF/1", "Solaris", "SunOS", "other") not null, change column rep_platform rep_platform enum("All", "DEC", "HP", "Macintosh", "PC", "SGI", "Sun", "Other");
11/20/98 Added searching of CC field. To better support this, added
some indexes to the CC table. You probably want to execute the following
mysql commands:
alter table cc add index (bug_id);
alter table cc add index (who);
10/27/98 security check for legal products in place. bug charts are not
available as an option if collectstats.pl has never been run. all products
get daily stats collected now. README updated: Chart::Base is listed as
a requirement, instructions for using collectstats.pl included as
an optional step. also got silly and added optional quips to bug
reports.
10/17/98 modified README installation instructions slightly.
10/7/98 Added a new table called "products". Right now, this is used
only to have a description for each product, and that description is
only used when initially adding a new bug. Anyway, you *must* create
the new table (which you can do by running the new makeproducttable.sh
script). If you just leave it empty, things will work much as they
did before, or you can add descriptions for some or all of your
products.
9/15/98 Everything has been ported to Perl. NO MORE TCL. This
transition should be relatively painless, except for the "params"
file. This is the file that contains parameters you've set up on the
editparams.cgi page. Before changing to Perl, this was a tcl-syntax
file, stored in the same directory as the code; after the change to
Perl, it becomes a perl-syntax file, stored in a subdirectory named
"data". See the README file for more details on what version of Perl
you need.
So, if updating from an older version of Bugzilla, you will need to
edit data/param, change the email address listed for
$::param{'maintainer'}, and then go revisit the editparams.cgi page
and reset all the parameters to your taste. Fortunately, your old
params file will still be around, and so you ought to be able to
cut&paste important bits from there.
Also, note that the "whineatnews" script has changed name (it now has
an extension of .pl instead of .tcl), so you'll need to change your
cron job.
And the "comments" file has been moved to the data directory. Just do
"cat comments >> data/comments" to restore any old comments that may
have been lost.
9/2/98 Changed the way password validation works. We now keep a
crypt'd version of the password in the database, and check against
that. (This is silly, because we're also keeping the plaintext
version there, but I have plans...) Stop passing the plaintext
password around as a cookie; instead, we have a cookie that references
a record in a new database table, logincookies.
IMPORTANT: if updating from an older version of Bugzilla, you must run
the following commands to keep things working:
./makelogincookiestable.sh
echo "alter table profiles add column cryptpassword varchar(64);" | mysql bugs
echo "update profiles set cryptpassword = encrypt(password,substring(rand(),3, 4));" | mysql bugs

View File

@@ -1,477 +0,0 @@
This is Bugzilla. See <http://www.mozilla.org/bugs/>.
==========
DISCLAIMER
==========
This is not very well packaged code. It's not packaged at all. Don't
come here expecting something you plop in a directory, twiddle a few
things, and you're off and using it. Work has to be done to get there.
We'd like to get there, but it wasn't clear when that would be, and so we
decided to let people see it first.
============
INSTALLATION
============
0. Introduction
Installation of bugzilla is pretty straight forward, especially if your
machine already has MySQL and the MySQL-related perl packages installed.
If those aren't installed yet, then that's the first order of business. The
other necessary ingredient is a web server set up to run cgi scripts.
1. Installing the Prerequisites
The software packages necessary for the proper running of bugzilla are:
1. MySQL database server and the mysql client
2. Perl (5.004 or greater)
3. DBI Perl module
4. Data::Dumper Perl module
5. MySQL related Perl module collection
6. TimeDate Perl module collection
7. GD perl module (1.18 or 1.19)
8. Chart::Base Perl module (0.99 through 0.99b)
9. The web server of your choice
Bugzilla has quite a few prerequisites, but none of them are TCL.
Previous versions required TCL, but it no longer needed (or used).
1.1. Getting and setting up MySQL database
Visit MySQL homepage at http://www.mysql.org and grab the latest stable
release of the server. Both binaries and source are available and which
you get shouldn't matter. Be aware that many of the binary versions
of MySQL store their data files in /var which on many installations
(particularly common with linux installations) is part of a smaller
root partition. If you decide to build from sources you can easily set
the dataDir as an option to configure.
If you've installed from source or non-package (RPM, deb, etc.) binaries
you'll want to make sure to add mysqld to your init scripts so the server
daemon will come back up whenever your machine reboots.
You also may want to edit those init scripts, to make sure that
mysqld will accept large packets. By default, mysqld is set up to only
accept packets up to 64K long. This limits the size of attachments you
may put on bugs. If you add something like "-O max_allowed_packet=1M"
to the command that starts mysqld (or safe_mysqld), then you will be
able to have attachments up to about 1 megabyte.
1.2. Perl (5.004 or greater)
Any machine that doesn't have perl on it is a sad machine indeed. Perl
for *nix systems can be gotten in source form from http://www.perl.com.
Perl is now a far cry from the the single compiler/interpreter binary it
once was. It now includes a great many required modules and quite a
few other support files. If you're not up to or not inclined to build
perl from source, you'll want to install it on your machine using some
sort of packaging system (be it RPM, deb, or what have you) to ensure
a sane install. In the subsequent sections you'll be installing quite
a few perl modules; this can be quite ornery if your perl installation
isn't up to snuff.
1.3. DBI Perl module
The DBI module is a generic Perl module used by other database related
Perl modules. For our purposes it's required by the MySQL-related
modules. As long as your Perl installation was done correctly the
DBI module should be a breeze. It's a mixed Perl/C module, but Perl's
MakeMaker system simplifies the C compilation greatly.
Like almost all Perl modules DBI can be found on the Comprehensive Perl
Archive Network (CPAN) at http://www.cpan.org . The CPAN servers have a
real tendency to bog down, so please use mirrors. The current location
at the time of this writing (02/17/99) can be found in Appendix A.
Quality, general Perl module installation instructions can be found on
the CPAN website, but basically you'll just need to:
1. Untar the module tarball -- it should create its own directory
2. Enter the following commands:
perl Makefile.PL
make
make test
make install
If everything went ok that should be all it takes. For the vast
majority of perl modules this is all that's required.
1.4 Data::Dumper Perl module
The Data::Dumper module provides data structure persistence for Perl
(similar to Java's serialization). It comes with later sub-releases of
Perl 5.004, but a re-installation just to be sure it's available won't
hurt anything.
Data::Dumper is used by the MySQL related Perl modules. It can be
found on CPAN (link in Appendix A) and can be installed by following
the same four step make sequence used for the DBI module.
1.5. MySQL related Perl module collection
The Perl/MySQL interface requires a few mutually-dependent perl
modules. These modules are grouped together into the the
Msql-Mysql-modules package. This package can be found at CPAN (link
in Appendix A). After the archive file has been downloaded it should
be untarred.
The MySQL modules are all build using one make file which is generated
by running:
perl Makefile.PL
The MakeMaker process will ask you a few questions about the desired
compilation target and your MySQL installation. For many of the questions
the provided default will be adequate.
When asked if your desired target is the MySQL or mSQL packages
selected the MySQL related ones. Later you will be asked if you wish
to provide backwards compatibility with the older MySQL packages; you
must answer YES to this question. The default will be no, and if you
select it things won't work later.
A host of 'localhost' should be fine and a testing user of 'test' and
a null password should find itself with sufficient access to run tests
on the 'test' database which MySQL created upon installation. If 'make
test' and 'make install' go through without errors you should be ready
to go as far as database connectivity is concerned.
1.6. TimeDate Perl module collection
Many of the more common date/time/calendar related Perl modules have
been grouped into a bundle similar to the MySQL modules bundle. This
bundle is stored on the CPAN under the name TimeDate. A (hopefully
current) link can be found in Appendix A. The component module we're
most interested in is the Date::Format module, but installing all of them
is probably a good idea anyway. The standard Perl module installation
instructions should work perfectly for this simple package.
1.7. GD Perl module (1.18 or 1.19)
The GD library was written by Thomas Boutell a long while ago to
programatically generate images in C. Since then it's become almost a
defacto standard for programatic image construction. The Perl bindings
to it found in the GD library are used on a million web pages to generate
graphs on the fly. That's what bugzilla will be using it for so you'd
better install it if you want any of the graphing to work.
Actually bugzilla uses the Graph module which relies on GD itself,
but isn't that always the way with OOP. At any rate, you can find the
GD library on CPAN (link in Appendix A). Note, however, that you MUST
use version 1.18 or 1.19, because newer versions have dropped support
for GIFs in favor of PNGs, and bugzilla has not yet been updated to
deal with this.
1.8. Chart::Base Perl module (0.99 through 0.99b)
The Chart module provides bugzilla with on-the-fly charting
abilities. It can be installed in the usual fashion after it has been
fetched from CPAN where it is found as the Chart-x.x... tarball in a
directory to be listed in Appendix A. Note that as with the GD perl
module, only the specific versions listed above will work.
1.9. HTTP server
You have a freedom of choice here - Apache, Netscape or any other
server on UNIX would do. You can easily run the web server on a different
machine than MySQL, but that makes MySQL permissions harder to manage.
You'll want to make sure that your web server will run any file
with the .cgi extension as a cgi and not just display it. If you're using
apache that means uncommenting the following line in the srm.conf file:
AddHandler cgi-script .cgi
With apache you'll also want to make sure that within the access.conf
file the line:
Options ExecCGI
is in the stanza that covers the directories you intend to put the
bugzilla .html and .cgi files into.
2. Installing the Bugzilla Files
You should untar the bugzilla files into a directory that you're
willing to make writable by the default web server user (probably
'nobody'). You may decide to put the files off of the main web space
for your web server or perhaps off of /usr/local with a symbolic link
in the web space that points to the bugzilla directory. At any rate,
just dump all the files in the same place (optionally omitting the CVS
directory if it accidentally got tarred up with the rest of bugzilla)
and make sure you can get at the files in that directory through your
web server.
Once all the files are in a web accessible directory, make that
directory writable by your webserver's user (which may require just
making it world writable).
Lastly, you'll need to set up a symbolic link from /usr/bonsaitools/bin
to the correct location of your perl executable (probably /usr/bin/perl).
Or, you'll have to hack all the .cgi files to change where they look
for perl.
3. Setting Up the MySQL database
After you've gotten all the software installed and working you're ready
to start preparing the database for its life as a the back end to a high
quality bug tracker.
First, you'll want to fix MySQL permissions. Bugzilla always logs
in as user "bugs", with no password. That needs to work. MySQL
permissions are a deep, nasty complicated thing. I've just turned
them off. If you want to do that, too, then the magic is to do run
"mysql mysql", and feed it commands like this (replace all instances of
HOSTNAME with the name of the machine mysql is running on):
DELETE FROM host;
DELETE FROM user;
INSERT INTO host VALUES
('localhost','%','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
INSERT INTO host VALUES
(HOSTNAME,'%','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
INSERT INTO user VALUES
('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y',
'Y','Y','Y','Y','Y');
INSERT INTO user VALUES
(HOSTNAME,'','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y',
'Y','Y','Y');
INSERT INTO user VALUES
(HOSTNAME,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y',
'Y','Y','Y','Y');
INSERT INTO user VALUES
('localhost','','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y',
'Y','Y','Y','Y');
The number of 'Y' entries to use varies with the version of MySQL; they
keep adding columns. The list here should work with version 3.22.23b.
This run of "mysql mysql" may need some extra parameters to deal with
whatever database permissions were set up previously. In particular,
you might have to say "mysql -uroot mysql", and give it an appropriate
password.
For much more information about MySQL permissions, see the MySQL
documentation.
After you've tweaked the permissions, run "mysqladmin reload" to make
sure that the database server knows to look at your new permission list.
Next, you can just run the magic checksetup.pl script. (Many thanks
to Holger Schurig <holgerschurig@nikocity.de> for writing this script!)
It will make sure things have reasonable permissions, set up the "data"
directory, and create all the MySQL tables. Just run:
./checksetup.pl
The first time you run it, it will create a file called "localconfig"
which you should examine and perhaps tweak a bit. Then re-run
checksetup.pl and it will do the real work.
At ths point, you should have a nearly empty copy of the bug tracking
setup.
4. Tweaking the Bugzilla->MySQL Connection Data
If you have played with MySQL permissions, rather than just opening it
wide open as described above, then you may need to tweak the Bugzilla
code to connect appropriately.
In order for bugzilla to be able to connect to the MySQL database
you'll have to tell bugzilla where the database server is, what
database you're connecting to, and whom to connect as. Simply open up
the globals.pl file in the bugzilla directory and find the line that
begins like:
$::db = Mysql->Connect("
That line does the actual database connection. The Connect method
takes four parameters which are (with appropriate values):
1. server's host: just use "localhost"
2. database name: "bugs" if you're following these directions
3. MySQL username: whatever you created for your webserver user
probably "nobody"
4. Password for the MySQL account in item 3.
Just fill in those values and close up globals.pl
5. Setting up yourself as Maintainer
Start by creating your own bugzilla account. To do so, just try to
"add a bug" from the main bugzilla menu (now available from your system
through your web browser!). You'll be prompted for logon info, and you
should enter your email address and then select 'mail me my password'.
When you get the password mail, log in with it. Don't finish entering
that new bug.
Now, add yourself to every group. The magic checksetup.pl script
can do this for you, if you run it again now. That script will notice
if there's exactly one user in the database, and if so, add that person
to every group.
If you want to add someone to every group by hand, you can do it by
typing the appropriate MySQL commands. Run mysql, and type:
update profiles set groupset=0x7fffffffffffffff
where login_name = 'XXX';
replacing XXX with your Bugzilla email address.
Now, if you go to the query page (off of the bugzilla main menu) where
you'll now find a 'edit parameters' option which is filled with editable
treats.
6. Setting Up the Whining Cron Job (Optional)
By now you've got a fully functional bugzilla, but what good are bugs
if they're not annoying? To help make those bugs more annoying you can
set up bugzilla's automatic whining system. This can be done by adding
the following command as a daily crontab entry (for help on that see that
crontab man page):
cd <your-bugzilla-directory> ; ./whineatnews.pl
7. Bug Graphs (Optional)
As long as you installed the GD and Graph::Base Perl modules you might
as well turn on the nifty bugzilla bug reporting graphs. Just add
the command:
cd <your-bugzilla-directory> ; ./collectstats.pl
as a nightly entry to your crontab and after two days have passed you'll
be able to view bug graphs from the Bug Reports page.
8. Real security for MySQL
MySQL has "interesting" default security parameters:
mysqld defaults to running as root
it defaults to allowing external network connections
it has a known port number, and is easy to detect
it defaults to no passwords whatsoever
it defaults to allowing "File_Priv"
This means anyone from anywhere on the internet can not only drop the
database with one SQL command, and they can write as root to the system.
To see your permissions do:
> mysql -u root -p
use mysql;
show tables;
select * from user;
select * from db;
To fix the gaping holes:
DELETE FROM user WHERE User='';
UPDATE user SET Password=PASSWORD('new_password') WHERE user='root';
FLUSH PRIVILEGES;
If you're not running "mit-pthreads" you can use:
GRANT USAGE ON *.* TO bugs@localhost;
GRANT ALL ON bugs.* TO bugs@localhost;
REVOKE DROP ON bugs.* FROM bugs@localhost;
FLUSH PRIVILEGES;
With "mit-pthreads" you'll need to modify the "globals.pl" Mysql->Connect
line to specify a specific host name instead of "localhost", and accept
external connections:
GRANT USAGE ON *.* TO bugs@bounce.hop.com;
GRANT ALL ON bugs.* TO bugs@bounce.hop.com;
REVOKE DROP ON bugs.* FROM bugs@bounce.hop.com;
FLUSH PRIVILEGES;
Consider also:
o Turning off external networking with "--skip-networking",
unless you have "mit-pthreads", in which case you can't.
Without networking, MySQL connects with a Unix domain socket.
o using the --user= option to mysqld to run it as an unprivileged
user.
o starting MySQL in a chroot jail
o running the httpd in a jail
o making sure the MySQL passwords are different from the OS
passwords (MySQL "root" has nothing to do with system "root").
o running MySQL on a separate untrusted machine
o making backups ;-)
---------[ Appendices ]-----------------------
Appendix A. Required Software Download Links
All of these sites are current as of February 17, 1999. Hopefully
they'll stay current for a while.
MySQL: http://www.mysql.org
Perl: http://www.perl.org
CPAN: http://www.cpan.org
DBI Perl module: ftp://ftp.cpan.org/pub/perl/CPAN/modules/by-module/DBI/
Data::Dumper module:
ftp://ftp.cpan.org/pub/perl/CPAN/modules/by-module/Data/
MySQL related Perl modules:
ftp://ftp.cpan.org/pub/perl/CPAN/modules/by-module/Mysql/
TimeDate Perl module collection:
ftp://ftp.cpan.org/pub/perl/CPAN/modules/by-module/Date/
GD Perl module: ftp://ftp.cpan.org/pub/perl/CPAN/modules/by-module/GD/
Chart::Base module:
ftp://ftp.cpan.org/pub/perl/CPAN/modules/by-module/Chart/
Appendix B. Modifying Your Running System
Bugzilla optimizes database lookups by storing all relatively static
information in the versioncache file, located in the data/ subdirectory
under your installation directory (we said before it needs to be writable,
right?!)
If you make a change to the structural data in your database (the
versions table for example), or to the "constants" encoded in
defparams.pl, you will need to remove the cached content from the data
directory (by doing a "rm data/versioncache"), or your changes won't show
up!
That file gets automatically regenerated whenever it's more than an
hour old, so Bugzilla will eventually notice your changes by itself, but
generally you want it to notice right away, so that you can test things.
Appendix C. Upgrading from previous versions of Bugzilla
The developers of Bugzilla are constantly adding new tables, columns and
fields. You'll get SQL errors if you just update the code. The strategy
to update is to simply always run the checksetup.pl script whenever
you upgrade your installation of Bugzilla. If you want to see what has
changed, you can read the comments in that file, starting from the end.
Appendix D. History
This document was originally adapted from the Bonsai installation
instructions by Terry Weissman <terry@mozilla.org>.
The February 25, 1999 re-write of this page was done by Ry4an Brase
<ry4an@ry4an.org>, with some edits by Terry Weissman, Bryce Nesbitt,
Martin Pool, & Dan Mosedale (But don't send bug reports to them!
Report them using bugzilla, at http://bugzilla.mozilla.org/enter_bug.cgi ,
project Webtools, component Bugzilla).
Comments from people using this document for the first time are
especially welcomed.

View File

@@ -1,98 +0,0 @@
#!/usr/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public License
# Version 1.0 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are Copyright (C) 1998
# Netscape Communications Corporation. All Rights Reserved.
#
# Contributor(s): Sam Ziegler <sam@ziegler.org>
# Terry Weissman <terry@mozilla.org>
# Mark Hamby <mhamby@logicon.com>
# Code derived from editcomponents.cgi, reports.cgi
use diagnostics;
use strict;
require "CGI.pl";
# Shut up misguided -w warnings about "used only once":
use vars @::legal_product;
confirm_login();
print "Content-type: text/html\n\n";
if (!UserInGroup("editcomponents")) {
print "<H1>Sorry, you aren't a member of the 'editcomponents' group.</H1>\n";
print "And so, you aren't allowed to add a new component.\n";
exit;
}
PutHeader("Add Component");
print "This page lets you add a component to bugzilla.\n";
unlink "data/versioncache";
GetVersionTable();
my $prodcode = "P0";
my $product_popup = make_options (\@::legal_product, $::legal_product[0]);
print "
<form method=post action=doaddcomponent.cgi>
<TABLE>
<TR>
<th align=right>Component:</th>
<TD><input size=60 name=\"component\" value=\"\"></TD>
</TR>
<TR>
<TH align=right>Program:</TH>
<TD><SELECT NAME=\"product\">
$product_popup
</SELECT></TD>
</TR>
<TR>
<TH align=right>Description:</TH>
<TD><input size=60 name=\"description\" value=\"\"></TD>
</TR>
<TR>
<TH align=right>Initial owner:</TH>
<TD><input size=60 name=\"initialowner\" value=\"\"></TD>
</TR>
";
if (Param('useqacontact')) {
print "
<TR>
<TH align=right>Initial QA contact:</TH>
<TD><input size=60 name=\"initialqacontact\" value=\"\"></TD>
</TR>
";
}
print "
</table>
<hr>
";
print "<CENTER><input type=submit value=\"Submit changes\"></CENTER>\n";
print "</form>\n";
PutFooter();

View File

@@ -1,245 +0,0 @@
#!/usr/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public License
# Version 1.0 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are Copyright (C) 1998
# Netscape Communications Corporation. All Rights Reserved.
#
# $Id: announce.cgi,v 1.1.2.4 2000-05-31 22:22:12 dkl%redhat.com Exp $
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
# Andrew Anderson <andrew@redhat.com>
# Dave Lawrence <dkl@redhat.com>
# include necessary packages
use strict;
use CGI;
require 'CGI.pl';
require 'globals.pl';
# set up necessary variables
$::cgi = new CGI;
my $submit = $::cgi->param('submit');
my $product = $::cgi->param('product');
my $version = $::cgi->param('version');
my $platform = $::cgi->param('arch');
my $severity = $::cgi->param('severity');
my $priority = $::cgi->param('priority');
my $class = $::cgi->param('class');
my $component = $::cgi->param('component');
my $synopsis = $::cgi->param('synopsis');
my $advisory = $::cgi->param('advisory');
my $keywords = $::cgi->param('keywords');
my $cross = $::cgi->param('cross');
my $topic = $::cgi->param('topic');
my $fixed = $::cgi->param('fixed');
# my $summary = "";
# my $desc = "";
print "Content-type: text/html\n\n";
if (!$submit) {
# construct a form for the rest of the information
PutHeader("Errata Announcement");
print $::cgi->startform(-ACTION=>'announce.cgi'),
$::cgi->table({-BGCOLOR=>'#ECECEC', -ALIGN=>'left', -WIDTH=>'75%', -CELLSPACING=>'0', -CELLPADDING=>'4'},
$::cgi->TR(
$::cgi->td({-BGCOLOR=>'#BFBFBF', -ALIGN=>'right'},
$::cgi->b('Package ')
),
$::cgi->td({-ALIGN=>'left'},
$::cgi->textfield(-NAME=>"component",
-VALUE=>"$component",
-SIZE=>60)
)
),
$::cgi->TR(
$::cgi->td({-BGCOLOR=>'#BFBFBF', -ALIGN=>'right'},
$::cgi->b('Product ')
),
$::cgi->td({-ALIGN=>'left'},
$::cgi->textfield(-NAME=>"product",
-VALUE=>"$product",
-SIZE=>60)
)
),
$::cgi->TR(
$::cgi->td({-BGCOLOR=>'#BFBFBF', -ALIGN=>'right'},
$::cgi->b('Version ')
),
$::cgi->td({-ALIGN=>'left'},
$::cgi->textfield(-NAME=>"version",
-VALUE=>"$version",
-SIZE=>60)
)
),
$::cgi->TR(
$::cgi->td({-BGCOLOR=>'#BFBFBF', -ALIGN=>'right'},
$::cgi->b('Advisory ID ')
),
$::cgi->td({-ALIGN=>'left'},
$::cgi->textfield(-NAME=>"advisory",
-VALUE=>"$advisory",
-SIZE=>60)
)
),
$::cgi->TR(
$::cgi->td({-BGCOLOR=>'#BFBFBF', -ALIGN=>'right'},
$::cgi->b('Synopsis ')
),
$::cgi->td({-ALIGN=>'left'},
$::cgi->textfield(-NAME=>"synopsis",
-VALUE=>"$synopsis",
-SIZE=>60)
)
),
$::cgi->TR(
$::cgi->td({-BGCOLOR=>'#BFBFBF', -ALIGN=>'right'},
$::cgi->b('Key Words ')
),
$::cgi->td({-ALIGN=>'left'},
$::cgi->textfield(-NAME=>"keywords",
-VALUE=>"$keywords",
-SIZE=>60)
)
),
$::cgi->TR(
$::cgi->td({-BGCOLOR=>'#BFBFBF', -ALIGN=>'right'},
$::cgi->b('Cross Reference ')
),
$::cgi->td({-ALIGN=>'left'},
$::cgi->textfield(-NAME=>"cross",
-VALUE=>"$cross",
-SIZE=>60)
)
),
$::cgi->TR(
$::cgi->td({-BGCOLOR=>'#BFBFBF', -ALIGN=>'right'},
$::cgi->b('Topic ')
),
$::cgi->td({-ALIGN=>'left'},
$::cgi->textarea(-NAME=>"topic",
-WRAP=>"hard",
-ROWS=>"2",
-COLUMNS=>"60",
-DEFAULT=>"$topic")
)
),
$::cgi->TR(
$::cgi->td({-BGCOLOR=>'#BFBFBF', -ALIGN=>'right'},
$::cgi->b('Bug IDs Fixed ')
),
$::cgi->td({-ALIGN=>'left'},
$::cgi->textarea(-NAME=>"fixed",
-WRAP=>"hard",
-ROWS=>"2",
-COLUMNS=>"60",
-DEFAULT=>"$fixed")
)
)
),
$::cgi->center($::cgi->submit(-name=>"submit", -value=>"View Final")),
$::cgi->endform;
PutFooter();
exit;
}
# After submit, print out form on clean page
print <<End_of_html;
<PRE>
---------------------------------------------------------------------
Red Hat, Inc. Errata Advisory
Synopsis: $synopsis
Advisory ID: $advisory
Issue date:
Updated on:
Keywords: $keywords
Cross references: $cross
---------------------------------------------------------------------
1. Topic:
$topic
2. Bug IDs fixed:
$fixed
3. Relevant releases/architectures:
$platform
4. Obsoleted by:
5. Conflicts with:
6. RPMs required:
Intel:
Alpha:
Sparc:
Source packages:
7. Problem description:
8. Solution:
For each RPM for your particular architecture, run:
rpm -Uvh <filename>
where filename is the name of the RPM.
9. Verification:
MD5 sum Package Name
--------------------------------------------------------------------------
These packages are also PGP signed by Red Hat Inc. for security. Our
key is available at:
http://www.redhat.com/corp/contact.html
You can verify each package with the following command:
rpm --checksig <filename>
If you only wish to verify that each package has not been corrupted or
tampered with, examine only the md5sum with the following command:
rpm --checksig --nopgp <filename>
10. References:
</PRE>
End_of_html
exit;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

View File

@@ -1,163 +0,0 @@
#!/usr/bonsaitools/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public License
# Version 1.0 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are Copyright (C) 1998
# Netscape Communications Corporation. All Rights Reserved.
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
# Provides a silly 'back-door' mechanism to let me automatically insert
# bugs from the netscape bugsystem. Other installations of Bugzilla probably
# don't need to worry about this file any.
use diagnostics;
use strict;
require "CGI.pl";
# Shut up misguided -w warnings about "used only once":
use vars %::versions;
ConnectToDatabase();
print "Content-type: text/plain\n\n";
# while (my ($key,$value) = each %ENV) {
# print "$key=$value\n";
# }
my $host = $ENV{'REMOTE_ADDR'};
SendSQL("select passwd from backdoor where host = '$host'");
my $passwd = FetchOneColumn();
if (!defined $passwd || !defined $::FORM{'passwd'} ||
$passwd ne crypt($::FORM{'passwd'}, substr($passwd, 0, 2))) {
print "Who are you?\n";
print "Env:\n";
while (my ($key,$value) = each %ENV) {
print "$key=$value\n";
}
print "\nForm:\n";
while (my ($key,$value) = each %::FORM) {
print "$key=$value\n";
}
exit;
}
my $prod = $::FORM{'product'};
my $comp = $::FORM{'component'};
my $version = $::FORM{'version'};
GetVersionTable();
sub Punt {
my ($label, $value) = (@_);
my $maintainer = Param("maintainer");
print "I don't know how to move into Bugzilla a bug with a $label of $value.
If you really do need to do this, speak to $maintainer and maybe he
can teach me.";
exit;
}
# Do remapping of things from BugSplat world to Bugzilla.
if ($prod eq "Communicator") {
$prod = "Browser";
$version = "other";
}
# Validate fields, and whine about things that we apparently couldn't remap
# into something legal.
if (!defined $::components{$prod}) {
Punt("product", $prod);
}
if (lsearch($::components{$prod}, $comp) < 0) {
Punt("component", $comp);
}
if (lsearch($::versions{$prod}, $version) < 0) {
$version = "other";
if (lsearch($::versions{$prod}, $version) < 0) {
Punt("version", $version);
}
}
$::FORM{'product'} = $prod;
$::FORM{'component'} = $comp;
$::FORM{'version'} = $version;
$::FORM{'long_desc'} =
"(This bug imported from BugSplat, Netscape's internal bugsystem. It
was known there as bug #$::FORM{'bug_id'}
http://scopus.netscape.com/bugsplat/show_bug.cgi?id=$::FORM{'bug_id'}
Imported into Bugzilla on " . time2str("%D %H:%M", time()) . ")
" . $::FORM{'long_desc'};
$::FORM{'reporter'} =
DBNameToIdAndCheck("$::FORM{'reporter'}\@netscape.com", 1);
$::FORM{'assigned_to'} =
DBNameToIdAndCheck("$::FORM{'assigned_to'}\@netscape.com", 1);
if ($::FORM{'qa_contact'} ne "") {
$::FORM{'qa_contact'} =
DBNameToIdAndCheck("$::FORM{'qa_contact'}\@netscape.com", 1);
} else {
$::FORM{'qa_contact'} = 0;
}
my @list = ('reporter', 'assigned_to', 'product', 'version', 'rep_platform',
'op_sys', 'bug_status', 'bug_severity', 'priority', 'component',
'short_desc', 'long_desc', 'creation_ts', 'delta_ts',
'bug_file_loc', 'qa_contact', 'groupset');
my @vallist;
foreach my $i (@list) {
push @vallist, SqlQuote($::FORM{$i});
}
my $query = "insert into bugs (" .
join(',', @list) .
") values (" .
join(',', @vallist) .
")";
SendSQL($query);
SendSQL("select LAST_INSERT_ID()");
my $zillaid = FetchOneColumn();
foreach my $cc (split(/,/, $::FORM{'cc'})) {
if ($cc ne "") {
my $cid = DBNameToIdAndCheck("$cc\@netscape.com", 1);
SendSQL("insert into cc (bug_id, who) values ($zillaid, $cid)");
}
}
print "Created bugzilla bug $zillaid\n";
system("./processmail", $zillaid);

View File

@@ -1,79 +0,0 @@
<html> <head>
<title>The "boolean chart" section of the query page</title>
</head>
<body>
<h1>The "boolean chart" section of the query page</h1>
("Boolean chart" is a terrible term; anyone got a better one I can use
instead?)
<p>
The Bugzilla query page is designed to be reasonably easy to use.
But, with such ease of use always comes some lack of power. The
"boolean chart" section is designed to let you do very powerful
queries, but it's not the easiest thing to learn (or explain).
<p>
So.
<p>
The boolean chart starts with a single "term". A term is a
combination of two pulldown menus and a text field.
You choose items from the menus, specifying "what kind of thing
am I searching for" and "what kind of matching do I want", and type in
a value on the text field, specifying "what should it match".
<p>
The real fun starts when you click on the "Or" or "And" buttons. If
you bonk on the "Or" button, then you get a second term to the right
of the first one. You can then configure that term, and the result of
the query will be anything that matches either of the terms.
<p>
Or, you can bonk the "And" button, and get a new term below the
original one, and now the result of the query will be anything that
matches both of the terms.
<p>
And you can keep clicking "And" and "Or", and get a page with tons of
terms. "Or" has higher precedence than "And". (In other words, you
can think of each line of "Or" stuff as having parenthesis around it.)
<p>
The most subtle thing is this "Add another boolean chart" button.
This is almost the same thing as the "And" button. The difference is
if you use one of the fields where several items can be associated
with a single bug. This includes "Comments", "CC", and all the
"changed [something]" entries. Now, if you have multiple terms that
all talk about one of these fields, it's ambiguous whether they are
allowed to be talking about different instances of that field. So,
to let you have it both ways, they always mean the same instance,
unless the terms appear on different charts.
<p>
For example: if you search for "priority changed to P5" and
"priority changed by person@addr", it will only find bugs where the
given person at some time changed the priority to P5. However, if
what you really want is to find all bugs where the milestone was
changed at some time by the person, and someone (possibly someone
else) at some time changed the milestone to P5, then you would put
the two terms in two different charts.
<p>
Clear as mud? Please, I beg you, rewrite this document to make
everything crystal clear, and send the improved version to <a
href="mailto:terry@mozilla.org">Terry</a>.
<hr>
<!-- hhmts start -->
Last modified: Fri Jan 28 12:34:41 2000
<!-- hhmts end -->
</body> </html>

File diff suppressed because it is too large Load Diff

View File

@@ -1,685 +0,0 @@
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
# David Lawrence <dkl@redhat.com>
use diagnostics;
use strict;
# Shut up misguided -w warnings about "used only once". For some reason,
# "use vars" chokes on me when I try it here.
sub bug_form_pl_sillyness {
my $zz;
$zz = %::FORM;
$zz = %::components;
$zz = %::prodmaxvotes;
$zz = %::versions;
$zz = @::legal_keywords;
$zz = @::legal_opsys;
$zz = @::legal_platform;
$zz = @::legal_product;
$zz = @::legal_priority;
$zz = @::legal_resolution_no_dup;
$zz = @::legal_severity;
$zz = %::target_milestone;
}
my %bug_form; # hash to hold variables passed on to the template
my $userid = 0; # user id of current member
my $changeable = 0; # whether the user can edit attributes of this bug
my $loginok = quietly_check_login();
if ($loginok) {
$userid = DBname_to_id($::COOKIE{'Bugzilla_login'});
}
my $id = $::FORM{'id'}; # id number of current bug
my $query = "
select
bugs.bug_id,
product,
version,
rep_platform,
op_sys,
bug_status,
resolution,
priority,
bug_severity,
component,
assigned_to,
reporter,
bug_file_loc,
short_desc,
target_milestone,
qa_contact,
status_whiteboard,
";
if ($::driver eq 'mysql') {
$query .= "
date_format(creation_ts,'%Y-%m-%d %H:%i'),
groupset,
delta_ts,
sum(votes.count)
from bugs left join votes using(bug_id)
where bugs.bug_id = $id
and bugs.groupset & $::usergroupset = bugs.groupset
group by bugs.bug_id";
} else {
$query .= "
TO_CHAR(creation_ts, 'YYYY-MM-DD HH:MI:SS'),
groupset,
TO_CHAR(delta_ts, 'YYYYMMDDHH24MISS')
from
bugs
where
bugs.bug_id = $id";
}
SendSQL($query);
my %bug;
my @row;
if (@row = FetchSQLData()) {
my $count = 0;
foreach my $field ("bug_id", "product", "version", "rep_platform",
"op_sys", "bug_status", "resolution", "priority",
"bug_severity", "component", "assigned_to", "reporter",
"bug_file_loc", "short_desc", "target_milestone",
"qa_contact", "status_whiteboard", "creation_ts",
"groupset", "delta_ts", "votes") {
$bug{$field} = shift @row;
if (!defined $bug{$field}) {
$bug{$field} = "";
}
$count++;
}
} else {
if ($::driver eq 'mysql') {
SendSQL("select groupset from bugs where bug_id = $id");
if (@row = FetchSQLData()) {
print "<H1>Permission denied.</H1>\n";
if ($loginok) {
print "Sorry; you do not have the permissions necessary to see\n";
print "bug $id.\n";
PutFooter();
exit;
} else {
print "Sorry; bug $id can only be viewed when logged\n";
print "into an account with the appropriate permissions. To\n";
print "see this bug, you must first\n";
print "<a href=\"show_bug.cgi?id=$id&GoAheadAndLogIn=1\">";
print "log in</a>.";
PutFooter();
exit;
}
}
}
PutError("<H1>Bug not found</H1>\n" .
"There does not seem to be a bug numbered $id.\n");
}
if ($::driver ne 'mysql') {
# If this bug has been set to private, lets see if we can view it.
if (!CanISee($id, $userid)) {
my $error = "<H1>Permission denied.</H1>\n";
if ($loginok) {
$error .= "Sorry; you do not have the permissions necessary to see\n";
$error .= "bug $id.\n";
} else {
$error .= "Sorry; bug $id can only be viewed when logged\n";
$error .= "into an account with the appropriate permissions. To\n";
$error .= "see this bug, you must first\n";
$error .= "<a href=\"show_bug.cgi?id=$id&GoAheadAndLogIn=1\">";
$error .= "log in</a>.";
}
PutError($error);
}
}
my $assignedtoid = $bug{'assigned_to'};
my $reporterid = $bug{'reporter'};
my $qacontactid = $bug{'qa_contact'};
# If changeable is true then changes to bug's attributes are allowed
if ($::driver ne 'mysql') {
if (CanIChange($id, $userid, $reporterid, $assignedtoid)) {
$changeable = 1;
} else {
$changeable = 0;
}
}
$bug{'assigned_to'} = DBID_to_name($bug{'assigned_to'});
$bug{'reporter'} = DBID_to_name($bug{'reporter'});
print qq{<FORM NAME="changeform" METHOD="POST" ACTION="process_bug.cgi">\n};
# foreach my $i (sort(keys(%bug))) {
# my $q = value_quote($bug{$i});
# print qq{<INPUT TYPE="HIDDEN" NAME="orig-$i" VALUE="$q">\n};
# }
$bug_form{'long_desc'} = GetLongDescriptionAsHTML($id);
$bug_form{'longdesclength'} = length($bug_form{'long_desc'});
GetVersionTable();
#
# These should be read from the database ...
#
$bug_form{'platform_popup'} = "";
$bug_form{'priority_popup'} = "";
$bug_form{'sev_popup'} = "";
$bug_form{'component_popup'} = "";
$bug_form{'component_text'} = "";
$bug_form{'cc_element'} = "";
$bug_form{'version_popup'} = "";
$bug_form{'product_popup'} = "";
$bug_form{'opsys_popup'} = "";
if ($changeable) {
$bug_form{'platform_popup'} = "<SELECT NAME=rep_platform>\n" .
make_options(\@::legal_platform, $bug{'rep_platform'}) .
"\n</SELECT>\n";
# Added by Red Hat for contract customer support
if (Param('contract')) {
if (UserInContract($userid) && UserInGroup('setcontract')) {
$bug_form{'priority_popup'} = "<SELECT NAME=priority>\n" .
make_options(\@::legal_priority_contract, $bug{'priority'}) .
"\n</SELECT>\n";
} elsif (UserInContract($userid) && $bug{'priority'} eq 'contract') {
$bug_form{'priority_popup'} = "contract<BR>" .
"<SELECT NAME=priority>\n" .
make_options(\@::legal_priority, $bug{'priority'}) .
"\n</SELECT>\n";
} else {
$bug_form{'priority_popup'} = "<SELECT NAME=priority>\n" .
make_options(\@::legal_priority, $bug{'priority'}) .
"\n</SELECT>\n";
}
} else {
$bug_form{'priority_popup'} = "<SELECT NAME=priority>\n" .
make_options(\@::legal_priority, $bug{'priority'}) .
"\n</SELECT>\n";
}
$bug_form{'severity_popup'} = "<SELECT NAME=bug_severity>\n" .
make_options(\@::legal_severity, $bug{'bug_severity'}) .
"\n</SELECT>\n";
$bug_form{'component_popup'} = "<B><A HREF=\"describecomponents.cgi?product=$bug{'product'}\">Component:</A></B>" .
"<BR><B>$bug{'component'}</B></TD>\n<TD ROWSPAN=3 VALIGN=top>" .
make_popup('component', $::components{$bug{'product'}}, $bug{'component'}, 1, 0);
# $bug_form{'component_text'} = "<INPUT NAME=component_text SIZE=20 VALUE=\"\">";
$bug_form{'component_text'} = "(Coming Soon)";
$bug_form{'cc_element'} = "Cc:</TH><TD ALIGN=left><INPUT NAME=cc SIZE=60 VALUE=\"" . ShowCcList($id) . "\">";
$bug_form{'version_popup'} = "<SELECT NAME=version>\n" .
make_options($::versions{$bug{'product'}}, $bug{'version'}) .
"\n</SELECT>\n";
$bug_form{'product_popup'} = "<SELECT NAME=product>\n" .
make_options(\@::legal_product, $bug{'product'}) .
"\n</SELECT>\n";
$bug_form{'opsys_popup'} = "<SELECT NAME=op_sys>\n" .
make_options(\@::legal_opsys, $bug{'op_sys'}) .
"</SELECT>\n";
} else {
$bug_form{'platform_popup'} = $bug{'rep_platform'};
$bug_form{'priority_popup'} = $bug{'priority'};
$bug_form{'sev_popup'} = $bug{'bug_severity'};
$bug_form{'component_popup'} = "<B><A HREF=\"describecomponents.cgi?product=$bug{'product'}\">Component:</A></B>" .
"</TD><TD ROWSPAN=3 VALIGN=top>" . $bug{'component'};
$bug_form{'component_text'} = "";
$bug_form{'cc_element'} = "Cc:</TH><TD ALIGN=left>" . ShowCcList($id);
$bug_form{'version_popup'} = $bug{'version'};
$bug_form{'product_popup'} = $bug{'product'};
$bug_form{'opsys_popup'} = $bug{'op_sys'};
}
$bug_form{'resolution_popup'} = make_options(\@::legal_resolution_no_dup,
$bug{'resolution'});
my $URL = $bug{'bug_file_loc'};
if (defined $URL && $URL ne "none" && $URL ne "NULL" && $URL ne "") {
$URL = "<B><A HREF=\"$URL\">URL:</A></B>";
} else {
$URL = "<B>URL:</B>";
}
if (Param("usetargetmilestone")) {
my $url = "";
if (defined $::milestoneurl{$bug{'product'}}) {
$url = $::milestoneurl{$bug{'product'}};
}
if ($url eq "") {
$url = "notargetmilestone.html";
}
if ($bug{'target_milestone'} eq "") {
$bug{'target_milestone'} = " ";
}
push(@::legal_target_milestone, " ");
$bug_form{'milestone_popup'} = "
<A href=\"$url\"><B>Target Milestone:</B></A></TD>
<TD><SELECT NAME=target_milestone>\n" .
make_options(\@::legal_target_milestone,
$bug{'target_milestone'}) .
"</SELECT>\n";
}
if (Param("useqacontact")) {
my $name = $bug{'qa_contact'} > 0 ? DBID_to_name($bug{'qa_contact'}) : "";
if ($changeable) {
$bug_form{'qacontact_element'} = "QA Contact:</TH><TD ALIGN=left><INPUT NAME=qa_contact VALUE=\"" .
value_quote($name) . "\" SIZE=60>";
} else {
$bug_form{'qacontact_element'} = "QA Contact:</TH><TD ALIGN=left>" . value_quote($name);
}
}
if ($changeable) {
$bug_form{'url_element'} = "$URL</TH><TD ALIGN=left><INPUT NAME=bug_file_loc VALUE=\"$bug{'bug_file_loc'}\" SIZE=60>";
} else {
$bug_form{'url_element'} = "$URL</TH><TD ALIGN=left>$bug{'bug_file_loc'}";
}
if ($changeable) {
$bug_form{'summary_element'} = "Summary:</TH><TD COLSPAN=2 ALIGN=left><INPUT NAME=short_desc VALUE=\"" .
value_quote($bug{'short_desc'}) . "\" SIZE=60>";
} else {
$bug_form{'summary_element'} = "Summary:</TH><TD ALIGN=left>$bug{'short_desc'}";
}
if (Param("usestatuswhiteboard")) {
if ($changeable) {
$bug_form{'whiteboard_element'} = "Status Whiteboard:</TH>" .
"<TD ALIGN=left><INPUT NAME=status_whiteboard VALUE=\"" .
value_quote($bug{'status_whiteboard'}) . "\" SIZE=60>";
} else {
$bug_form{'whiteboard_element'} = "Status Whiteboard:</TH>" .
"<TD ALIGN=left>$bug{'status_whiteboard'}";
}
}
if (@::legal_keywords) {
SendSQL("SELECT keyworddefs.name
FROM keyworddefs, keywords
WHERE keywords.bug_id = $id AND keyworddefs.id = keywords.keywordid
ORDER BY keyworddefs.name");
my @list;
while (MoreSQLData()) {
push(@list, FetchOneColumn());
}
my $value = value_quote(join(', ', @list));
$bug_form{'keywords_element'} = "
<A HREF=\"describekeywords.cgi\">Keywords</A>:</TH>
<TD ALIGN=left><INPUT NAME=\"keywords\" VALUE=\"$value\" SIZE=60>\n";
}
$bug_form{'attachment_element'} = "<TABLE WIDTH=\"100%\">\n";
if ($::driver eq 'mysql') {
SendSQL("select attach_id, filename, date_format(creation_ts, '%Y-%m-%d %h:%i:%s'), " .
"description from attachments where bug_id = $id");
} else {
SendSQL("select attach_id, filename, TO_CHAR(creation_ts, 'YYYY-MM-DD HH:MI:SS'), " .
"description from attachments where bug_id = $id");
}
while (MoreSQLData()) {
my ($attachid, $filename, $date, $desc) = (FetchSQLData());
# if ($date =~ /^(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/) {
# $date = "$3/$4/$2 $5:$6";
# }
my $link = "showattachment.cgi?attach_id=$attachid";
$desc = value_quote($desc);
$bug_form{'attachment_element'} .= qq{
<TR>
<TD>$date</TD><TD><A HREF="$link">$filename</A></TD><TD>$desc</TD>
</TR>
};
}
if ($changeable) {
$bug_form{'attachment_element'} .= qq{
<TR>
<TD COLSPAN=6><A HREF="createattachment.cgi?id=$id">
Create a new attachment</A> (proposed patch, testcase, etc.)</TD>
</TR>
};
}
$bug_form{'attachment_element'} .= "</TABLE>\n";
sub EmitDependList {
my ($desc, $myfield, $targetfield) = (@_);
my $depends;
$depends = "<TD ALIGN=right>$desc:</TD><TD>";
my @list;
SendSQL("select dependencies.$targetfield, bugs.bug_status " .
"from dependencies, bugs " .
"where dependencies.$myfield = $id " .
"and bugs.bug_id = dependencies.$targetfield " .
"order by dependencies.$targetfield");
while (MoreSQLData()) {
my ($i, $stat) = (FetchSQLData());
push(@list, $i);
my $opened = ($stat eq "NEW" || $stat eq "ASSIGNED" ||
$stat eq "REOPENED");
if (!$opened) {
$depends .= "<STRIKE>";
}
$depends .= qq{<A HREF="show_bug.cgi?id=$i">$i</A>};
if (!$opened) {
$depends .= "</STRIKE>";
}
$depends .= " ";
}
if ($changeable) {
$depends .= "</TD><TD><INPUT NAME=$targetfield VALUE=\"" .
join(',', @list) . "\"></TD>\n";
} else {
$depends .= "</TD>\n";
}
return $depends;
}
if (Param("usedependencies")) {
$bug_form{'depends_element'} = "<TABLE><TR>\n<TH ALIGN=right>Dependencies:</TH>\n";
$bug_form{'depends_element'} .= EmitDependList("Bug $id depends on", "blocked", "dependson");
$bug_form{'depends_element'} .= qq{
<TD ROWSPAN=2><A HREF="showdependencytree.cgi?id=$id">Show dependency tree</A>
};
if (Param("webdotbase") ne "") {
$bug_form{'depends_element'} .= qq{
<BR><A HREF="showdependencygraph.cgi?id=$id">Show dependency graph</A>
};
}
$bug_form{'depends_element'} .= "</TD></TR><TR><TD></TD>";
$bug_form{'depends_element'} .= EmitDependList("Bug $id blocks", "dependson", "blocked");
$bug_form{'depends_element'} .= "</TR></TABLE>\n";
}
if ($::prodmaxvotes{$bug{'product'}}) {
$bug_form{'votes_element'} = qq{
<TABLE><TR>
<TH><A HREF="votehelp.html">Votes</A> for bug $id:</TH><TD>
<A HREF="showvotes.cgi?bug_id=$id">$bug{'votes'}</A>
&nbsp;&nbsp;&nbsp;<A HREF="showvotes.cgi?voteon=$id">Vote for this bug</A>
</TD></TR></TABLE>
};
}
if ($::driver eq 'mysql') {
if ($::usergroupset ne '0') {
SendSQL("select bit, description, (bit & $bug{'groupset'} != 0) from groups where bit & $::usergroupset != 0 and isbuggroup != 0 order by bit");
while (MoreSQLData()) {
my ($bit, $description, $ison) = (FetchSQLData());
my $check0 = !$ison ? " SELECTED" : "";
my $check1 = $ison ? " SELECTED" : "";
print "<SELECT NAME=bit-$bit><OPTION VALUE=0$check0>\n";
print "People not in the \"$description\" group can see this bug\n";
print "<OPTION VALUE=1$check1>\n";
print "Only people in the \"$description\" group can see this bug\n";
print "</SELECT><BR>\n";
}
}
}
if ($changeable) {
# Find the default owner so user will know who assigning to
# if they choose the 'Assign to owner of selected component'
my $query = "select initialowner from components " .
"where program = " . SqlQuote($bug{'product'}) .
" and value = " . SqlQuote($bug{'component'});
SendSQL($query);
my $initial_owner = "(" . FetchOneColumn() . ")";
$bug_form{'resolution_change'} = qq{
<TABLE CELLSPACING=0 CELLPADDING=3 BORDER=1 WIDTH=100%>
<TR BGCOLOR="#CFCFCF">
<TD ALIGN=left><B>Change State or Resolution</B>
<BR>(Allowed only by reporter and privileged members)</TD>
</TR><TR BGCOLOR="#ECECEC">
<TD ALIGN=left>
<INPUT TYPE=radio NAME=knob VALUE=none CHECKED>
Leave as <b>$bug{'bug_status'} $bug{'resolution'}</b><br>
};
# knum is which knob number we're generating, in javascript terms.
my $knum = 1;
my $status = $bug{'bug_status'};
if ($status eq "NEW" || $status eq "ASSIGNED" || $status eq "REOPENED") {
if ($status ne "ASSIGNED") {
$bug_form{'resolution_change'} .= "<INPUT TYPE=radio NAME=knob VALUE=accept>" .
"Accept bug (change status to <b>ASSIGNED</b>)<br>";
$knum++;
}
if ($bug{'resolution'} ne "") {
$bug_form{'resolution_change'} .= "<INPUT TYPE=radio NAME=knob VALUE=clearresolution>\n" .
"Clear the resolution (remove the current resolution of\n" .
"<b>$bug{'resolution'}</b>)<br>\n";
$knum++;
}
$bug_form{'resolution_change'} .= "<INPUT TYPE=radio NAME=knob VALUE=resolve>" .
"Resolve bug, changing <A HREF=\"bug_status.cgi\">resolution</A> to " .
"<SELECT NAME=resolution " .
"ONCHANGE=\"document.changeform.knob\[$knum\].checked=true\"> " .
$bug_form{'resolution_popup'} . "</SELECT><br>\n";
$knum++;
$bug_form{'resolution_change'} .= "<INPUT TYPE=radio NAME=knob VALUE=duplicate> " .
"Resolve bug, mark it as duplicate of bug # " .
"<INPUT NAME=dup_id SIZE=6 ONCHANGE=\"document.changeform.knob\[$knum\].checked=true\">\n" .
"(<A HREF=\"buglist.cgi?component=$bug{'component'}\" target=\"new_window\">$bug{'component'} bugs</A>)<BR>\n";
$knum++;
my $assign_element = "<INPUT NAME=\"assigned_to\" SIZE=25 MAXSIZE=50 ONCHANGE=\"document.changeform.knob\[$knum\].checked=true\" VALUE=\"$bug{'assigned_to'}\">";
$bug_form{'resolution_change'} .= "<INPUT TYPE=radio NAME=knob VALUE=assign> " .
"<A HREF=\"bug_status.cgi#assigned_to\">Assign</A> bug to $assign_element <BR>\n";
$knum++;
$bug_form{'resolution_change'} .= "<INPUT TYPE=radio NAME=knob VALUE=assignbycomponent> " .
"Assign bug to owner of selected component &nbsp;$initial_owner<br>\n";
$knum++;
} else {
$bug_form{'resolution_change'} .= "<INPUT TYPE=hidden NAME=assigned_to VALUE=\"$bug{'assigned_to'}\">\n";
$bug_form{'resolution_change'} .= "<INPUT TYPE=radio NAME=knob VALUE=reopen> Reopen bug<br>\n";
$knum++;
if ($status eq "RESOLVED") {
$bug_form{'resolution_change'} .= "<INPUT TYPE=radio NAME=knob VALUE=verify> " .
"Mark bug as <b>VERIFIED</b><br>\n";
$knum++;
}
if ($status ne "CLOSED") {
$bug_form{'resolution_change'} .= "<INPUT TYPE=radio NAME=knob VALUE=close> " .
"Mark bug as <b>CLOSED</b><br>\n";
$knum++;
}
}
$bug_form{'resolution_change'} .= "
</TD>
</TR>
</TABLE>
";
# Find out which groups we are a member of and form radio buttons
SendSQL("select user_group.groupid, groups.description, groups.isbuggroup " .
"from user_group, groups " .
"where user_group.groupid = groups.groupid " .
"and user_group.userid = $userid order by groups.groupid");
my %grouplist;
my @buggrouplist;
my @row;
my $flag = 0;
while (@row = FetchSQLData()) {
if ($row[2] == 0) {
next;
}
$grouplist{$row[0]} = $row[1];
$flag = 1;
}
if ($flag) {
$bug_form{'group_change'} = "
<TABLE CELLSPACING=0 CELLPADDING=3 BORDER=1>
<TR BGCOLOR=\"#CFCFCF\">
<TD ALIGN=left><B>Groups that can see this bug.</B><BR>
(If all unchecked then same as everyone)</TD>
</TR><TR BGCOLOR=\"ECECEC\">
<TD ALIGN=left>
";
SendSQL("select groupid from bug_group where bugid = $id");
while (@row = FetchSQLData()) {
push (@buggrouplist, $row[0]);
}
foreach my $group (keys %grouplist) {
my $checked = lsearch(\@buggrouplist, $group) >= 0 ? "CHECKED" : "";
$bug_form{'group_change'} .= "<INPUT TYPE=checkbox NAME=group-$group $checked VALUE=1>\n" .
"Only <B>$grouplist{$group}</B> can see this bug.<BR>\n";
}
$bug_form{'group_change'} .= "
</TD>
</TR>
</TABLE>
";
}
}
# added <INPUT TYPE=hidden NAME=reporter VALUE=$bug{'reporter'}> to get the necessary
# redhat changes in process_bug.cgi to work which disallows all users to make changes
if ($changeable) {
$bug_form{'commit_change'} = "
<TABLE CELLSPACING=0 CELLPADDING=3 BORDER=1>
<TR BGCOLOR=\"#CFCFCF\">
<TD ALIGN=left><B>Private Changes</B><BR>
(Reporter, assigned, or privileged members only)</TD>
</TR><TR BGCOLOR=\"#ECECEC\">
<TD ALIGN=center>
<TABLE>
<TR>
<TD ALIGN=center VALIGN=top>
<INPUT TYPE=\"submit\" VALUE=\"Save Changes\">
</TD><TD ALIGN=center VALIGN=top>
<INPUT TYPE=\"reset\" VALUE=\"Reset\">
<INPUT TYPE=hidden name=form_name VALUE=process_bug>
<INPUT TYPE=hidden NAME=reporter VALUE=\"$bug{'reporter'}\">
</FORM>
</TD>
";
if (UserInGroup("errata")) {
$bug_form{'commit_change'} .= "
<TD ALIGN=center VALIGN=top>
<FORM ACTION=\"http://porkchop.redhat.com/bugzilla/newerrata.cgi\">
<INPUT TYPE=hidden NAME=product VALUE=\"$bug{'product'}\">
<INPUT TYPE=hidden NAME=synopsis VALUE=\"$bug{'component'}\">
<INPUT TYPE=hidden NAME=id_fixed VALUE=\"$::FORM{'id'}\">
<INPUT TYPE=hidden NAME=\"rep_platform-$bug{'rep_platform'}\" VALUE=\"$bug{'rep_platform'}\">
<INPUT TYPE=hidden NAME=\"release-$bug{'version'}\" VALUE=\"$bug{'version'}\">
<INPUT TYPE=submit NAME=action VALUE=\"New Errata\">
</FORM>
</TD>
";
}
$bug_form{'commit_change'} .= "
</TR>
</TABLE>
";
} else {
$bug_form{'commit_change'} = "
<TABLE CELLSPACING=0 CELLPADDING=3 BORDER=1>
<TR BGCOLOR=\"CFCFCF\">
<TD ALIGN=left>
<B>Public Changes</B><BR>(Non-members will need to create account)</TD>
</TR><TR BGCOLOR=\"#ECECEC\">
<TD>
<TABLE CELLSPACING=0 CELLPADDING=0 WIDTH=\"100%\">
<TR>
<TD ALIGN=center VALIGN=center>
<INPUT TYPE=hidden NAME=id VALUE=$id>
<INPUT TYPE=hidden NAME=product VALUE=\"$bug{'product'}\">
<INPUT TYPE=hidden NAME=version VALUE=\"$bug{'version'}\">
<INPUT TYPE=hidden NAME=component VALUE=\"$bug{'component'}\">
<INPUT TYPE=hidden name=knob VALUE=add_comment>
<INPUT TYPE=submit NAME=add_comment VALUE=\"Add Comment\">
</FORM></TD>
<TD ALIGN=center VALIGN=center>
<FORM METHOD=post ACTION=process_bug.cgi>
<INPUT TYPE=hidden NAME=id VALUE=$id>
<INPUT TYPE=hidden NAME=product VALUE=\"$bug{'product'}\">
<INPUT TYPE=hidden NAME=version VALUE=\"$bug{'version'}\">
<INPUT TYPE=hidden NAME=component VALUE=\"$bug{'component'}\">
<INPUT TYPE=hidden name=knob VALUE=add_cc>
<INPUT TYPE=submit NAME=add_cc VALUE=\"Add Me to CC List\">
</FORM></TD>
<TD ALIGN=center VALIGN=center>
<FORM METHOD=post ACTION=process_bug.cgi>
<INPUT TYPE=hidden NAME=id VALUE=$id>
<INPUT TYPE=hidden NAME=product VALUE=\"$bug{'product'}\">
<INPUT TYPE=hidden NAME=version VALUE=\"$bug{'version'}\">
<INPUT TYPE=hidden NAME=component VALUE=\"$bug{'component'}\">
<INPUT TYPE=hidden name=knob VALUE=rem_cc>
<INPUT TYPE=submit NAME=add_cc VALUE=\"Remove Me from CC List\">
</FORM>
</TD>
</TR>
</TABLE>
</TR>
</TABLE>
";
}
# We need to throw all remaining %bug variables into %bug_form for display if needed
foreach my $key (keys %bug) {
$bug_form{$key} = $bug{$key};
}
foreach my $key (keys %::FORM) {
$bug_form{$key} = $::FORM{$key};
}
# we can now fill in the bug form template
print LoadTemplate('bugform_redhat.tmpl', \%bug_form);
# To add back option of editing the long description, insert after the above
# long_list.cgi line:
# <A HREF=\"edit_desc.cgi?id=$id\">Edit Long Description</A>
1;

View File

@@ -1,196 +0,0 @@
#!/usr/bin/perl -w
use diagnostics;
use strict;
require 'CGI.pl';
print "Content-type:text/html\n\n";
PutHeader("Form Help");
print "
<TABLE WIDTH=800 ALIGN=center><TR><TD ALIGN=left>
<H1>A Bug's Life Cycle</H1>
The <B>status</B> and <B>resolution</B> field define and track the
life cycle of a bug.
<P>
<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0 WIDTH=100%>
<TR ALIGN=center VALIGN=top>
<TD WIDTH=\"50%\"><H1>STATUS</H1></TD>
<TD><H1>RESOLUTION</H1></TD>
</TR>
<TR VALIGN=top>
<TD>The <A NAME=\"status\"><B>status</B></A> field indicates the general
health of a bug. Only certain status transitions are allowed.</TD>
<TD>The <A NAME=\"resolution\"><B>resolution</B></A> field indicates what
happened to this bug.</TD>
</TR>
<TR VALIGN=top>
<TD>
<DL>
<DT><A NAME=\"new\"><B>NEW</B></A>
<DD> This bug has recently been added to the list of bugs and must
be processed. Bugs in this state may be <B>VERIFIED</B>,
remain <B>NEW</B>, or resolved and marked <B>RESOLVED</B>.
<DT><A NAME=\"verified\"><B>VERIFIED</B></A>
<DD> This bug has been verified as a bug. Bugs in this state may
be <B>ASSIGNED</B>, or remain <B>VERIFIED</B>.
<DT><A NAME=\"assigned\"><B>ASSIGNED</B></A>
<DD> This bug is not yet resolved, but is assigned to the proper
person. From here bugs can be given to another person, or
resolved and become <B>RESOLVED</B>.
<DT><A NAME=\"reopened\"><B>REOPENED</B></A>
<DD>This bug was once resolved, but the resolution was deemed
incorrect. For example, a <B>WORKSFORME</B> bug is
<B>REOPENED</B> when more information shows up and the bug is now
reproducible. From here bugs are either marked <B>ASSIGNED</B>
or <B>RESOLVED</B>.
</DL>
</TD>
<TD>
<DL>
No resolution yet. All bugs which are <B>NEW</B>,
<B>VERIFIED</B>, <B>ASSIGNED</B>, or <B>REOPENED</B> have the
resolution set to blank. All other bugs will be marked with
one of the following resolutions.
</DL>
</TD>
</TR>
<TR VALIGN=top>
<TD>
<DL>
<DT><A NAME=\"resolved\"><B>RESOLVED</B></A>
<DD> A resolution has been found. From here bugs can be
<B>REOPENED</B>.
</DL>
</TD>
<TD>
<DL>
<DT><A NAME=\"notabug\"><B>NOTABUG</B></A>
<DD> The problem described is not a bug.
<DT><A NAME=\"wontfix\"><B>WONTFIX</B></A>
<DD> The problem described is a bug which will never be fixed.
<DT><A NAME=\"deferred\"><B>DEFERRED</B></A>
<DD> The problem described is a bug which will not be fixed in this
version of the product.
<DT><A NAME=\"duplicate\"><B>DUPLICATE</B></A>
<DD> The problem is a duplicate of an existing bug. Marking a bug
duplicate requires the bug# of the duplicating bug and will at
least put that bug number in the description field.
<DT><A NAME=\"worksforme\"><B>WORKSFORME</B></A>
<DD> All attempts at reproducing this bug were futile, reading the
code produces no clues as to why this behavior would occur. If
more information appears later, please re-assign the bug, for
now, file it.
<DT><A NAME=\"currentrelease\"><B>CURRENTRELEASE</B></A>
<DD> The problem described has already been fixed and can be obtained
in the latest version of our product.
<DT><A NAME=\"rawhide\"><B>RAWHIDE</B></A>
<DD> The problem describe has been fixed in the latest development
release of our product obtainable from our ftp site.
<DT><A NAME=\"errata\"><B>ERRATA</B></A>
<DD> The problem described has been fixed and will be available as
an errata update from our support web site. Please check the site
to see if it is currently available for download.
</DL>
</TD>
</TR>
</TABLE>
<H1>Other Fields</H1>
<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0 WIDTH=100%>
<TR>
<TH ALIGN=center VALIGN=center><A NAME=\"severity\">
<H2>Severity</H2></A>
</TH>
<TH ALIGN=center VALIGN=center><a name=\"priority\">
<h2>Priority</h2></a>
</TH>
</TR>
<TR>
<TD ALIGN=center VALIGN=center>This field describes the impact of a bug.</TD>
<TD ALIGN=center VALIGN=center>This field describes the importance and order in which
a bug should be fixed. The available priorities are:
</TD>
</TR>
<TR>
<TD VALIGN=top>
<TABLE CELLPADDING=4>
<TR>
<TD><B>Security</B></TD>
<TD>security issue</TD>
</TR><TR>
<TD><B>High</B></TD>
<TD>crashes, loss of data, severe memory leak</TD>
</TR><TR>
<TD><B>Low</B></TD>
<TD>minor loss of function, or other problem where
easy workaround is present</TD>
</TR><TR>
<TD><B>Enhancement</B></TD>
<TD>some feature or change you would like to see in any future releases of the product</TD>
</TR>
</TABLE>
</TD>
<TD VALIGN=top>
<TABLE CELLPADDING=4>
<TR>
<TD><B>High</B></TD>
<TD>Most important</TD>
</TR><TR>
<TD><B>Normal</B></TD>
<TD>Average Importance</TD>
</TR><TR>
<TD><B>Low</B></TD>
<TD>Least important</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<A NAME=\"rep_platform\"><H2>Platform</H2></a>
This is the platform against which the bug was reported.
Legal platforms include:
<UL>
<LI> All (happens on all platforms; cross-platform bug)
<LI> i386
<LI> sparc
<LI> alpha
</UL>
<B>Note:</B> Selecting the option \"All\" does not select bugs assigned
against all platforms. It merely selects bugs that <B>occur</B> on
all platforms.
<A NAME=\"assigned_to\"><H2>Assigned To</H2></a>
This is the person in charge of resolving the bug.
<A NAME=\"reporter\"><H2>Reporter</H2></a>
This is the person who reported the bug.
<p>
The default status for queries is set to NEW, ASSIGNED and REOPENED. When
searching for bugs that have been resolved or verified, remember to set the
status field appropriately.
<P>
<A NAME=\"description\"><H2>Description and Additional Comments</H2></a>
Markup tags entered in these fields will appear as plain text. Numbers preceded by the word
'bug' will be converted to hyperlinks<BR>pointing to the proper bug reports. Any email addresses
will be automatically converted to mailto: hyperlinks. Also any urls starting<BR>with http://
will be made automatically into hyperlinks.
</TD></TR></TABLE>
";
PutFooter();

View File

@@ -1,201 +0,0 @@
<HTML>
<!--
The contents of this file are subject to the Mozilla Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is the Bugzilla Bug Tracking System.
The Initial Developer of the Original Code is Netscape Communications
Corporation. Portions created by Netscape are
Copyright (C) 1998 Netscape Communications Corporation. All
Rights Reserved.
Contributor(s):
Contributor(s): Terry Weissman <terry@mozilla.org>
-->
<TITLE>A Bug's Life Cycle</TITLE>
<h1 ALIGN=CENTER>A Bug's Life Cycle</h1>
The <B>status</B> and <B>resolution</B> field define and track the
life cycle of a bug.
<a name="status">
<p>
</a>
<TABLE BORDER=1 CELLPADDING=4>
<TR ALIGN=CENTER VALIGN=TOP>
<TD WIDTH=50%><H1>STATUS</H1> <TD><H1>RESOLUTION</H1>
<TR VALIGN=TOP>
<TD>The <B>status</B> field indicates the general health of a bug. Only
certain status transitions are allowed.
<TD>The <b>resolution</b> field indicates what happened to this bug.
<TR VALIGN=TOP><TD>
<DL><DT><B>UNCONFIRMED</B>
<DD> This bug has recently been added to the database. Nobody has
validated that this bug is true. Users who have the "canconfirm"
permission set may confirm this bug, changing its state to NEW.
Or, it may be directly resolved and marked RESOLVED.
<DT><B>NEW</B>
<DD> This bug has recently been added to the assignee's list of bugs
and must be processed. Bugs in this state may be accepted, and
become <B>ASSIGNED</B>, passed on to someone else, and remain
<B>NEW</B>, or resolved and marked <B>RESOLVED</B>.
<DT><B>ASSIGNED</B>
<DD> This bug is not yet resolved, but is assigned to the proper
person. From here bugs can be given to another person and become
<B>NEW</B>, or resolved and become <B>RESOLVED</B>.
<DT><B>REOPENED</B>
<DD>This bug was once resolved, but the resolution was deemed
incorrect. For example, a <B>WORKSFORME</B> bug is
<B>REOPENED</B> when more information shows up and the bug is now
reproducible. From here bugs are either marked <B>ASSIGNED</B>
or <B>RESOLVED</B>.
</DL>
<TD>
<DL>
<DD> No resolution yet. All bugs which are in one of these "open" states
have the resolution set to blank. All other bugs
will be marked with one of the following resolutions.
</DL>
<TR VALIGN=TOP><TD>
<DL>
<DT><B>RESOLVED</B>
<DD> A resolution has been taken, and it is awaiting verification by
QA. From here bugs are either re-opened and become
<B>REOPENED</B>, are marked <B>VERIFIED</B>, or are closed for good
and marked <B>CLOSED</B>.
<DT><B>VERIFIED</B>
<DD> QA has looked at the bug and the resolution and agrees that the
appropriate resolution has been taken. Bugs remain in this state
until the product they were reported against actually ships, at
which point they become <B>CLOSED</B>.
<DT><B>CLOSED</B>
<DD> The bug is considered dead, the resolution is correct. Any zombie
bugs who choose to walk the earth again must do so by becoming
<B>REOPENED</B>.
</DL>
<TD>
<DL>
<DT><B>FIXED</B>
<DD> A fix for this bug is checked into the tree and tested.
<DT><B>INVALID</B>
<DD> The problem described is not a bug
<DT><B>WONTFIX</B>
<DD> The problem described is a bug which will never be fixed.
<DT><B>LATER</B>
<DD> The problem described is a bug which will not be fixed in this
version of the product.
<DT><B>REMIND</B>
<DD> The problem described is a bug which will probably not be fixed in this
version of the product, but might still be.
<DT><B>DUPLICATE</B>
<DD> The problem is a duplicate of an existing bug. Marking a bug
duplicate requires the bug# of the duplicating bug and will at
least put that bug number in the description field.
<DT><B>WORKSFORME</B>
<DD> All attempts at reproducing this bug were futile, reading the
code produces no clues as to why this behavior would occur. If
more information appears later, please re-assign the bug, for
now, file it.
</DL>
</TABLE>
<H1>Other Fields</H1>
<table border=1 cellpadding=4><tr><td>
<a name="severity"><h2>Severity</h2></a>
This field describes the impact of a bug.
<p>
<p>
<table>
<tr><th>Blocker</th><td>Blocks development and/or testing work
<tr><th>Critical</th><td>crashes, loss of data, severe memory leak
<tr><th>Major</th><td>major loss of function
<tr><th>Minor</th><td>minor loss of function, or other problem where easy workaround is present
<tr><th>Trivial</th><td>cosmetic problem like misspelt words or misaligned text
<tr><th>Enhancement</th><td>Request for enhancement
</table>
</td><td>
<a name="priority"><h2>Priority</h2></a>
This field describes the importance and order in which a bug should be
fixed. This field is utilized by the programmers/engineers to
prioritized their work to be done. The available priorities are:
<p>
<p>
<table>
<tr><th>P1</th><td>Most important
<tr><th>P2</th><td>
<tr><th>P3</th><td>
<tr><th>P4</th><td>
<tr><th>P5</th><td>Least important
</table>
</tr></table>
<a name="rep_platform"><h2>Platform</h2></a>
This is the hardware platform against which the bug was reported. Legal
platforms include:
<UL>
<LI> All (happens on all platform; cross-platform bug)
<LI> Macintosh
<LI> PC
<LI> Sun
<LI> HP
</UL>
<b>Note:</b> Selecting the option "All" does not select bugs assigned against all platforms. It
merely selects bugs that <b>occur</b> on all platforms.
<a name="op_sys"><h2>Operating System</h2></a>
This is the operating system against which the bug was reported. Legal
operating systems include:
<UL>
<LI> All (happens on all operating systems; cross-platform bug)
<LI> Windows 95
<LI> Mac System 8.0
<LI> Linux
</UL>
Note that the operating system implies the platform, but not always.
For example, Linux can run on PC and Macintosh and others.
<a name="assigned_to"><h2>Assigned To</h2></a>
This is the person in charge of resolving the bug. Every time this
field changes, the status changes to <B>NEW</B> to make it easy to see
which new bugs have appeared on a person's list.
The default status for queries is set to NEW, ASSIGNED and REOPENED. When
searching for bugs that have been resolved or verified, remember to set the
status field appropriately.
<hr>
<!-- hhmts start -->
Last modified: Wed Feb 16 20:41:24 2000
<!-- hhmts end -->
</body> </html>

File diff suppressed because it is too large Load Diff

View File

@@ -1,281 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Symantec Visual Page 1.0">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
<TITLE>Bug Writing Guidelines</TITLE>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000">
<H1 ALIGN="CENTER">bug writing guidelines</H1>
<P ALIGN="CENTER"><FONT SIZE="2"><B>(Please send feedback/update requests to </B></FONT><A
HREF="mailto:eli@prometheus-music.com"><FONT SIZE="2"><B>Eli Goldberg</B></FONT></A><FONT
SIZE="2"><B>)</B></FONT></P>
<P><FONT SIZE="4"><B><BR>
Why You Should Read This</B></FONT>
<BLOCKQUOTE>
<P>Simply put, the more effectively you report a bug, the more likely an engineer
will actually fix it. <BR>
<A HREF="http://bugzilla.mozilla.org"><BR>
</A>These bug writing guidelines are an attempt at a general tutorial on writing
effective bug reports for novice bug writers; not every sentence may precisely apply
to your software project.
</BLOCKQUOTE>
<P><FONT SIZE="4"><B><BR>
How to Write a Useful Bug Report</B></FONT>
<BLOCKQUOTE>
<P>Useful bug reports are ones that get bugs fixed. A useful bug report normally
has two qualities:
<OL>
<LI><B>Reproducible.</B> If an engineer can't see it or conclusively prove that it
exists, the engineer will probably stamp it &quot;WORKSFORME&quot; or &quot;INVALID&quot;,
and move on to the next bug. Every detail you can provide helps. <BR>
<BR>
<LI><B>Specific.</B> The quicker the engineer can isolate the issue to a specific
problem, the more likely it'll be expediently fixed.<B> </B>(If a programmer or tester
has to decypher a bug, they spend more time cursing the submitter than fixing or
testing the problem.)
</OL>
<P>Let's say the application you're testing is a web browser. You crash at foo.com,
and want to write up a bug report:
<BLOCKQUOTE>
<P><B>BAD:</B> &quot;My browser crashed. I think I was on foo.com. My computer uses
Windows. I think that this is a really bad problem and you should fix it now. By
the way, your icons really suck. Nobody will use your software if you keep those
ugly icons. Oh, and my grandmother's home page doesn't look right, either, it's all
messed up. Good luck.&quot;<BR>
<BR>
<B>GOOD: </B>&quot;I crashed each time when I went to foo.com, using the 10.28.99
build on a Win NT 4.0 (Service Pack 5) system. I also rebooted into Linux, and reproduced
this problem using the 10.28.99 Linux build.<BR>
<BR>
It again crashed each time upon drawing the Foo banner at the top of the page. I
broke apart the page, and discovered that the following image link will crash the
application reproducibly, unless you remove the &quot;border=0&quot; attribute:<BR>
<BR>
<FONT SIZE="2"><TT>&lt;IMG SRC=&quot;http://foo.com/images/topics/topicfoos.gif&quot;
width=34 height=44 border=0 alt=&quot;News&quot;&gt;</TT>&quot;</FONT>
</BLOCKQUOTE>
</BLOCKQUOTE>
<P><FONT SIZE="4"><B><BR>
<BR>
How to Enter your Useful Bug Report into Bugzilla</B>:</FONT>
<BLOCKQUOTE>
<P>Before you enter your bug, use the Bugzilla Query Page to determine whether the
defect you've discovered is a known bug, and has already been reported. (If your
bug is the 37th duplicate of a known issue, you're more likely to annoy the engineer.
Annoyed engineers fix fewer bugs.)<BR>
<BR>
Next, be sure that you've reproduced your bug using a recent build. (Engineers tend
to be most interested in problems afflicting the code base that they're actively
working on, rather than those in a code base that's hundreds of bug fixes obsolete.)<BR>
<BR>
If you've discovered a new bug using a current build, report it in Bugzilla:
</BLOCKQUOTE>
<OL>
<OL>
<LI>From your Bugzilla main page, choose &quot;Enter a new bug&quot;.
<LI>Select the product that you've found a bug in.
<LI>Enter your E-mail address, Password, and press the &quot;Login&quot; button.
(If you don't yet have a password, leave the password text box empty, and press the
&quot;E-mail me a password&quot; button instead. You'll receive an E-mail message
with your password shortly.)
</OL>
<P>Now, fill out the form. Here's what it all means:
</OL>
<BLOCKQUOTE>
<P><B>Where did you find the bug?</B>
<BLOCKQUOTE>
<P><B>Product: In which product did you find the bug?</B><BR>
You just filled this out on the last page.</P>
<P><B>Version: In which product version did you find the bug?</B><BR>
If applicable.</P>
<P><B>Component: In which component does the bug exist?</B><BR>
Bugzilla requires that you select a component to enter a bug. (If they all look meaningless,
click on the Component link, which links to descriptions of each component, to help
you make the best choice.)</P>
<P><B>Platform:&#160;On which hardware platform did you find this bug?</B><FONT SIZE="2"><B>
</B>(e.g. Macintosh, SGI, Sun, PC.) </FONT><BR>
If you know the bug happens on all hardware platforms, choose 'All'. Otherwise, select
the platform that you found the bug on, or &quot;Other&quot; if your platform isn't
listed.</P>
<P><B>OS: On which Operating System (OS) did you find this bug?</B> <FONT SIZE="2">(e.g.
Linux, Windows NT, Mac OS 8.5.)</FONT><BR>
If you know the bug happens on all OSs, choose 'All'. Otherwise, select the OS that
you found the bug on, or &quot;Other&quot; if your OS isn't listed.</P>
</BLOCKQUOTE>
<P><B><BR>
How important is the bug?</B>
<BLOCKQUOTE>
<P><B>Severity: How damaging is the bug?</B><BR>
This item defaults to 'normal'. (To determine the most appropriate severity for a
particular bug, click on the Severity link for a full explanation of each choice,
from Critical to Enhancement.)
</BLOCKQUOTE>
<P><B><BR>
Who will be following up on the bug?</B>
<BLOCKQUOTE>
<P><B>Assigned To: Which engineer should be responsible for fixing this bug?</B><BR>
Bugzilla will automatically assign the bug to a default engineer upon submitting
a bug report; the text box exists to allow you to manually assign it to a different
engineer. (To see the list of default engineers for each component, click on the
Component link.)</P>
<P><B>Cc: Who else should receive e-mail updates on changes to this bug? </B><BR>
List the full e-mail addresses of other individuals who should receive an e-mail
update upon every change to the bug report. You can enter as many e-mail addresses
as you'd like; e-mail addresses must be separated by commas, with no spaces between
the addresses.
</BLOCKQUOTE>
<P><B><BR>
What else can you tell the engineer about the bug?</B></P>
<BLOCKQUOTE>
<P><B>URL: On what URL did you discover this bug?</B><BR>
If you encountered the bug on a particular URL, please provide it (or, them) here.
If you've isolated the bug to a specific HTML snippet, please also provide a URL
for that, too.</P>
<P><B>Summary:</B> <B>How would you describe the bug, in approximately 60 or fewer
characters?</B><BR>
A good summary should <U>quickly and uniquely identify a bug report</U>. Otherwise,
developers cannot meaningfully query by bug summary, and will often fail to pay attention
to your bug report when reviewing a 10 page bug list.<BR>
<BR>
A summary of &quot;PCMCIA install fails on Tosh Tecra 780DVD w/ 3c589C&quot; is a
useful title. &quot;Software fails&quot; or &quot;install problem&quot; would be
examples of a bad title.</P>
<P><BR>
<B>Description: What else can you tell the engineer about this bug? </B><BR>
Please provide as detailed of a problem diagnosis in this field as possible. <BR>
<BR>
Where applicable, using the following bug report template will help ensure that all
relevant information comes through:
<BLOCKQUOTE>
<P><B>Overview Description:</B> More detailed expansion of summary.
<BLOCKQUOTE>
<PRE><FONT SIZE="2">Drag-selecting any page crashes Mac builds in NSGetFactory</FONT></PRE>
</BLOCKQUOTE>
<P><B>Steps to Reproduce: </B>The minimal set of steps necessary to trigger the bug.
Include any special setup steps.
<BLOCKQUOTE>
<PRE><FONT SIZE="2">1) View any web page. (I used the default sample page,
resource:/res/samples/test0.html)
2) Drag-select the page. (Specifically, while holding down the
mouse button, drag the mouse pointer downwards from any point in
the browser's content region to the bottom of the browser's
content region.)</FONT></PRE>
</BLOCKQUOTE>
<P><B>Actual Results:</B> What the application did after performing the above steps.
<BLOCKQUOTE>
<PRE><FONT SIZE="2">The application crashed. Stack crawl appended below from MacsBug.</FONT></PRE>
</BLOCKQUOTE>
<P><B>Expected Results:</B> What the application should have done, were the bug not
present.
<BLOCKQUOTE>
<PRE><FONT SIZE="2">The window should scroll downwards. Scrolled content should
be selected. (Or, at least, the application should not crash.)</FONT></PRE>
</BLOCKQUOTE>
<P><B>Build Date &amp; Platform:</B> Date and platform of the build that you first
encountered the bug in.
<BLOCKQUOTE>
<PRE><FONT SIZE="2">11/2/99 build on Mac OS (Checked Viewer &amp; Apprunner)</FONT></PRE>
</BLOCKQUOTE>
<P><B>Additional Builds and Platforms:</B> Whether or not the bug takes place on
other platforms or browsers.
<BLOCKQUOTE>
<PRE><FONT SIZE="2"> - Occurs On
Seamonkey (11/2/99 build on Windows NT 4.0)
- Doesn't Occur On
Seamonkey (11/4/99 build on Red Hat Linux; feature not supported)
Internet Explorer 5.0 (RTM build on Windows NT 4.0)
Netscape Communicator 4.5 (RTM build on Mac OS)</FONT>
</PRE>
</BLOCKQUOTE>
<P><B>Additional Information:</B> Any other debugging information. For crashing bugs:
<UL>
<LI><B>Win32:</B> if you receive a Dr. Watson error, please note the type of the
crash, and the module that the application crashed in. (e.g. access violation in
apprunner.exe)
<LI><B>Mac OS:</B> if you're running MacsBug, please provide the results of a <B><TT>how</TT></B>
and an <B><TT>sc</TT></B>.
<LI><B>Unix: </B>please provide a minimized stack trace, which can be generated by
typing <B><TT>gdb apprunner core</TT></B> into a shell prompt.
</UL>
<BLOCKQUOTE>
<P>
<PRE><FONT SIZE="2">*** MACSBUG STACK CRAWL OF CRASH (Mac OS)
Calling chain using A6/R1 links
Back chain ISA Caller
00000000 PPC 0BA85E74
03AEFD80 PPC 0B742248
03AEFD30 PPC 0B50FDDC NSGetFactory+027FC
PowerPC unmapped memory exception at 0B512BD0 NSGetFactory+055F0</FONT></PRE>
</BLOCKQUOTE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<P>You're done! <BR>
<BR>
After double-checking your entries for any possible errors, press the &quot;Commit&quot;
button, and your bug report will now be in the Bugzilla database.<BR>
<I><BR>
<BR>
</I><FONT SIZE="2">(Thanks to Claudius Gayle, Peter Mock, Chris Pratt, Tom Schutter,
and Chris Yeh for contributing to this document. Constructive </FONT><A HREF="mailto:eli@prometheus-music.com"><FONT
SIZE="2">suggestions</FONT></A><FONT SIZE="2"> welcome.)</FONT>
</BLOCKQUOTE>
</BODY>
</HTML>

View File

@@ -1,37 +0,0 @@
#!/usr/bonsaitools/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
print q{Content-type: text/html
<HTML>
<HEAD>
<META HTTP-EQUIV="Refresh"
CONTENT="0; URL=userprefs.cgi">
</HEAD>
<BODY>
This URL is obsolete. Forwarding you to the correct one.
<P>
Going to <A HREF="userprefs.cgi">userprefs.cgi</A>
<BR>
</BODY>
</HTML>
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,115 +0,0 @@
#!/usr/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public License
# Version 1.0 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are Copyright (C) 1998
# Netscape Communications Corporation. All Rights Reserved.
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
use diagnostics;
use strict;
require "CGI.pl";
print "Content-type: text/html\n";
# The master list not only says what fields are possible, but what order
# they get displayed in.
my @masterlist = ("opendate", "changeddate", "severity", "priority",
"platform", "owner", "reporter", "status", "resolution",
"component", "product", "version", "project", "os", "votes");
if (Param("usetargetmilestone")) {
push(@masterlist, "target_milestone");
}
if (Param("useqacontact")) {
push(@masterlist, "qa_contact");
}
if (Param("usestatuswhiteboard")) {
push(@masterlist, "status_whiteboard");
}
push(@masterlist, ("summary", "summaryfull"));
my $cookiepath = Param('cookiepath');
my @collist;
if (defined $::FORM{'rememberedquery'}) {
if (defined $::FORM{'resetit'}) {
@collist = @::default_column_list;
} else {
foreach my $i (@masterlist) {
if (defined $::FORM{"column_$i"}) {
push @collist, $i;
}
}
}
my $list = join(" ", @collist);
print "Set-Cookie: COLUMNLIST=$list ; path=$cookiepath ; expires=Sun, 30-Jun-2029 00:00:00 GMT\n";
print "Refresh: 0; URL=buglist.cgi?$::FORM{'rememberedquery'}\n";
print "\n";
print "<TITLE>What a hack.</TITLE>\n";
PutHeader ("Change columns");
print "Resubmitting your query with new columns...\n";
exit;
}
if (defined $::COOKIE{'COLUMNLIST'}) {
@collist = split(/ /, $::COOKIE{'COLUMNLIST'});
} else {
@collist = @::default_column_list;
}
my %desc;
foreach my $i (@masterlist) {
$desc{$i} = $i;
}
$desc{'summary'} = "Summary (first 60 characters)";
$desc{'summaryfull'} = "Full Summary";
print "\n";
PutHeader ("Change columns");
print "<TABLE ALIGN=center CELLSPACING=0 CELLPADDING=4 BORDER=1>\n<TR>\n<TD ALIGN=left>";
print "<B>Check which columns you wish to appear on the list, and then click\n";
print "on submit.</B>\n";
print "<p>\n";
print "<FORM ACTION=colchange.cgi>\n";
print "<INPUT TYPE=HIDDEN NAME=rememberedquery VALUE=$::buffer>\n";
foreach my $i (@masterlist) {
my $c;
if (lsearch(\@collist, $i) >= 0) {
$c = 'CHECKED';
} else {
$c = '';
}
print "<INPUT TYPE=checkbox NAME=column_$i $c>$desc{$i}<br>\n";
}
print "<P>\n";
print "<CENTER><INPUT TYPE=\"submit\" VALUE=\"Submit\">\n";
print "</FORM>\n";
print "<FORM ACTION=colchange.cgi>\n";
print "<INPUT TYPE=HIDDEN NAME=rememberedquery VALUE=$::buffer>\n";
print "<INPUT TYPE=HIDDEN NAME=resetit VALUE=1>\n";
print "<INPUT TYPE=\"submit\" VALUE=\"Reset to Bugzilla default\"></CENTER>\n";
print "</FORM>\n";
print "</TD>\n</TR>\n</TABLE>\n";
PutFooter();

View File

@@ -1,100 +0,0 @@
#!/usr/bonsaitools/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s): Terry Weissman <terry@mozilla.org>,
# Harrison Page <harrison@netscape.com>
# Run me out of cron at midnight to collect Bugzilla statistics.
use diagnostics;
use strict;
use vars @::legal_product;
require "globals.pl";
ConnectToDatabase();
GetVersionTable();
my @myproducts;
push( @myproducts, "-All-", @::legal_product );
foreach (@myproducts) {
my $dir = "data/mining";
&check_data_dir ($dir);
&collect_stats ($dir, $_);
}
sub check_data_dir {
my $dir = shift;
if (! -d) {
mkdir $dir, 0777;
chmod 0777, $dir;
}
}
sub collect_stats {
my $dir = shift;
my $product = shift;
my $when = localtime (time);
$product =~ s/\//-/gs;
my $file = join '/', $dir, $product;
my $exists = -f $file;
if (open DATA, ">>$file") {
push my @row, &today;
foreach my $status ('NEW', 'ASSIGNED', 'REOPENED') {
if( $product eq "-All-" ) {
SendSQL("select count(bug_status) from bugs where bug_status='$status'");
} else {
SendSQL("select count(bug_status) from bugs where bug_status='$status' and product='$product'");
}
push @row, FetchOneColumn();
}
if (! $exists)
{
print DATA <<FIN;
# Bugzilla daily bug stats
#
# do not edit me! this file is generated.
#
# fields: date|new|assigned|reopened
# product: $product
# created: $when
FIN
}
print DATA (join '|', @row) . "\n";
close DATA;
} else {
print "$0: $file, $!";
}
}
sub today {
my ($dom, $mon, $year) = (localtime(time))[3, 4, 5];
return sprintf "%04d%02d%02d", 1900 + $year, ++$mon, $dom;
}

View File

@@ -1,154 +0,0 @@
<HTML><head>
<!--
The contents of this file are subject to the Mozilla Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is the Bugzilla Bug Tracking System.
The Initial Developer of the Original Code is Netscape Communications
Corporation. Portions created by Netscape are
Copyright (C) 2000 Netscape Communications Corporation. All
Rights Reserved.
Contributor(s): Terry Weissman <terry@mozilla.org>
-->
<title>Understanding the UNCONFIRMED state, and other recent changes</title>
</head>
<body>
<h1>Understanding the UNCONFIRMED state, and other recent changes</h1>
[This document is aimed primarily at people who have used Bugzilla
before the UNCONFIRMED state was implemented. It might be helpful for
newer users as well.]
<p>
New bugs in some products will now show up in a new state,
UNCONFIRMED. This means that we have nobody has confirmed that the
bug is real. Very busy engineers will probably generally ignore
UNCONFIRMED that have been assigned to them, until they have been
confirmed in one way or another. (Engineers with more time will
hopefully glance over their UNCONFIRMED bugs regularly.)
<p>
The <a href="bug_status.html">page describing bug fields</a> has been
updated to include UNCONFIRMED.
<p>
There are two basic ways that a bug can become confirmed (and enter
the NEW) state.
<ul>
<li> A user with the appropriate permissions (see below for more on
permissions) decides that the bug is a valid one, and confirms
it. We hope to gather a small army of responsible volunteers
to regularly go through bugs for us.
<li> The bug gathers a certain number of votes. <b>Any</b> valid
Bugzilla user may vote for bugs (each user gets a certain
number of bugs); any UNCONFIRMED bug which enough bugs becomes
automatically confirmed, and enters the NEW state.
</ul>
One implication of this is that it is worth your time to search the
bug system for duplicates of your bug to vote on them, before
submitting your own bug. If we can spread around knowledge of this
fact, it ought to help cut down the number of duplicate bugs in the
system.
<h2>Permissions.</h2>
Users now have a certain set of permissions. To see your permissions,
check out the
<a href="userprefs.cgi?bank=permissions">user preferences</a> page.
<p>
If you have the "Can confirm a bug" permission, then you will be able
to move UNCONFIRMED bugs into the NEW state.
<p>
If you have the "Can edit all aspects of any bug" permission, then you
can tweak anything about any bug. If not, you may only edit those
bugs that you have submitted, or that you have assigned to you (or
qa-assigned to you). However, anyone may add a comment to any bug.
<p>
Some people (initially, the initial owners and initial qa-contacts for
components in the system) have the ability to give the above two
permissions to other people. So, if you really feel that you ought to
have one of these permissions, a good person to ask (via private
email, please!) is the person who is assigned a relevant bug.
<h2>Other details.</h2>
An initial stab was taken to decide who would be given which of the
above permissions. This was determined by some simple heurstics of
who was assigned bugs, and who the default owners of bugs were, and a
look at people who seem to have submitted several bugs that appear to
have been interesting and valid. Inevitably, we have failed to give
someone the permissions they deserve. Please don't take it
personally; just bear with us as we shake out the new system.
<p>
People with one of the two bits above can easily confirm their own
bugs, so bugs they submit will actually start out in the NEW state.
They can override this when submitting a bug.
<p>
People can ACCEPT or RESOLVE a bug assigned to them, even if they
aren't allowed to confirm it. However, the system remembers, and if
the bug gets REOPENED or reassigned to someone else, it will revert
back to the UNCONFIRMED state. If the bug has ever been confirmed,
then REOPENing or reassigning will cause it to go to the NEW or
REOPENED state.
<p>
Note that only some products support the UNCONFIRMED state. In other
products, all new bugs will automatically start in the NEW state.
<h2>Things still to be done.</h2>
There probably ought to be a way to get a bug back into the
UNCONFIRMED state, but there isn't yet.
<p>
If a person has submitted several bugs that get confirmed, then this
is probably a person who understands the system well, and deserves the
"Can confirm a bug" permission. This kind of person should be
detected and promoted automatically.
<p>
There should also be a way to automatically promote people to get the
"Can edit all aspects of any bug" permission.
<p>
The "enter a new bug" page needs to be revamped with easy ways for new
people to educate themselves on the benefit of searching for a bug
like the one they're about to submit and voting on it, rather than
adding a new useless duplicate.
<hr>
<!-- hhmts start -->
Last modified: Wed Feb 16 21:04:56 2000
<!-- hhmts end -->
</body> </html>

View File

@@ -1,79 +0,0 @@
# -*- Mode: perl; indent-tabs-mode: nil -*-
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# This code is based on code found in bug_email.pl from the bugzilla
# email tracker. Initial contributors are ::
# Terry Weissman <terry@mozilla.org>
# Gregor Fischer <fischer@suse.de>
# Klaas Freitag <freitag@suse.de>
# Seth Landsman <seth@dworkin.net>
# The purpose of this module is to abstract out a bunch of the code
# that is central to email interfaces to bugzilla and its database
# Contributor : Seth Landsman <seth@dworkin.net>
# Initial checkin : 03/15/00 (SML)
# findUser() function moved from bug_email.pl to here
push @INC, "../."; # this script now lives in contrib
require "globals.pl";
use diagnostics;
use strict;
my $EMAIL_TRANSFORM_NONE = "email_transform_none";
my $EMAIL_TRANSFORM_BASE_DOMAIN = "email_transform_base_domain";
my $EMAIL_TRANSFORM_NAME_ONLY = "email_transform_name_only";
# change to do incoming email address fuzzy matching
my $email_transform = $EMAIL_TRANSFORM_NAME_ONLY;
# findUser()
# This function takes an email address and returns the user email.
# matching is sloppy based on the $email_transform parameter
sub findUser($) {
my ($address) = @_;
# if $email_transform is $EMAIL_TRANSFORM_NONE, return the address, otherwise, return undef
if ($email_transform eq $EMAIL_TRANSFORM_NONE) {
my $stmt = "SELECT login_name FROM profiles WHERE profiles.login_name = \'$address\';";
SendSQL($stmt);
my $found_address = FetchOneColumn();
return $found_address;
} elsif ($email_transform eq $EMAIL_TRANSFORM_BASE_DOMAIN) {
my ($username) = ($address =~ /(.+)@/);
my $stmt = "SELECT login_name FROM profiles WHERE profiles.login_name RLIKE \'$username\';";
SendSQL($stmt);
my $domain;
my $found = undef;
my $found_address;
my $new_address = undef;
while ((!$found) && ($found_address = FetchOneColumn())) {
($domain) = ($found_address =~ /.+@(.+)/);
if ($address =~ /$domain/) {
$found = 1;
$new_address = $found_address;
}
}
return $new_address;
} elsif ($email_transform eq $EMAIL_TRANSFORM_NAME_ONLY) {
my ($username) = ($address =~ /(.+)@/);
my $stmt = "SELECT login_name FROM profiles WHERE profiles.login_name RLIKE \'$username\';";
SendSQL($stmt);
my $found_address = FetchOneColumn();
return $found_address;
}
}
1;

View File

@@ -1,18 +0,0 @@
This directory contains contributed software related to Bugzilla.
Things in here have not necessarily been tested or tried by anyone
except the original contributor, so tred carefully. But it may still
be useful to you.
This directory includes:
gnats2bz.pl -- a perl script to help import bugs from a GNATS
database into a Bugzilla database. Contributed by
Tom Schutter <tom@platte.com>
bug_email.pl -- a perl script that can receive email containing
bug reports (email-interface). Contributed by
Klaas Freitag <freitag@SuSE.de>
README.Mailif -- Readme describing the mail interface.
bugmail_help.html -- User help page for the mail interface.

View File

@@ -1,80 +0,0 @@
The Bugzilla Mail interface
===========================
(UPDATE 03/14/00 to better reflect reality by SML)
The Bugzilla Mail interface allows to submit bugs to Bugzilla by email.
The Mail Interface Contribution consists of three files:
README.Mailif - this readme.
bug_email.pl - the script
bugmail_help.html - a user help html site
Installation:
Next is to add a user who receives the bugmails, e. g. bugmail. Create a
mail account and a home directory for the user.
The mailinterface script bug_email.pl needs to get the mail through stdin.
I use procmail for that, with the following line in the .procmailrc:
BUGZILLA_HOME=/usr/local/httpd/htdocs/bugzilla
:0 c
|(cd $BUGZILLA_HOME/contrib; ./bug_email.pl)
This defines the Bugzilla directory as the variable BUGZILLA_HOME and passes
all incoming mail to the script after cd'ing into the bugzilla home.
In some cases, it is necessary to alter the headers of incoming email. The
additional line to procmail :
:0 fhw
| formail -I "From " -a "From "
fixes many problems.
See bugzilla.procmailrc for a sample procmailrc that works for me (SML) and
also deals with bugzilla_email_append.pl
Customation:
There are some values inside the script which need to be customized for your
needs:
1. In sub-routine Reply (search 'sub Reply':
there is the line
print MAIL "From: Bugzilla Mailinterface<yourmail\@here.com>\n";
^^^^^^^^^^^^^^^^^^^^
Fill in your correct mail here. That will make it easy for people to reply
to the mail.
2. check, if your sendmail resides in /usr/sbin/sendmail, change the path if neccessary.
Search the script after 'default' - you find some default-Settings for bug
reports, which are used, if the sender did not send a field for it. The defaults
should be checked and changed.
Thats hopefully all, we will come up with any configuration file or something.
If your mail works, your script will insert mails from now on.
The mailinterface supports two commandline switches:
There are two command line switches :
-t: Testmode
The mailinterface does not really insert the bug into the database, but
writes some debug output to stdout and writes the mail into the file
bug_email_test.log in the data-dir.
-r: restricted mode
All lines before the first line with a keyword character are skipped.
In not restricted, default mode, these lines are added to the long
description of the bug.
02/2000 - Klaas Freitag, SuSE GmbH <freitag@suse.de>
03/2000 - Seth M. Landsman <seth@cs.brandeis.edu>
bug_email.pl now lives out of bugzilla/contrib
added line about formail

File diff suppressed because it is too large Load Diff

View File

@@ -1,223 +0,0 @@
<HTML>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<!--
The contents of this file are subject to the Mozilla Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is the Bugzilla Bug Tracking System.
Contributor(s): Klaas Freitag <Freitag@SuSE.de>
-->
<HEAD> <TITLE>Bugzilla Mail Interface</TITLE> </HEAD>
<BODY BGCOLOR="#FFFFFF">
<CENTER><H1>The Bugzilla Mail Interface</H1>
Contributor: <A HREF="mailto:freitag@suse.de">Klaas Freitag</A>, SuSE GmbH
</CENTER>
<P>
The bugzilla Mail interface allows the registered bugzilla users to submit bugs by
sending email with a bug description. This is usefull for people, who do not work
inhouse and want to submitt bugs to the bugzilla system.
<p>
I know, show me the <A HREF="#examplemail">example-mail !</A>
<H2>What do you need to do to submitt a bug by mail ?</H2>
You need to send a email in the described format to the bugmail-user of the
bugzilla-system. This is <A HREF="mailto:our_bugzilla@xyz.com">yourbugzilla@here.com</A>
You receive a reply mail with the new bug-ID if your request was ok.
If not, you get a mail with
some help on the bugmail system and a specific analysis of your request.
<P>
Please dont refuse to send one or two wrong mails, you will get all the information
you need in the replies, and <I>only</I> in the mail replies. The information on this
page, concerning available products, versions and so on, is not dynamicly generated and
may be old therefore.
<H1>The Mail Format</H1>
The bugmail needs a special format , which consists of some keywords and suitable
values for them and a description text. Note that the keyword block needs to be
above of the description text.
<H2>Keywords</H2>
You need to tell bugzilla some properties of the bugs. This is done by keywords, which
start on a new line with a @, followed by the keyword and and equal-sign, followed by a
hopefully valid value.
<TABLE BORDER=4 FRAME=box CELLSPACING="5" width=95%> <COLGROUP> <col width="2*">
<col width="5*"> <col width="1*"> </COLGROUP>
<TR>
<TH>Keyword</TH>
<TH>Value description</TH>
<TH>required and default value</TH>
</TR>
<TR>
<TD>@product</TD>
<TD>The product which has a bug</TD>
<TD>yes. <br> This is the most important information. Many other
fields depend on the product.</TD>
</TR>
<TR>
<TD>@component</TD>
<TD>the desired component which is affected by the bug</TD>
<TD>yes. <br> As the @product, this is a very important
field.</TD>
</TR>
<TR>
<TD>@version</TD>
<TD>The version of the product</TD>
<TD>yes. <br>See @product and @component</TD>
</TR>
<TR>
<TD>@short_desc</TD>
<TD>A summary of your bug report</TD>
<TD>yes. <br>This summary of the error you want to report
describes what happen. You may skip the long description,
but not this summary.<br>
<b>Note:</b>The short description may be given in the mail subject
instead of using the keyword !</TD>
</TR>
<TR>
<TD>@rep_platform</TD>
<TD>The desired platform</TD>
<TD>no.<br>If you dont give a value, this field is set to <I>All</I>.</TD>
</TR>
<TR>
<TD>@bug_severity</TD>
<TD>The severity of the bug</TD>
<TD>no. <br> If you dont give a value, this field is set to
<I>normal</I></TD>
</TR>
<TR>
<TD>@priority</TD>
<TD>The priority of the bug</TD>
<TD>no.<br>If you dont give a value, this field is set to <I>P3</I></TD>
</TR>
<TR>
<TD>@op_sys</TD>
<TD>The operating system</TD>
<TD>no.<br>If you dont give a value, this field is set to <I>Linux</I>.</TD>
</TR>
<TR>
<TD>@assigned_to</TD>
<TD>The one to whom the bug is assigned to</TD>
<TD>no. <br>There is an initial owner for every product/version/component.
He owns the bug by default. The initial owner can only be found if
product, version and component are valid.</TD>
</TR>
<TR>
<TD>@bug_file_loc</TD>
<TD>?</TD>
<TD>no.</TD>
</TR>
<TR>
<TD>@status_whiteboard</TD>
<TD>?</TD>
<TD>no.</TD>
</TR>
<TR>
<TD>@target_milestone</TD>
<TD>?</TD>
<TD>no.</TD>
</TR>
<TR>
<TD>@groupset</TD>
<TD>rules the visibility of the bug.</TD>
<TD>no.<br>This value defaults to the smallest of the available groups,
which is <I>readInternal</I>.</TD>
</TR>
<TR>
<TD>@qa_contact</TD>
<TD>the quality manager for the product</TD>
<TD>no.<br>This value can be retrieved from product, component and
version</TD>
</TR>
</TABLE>
<H2>Valid values</H2>
Give string values for the most keys above. Some keywords require special values:<br>
<ol>
<li>E-Mail adresses: If you want to set the qa-contact, specify a email-adress for @qa_contact. The email must be known by bugzilla of course.</li>
<li>Listvalues: Most of the values have to be one of a list of valid values. Try by sending
a mail and read the reply. Skip fields if you dont get help for them unless you dont know
which values you may choose.</li>
<li>free Text: The descriptions may be free text. </li>
<li>Special: The field groupset may be specified in different in three different kinds:
<ol>
<li> A plain numeric way, which is one usually huge number, e. g. <I>65536</I></li>
<li> a string with added numbers e.g. <I>65536+131072</I></li>
<li> a string list, e.g. <I>ReadInternal, ReadBeta </I></li>
</ol>
</li>
</ol>
<p>
But most of them need <b>valid</b> values.
<p>
Sorry, you will not find lists of valid products, components and the other stuff
here. Send a mail to with any text, and you will get a list of valid keywords in the reply.
<p>
Some of the values must be choosen from a list:<br>
<ol>
<li>bug_severity: blocker, critical, major, normal, minor, trivial, enhancement</li>
<li>op_sys: Linux </li>
<li>priority: P1, P2, P3, P4, P5</li>
<li>rep_platform: All, i386, AXP, i686, Other</li></ol>
<p>
After you have specified the required keywords and maybe some other value, you may
describe your bug. You dont need a keyword for starting your bug description. All
text which follows the keyword block is handled as long description of the bug.
<p>
The bugmail interface is able to find required information by itself. E.g. if you specify
a product which has exactly one component, this component will be found by the interface
automatically.
<H1>Attachments</H1>
The mail interface is able to cope with MIME-attachments.
People could for example add a logfile as a mail attachment, and it will appear in
bugzilla as attachment. A comment for the attachment should be added, it will describe
the attachment in bugzilla.
<H1><A NAME="examplemail">Example Mail</A></H1>
See the example of the mail <b>body</b> (Dont forget to specify the short description
in the mail subject):<hr><pre>
@product = Bugzilla
@component = general
@version = All
@groupset = ReadWorld ReadPartners
@op_sys = Linux
@priority = P3
@rep_platform = i386
This is the description of the bug I found. It is not neccessary to start
it with a keyword.
Note: The short_description is neccessary and may be given with the keyword
@short_description or will be retrieved from the mail subject.
</pre><hr>
</BODY>
</HTML>

View File

@@ -1,30 +0,0 @@
:0 fhw
| formail -I "From " -a "From "
BUGZILLA_HOME=/home/bugzilla/WEB/bugzilla/contrib
:0
* ^Subject: .*\[Bug .*\]
RESULT=|(cd $BUGZILLA_HOME && ./bugzilla_email_append.pl)
# Feed mail to stdin of bug_email.pl
:0 Ec
#* !^Subject: .*[Bug .*]
RESULT=|(cd $BUGZILLA_HOME && ./bug_email.pl )
# write result to a logfile
:0 c
|echo `date '+%d.%m.%y %H:%M: '` $RESULT >> $HOME/bug_email.log
:0 c
|echo "----------------------------------" >> $HOME/bug_email.log
:0 c
$HOME/bug_email.log
# Move mail to the inbox
:0
$HOME/Mail/INBOX

View File

@@ -1,189 +0,0 @@
#!/usr/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
# The purpose of this script is to take an email message, which
# specifies a bugid and append it to the bug as part of the longdesc
# table
# Contributor : Seth M. Landsman <seth@dworkin.net>
# 03/15/00 : Initial version by SML
# 03/15/00 : processmail gets called
# Email subject must be of format :
# .* Bug ### .*
# replying to a typical bugzilla email should be valid
# TODO :
# 1. better way to get the body text (I don't know what dump_entity() is
# actually doing
use diagnostics;
use strict;
use MIME::Parser;
push @INC, "../."; # this script lives in contrib
require "globals.pl";
require "BugzillaEmail.pm";
# Create a new MIME parser:
my $parser = new MIME::Parser;
my $Comment = "";
# Create and set the output directory:
# FIXME: There should be a $BUGZILLA_HOME variable (SML)
(-d "../data/mimedump-tmp") or mkdir "../data/mimedump-tmp",0755 or die "mkdir: $!";
(-w "../data/mimedump-tmp") or die "can't write to directory";
$parser->output_dir("../data/mimedump-tmp");
# Read the MIME message:
my $entity = $parser->read(\*STDIN) or die "couldn't parse MIME stream";
$entity->remove_sig(10); # Removes the signature in the last 10 lines
# Getting values from parsed mail
my $Sender = $entity->get( 'From' );
$Sender ||= $entity->get( 'Reply-To' );
my $Message_ID = $entity->get( 'Message-Id' );
die (" *** Cant find Sender-adress in sent mail ! ***\n" ) unless defined( $Sender );
chomp( $Sender );
chomp( $Message_ID );
print "Dealing with the sender $Sender\n";
ConnectToDatabase();
my $SenderShort = $Sender;
$SenderShort =~ s/^.*?([a-zA-Z0-9_.-]+?\@[a-zA-Z0-9_.-]+\.[a-zA-Z0-9_.-]+).*$/$1/;
$SenderShort = findUser($SenderShort);
print "SenderShort is $SenderShort\n";
if (!defined($SenderShort)) {
$SenderShort = $Sender;
$SenderShort =~ s/^.*?([a-zA-Z0-9_.-]+?\@[a-zA-Z0-9_.-]+\.[a-zA-Z0-9_.-]+).*$/$1/;
}
print "The sendershort is now $SenderShort\n";
if (!defined($SenderShort)) {
DealWithError("No such user $SenderShort exists.");
}
my $Subject = $entity->get('Subject');
print "The subject is $Subject\n";
my ($bugid) = ($Subject =~ /\[Bug ([\d]+)\]/);
print "The bugid is $bugid\n";
# make sure the bug exists
SendSQL("SELECT bug_id FROM bugs WHERE bug_id = $bugid;");
my $found_id = FetchOneColumn();
print "Did we find the bug? $found_id-\n";
if (!defined($found_id)) {
DealWithError("Bug $bugid does not exist");
}
# get the user id
SendSQL("SELECT userid FROM profiles WHERE login_name = \'$SenderShort\';");
my $userid = FetchOneColumn();
if (!defined($userid)) {
DealWithError("Userid not found for $SenderShort");
}
# parse out the text of the message
dump_entity($entity);
# Get rid of the bug id
$Subject =~ s/\[Bug [\d]+\]//;
#my $Comment = "This is only a test ...";
my $Body = "Subject: " . $Subject . "\n" . $Comment;
# shove it in the table
my $long_desc_query = "INSERT INTO longdescs SET bug_id=$found_id, who=$userid, bug_when=NOW(), thetext=" . SqlQuote($Body) . ";";
SendSQL($long_desc_query);
system("cd .. ; ./processmail $found_id '$SenderShort'");
sub DealWithError {
my ($reason) = @_;
print $reason . "\n";
}
# Yanking this wholesale from bug_email, 'cause I know this works. I'll
# figure out what it really does later
#------------------------------
#
# dump_entity ENTITY, NAME
#
# Recursive routine for parsing a mime coded mail.
# One mail may contain more than one mime blocks, which need to be
# handled. Therefore, this function is called recursively.
#
# It gets the for bugzilla important information from the mailbody and
# stores them into the global attachment-list @attachments. The attachment-list
# is needed in storeAttachments.
#
sub dump_entity {
my ($entity, $name) = @_;
defined($name) or $name = "'anonymous'";
my $IO;
# Output the body:
my @parts = $entity->parts;
if (@parts) { # multipart...
my $i;
foreach $i (0 .. $#parts) { # dump each part...
dump_entity($parts[$i], ("$name, part ".(1+$i)));
}
} else { # single part...
# Get MIME type, and display accordingly...
my $msg_part = $entity->head->get( 'Content-Disposition' );
$msg_part ||= "";
my ($type, $subtype) = split('/', $entity->head->mime_type);
my $body = $entity->bodyhandle;
my ($data, $on_disk );
if( $msg_part =~ /^attachment/ ) {
# Attached File
my $des = $entity->head->get('Content-Description');
$des ||= "";
if( defined( $body->path )) { # Data is on disk
$on_disk = 1;
$data = $body->path;
} else { # Data is in core
$on_disk = 0;
$data = $body->as_string;
}
# push ( @attachments, [ $data, $entity->head->mime_type, $on_disk, $des ] );
} else {
# Real Message
if ($type =~ /^(text|message)$/) { # text: display it...
if ($IO = $body->open("r")) {
$Comment .= $_ while (defined($_ = $IO->getline));
$IO->close;
} else { # d'oh!
print "$0: couldn't find/open '$name': $!";
}
} else { print "Oooops - no Body !\n"; }
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,93 +0,0 @@
#!/usr/bonsaitools/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
# David Gardiner <david.gardiner@unisa.edu.au>
use diagnostics;
use strict;
require "CGI.pl";
# Shut up misguided -w warnings about "used only once":
use vars %::FORM;
ConnectToDatabase();
# Clear out the login cookies. Make people log in again if they create an
# account; otherwise, they'll probably get confused.
my $cookiepath = Param('cookiepath');
print "Set-Cookie: Bugzilla_login= ; path=$cookiepath ; expires=Sun, 30-Jun-80 00:00:00 GMT
Set-Cookie: Bugzilla_logincookie= ; path=$cookiepath ; expires=Sun, 30-Jun-80 00:00:00 GMT
Set-Cookie: Bugzilla_password= ; path=$cookiepath ; expires=Sun, 30-Jun-80 00:00:00 GMT
Content-type: text/html
";
my $login = $::FORM{'login'};
my $realname = $::FORM{'realname'};
if (defined $login) {
CheckEmailSyntax($login);
if (DBname_to_id($login) != 0) {
PutHeader("Account exists");
print "<CENTER>A bugzilla account for the name <B><tt>$login</tt></B> already\n";
print "exists.<P>If you have forgotten the password for it, then\n";
print "<a href=query.cgi?GoAheadAndLogIn>click here</a> and use\n";
print "the <b>E-mail me a password</b> button.</CENTER>\n";
PutFooter();
exit;
}
PutHeader("Account created");
my $password = InsertNewUser($login, $realname);
MailPassword($login, $password);
print "<CENTER>A bugzilla account for <B><tt>$login</tt></B> has been created. The\n";
print "password has been e-mailed to that address.<P>When it is\n";
print "received, you may <a href=query.cgi?GoAheadAndLogIn>click\n";
print "here</a> and log in. Or, you can just <a href=\"\">go back to\n";
print "the top</a>.</CENTER>\n";
PutFooter();
exit;
}
PutHeader("Create a new bugzilla account");
print qq{
<CENTER><B>
To create a bugzilla account, all that you need to do is to enter a<BR>
legitimate e-mail address. The account will be created, and its<BR>
password will be mailed to you. Optionally you may enter your<BR>real name
as well.
<FORM method=get>
<TABLE>
<TR>
<TH ALIGN=right>E-mail address:</TH>
<TD><INPUT SIZE=35 NAME=login></TD>
</TR><TR>
<TD ALIGN=right><B>Real name:</B></TD>
<TD><INPUT SIZE=35 NAME=realname></TD>
</TR>
</TABLE>
<INPUT TYPE=submit NAME=submit VALUE="Submit">
</CENTER>
};
PutFooter();

View File

@@ -1,130 +0,0 @@
#!/usr/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public License
# Version 1.0 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are Copyright (C) 1998
# Netscape Communications Corporation. All Rights Reserved.
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
# David Gardiner <david.gardiner@unisa.edu.au>
use diagnostics;
use strict;
require "CGI.pl";
use vars %::COOKIE, %::FILENAME;
sub Punt {
my ($str) = (@_);
print "<CENTER>$str<P>Please hit <b>Back</b> and try again.</CENTER>\n";
exit;
}
confirm_login();
my $id = $::FORM{'id'};
print "Content-type: text/html\n\n";
PutHeader("Create an attachment", "Create attachment", "Bug $id");
if (!defined($::FORM{'data'})) {
print qq{
<TABLE ALIGN=center><TR><TD ALIGN=left>
<FORM METHOD=post ENCTYPE="multipart/form-data">
<INPUT TYPE=hidden NAME=id value=$id>
To attach a file to <A HREF="show_bug.cgi?id=$id">bug $id</A>, place it in a
file on your local machine, and enter the path to that file here:<BR>
<INPUT TYPE=file NAME=data SIZE=60>
<P>
Please also provide a one-line description of this attachment:<BR>
<INPUT NAME=description SIZE=60>
<BR>
What kind of file is this?
<BR><INPUT TYPE=radio NAME=type VALUE=patch>Patch file (text/plain, diffs)
<BR><INPUT TYPE=radio NAME=type VALUE="text/plain">Plain text (text/plain)
<BR><INPUT TYPE=radio NAME=type VALUE="text/html">HTML source (text/html)
<BR><INPUT TYPE=radio NAME=type VALUE="image/gif">GIF Image (image/gif)
<BR><INPUT TYPE=radio NAME=type VALUE="image/jpeg">JPEG Image (image/jpeg)
<BR><INPUT TYPE=radio NAME=type VALUE="image/png">PNG Image (image/png)
<BR><INPUT TYPE=radio NAME=type VALUE="application/octet-stream">Binary file (application/octet-stream)
<BR><INPUT TYPE=radio NAME=type VALUE="other">Other (enter mime type: <INPUT NAME=othertype size=30>)
<P>
<CENTER><INPUT TYPE=submit VALUE="Submit"></CENTER>
</FORM>
</TD></TR></TABLE>
<P>
};
} else {
if ($::FORM{'data'} eq "" || !defined $::FILENAME{'data'}) {
Punt("No file was provided, or it was empty.");
}
my $desc = trim($::FORM{'description'});
if ($desc eq "") {
Punt("You must provide a description of your attachment.");
}
my $ispatch = 0;
my $mimetype = $::FORM{'type'};
if (!defined $mimetype) {
Punt("You must select which kind of file you have.");
}
$mimetype = trim($mimetype);
if ($mimetype eq "patch") {
$mimetype = "text/plain";
$ispatch = 1;
}
if ($mimetype eq "other") {
$mimetype = $::FORM{'othertype'};
}
if ($mimetype !~ m@^(\w|-)+/(\w|-)+$@) {
Punt("You must select a legal mime type. '<tt>$mimetype</tt>' simply will not do.");
}
if ($::driver eq "mysql") {
SendSQL("insert into attachments (bug_id, filename, description, mimetype, " .
"ispatch, submitter_id, thedata) values ($id," .
SqlQuote($::FILENAME{'data'}) . ", " . SqlQuote($desc) . ", " .
SqlQuote($mimetype) . ", $ispatch, " .
DBNameToIdAndCheck($::COOKIE{'Bugzilla_login'}) . ", " .
SqlQuote($::FORM{'data'}) . ")");
SendSQL("select LAST_INSERT_ID()");
} else {
# all this is necessary to allow inserting large fields into Oracle
use DBD::Oracle qw{:ora_types};
my $query = "insert into attachments (attach_id, bug_id, filename, description, mimetype, " .
"ispatch, submitter_id, creation_ts, thedata) values (attachments_seq.nextval, $id," .
SqlQuote($::FILENAME{'data'}) . ", " . SqlQuote($desc) . ", " .
SqlQuote($mimetype) . ", $ispatch, " .
DBNameToIdAndCheck($::COOKIE{'Bugzilla_login'}) . ", sysdate, :1)";
my $oracle_sth = $::db->prepare($query);
$oracle_sth->bind_param(1, $::FORM{'data'}, { ora_field => 'thedata', ora_type => ORA_BLOB });
$oracle_sth->execute || die "$query: " . $DBI::errstr;
# get the attach_id we just created
SendSQL("select attachments_seq.currval from dual");
}
my $attachid = FetchOneColumn();
AppendComment($id, $::COOKIE{"Bugzilla_login"},
"Created an attachment (id=$attachid)\n$desc\n");
print "<TABLE BORDER=1 CELLSPACING=0 ALIGN=center><TD><H2>Attachment to bug $id created</H2>\n";
system("./processmail", $id, $::COOKIE{'Bugzilla_login'});
print "<TD><A HREF=\"show_bug.cgi?id=$id\">Go Back to BUG# $id</A></TABLE>\n";
}
PutFooter();

View File

@@ -1,882 +0,0 @@
#!/usr/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public License
# Version 1.0 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are Copyright (C) 1998
# Netscape Communications Corporation. All Rights Reserved.
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
# David Lawrence <dkl@redhat.com>
use diagnostics;
use strict;
use XML::Generator;
use XML::Parser;
use CGI::XMLForm;
use Net::FTP;
require 'CGI.pl';
require 'globals.pl';
############### Global variables and other stuff
use vars qw{$cgi};
my $xml_dir = '/home/httpd/html/bugzilla/data/errata_xml/';
# HACK: This should be done automatically
my @final_releases = ('4.2', '5.2', '6.1');
# update server information
my $server = "wallace.redhat.com";
my $login = "anonymous";
my $password = "bugzilla\@redhat.com";
my $tmp_dir = "/tmp/errata";
# todays date
my ($day, $mon, $year) = (localtime)[3,4,5];
$year = $year+1900;
$mon = $mon+1;
umask 0000;
############### Start Security
confirm_login();
if (!UserInGroup("errata")) {
print "<P><FONT COLOR=red><B>Sorry: </B></FONT>\n";
print "<B>You are not a member of the 'Errata' group.</B>\n";
exit;
}
############### End Security
GetVersionTable();
############### Start XML/HTML subroutines
################################################################################
#
# Subroutine: gen_xml
#
# Description: Creates a xml file with errata information contained within
#
# Exceptions: NONE
#
# Parameters:
#
# Return Value: exits upon successful completetion
sub gen_xml {
my $update = $cgi->param('update');
$cgi->delete('update');
$cgi->delete('action');
my $filename = $cgi->param("/errata/metadata/id") . ".xml";
open(OUT, ">$xml_dir/$filename") or die "Could not open $filename for writing: $!";
if ($cgi->param()) {
print OUT $cgi->toXML;
}
close(OUT);
print "<A HREF=\"createerrata.cgi?load_file=$filename&action=Update+Errata&update=1\">$filename</A> saved!<P>\n";
insert_db($cgi->param('/errata/metadata/type'),
$cgi->param('/errata/metadata/issued_on'),
$cgi->param('/errata/metadata/updated_on'),
$cgi->param('/errata/metadata/id'));
}
################################################################################
#
# Subroutine: load_xml
#
# Description: load in xml file for editing and resubmitting
#
# Exceptions: NONE
#
# Parameters: advisory string
#
# Return Value: NONE
sub load_xml {
my $filename = $::FORM{'load_file'};
my %form_vars = ("/errata/metadata/type" => "type",
"/errata/metadata/issued_on" => "issued_on",
"/errata/metadata/updated_on" => "updated_on",
"/errata/metadata/id" => "advisory_id",
"/errata/metadata/component" => "component",
"/errata/metadata/synopsis" => "synopsis",
"/errata/metadata/keywords" => "keywords",
"/errata/metadata/cross_ref" => "cross_ref",
"/errata/content/obsoleted" => "obsoleted",
"/errata/content/conflicts" => "conflicts",
"/errata/content/topic" => "topic",
"/errata/content/description" => "description",
"/errata/content/solution" => "solution",
"/errata/content/id_fixed" => "id_fixed",
"/errata/content/references" => "references",
"/errata/content/release_arch" => "release_arch",
"/errata/content/rpms" => "packages" );
my @queries = keys %form_vars;
####
# foreach my $query (@queries) {
# print "$query <BR>\n";
# }
# print "<P>\n";
open(inXML, "<$xml_dir/$filename") or die "Could not open $filename for reading: $!";
my @results = $cgi->readXML(*inXML, @queries);
close(inXML);
####
# foreach my $result (@results) {
# print "$result <BR>\n";
# }
# print "<P>\n";
my %hash;
my $count = 0;
while($count <= $#results) {
my $temp = $results[$count];
$count = $count + 1;
$hash{$temp} = $results[$count];
$count = $count + 1;
}
foreach my $k (keys %hash) {
if (!defined($hash{$k})) {
next;
}
$::FORM{$form_vars{$k}} = $hash{$k};
}
# make updated_on today's date
$::FORM{'updated_on'} = sprintf("%s-%s-%s", $year, $mon, $day);
# fix the advisory_id
my @temp = split(':', $::FORM{'advisory_id'});
$::FORM{'advisory_id'} = $temp[1];
# if ($::FORM{'update'} eq "1") {
# @temp = split('-', $::FORM{'advisory_id'});
# $temp[1] = sprintf("%.2d", $temp[1]+1);
# $::FORM{'advisory_id'} = "$temp[0]-$temp[1]";
# }
# fix the release and arch form stuff
my @form_items;
foreach my $form (split ("\n", $::FORM{'release_arch'})) {
my @form_items = split (' ', $form);
$::FORM{"rel_arch-$form_items[0]-$form_items[1]"} = "$form_items[0]-$form_items[1]";
}
####
# foreach my $i (keys %::FORM) {
# print "$i = $::FORM{$i}<BR>\n";
# }
# call form generation and exit
gen_form();
PutFooter();
exit;
}
################################################################################
#
# Subroutine: insert_db
#
# Description: insert new errata identifier into the database
#
# Exceptions: NONE
#
# Parameters: global advisory string parameters
#
# Return Value:
sub insert_db {
my $type = shift;
my $issue = shift;
my $updated = shift;
my $id = shift;
my ($next_id, $rev) = ("", "");
my @temp;
if ($type eq "Security Advisory") {
$type = 'RHSA';
}
if ($type eq "Bug Fix Advisory") {
$type = 'RHBA';
}
if ($type eq "Product Enhancement Advisory") {
$type = 'RHEA';
}
@temp = split(':', $id);
($next_id, $rev) = split('-', $temp[1]);
my $query ="";
if ($::FORM{'update'} eq "1") {
$query = "update errata set revision = $rev" .
", updated_on = " . SqlQuote($updated) .
" where id = $next_id";
} else {
$query = "insert into errata (id, revision, issue_date, type) " .
" values ($next_id, $rev, " . SqlQuote($issue) .
", " . SqlQuote($type) . ")";
}
SendSQL($query);
print "Database updated.\n";
}
################################################################################
#
# Subroutine: gen_advisory_string
#
# Description: Generate an unique advisory identifier
#
# Exceptions: NONE
#
# Parameters:
#
# Return Value: Returns an unique advisory identifier string
sub gen_advisory_string {
if ($::FORM{'type'} eq "Security Advisory") {
return "RHSA-$year:" . $::FORM{'advisory_id'};
}
if ($::FORM{'type'} eq "Bug Fix Advisory") {
return "RHBA-$year:" . $::FORM{'advisory_id'};
}
if ($::FORM{'type'} eq "Product Enhancement Advisory") {
return "RHEA-$year:" . $::FORM{'advisory_id'};
}
}
################################################################################
#
# Subroutine: gen_preview
#
# Description: Generate a formatted view of how the Errata will look.
#
# Exceptions: NONE
#
# Parameters:
#
# Return Value:
sub gen_preview {
check_form();
# if we are updating then increment the advisory id
if ($::FORM{'update'} eq "1") {
my @temp = split('-', $::FORM{'advisory_id'});
$temp[0] = sprintf("%.3d", $temp[0]);
$temp[1] = sprintf("%.2d", $temp[1]+1);
$::FORM{'advisory_id'} = "$temp[0]-$temp[1]";
}
my $advisory = gen_advisory_string();
print qq{
<P>
<TABLE WIDTH=800 BORDER=1 CELLPADDING=3 CELLSPACING=0>
<TR BGCOLOR="#ECECEC">
<TD>
<PRE>
---------------------------------------------------------------------
Red Hat, Inc. $::FORM{'type'}
Synopsis: $::FORM{'synopsis'}
Advisory ID: $advisory
Issue date: $::FORM{'issued_on'}
Updated on: $::FORM{'updated_on'}
Keywords: $::FORM{'keywords'}
Cross references: $::FORM{'cross_ref'}
---------------------------------------------------------------------
1. Topic:
$::FORM{'topic'}
2. Relevant releases/architectures:
};
my %rel_arch;
foreach my $rel (grep(/^rel_arch-.*$/, keys %::FORM)) {
$rel =~ s/^rel_arch-//g;
my @temp = split('-', $rel);
push (@{$rel_arch{$temp[0]}}, $temp[1]);
}
foreach my $line (sort(keys %rel_arch)) {
my @reverse = reverse @{$rel_arch{$line}};
@{$rel_arch{$line}} = @reverse;
print "Red Hat Linux " . int($line) . ".x - @{$rel_arch{$line}}\n";
}
print qq{
3. Problem description:
$::FORM{'description'}
4. Solution:
$::FORM{'solution'}
5. Bug IDs fixed (http://bugzilla.redhat.com/bugzilla for more info):
};
# Generate summarys for each of the bugs listed
foreach my $bug (split(' ', $::FORM{'id_fixed'})) {
SendSQL("select short_desc from bugs where bug_id = $bug");
while(my $desc = FetchOneColumn()) {
print "$bug - $desc\n";
}
}
print qq{
6. Obsoleted by:
$::FORM{'obsoleted'}
7. Conflicts with:
$::FORM{'conflicts'}
8. RPMs required:
};
# Generate rpms lists based on release-arch info and rpm names
my @full_paths;
my @releases = keys (%rel_arch);
foreach my $release (sort(@releases)) {
print "\nRed Hat Linux " . int($release) . ".x:\n";
my @rpms;
my @names;
foreach my $line (split ('\n', $::FORM{'packages'})) {
chomp($line);
$line =~ s/\s+//g;
if ($line eq "") {
next;
}
push (@names, $line);
}
foreach my $arch (@{$rel_arch{$release}}) {
print "\n$arch:\n";
foreach my $name (sort(@names)) {
my $full_path = "ftp://ftp.redhat.com/redhat/updates/$release/$arch/$name.$arch.rpm";
print "$full_path\n";
push (@full_paths, $full_path);
}
}
print "\nSRPMS:\n";
foreach my $name (@names) {
my $full_path = "ftp://ftp.redhat.com/redhat/updates/$release/SRPMS/$name.src.rpm";
print "$full_path\n";
push (@full_paths, );
}
}
print qq{
9. Verification:
MD5 sum Package Name
--------------------------------------------------------------------------
};
# This will eventually print md5sums automatically
my $md5sum = gen_md5sum(\@full_paths);
print $md5sum;
print qq{
These packages are GPG signed by Red Hat, Inc. for security. Our key
is available at:
http://www.redhat.com/corp/contact.html
You can verify each package with the following command:
rpm --checksig <filename>
If you only wish to verify that each package has not been corrupted or
tampered with, examine only the md5sum with the following command:
rpm --checksig --nogpg <filename>
10. References:
$::FORM{'references'}
</PRE>
</TD>
</TR>
</TABLE>
};
####################### XML Stuff #########################
# resend all the form elements formatted for xml creation #
print $cgi->startform(-METHOD=>"GET"),
$cgi->hidden(-NAME=>"/errata/metadata/type", -VALUE=>$::FORM{'type'}),
$cgi->hidden(-NAME=>"/errata/metadata/component", -VALUE=>$::FORM{'component'}),
$cgi->hidden(-NAME=>"/errata/metadata/issued_on", -VALUE=>$::FORM{'issued_on'}),
$cgi->hidden(-NAME=>"/errata/metadata/updated_on", -VALUE=>$::FORM{'updated_on'}),
$cgi->hidden(-NAME=>"/errata/metadata/id", -VALUE=>$advisory),
$cgi->hidden(-NAME=>"/errata/metadata/synopsis", -VALUE=>$::FORM{'synopsis'}),
$cgi->hidden(-NAME=>"/errata/metadata/keywords", -VALUE=>$::FORM{'keywords'}),
$cgi->hidden(-NAME=>"/errata/metadata/cross_ref", -VALUE=>$::FORM{'cross_ref'}),
$cgi->hidden(-NAME=>"/errata/content/id_fixed", -VALUE=>$::FORM{'id_fixed'}),
$cgi->hidden(-NAME=>"/errata/content/obsoleted", -VALUE=>$::FORM{'obsoleted'}),
$cgi->hidden(-NAME=>"/errata/content/conflicts", -VALUE=>$::FORM{'conflicts'}),
$cgi->hidden(-NAME=>"/errata/content/topic", -VALUE=>$::FORM{'topic'}),
$cgi->hidden(-NAME=>"/errata/content/solution", -VALUE=>$::FORM{'solution'}),
$cgi->hidden(-NAME=>"/errata/content/description", -VALUE=>$::FORM{'description'}),
$cgi->hidden(-NAME=>"/errata/content/references", -VALUE=>$::FORM{'references'});
# Release per architecture information
my $rel_arch_string;
foreach my $line (sort(keys %rel_arch)) {
foreach my $arch (@{$rel_arch{$line}}) {
$rel_arch_string .= "$line $arch\n";
}
}
print $cgi->hidden(-NAME=>"/errata/content/release_arch", -VALUE=>$rel_arch_string);
# If this is an update then pass it along
if ($::FORM{'update'}) {
print $cgi->hidden(-NAME=>'update', -VALUE=>'1');
}
print $cgi->hidden(-NAME=>"/errata/content/rpms", -VALUE=>$::FORM{'packages'}),
$cgi->submit(-NAME=>'action', -VALUE=>'Generate Errata'), "&nbsp;",
$cgi->a({-HREF=>'createerrata.cgi?action=New+Errata'}, "[Start Over]"),
$cgi->endform();
# #
##################### End XML Stuff #######################
}
################################################################################
#
# Subroutine: gen_form
#
# Description: Generate the form for entering in additional errata information
#
# Exceptions: None
#
# Parameters: None
#
# Return Value: None
sub gen_form {
# lets set some sane defaults
if (!$::FORM{'type'}) {
$::FORM{'type'} = "Security Advisory";
}
print qq{
<FORM METHOD="GET" ACTION="createerrata.cgi">
<!-- Begin Meta Data -->
<TABLE WIDTH=800 CELLPADDING=3 CELLSPACING=0 BORDER=1>
<TR BGCOLOR="#BFBFBF">
<TH ALIGN=left><B>Meta Data</B></TH>
</TR><TR BGCOLOR="#ECECEC">
<TD ALIGN=left>
<TABLE WIDTH="100%" BORDER=0 CELLSPACING=0 CELLPADDING=3>
<TR>
<TD ALIGN=right><B>Errata Type</B></TD>
<TD ALIGN=left>
};
foreach my $i ("Security Advisory", "Bug Fix Advisory", "Product Enhancement Advisory") {
if ($::FORM{'type'} eq $i) {
print qq{\t\t<INPUT TYPE="radio" NAME="type" VALUE="$i" CHECKED>$i<BR>\n};
} else {
print qq{\t\t<INPUT TYPE="radio" NAME="type" VALUE="$i">$i<BR>\n};
}
}
print qq{
</TD>
<TD ALIGN=right><B>Advisory&nbsp;ID</B></TD>
<TD ALIGN=left><INPUT TYPE="text" NAME="advisory_id" VALUE="$::FORM{'advisory_id'}" SIZE=20 MAXLENGTH=20><BR>
(Incremented automatically for updates)</TD>
</TR><TR>
<TD ALIGN=right><B>Synopsis</B></TD>
<TD ALIGN=left COLSPAN="3">
<INPUT TYPE="text" NAME="synopsis" VALUE="$::FORM{'synopsis'}" SIZE=60 MAXLENGTH=78>
</TD>
</TR><TR>
<TD ALIGN=right><B>Issue date</B></TD>
<TD ALIGN=left>
<INPUT TYPE="text" NAME="issued_on" VALUE="$::FORM{'issued_on'}" SIZE=15 MAXLENGTH=15>
</TD>
<TD ALIGN=right><B>Updated On</B></TD>
<TD ALIGN=left>
<INPUT TYPE="text" NAME="updated_on" VALUE="$::FORM{'updated_on'}" SIZE=15 MAXLENGTH=15>
</TD>
</TR><tr>
<TD ALIGN=right><B>Keywords</B></TD>
<TD ALIGN=left COLSPAN="3"><INPUT TYPE="text" NAME="keywords" VALUE="$::FORM{'keywords'}" SIZE=60 MAXLENGTH=78></TD>
</TR><TR>
<TD ALIGN=right><B>Cross References</B></TD>
<TD ALIGN=left COLSPAN="3"><INPUT TYPE="text" NAME="cross_ref" VALUE="$::FORM{'cross_ref'}" SIZE=60 MAXLENGTH=78></TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<P>
<!-- Begin Content Data -->
<TABLE WIDTH=800 CELLPADDING=3 CELLSPACING=0 BORDER=1>
<TR BGCOLOR="#BFBFBF">
<TH ALIGN=left><B>Content Data</B></TH>
</TR><TR BGCOLOR="#ECECEC">
<TD ALIGN=left>
<TABLE WIDTH="100%" CELLSPACING=0 CELLPADDING=3>
<TR>
<TD ALIGN=right><B>Topic</B></TD>
<TD ALIGN=left COLSPAN=3>
<TEXTAREA NAME="topic" ROWS=10 COLS=70 WRAP=hard>$::FORM{'topic'}</TEXTAREA>
</TD>
</TR><TR>
<TD ALIGN=right><B>Bug IDs fixed</B></TD>
<TD ALIGN=left COLSPAN="3"><INPUT TYPE="text" NAME="id_fixed" VALUE="$::FORM{'id_fixed'}" SIZE=60></TD>
</TR><TR>
<TD ALIGN=right><B>Releases</B></TD>
<TD ALIGN=left>
<TABLE BORDER=0 CELLPADDING=3 CELLSPACING=2>
<TR>
<TH></TH>
<TH ALIGN=center COLSPAN=4>Architectures</TH>
</TR><TR>
<TD ALIGN=center></TD>
<TD ALIGN=center>i386</TD>
<TD ALIGN=center>Alpha</TD><TD ALIGN=center>Sparc</TD>
</TR>
};
foreach my $i (@final_releases) {
if ($i eq "src") { next; }
print "\t\t<TR>\n\t\t\t<TD ALIGN=center WIDTH=30>$i</TD>\n\t\t\t";
foreach my $j (@::legal_platform) {
if ($j eq "All") { next; }
print "<TD ALIGN=center WIDTH=30>";
if ($::FORM{"release-$i"} and $::FORM{"rep_platform-$j"}) {
print qq{<INPUT TYPE="checkbox" NAME="rel_arch-$i-$j" VALUE="$i-$j" CHECKED>};
} elsif ($::FORM{"rel_arch-$i-$j"}) {
print qq{<INPUT TYPE="checkbox" NAME="rel_arch-$i-$j" VALUE="$i-$j" CHECKED>};
} else {
print qq{<INPUT TYPE="checkbox" NAME="rel_arch-$i-$j" VALUE="$i-$j">};
}
print "</TD>\n";
}
print "</TR>\n";
}
print qq{
</TABLE>
</TD>
};
print qq{
</TR><TR>
<TD ALIGN=right><B>Obsoleted&nbsp;by</B></TD>
<TD ALIGN=left><INPUT TYPE="text" NAME="obsoleted" SIZE=24 MAXSIZE=40 VALUE="$::FORM{'obsoleted'}"></TD>
<TD ALIGN=right><B>Conflicts&nbsp;with</B></TD>
<TD ALIGN=left><INPUT TYPE="text" NAME="conflicts" SIZE=24 MAXSIZE=40 VALUE="$::FORM{'conflicts'}"></TD>
</TR><TR>
<TD ALIGN=right><B>Problem Description</B></TD>
<TD ALIGN=left COLSPAN=3>
<TEXTAREA NAME="description" ROWS=10 COLS=70 WRAP=hard>$::FORM{'description'}</TEXTAREA>
</TD>
</TR><TR>
<TD ALIGN=right><B>Solution</B></TD>
<TD ALIGN=left COLSPAN=3>
<TEXTAREA NAME="solution" ROWS=10 COLS=70 WRAP=hard>$::FORM{'solution'}
</TEXTAREA>
</TD>
</TR><TR>
<TD ALIGN=right><B>Name-Version-Rev</B><BR>(package links get<BR>automatically generated)</TD>
<TD ALIGN=left COLSPAN=3>
<TEXTAREA NAME="packages" ROWS=10 COLS=70 WRAP=hard>$::FORM{'packages'}</TEXTAREA>
</TD>
</TR><TR>
<TD ALIGN=right><B>References</B></TD>
<TD ALIGN=left COLSPAN=3>
<TEXTAREA NAME="references" ROWS=10 COLS=70 WRAP=hard>$::FORM{'references'}</TEXTAREA>
</TABLE>
</TD>
</TR>
</TABLE>
<P>
<TABLE>
<TR>
<TD><B><INPUT TYPE="submit" NAME=action VALUE="Preview Errata"></B></TD>
<TD><B><INPUT TYPE="submit" NAME=action VALUE="Past Errata"></B></TD>
</TR>
</TABLE>
};
if($::FORM{'update'}) {
print qq{<INPUT TYPE=hidden NAME=update VALUE=1>};
}
print qq{
</FORM>
};
}
################################################################################
#
# Subroutine: gen_list
#
# Description: Generate a link to past errata and link them for loading
#
# Exceptions: None
#
# Parameters: None
#
# Return Value: None
sub gen_list {
print qq{
<P>
(Click to edit or view old errata announcement)
<TABLE CELLPADDING=3 CELLSPACING=0 BORDER=1 WIDTH=600>
<TR BGCOLOR="#BFBFBF">
<TH ALIGN=left>Full Name</TH>
<TH ALIGN=left>ID/Rev</TH>
<TH ALIGN=left>Errata Type</TH>
<TH ALIGN=left>Issue Date</TH>
<TH ALIGN=left>Updated On</TH>
</TR>
};
my @row;
SendSQL("select * from errata");
while (@row = FetchSQLData()) {
my $id = sprintf("%.3d", $row[0]);
my $rev = sprintf("%.2d", $row[1]);
my $errata_type = $row[2];
my $date = $row[3];
my ($year, $mon, $day) = ($date =~ /(\d+)-(\d+)-(\d+)/);
print "<TR BGCOLOR=\"#ECECEC\">\n";
print "<TD ALIGN=left><A HREF=\"createerrata.cgi?action=Update+Errata&update=1&load_file=$errata_type-$year:$id-$rev.xml\">";
print "$errata_type-$year:$id-$rev</A></TD>\n";
print "<TD ALIGN=left>$id-$rev</TD>\n";
print "<TD ALIGN=left>";
if ($errata_type eq "RHSA") {
print "Security Advisory";
} elsif ($errata_type eq "RHBA") {
print "Bug Fix Advisory";
} elsif ($errata_type eq "RHEA") {
print "Product Enhancement Advisory";
}
print "</TD>\n";
print "<TD ALIGN=left>$date</TD>\n";
print "<TD ALIGN=left>$row[4]&nbsp;</TD>\n";
print "</TD>\n";
}
print qq{
</TABLE>
};
}
################################################################################
#
# Subroutine: check_form
#
# Description: sanity checking of some form variables
#
# Exceptions: None
#
# Parameters: None
#
# Return Value: None
sub check_form {
# A little sanity checking
# Advisory ID #
if ($::FORM{'advisory_id'} =~ /\s/) {
print "Advisory ID can not contain spaces!";
exit;
}
# Issue Date #
if ($::FORM{'issued_on'} !~ m/\d{4}-\d{1,2}-\d{1,2}/) {
print "Issue Date must be in the form YYYY-MM-DD!";
exit;
}
# Updated On #
if ($::FORM{'update'} eq "1") {
if ($::FORM{'updated_on'} !~ m/\d{4}-\d{1,2}-\d{1,2}/) {
print "Updated Date must be in the form YYYY-MM-DD!";
exit;
}
}
# Packages #
# if ($::FORM{'packages'} !~ m!\S+\s+[^-\s]+-[^-\s]+-\S+!) {
# print "Package entries must match 'RHL N-R-V md5sum'!";
# exit;
# }
# Topic #
if ($::FORM{'topic'} eq "") {
$::FORM{'topic'} = "N-A";
}
# Synopsis #
if ($::FORM{'synopsis'} eq "") {
$::FORM{'synopsis'} = "N-A";
}
# Cross references #
if ($::FORM{'cross_ref'} eq "") {
$::FORM{'cross_ref'} = "N-A";
}
# Keywords #
if ($::FORM{'keywords'} eq "") {
$::FORM{'keywords'} = "N-A";
}
# Description #
if ($::FORM{'description'} eq "") {
$::FORM{'description'} = "N-A";
}
# Obsoleted by #
if ($::FORM{'obsoleted'} eq "") {
$::FORM{'obsoleted'} = "N-A";
}
# Conflicts with #
if ($::FORM{'conflicts'} eq "") {
$::FORM{'conflicts'} = "N-A";
}
# References #
if ($::FORM{'references'} eq "") {
$::FORM{'references'} = "N-A";
}
}
################################################################################
#
# Subroutine: check_form
#
# Description: sanity checking of some form variables
#
# Exceptions: None
#
# Parameters: None
#
# Return Value: None
sub gen_md5sum {
my @full_paths = @{ shift; };
my $md5sums;
my $local;
# if (! -d $tmp_dir) {
# mkdir($tmp_dir);
# }
my $ftp = new Net::FTP($server);
$ftp->login($login, $password);
$ftp->binary;
foreach my $path (@full_paths) {
$path =~ s/ftp:\/\/ftp.redhat.com\///g;
$local = rindex($path, '/');
$local = substr($path, $local+1);
my $result = $ftp->get($path, "$tmp_dir/$local");
if ($result) {
$md5sums .= "*insert md5sum here* $path \n";
} else {
$md5sums .= "*insert md5sum here* $path \n";
}
}
# foreach my $foo (@full_paths) {
# $foo =~ s/ftp:\/\/ftp.redhat.com\/redhat/updates\///g;
# $md5sums .= "*insert md5sum here* $foo\n";
# }
$ftp->quit;
return $md5sums;
}
############## Start Main
print "Content-type: text/html\n\n";
$cgi = new CGI::XMLForm;
# Uncomment the next line for debugging purposes
# print $cgi->dump;
if ($::FORM{'action'} eq "Generate Errata") {
PutHeader("Generate Errata");
$cgi->delete('action');
gen_xml();
} elsif ($::FORM{'action'} eq "Preview Errata") {
PutHeader("Preview Errata");
delete $::FORM{'action'};
gen_preview();
} elsif ($::FORM{'action'} eq "Past Errata") {
PutHeader("Past Errata");
gen_list();
} elsif ($::FORM{'action'} eq "Update Errata") {
PutHeader("Update Errata");
delete $::FORM{'action'};
load_xml();
gen_form();
} elsif ($::FORM{'action'} eq "New Errata") {
PutHeader("New Errata");
delete $::FORM{'action'};
# select the next id information from database
SendSQL("select max(id) from errata");
my $next_id = FetchOneColumn() + 1;
my $rev = 1;
$next_id = sprintf("%.3d", $next_id);
$rev = sprintf("%.2d", $rev);
$::FORM{'advisory_id'} = "$next_id-$rev";
# issue date for new errata's is todays date
$::FORM{'issued_on'} = sprintf("%s-%s-%s", $year, $mon, $day);
$::FORM{'updated_on'} = sprintf("%s-%s-%s", $year, $mon, $day);
gen_form();
} else {
PutHeader("Illegal Errata Action");
}
PutFooter();
exit;
############### End Main

View File

@@ -1,592 +0,0 @@
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
# Dawn Endico <endico@mozilla.org>
# Dan Mosedale <dmose@mozilla.org>
# Joe Robins <jmrobins@tgix.com>
# David Lawrence <dkl@redhat.com>
# This file defines all the parameters that we have a GUI to edit within
# Bugzilla.
use diagnostics;
use strict;
# Shut up misguided -w warnings about "used only once". For some reason,
# "use vars" chokes on me when I try it here.
sub bug_form_pl_sillyness {
my $zz;
$zz = %::param_checker;
$zz = %::param_desc;
$zz = %::param_type;
}
sub WriteParams {
foreach my $i (@::param_list) {
if (!defined $::param{$i}) {
$::param{$i} = $::param_default{$i};
if (!defined $::param{$i}) {
die "No default parameter ever specified for $i";
}
}
}
mkdir("data", 0777);
chmod 0777, "data";
my $tmpname = "data/params.$$";
open(FID, ">$tmpname") || die "Can't create $tmpname";
my $v = $::param{'version'};
delete $::param{'version'}; # Don't write the version number out to
# the params file.
print FID GenerateCode('%::param');
$::param{'version'} = $v;
print FID "1;\n";
close FID;
rename $tmpname, "data/params" || die "Can't rename $tmpname to data/params";
chmod 0666, "data/params";
}
sub DefParam {
my ($id, $desc, $type, $default, $checker) = (@_);
push @::param_list, $id;
$::param_desc{$id} = $desc;
$::param_type{$id} = $type;
$::param_default{$id} = $default;
if (defined $checker) {
$::param_checker{$id} = $checker;
}
}
sub check_numeric {
my ($value) = (@_);
if ($value !~ /^[0-9]+$/) {
return "must be a numeric value";
}
return "";
}
sub check_shadowdb {
my ($value) = (@_);
$value = trim($value);
if ($value eq "") {
return "";
}
SendSQL("SHOW DATABASES");
while (MoreSQLData()) {
my $n = FetchOneColumn();
if (lc($n) eq lc($value)) {
return "The $n database already exists. If that's really the name you want to use for the backup, please CAREFULLY make the existing database go away somehow, and then try again.";
}
}
SendSQL("CREATE DATABASE $value");
SendSQL("INSERT INTO shadowlog (command) VALUES ('SYNCUP')", 1);
return "";
}
@::param_list = ();
# OK, here are the definitions themselves.
#
# The type of parameters (the third parameter to DefParam) can be one
# of the following:
#
# t -- A short text entry field (suitable for a single line)
# l -- A long text field (suitable for many lines)
# b -- A boolean value (either 1 or 0)
# i -- An integer.
# defenum -- This param defines an enum that defines a column in one of
# the database tables. The name of the parameter is of the form
# "tablename.columnname".
DefParam("contract",
"Contract support (Red Hat)",
"b",
1);
DefParam("templatepath",
"The path to your html template files",
"t",
"templates");
DefParam("maintainer",
"The email address of the person who maintains this installation of Bugzilla.",
"t",
'THE MAINTAINER HAS NOT YET BEEN SET');
DefParam("urlbase",
"The URL that is the common initial leading part of all Bugzilla URLs.",
"t",
"http://bugzilla.redhat.com/bugzilla/",
\&check_urlbase);
sub check_urlbase {
my ($url) = (@_);
if ($url !~ m:^http.*/$:) {
return "must be a legal URL, that starts with http and ends with a slash.";
}
return "";
}
DefParam("preferlists",
"If this is on, Bugzilla will display most selection options as selection lists. If this is off, Bugzilla will use radio buttons and checkboxes instead.",
"b",
1);
DefParam("prettyasciimail",
"If this is on, Bugzilla will send email reports formatted (assuming 76 character monospace font display). If this is off, email reports are sent using the old 'one-item-per-line' format.",
"b",
0);
DefParam("capitalizelists",
"If this is on, Bugzilla will capitalize list entries, checkboxes, and radio buttons. If this is off, Bugzilla will leave these items untouched.",
"b",
0);
DefParam("usequip",
"If this is on, Bugzilla displays a silly quip at the beginning of buglists, and lets users add to the list of quips.",
"b",
1);
# Added parameter - JMR, 2/16/00
DefParam("usebuggroups",
"If this is on, Bugzilla will associate a bug group with each product in the database, and use it for querying bugs.",
"b",
0);
# Added parameter - JMR, 2/16/00
DefParam("usebuggroupsentry",
"If this is on, Bugzilla will use product bug groups to restrict who can enter bugs. Requires usebuggroups to be on as well.",
"b",
0);
DefParam("shadowdb",
"If non-empty, then this is the name of another database in which Bugzilla will keep a shadow read-only copy of everything. This is done so that long slow read-only operations can be used against this db, and not lock up things for everyone else. Turning on this parameter will create the given database; be careful not to use the name of an existing database with useful data in it!",
"t",
"",
\&check_shadowdb);
DefParam("queryagainstshadowdb",
"If this is on, and the shadowdb is set, then queries will happen against the shadow database.",
"b",
0);
DefParam("usedespot",
"If this is on, then we are using the Despot system to control our database of users. Bugzilla won't ever write into the user database, it will let the Despot code maintain that. And Bugzilla will send the user over to Despot URLs if they need to change their password. Also, in that case, Bugzilla will treat the passwords stored in the database as being crypt'd, not plaintext.",
"b",
0);
DefParam("despotbaseurl",
"The base URL for despot. Used only if <b>usedespot</b> is turned on, above.",
"t",
"http://cvs-mirror.mozilla.org/webtools/despot/despot.cgi",
\&check_despotbaseurl);
sub check_despotbaseurl {
my ($url) = (@_);
if ($url !~ /^http.*cgi$/) {
return "must be a legal URL, that starts with http and ends with .cgi";
}
return "";
}
DefParam("headerhtml",
"Additional HTML to add to the HEAD area of documents, eg. links to stylesheets.",
"l",
'');
DefParam("footerhtml",
"HTML to add to the bottom of every page. By default it displays the blurbhtml, and %commandmenu%, a menu of useful commands. You probably really want either headerhtml or footerhtml to include %commandmenu%.",
"l",
'<TABLE BORDER="0"><TR><TD BGCOLOR="#000000" VALIGN="TOP">
<TABLE BORDER="0" CELLPADDING="10" CELLSPACING="0" WIDTH="100%" BGCOLOR="lightyellow">
<TR><TD>
%blurbhtml%
<BR>
%commandmenu%
</TD></TR></TABLE></TD></TR></TABLE>');
DefParam("errorhtml",
"This is what is printed out when a form is improperly filled out. %errormsg% is replaced by the actual error itself; %<i>anythingelse</i>% gets replaced by the definition of that parameter (as defined on this page).",
"l",
qq{<TABLE CELLPADDING=20><TR><TD BGCOLOR="#ff0000">
<FONT SIZE="+2">%errormsg%</FONT></TD></TR></TABLE>
<P>Please press <B>Back</B> and try again.<P>});
DefParam("bannerhtml",
"The html that gets emitted at the head of every Bugzilla page.
Anything of the form %<i>word</i>% gets replaced by the defintion of that
word (as defined on this page).",
"l",
q{<TABLE BGCOLOR="#000000" WIDTH="100%" BORDER=0 CELLPADDING=0 CELLSPACING=0>
<TR><TD><A HREF="http://www.mozilla.org/"><IMG
SRC="http://www.mozilla.org/images/mozilla-banner.gif" ALT=""
BORDER=0 WIDTH=600 HEIGHT=58></A></TD></TR></TABLE>
<CENTER><FONT SIZE=-1>Bugzilla version %version%
</FONT></CENTER>});
DefParam("blurbhtml",
"A blurb that appears as part of the header of every Bugzilla page. This is a place to put brief warnings, pointers to one or two related pages, etc.",
"l",
"This is <B>Bugzilla</B>: the Mozilla bug system. For more
information about what Bugzilla is and what it can do, see
<A HREF=\"http://www.mozilla.org/\">mozilla.org</A>'s
<A HREF=\"http://www.mozilla.org/bugs/\"><B>bug pages</B></A>.");
DefParam("mybugstemplate",
"This is the URL to use to bring up a simple 'all of my bugs' list for a user. %userid% will get replaced with the login name of a user.",
"t",
"buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&email1=%userid%&emailtype1=exact&emailassigned_to1=1&emailreporter1=1");
DefParam("shutdownhtml",
"If this field is non-empty, then Bugzilla will be completely disabled and this text will be displayed instead of all the Bugzilla pages.",
"l",
"");
DefParam("passwordmail",
q{The email that gets sent to people to tell them their password. Within
this text, %mailaddress% gets replaced by the person's email address,
%login% gets replaced by the person's login (usually the same thing), and
%password% gets replaced by their password. %<i>anythingelse</i>% gets
replaced by the definition of that parameter (as defined on this page).},
"l",
q{From: bugzilla@redhat.com
To: %mailaddress%
X-loop: bugzilla@redhat.com
Subject: Your Bugzilla password.
To use the wonders of Bugzilla, you can use the following:
E-mail address: %login%
Password: %password%
To change your password, go to:
%urlbase%userprefs.cgi
});
DefParam("changedmail",
q{The email that gets sent to people when a bug changes. Within this
text, %to% gets replaced by the assigned-to and reported-by people,
separated by a comma (with duplication removed, if they're the same
person). %cc% gets replaced by the list of people on the CC list,
separated by commas. %bugid% gets replaced by the bug number.
%diffs% gets replaced by the diff text from the old version to the new
version of this bug. %neworchanged% is either "New" or "Changed",
depending on whether this mail is reporting a new bug or changes made
to an existing one. %summary% gets replaced by the summary of this
bug. %<i>anythingelse</i>% gets replaced by the definition of that
parameter (as defined on this page).},
"l",
"From: bugzilla\@redhat.com
To: %to%
X-loop: bugzilla\@redhat.com
Cc: %cc%
Subject: [Bug %bugid%] %neworchanged% - %summary%
%urlbase%show_bug.cgi?id=%bugid%
%diffs%");
DefParam("newemailtech",
q{There is now experimental code in Bugzilla to do the email diffs in a
new and exciting way. But this stuff is not very cooked yet. So, right
now, to use it, the maintainer has to turn on this checkbox, and each user
has to then turn on the "New email tech" preference.},
"b",
0);
DefParam("newchangedmail",
q{The same as 'changedmail', but used for the newemailtech stuff.},
"l",
"From: bugzilla\@redhat.com
To: %to%
Cc: %cc%
Subject: [Bug %bugid%] %neworchanged% - %summary%
%urlbase%show_bug.cgi?id=%bugid%
%diffs%");
DefParam("whinedays",
"The number of days that we'll let a bug sit untouched in a NEW state before our cronjob will whine at the owner.",
"t",
7,
\&check_numeric);
DefParam("whinemail",
"The email that gets sent to anyone who has a NEW bug that hasn't been touched for more than <b>whinedays</b>. Within this text, %email% gets replaced by the offender's email address. %userid% gets replaced by the offender's bugzilla login (which, in most installations, is the same as the email address.) %<i>anythingelse</i>% gets replaced by the definition of that parameter (as defined on this page).<p> It is a good idea to make sure this message has a valid From: address, so that if the mail bounces, a real person can know that there are bugs assigned to an invalid address.",
"l",
q{From: %maintainer%
To: %email%
Subject: Your Bugzilla buglist needs attention.
[This e-mail has been automatically generated.]
You have one or more bugs assigned to you in the Bugzilla
bugsystem (%urlbase%) that require
attention.
All of these bugs are in the NEW state, and have not been touched
in %whinedays% days or more. You need to take a look at them, and
decide on an initial action.
Generally, this means one of three things:
(1) You decide this bug is really quick to deal with (like, it's INVALID),
and so you get rid of it immediately.
(2) You decide the bug doesn't belong to you, and you reassign it to someone
else. (Hint: if you don't know who to reassign it to, make sure that
the Component field seems reasonable, and then use the "Reassign bug to
owner of selected component" option.)
(3) You decide the bug belongs to you, but you can't solve it this moment.
Just use the "Accept bug" command.
To get a list of all NEW bugs, you can use this URL (bookmark it if you like!):
%urlbase%buglist.cgi?bug_status=NEW&assigned_to=%userid%
Or, you can use the general query page, at
%urlbase%query.cgi.
Appended below are the individual URLs to get to all of your NEW bugs that
haven't been touched for a week or more.
You will get this message once a day until you've dealt with these bugs!
});
DefParam("defaultquery",
"This is the default query that initially comes up when you submit a bug. It's in URL parameter format, which makes it hard to read. Sorry!",
"t",
"bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&order=%22Importance%22");
DefParam("letsubmitterchoosepriority",
"If this is on, then people submitting bugs can choose an initial priority for that bug. If off, then all bugs initially have the default priority selected above.",
"b",
1);
sub check_priority {
my ($value) = (@_);
GetVersionTable();
if (lsearch(\@::legal_priority, $value) < 0) {
return "Must be a legal priority value: one of " .
join(", ", @::legal_priority);
}
return "";
}
DefParam("defaultpriority",
"This is the priority that newly entered bugs are set to.",
"t",
"normal",
\&check_priority);
DefParam("usetargetmilestone",
"Do you wish to use the Target Milestone field?",
"b",
0);
DefParam("nummilestones",
"If using Target Milestone, how many milestones do you wish to
appear?",
"t",
10,
\&check_numeric);
DefParam("curmilestone",
"If using Target Milestone, Which milestone are we working toward right now?",
"t",
1,
\&check_numeric);
DefParam("useqacontact",
"Do you wish to use the QA Contact field?",
"b",
0);
DefParam("usestatuswhiteboard",
"Do you wish to use the Status Whiteboard field?",
"b",
0);
DefParam("usebrowserinfo",
"Do you want bug reports to be assigned an OS & Platform based on the browser
the user makes the report from?",
"b",
0);
DefParam("usedependencies",
"Do you wish to use dependencies (allowing you to mark which bugs depend on which other ones)?",
"b",
1);
DefParam("webdotbase",
"This is the URL prefix that is common to all requests for webdot. The <a href=\"http://www.research.att.com/~north/cgi-bin/webdot.cgi\">webdot package</a> is a very swell thing that generates pictures of graphs. If you have an installation of bugsplat that hides behind a firewall, then to get graphs to work, you will have to install a copy of webdot behind your firewall, and change this path to match. Also, webdot has some trouble with software domain names, so you may have to play games and hack the %urlbase% part of this. If this all seems like too much trouble, you can set this paramater to be the empty string, which will cause the graphing feature to be disabled entirely.",
"t",
"http://www.research.att.com/~north/cgi-bin/webdot.cgi/%urlbase%");
DefParam("entryheaderhtml",
"This is a special header for the bug entry page. The text will be printed after the page header, before the bug entry form. It is meant to be a place to put pointers to intructions on how to enter bugs.",
"l",
'<A HREF="bugwritinghelp.html">Bug writing guidelines</A>');
DefParam("expectbigqueries",
"If this is on, then we will tell mysql to <tt>set option SQL_BIG_TABLES=1</tt> before doing queries on bugs. This will be a little slower, but one will not get the error <tt>The table ### is full</tt> for big queries that require a big temporary table.",
"b",
0);
DefParam("emailregexp",
'This defines the regexp to use for legal email addresses. The default tries to match fully qualified email addresses. Another popular value to put here is <tt>^[^@, ]*$</tt>, which means "local usernames, no @ allowed.',
"t",
q:^[^@, ]*@[^@, ]*\\.[^@, ]*$:);
DefParam("emailregexpdesc",
"This describes in english words what kinds of legal addresses are allowed by the <tt>emailregexp</tt> param.",
"l",
"A legal address must contain exactly one '\@', and at least one '.' after the \@, and may not contain any commas or spaces.");
DefParam("emailsuffix",
"This is a string to append to any email addresses when actually sending mail to that address. It is useful if you have changed the <tt>emailregexp</tt> param to only allow local usernames, but you want the mail to be delivered to username\@my.local.hostname.",
"t",
"");
DefParam("voteremovedmail",
q{This is a mail message to send to anyone who gets a vote removed from a bug for any reason. %to% gets replaced by a comma-separated list of people who used to be voting for this bug. %bugid% gets replaced by the bug number. %reason% gets replaced by a short reason describing why the vote was removed. %count% is how many votes got removed. %<i>anythingelse</i>% gets replaced by the definition of thatparameter (as defined on this page).},
"l",
"From: bugzilla\@redhat.com
To: %to%
X-loop: bugzilla\@redhat.com
Subject: [Bug %bugid%] Your vote has been removed from this bug
You used to have a vote on bug %bugid%, but it has been removed.
Reason: %reason%
Votes removed: %count%
%urlbase%show_bug.cgi?id=%bugid%
");
DefParam("allowbugdeletion",
q{The pages to edit products and components and versions can delete all associated bugs when you delete a product (or component or version). Since that is a pretty scary idea, you have to turn on this option before any such deletions will ever happen.},
"b",
0);
DefParam("allowuserdeletion",
q{The pages to edit users can also let you delete a user. But there is no code that goes and cleans up any references to that user in other tables, so such deletions are kinda scary. So, you have to turn on this option before any such deletions will ever happen.},
"b",
0);
DefParam("strictvaluechecks",
"Do stricter integrity checking on both form submission values and values read in from the database.",
"b",
0);
DefParam("browserbugmessage",
"If strictvaluechecks is on, and the bugzilla gets unexpected data from the browser, in addition to displaying the cause of the problem, it will output this HTML as well.",
"l",
"this may indicate a bug in your browser.\n");
#
# Parameters to force users to comment their changes for different actions.
DefParam("commentonaccept",
"If this option is on, the user needs to enter a short comment if he accepts the bug",
"b", 0 );
DefParam("commentonclearresolution",
"If this option is on, the user needs to enter a short comment if the bugs resolution is cleared",
"b", 0 );
DefParam("commentonconfirm",
"If this option is on, the user needs to enter a short comment when confirming a bug",
"b", 0 );
DefParam("commentonresolve",
"If this option is on, the user needs to enter a short comment if the bug is resolved",
"b", 0 );
DefParam("commentonreassign",
"If this option is on, the user needs to enter a short comment if the bug is reassigned",
"b", 0 );
DefParam("commentonreassignbycomponent",
"If this option is on, the user needs to enter a short comment if the bug is reassigned by component",
"b", 0 );
DefParam("commentonreopen",
"If this option is on, the user needs to enter a short comment if the bug is reopened",
"b", 0 );
DefParam("commentonverify",
"If this option is on, the user needs to enter a short comment if the bug is verified",
"b", 0 );
DefParam("commentonclose",
"If this option is on, the user needs to enter a short comment if the bug is closed",
"b", 0 );
DefParam("commentonduplicate",
"If this option is on, the user needs to enter a short comment if the bug is marked as duplicate",
"b", 0 );
# Added so that multiple instances of bugzilla may be ran on the same web server
DefParam("cookiepath",
"Html path is set each time a cookie is sent to the user's browser",
"t",
"/bugzilla/");
1;

View File

@@ -1,100 +0,0 @@
#!/usr/bonsaitools/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
use vars %::FORM;
use diagnostics;
use strict;
require "CGI.pl";
ConnectToDatabase();
GetVersionTable();
print "Content-type: text/html\n\n";
my $product = $::FORM{'product'};
if (!defined $product || lsearch(\@::legal_product, $product) < 0) {
PutHeader("Components");
print "
<FORM>
<CENTER><B>Please specify the product whose components you want described.</B>
<P>
Product: <SELECT NAME=product>
";
print make_options(\@::legal_product);
print "
</SELECT>
<P>
<INPUT TYPE=\"submit\" VALUE=\"Submit\">
</CENTER>
</FORM>
";
PutFooter();
exit;
}
PutHeader("Components", "Components", $product);
print "
<TABLE ALIGN=center WIDTH=800>
<TR>
<TH ALIGN=left>Component</TH>
<TH ALIGN=left>Default owner</TH>
";
my $useqacontact = Param("useqacontact");
my $cols = 2;
if ($useqacontact) {
print "<TH ALIGN=left>Default qa contact</TH>";
$cols++;
}
my $colbut1 = $cols - 1;
print "</TR>";
SendSQL("select value, initialowner, initialqacontact, description from components where program = " . SqlQuote($product) . " order by value");
while (MoreSQLData()) {
my @row = FetchSQLData();
my ($component, $initialowner, $initialqacontact, $description) = (@row);
print qq|
<tr><td colspan=$cols><hr></td></tr>
<tr><td rowspan=2>$component</td>
<td><a href="mailto:$initialowner">$initialowner</a></td>
|;
if ($useqacontact) {
print qq|
<td><a href="mailto:$initialqacontact">$initialqacontact</a></td>
|;
}
print "</TR><TR><TD COLSPAN=$colbut1>$description</TD></TR>\n";
}
print "<TR><TD COLSPAN=$cols><HR></TD></TR></TABLE>\n";
PutFooter();

View File

@@ -1,97 +0,0 @@
#!/usr/bonsaitools/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Terry Weissman.
# Portions created by Terry Weissman are
# Copyright (C) 2000 Terry Weissman. All
# Rights Reserved.
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
use diagnostics;
use strict;
require "CGI.pl";
ConnectToDatabase();
print "Content-type: text/html\n\n";
PutHeader("Bugzilla keyword description");
my $tableheader = qq{
<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0 ALIGN=center>
<TR BGCOLOR="#BFBFBF">
<TH ALIGN="left">Name</TH>
<TH ALIGN="left">Description</TH>
<TH ALIGN="left">Bugs</TH>
</TR>
};
print $tableheader;
my $line_count = 0;
my $max_table_size = 50;
if ($::driver eq 'mysql') {
SendSQL("SELECT keyworddefs.name, keyworddefs.description,
COUNT(keywords.bug_id), keywords.bug_id
FROM keyworddefs LEFT JOIN keywords ON keyworddefs.id=keywords.keywordid
GROUP BY keyworddefs.id
ORDER BY keyworddefs.name");
} else {
SendSQL("SELECT keyworddefs.name, keyworddefs.description,
COUNT(keywords.bug_id), keywords.bug_id
FROM keyworddefs, keywords
WHERE keyworddefs.id = keywords.keywordid (+)
GROUP BY keyworddefs.name, keyworddefs.description, keywords.bug_id
ORDER BY keyworddefs.name");
}
while (MoreSQLData()) {
my ($name, $description, $bugs, $onebug) = FetchSQLData();
if ($bugs && $onebug) {
# This 'onebug' stuff is silly hackery for old versions of
# MySQL that seem to return a count() of 1 even if there are
# no matching. So, we ask for an actual bug number. If it
# can't find any bugs that match the keyword, then we set the
# count to be zero, ignoring what it had responded.
my $q = url_quote($name);
$bugs = qq{<A HREF="buglist.cgi?keywords=$q">$bugs</A>};
} else {
$bugs = "none";
}
if ($line_count == $max_table_size) {
print "</table>\n$tableheader";
$line_count = 0;
}
$line_count++;
print qq{
<TR BGCOLOR="#ECECEC">
<TH ALIGN=left>$name</TH>
<TD>$description</TD>
<TD ALIGN=left>$bugs</TD>
</TR>
};
}
print "</TABLE><P>\n";
quietly_check_login();
if (UserInGroup("editkeywords")) {
print "<p><CENTER><a href=editkeywords.cgi>Edit keywords</a></CENTER><p>\n";
}
PutFooter();

View File

@@ -1,104 +0,0 @@
#!/usr/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public License
# Version 1.0 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are Copyright (C) 1998
# Netscape Communications Corporation. All Rights Reserved.
#
# Contributor(s): Sam Ziegler <sam@ziegler.org>
# Terry Weissman <terry@mozilla.org>
# Mark Hamby <mhamby@logicon.com>
# Code derived from doeditcomponents.cgi
use diagnostics;
use strict;
require "CGI.pl";
confirm_login();
print "Content-type: text/html\n\n";
# foreach my $i (sort(keys %::FORM)) {
# print value_quote("$i $::FORM{$i}") . "<BR>\n";
# }
if (!UserInGroup("editcomponents")) {
print "<H1>Sorry, you aren't a member of the 'editcomponents' group.</H1>\n";
print "And so, you aren't allowed to add components.\n";
exit;
}
PutHeader("Adding new component");
unlink "data/versioncache";
GetVersionTable();
my $component = trim($::FORM{"component"});
my $product = trim($::FORM{"product"});
my $description = trim($::FORM{"description"});
my $initialowner = trim($::FORM{"initialowner"});
if (!defined $::FORM{"initialqacontact"}) {
# May not be defined if we're not using this field.
$::FORM{'initialqacontact'} = "";
}
my $initialqacontact = trim($::FORM{"initialqacontact"});
if ($component eq "") {
print "You must enter a name for the new component. Please press\n";
print "<b>Back</b> and try again.\n";
exit;
}
# Check to ensure the component doesn't exist already.
SendSQL("SELECT value FROM components WHERE " .
"program = " . SqlQuote($product) . " and " .
"value = " . SqlQuote($component));
my @row = FetchSQLData();
if (@row) {
print "<H1>Component already exists</H1>";
print "The component '$component' already exists\n";
print "for product '$product'.<P>\n";
print "<p><a href=query.cgi>Go back to the query page</a>\n";
exit;
}
# Check that the email addresses are legitimate.
foreach my $addr ($initialowner, $initialqacontact) {
if ($addr ne "") {
DBNameToIdAndCheck($addr);
}
}
# Add the new component.
SendSQL("INSERT INTO components ( " .
"value, program, description, initialowner, initialqacontact" .
" ) VALUES ( " .
SqlQuote($component) . "," .
SqlQuote($product) . "," .
SqlQuote($description) . "," .
SqlQuote($initialowner) . "," .
SqlQuote($initialqacontact) . ")" );
unlink "data/versioncache";
print "OK, done.<p>\n";
print "<a href=addcomponent.cgi>Edit another new component.</a><p>\n";
print "<a href=editcomponents.cgi>Edit existing components.</a><p>\n";
print "<a href=query.cgi>Go back to the query page.</a>\n";

View File

@@ -1,73 +0,0 @@
#!/usr/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public License
# Version 1.0 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are Copyright (C) 1998
# Netscape Communications Corporation. All Rights Reserved.
#
# $Id: doeditcomponents.cgi,v 1.6.2.4 2000-05-31 22:22:14 dkl%redhat.com Exp $
#
# Contributor(s): Sam Ziegler <sam@ziegler.org>
# Andrew Anderson <andrew@redhat.com>
use diagnostics;
use strict;
use CGI;
$::cgi = new CGI;
require "CGI.pl";
confirm_login();
print "Content-type: text/html\n\n";
if (!UserInGroup("editcomponents")) {
print "<H1>Sorry, you aren't a member of the 'editcomponents' group.</H1>\n";
print "And so, you aren't allowed to edit the owners.\n";
exit;
}
PutHeader("Saving new owners");
SendSQL("select program, value, initialowner from components
where program = \'" . $::cgi->param('cur_program') . "\' order by program, value");
my @line;
my @updates;
my $curIndex = 0;
my $cgiItem;
while (@line = FetchSQLData()) {
my $curItem = "$line[0]_$line[1]";
my $cgiItem = $::cgi->param($curItem);
if ($cgiItem ne "") {
$cgiItem =~ s/\r\n/\n/;
if ($cgiItem ne "$line[2]") {
print "$line[0]: $line[1] is now owned by $cgiItem.<BR>\n";
$updates[$curIndex++] = "update components set initialowner = '$cgiItem' where program = '$line[0]' and value = '$line[1]'";
}
}
}
foreach my $update (@updates) {
#print $::cgi->pre($update);
SendSQL($update);
}
print "OK, done.<P>\n",
$::cgi->a({-href=>"editcomponents.cgi"}, "Edit the owners some more."),
$::cgi->br,
$::cgi->a({-href=>"query.cgi"}, "Go back to the query page.");

View File

@@ -1,78 +0,0 @@
#!/usr/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public License
# Version 1.0 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are Copyright (C) 1998
# Netscape Communications Corporation. All Rights Reserved.
#
# Contributor(s): Sam Ziegler <sam@ziegler.org>
# Terry Weissman <terry@mozilla.org>
# David Lawrence <dkl@redhat.com>
use diagnostics;
use strict;
require "CGI.pl";
require "globals.pl";
confirm_login();
print "Content-type: text/html\n\n";
if (!UserInGroup("editcomponents")) {
print "<H1>Sorry, you aren't a member of the 'editcomponents' group.</H1>\n";
print "And so, you aren't allowed to edit member data.\n";
exit;
}
PutHeader("Saving new \nmember data");
foreach my $key (keys(%::FORM)) {
$::FORM{url_decode($key)} = $::FORM{$key};
}
foreach my $i (keys %::FORM) {
my $userid = "";
my $query = "";
if ($i =~ /^login_name/) {
$userid = $i;
$userid =~ s/^.*-//;
$query = "update profiles set login_name = " . SqlQuote($::FORM{$i}) .
" where userid = $userid";
print "Changing login_name for userid $userid to $::FORM{$i}.<BR>\n";
SendSQL($query);
}
if ($i =~ /^realname/) {
$userid = $i;
$userid =~ s/^.*-//;
$query = "update profiles set realname = " . SqlQuote($::FORM{$i}) .
" where userid = $userid";
print "Changing realname for userid $userid to $::FORM{$i}.<BR>\n";
SendSQL($query);
}
if ($i =~ /^groupset/ ) {
$userid = $i;
$userid =~ s/^.*-//;
$query = "update profiles set groupset = " . SqlQuote($::FORM{$i}) .
" where userid = $userid";
print "Changing groupset for userid $userid to $::FORM{$i}.<BR>\n";
SendSQL($query);
}
}
print "OK, done.<p>\n";
print "<a href=editmembers.cgi>Edit the members some more.</a><p>\n";
PutFooter();

View File

@@ -1,68 +0,0 @@
#!/usr/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public License
# Version 1.0 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are Copyright (C) 1998
# Netscape Communications Corporation. All Rights Reserved.
#
# Contributor(s): Sam Ziegler <sam@ziegler.org>
use diagnostics;
use strict;
require "CGI.pl";
confirm_login();
print "Content-type: text/html\n\n";
if (!UserInGroup("editcomponents")) {
print "<H1>Sorry, you aren't a member of the 'editcomponents' group.</H1>\n";
print "And so, you aren't allowed to edit the owners.\n";
exit;
}
PutHeader("Saving new owners");
SendSQL("select program, value, initialowner from components order by program, value");
my @line;
foreach my $key (keys(%::FORM)) {
$::FORM{url_decode($key)} = $::FORM{$key};
}
my @updates;
my $curIndex = 0;
while (@line = FetchSQLData()) {
my $curItem = "$line[0]_$line[1]";
if (exists $::FORM{$curItem}) {
$::FORM{$curItem} =~ s/\r\n/\n/;
if ($::FORM{$curItem} ne $line[2]) {
print "$line[0] : $line[1] is now owned by $::FORM{$curItem}.<BR>\n";
$updates[$curIndex++] = "update components set initialowner = '$::FORM{$curItem}' where program = '$line[0]' and value = '$line[1]'";
}
}
}
foreach my $update (@updates) {
SendSQL($update);
}
print "OK, done.<p>\n";
print "<a href=editowners.cgi>Edit the owners some more.</a><p>\n";
print "<a href=query.cgi>Go back to the query page.</a>\n";

View File

@@ -1,83 +0,0 @@
#!/usr/bonsaitools/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
use diagnostics;
use strict;
require "CGI.pl";
require "defparams.pl";
# Shut up misguided -w warnings about "used only once":
use vars %::param,
%::param_default,
@::param_list;
confirm_login();
print "Content-type: text/html\n\n";
if (!UserInGroup("tweakparams")) {
print "<H1>Sorry, you aren't a member of the 'tweakparams' group.</H1>\n";
print "And so, you aren't allowed to edit the parameters.\n";
PutFooter();
exit;
}
PutHeader("Saving new parameters", undef, undef, undef, 1);
foreach my $i (@::param_list) {
# print "Processing $i...<BR>\n";
if (exists $::FORM{"reset-$i"}) {
$::FORM{$i} = $::param_default{$i};
}
$::FORM{$i} =~ s/\r\n/\n/; # Get rid of windows-style line endings.
if ($::FORM{$i} ne Param($i)) {
if (defined $::param_checker{$i}) {
my $ref = $::param_checker{$i};
my $ok = &$ref($::FORM{$i});
if ($ok ne "") {
print "New value for $i is invalid: $ok<p>\n";
print "Please hit <b>Back</b> and try again.\n";
PutFooter();
exit;
}
}
print "Changed $i.<br>\n";
$::param{$i} = $::FORM{$i}
}
}
WriteParams();
unlink "data/versioncache";
print "<PRE>";
system("./syncshadowdb -v");
print "</PRE>";
print "OK, done.<p>\n";
print "<a href=editparams.cgi>Edit the params some more.</a><p>\n";
print "<a href=query.cgi>Go back to the query page.</a>\n";
PutFooter();

View File

@@ -1,118 +0,0 @@
#!/usr/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public License
# Version 1.0 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are Copyright (C) 1998
# Netscape Communications Corporation. All Rights Reserved.
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
use diagnostics;
use strict;
require "CGI.pl";
confirm_login();
print "Content-type: text/html\n\n";
ConnectToDatabase();
GetVersionTable();
my $who = DBNameToIdAndCheck($::COOKIE{'Bugzilla_login'});
if ($who ne $::FORM{'who'}) {
PutHeader("Wrong login.");
print "The login info got confused. If you want to adjust the votes\n";
print "for <tt>$::COOKIE{'Bugzilla_login'}</tt>, then please\n";
print "<a href=showvotes.cgi?user=$who>click here</a>.<hr>\n";
navigation_header();
exit();
}
my @buglist = grep {/^\d+$/} keys(%::FORM);
if (0 == @buglist) {
PutHeader("Oops?");
print "Something got confused. Please click <b>Back</b> and try again.";
navigation_header();
exit();
}
foreach my $id (@buglist) {
$::FORM{$id} = trim($::FORM{$id});
if ($::FORM{$id} !~ /\d+/ || $::FORM{$id} < 0) {
PutHeader("Numbers only, please");
print "Only use numeric values for your bug votes.\n";
print "Please click <b>Back</b> and try again.<hr>\n";
navigation_header();
exit();
}
}
SendSQL("select bug_id, product from bugs where bug_id = " .
join(" or bug_id = ", @buglist));
my %prodcount;
while (MoreSQLData()) {
my ($id, $prod) = (FetchSQLData());
if (!defined $prodcount{$prod}) {
$prodcount{$prod} = 0;
}
$prodcount{$prod} += $::FORM{$id};
}
foreach my $prod (keys(%prodcount)) {
if ($prodcount{$prod} > $::prodmaxvotes{$prod}) {
PutHeader("Don't overstuff!", "Illegal vote");
print "You may only use $::prodmaxvotes{$prod} votes for bugs in the\n";
print "<tt>$prod</tt> product, but you are using $prodcount{$prod}.\n";
print "Please click <b>Back</b> and try again.<hr>\n";
navigation_header();
exit();
}
}
my %affected;
SendSQL("lock tables bugs write, votes write");
SendSQL("select bug_id from votes where who = $who");
while (MoreSQLData()) {
my $id = FetchOneColumn();
$affected{$id} = 1;
}
SendSQL("delete from votes where who = $who");
foreach my $id (@buglist) {
if ($::FORM{$id} > 0) {
SendSQL("insert into votes (who, bug_id, count) values ($who, $id, $::FORM{$id})");
}
$affected{$id} = 1;
}
foreach my $id (keys %affected) {
SendSQL("select sum(count) from votes where bug_id = $id");
my $v = FetchOneColumn();
SendSQL("update bugs set votes = $v, delta_ts=delta_ts where bug_id = $id");
}
SendSQL("unlock tables");
PutHeader("Voting tabulated", "Voting tabulated", $::COOKIE{'Bugzilla_login'});
print "Your votes have been recorded.\n";
print qq{<p><a href="showvotes.cgi?user=$who">Review your votes</a><hr>\n};
navigation_header();
exit();

View File

@@ -1,843 +0,0 @@
#!/usr/bonsaitools/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Holger
# Schurig. Portions created by Holger Schurig are
# Copyright (C) 1999 Holger Schurig. All
# Rights Reserved.
#
# Contributor(s): Holger Schurig <holgerschurig@nikocity.de>
# Terry Weissman <terry@mozilla.org>
#
# Direct any questions on this source code to
#
# Holger Schurig <holgerschurig@nikocity.de>
use diagnostics;
use strict;
require "CGI.pl";
require "globals.pl";
# Shut up misguided -w warnings about "used only once". For some reason,
# "use vars" chokes on me when I try it here.
sub sillyness {
my $zz;
$zz = $::buffer;
}
my $dobugcounts = (defined $::FORM{'dobugcounts'});
# TestProduct: just returns if the specified product does exists
# CheckProduct: same check, optionally emit an error text
# TestComponent: just returns if the specified product/component combination exists
# CheckComponent: same check, optionally emit an error text
sub TestProduct ($)
{
my $prod = shift;
# does the product exist?
SendSQL("SELECT product
FROM products
WHERE product = " . SqlQuote($prod));
return FetchOneColumn();
}
sub CheckProduct ($)
{
my $prod = shift;
# do we have a product?
unless ($prod) {
print "<CENTER>Sorry, you haven't specified a product.</CENTER>\n";
PutTrailer();
exit;
}
unless (TestProduct $prod) {
print "<CENTER>Sorry, product '$prod' does not exist.</CENTER>\n";
PutTrailer();
exit;
}
}
sub TestComponent ($$)
{
my ($prod,$comp) = @_;
# does the product exist?
SendSQL("SELECT program,value
FROM components
WHERE program = " . SqlQuote($prod) . " and value = " . SqlQuote($comp));
return FetchOneColumn();
}
sub CheckComponent ($$)
{
my ($prod,$comp) = @_;
# do we have the component?
unless ($comp) {
print "<CENTER>Sorry, you haven't specified a component.</CENTER>\n";
PutTrailer();
exit;
}
CheckProduct($prod);
unless (TestComponent $prod,$comp) {
print "<CENTER>Sorry, component '$comp' for product '$prod' does not exist.</CENTER>\n";
PutTrailer();
exit;
}
}
#
# Displays the form to edit component parameters
#
sub EmitFormElements ($$$$$)
{
my ($product, $component, $initialowner, $initialqacontact, $description) = @_;
print " <TH ALIGN=\"right\">Component:</TH>\n";
print " <TD><INPUT SIZE=64 MAXLENGTH=255 NAME=\"component\" VALUE=\"" .
value_quote($component) . "\">\n";
print " <INPUT TYPE=HIDDEN NAME=\"product\" VALUE=\"" .
value_quote($product) . "\"></TD>\n";
print "</TR><TR>\n";
print " <TH ALIGN=\"right\">Description:</TH>\n";
print " <TD><TEXTAREA ROWS=4 COLS=64 WRAP=VIRTUAL NAME=\"description\">" .
value_quote($description) . "</TEXTAREA></TD>\n";
print "</TR><TR>\n";
print " <TH ALIGN=\"right\">Initial owner:</TH>\n";
print " <TD><INPUT TYPE=TEXT SIZE=64 MAXLENGTH=255 NAME=\"initialowner\" VALUE=\"" .
value_quote($initialowner) . "\"></TD>\n";
if (Param('useqacontact')) {
print "</TR><TR>\n";
print " <TH ALIGN=\"right\">Initial QA contact:</TH>\n";
print " <TD><INPUT TYPE=TEXT SIZE=64 MAXLENGTH=255 NAME=\"initialqacontact\" VALUE=\"" .
value_quote($initialqacontact) . "\"></TD>\n";
}
}
#
# Displays a text like "a.", "a or b.", "a, b or c.", "a, b, c or d."
#
sub PutTrailer (@)
{
my (@links) = ("Back to the <A HREF=\"query.cgi\">query page</A>", @_);
my $count = $#links;
my $num = 0;
print "<P><CENTER>\n";
# if (!$dobugcounts) {
# print qq{<a href="editcomponents.cgi?dobugcounts=1&$::buffer">};
# print qq{Redisplay table with bug counts (slower)</a><p>\n};
# }
foreach (@links) {
print $_;
if ($num == $count) {
print ".\n";
}
elsif ($num == $count-1) {
print " or ";
}
else {
print ", ";
}
$num++;
}
print "</CENTER>\n";
PutFooter();
}
#
# Preliminary checks:
#
confirm_login();
print "Content-type: text/html\n\n";
unless (UserInGroup("editcomponents")) {
PutHeader("Not allowed");
print "<CENTER>Sorry, you aren't a member of the 'editcomponents' group.\n";
print "And so, you aren't allowed to add, modify or delete components.</CENTER>\n";
PutTrailer();
exit;
}
#
# often used variables
#
my $product = trim($::FORM{product} || '');
my $component = trim($::FORM{component} || '');
my $action = trim($::FORM{action} || '');
my $localtrailer;
if ($product) {
$localtrailer = "<A HREF=\"editcomponents.cgi?product=" . url_quote($product) . "\">edit</A> more components";
} else {
$localtrailer = "<A HREF=\"editcomponents.cgi\">edit</A> more components";
}
#
# product = '' -> Show nice list of products
#
unless ($product) {
PutHeader("Select product");
# if ($dobugcounts){
# if ($::driver eq 'mysql') {
# SendSQL("SELECT products.product, products.description, COUNT(bug_id)
# FROM products LEFT JOIN bugs
# ON products.product=bugs.product
# GROUP BY products.product
# ORDER BY products.product");
# } else {
# SendSQL("SELECT products.product, products.description, COUNT(bug_id)
# FROM products, bugs
# WHERE products.product = bugs.product (+)
# ORDER BY products.product");
# }
# } else {
SendSQL("SELECT products.product, products.description
FROM products
ORDER BY products.product");
# }
print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0 ALIGN=center BGCOLOR=\"#ECECEC\">\n";
print "<TR BGCOLOR=\"#BFBFBF\">\n";
print " <TH ALIGN=\"left\">Edit components of ...</TH>\n";
print " <TH ALIGN=\"left\">Description</TH>\n";
if ($dobugcounts) {
print " <TH ALIGN=\"left\">Bugs</TH>\n";
}
#print " <TH ALIGN=\"left\">Edit</TH>\n";
print "</TR>";
while ( MoreSQLData() ) {
my ($product, $description, $bugs) = FetchSQLData();
$description ||= "<FONT COLOR=\"red\">missing</FONT>";
print "<TR>\n";
print " <TD VALIGN=\"top\"><A HREF=\"editcomponents.cgi?product=", url_quote($product), "\"><B>$product</B></A></TD>\n";
print " <TD VALIGN=\"top\">$description</TD>\n";
if ($dobugcounts) {
$bugs ||= "none";
print " <TD VALIGN=\"top\">$bugs</TD>\n";
}
#print " <TD VALIGN=\"top\"><A HREF=\"editproducts.cgi?action=edit&product=", url_quote($product), "\">Edit</A></TD>\n";
}
print "</TR></TABLE>\n";
PutTrailer();
exit;
}
#
# action='' -> Show nice list of components
#
unless ($action) {
PutHeader("Select component", "Select component", $product);
CheckProduct($product);
if ($dobugcounts) {
if ($::driver eq 'mysql') {
SendSQL("SELECT value, description, initialowner, initialqacontact, COUNT(bug_id)
FROM components LEFT JOIN bugs
ON components.program = bugs.product AND components.value = bugs.component
WHERE components.program = " . SqlQuote($product) . "
GROUP BY components.value");
} else {
SendSQL("SELECT value, description, initialowner, initialqacontact, COUNT(bug_id)
FROM components, bugs
WHERE components.program = bugs.product (+)
AND components.value = bugs.component (+)
AND components.program = " . SqlQuote($product) .
" ORDER by bugs.bug_id");
}
} else {
SendSQL("SELECT value, description, initialowner, initialqacontact
FROM components
WHERE program = " . SqlQuote($product) . "
ORDER BY value");
}
print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0 ALIGN=center BGCOLOR=\"#ECECEC\">\n";
print "<TR BGCOLOR=\"#BFBFBF\">\n";
print " <TH ALIGN=\"left\">Edit component ...</TH>\n";
print " <TH ALIGN=\"left\">Description</TH>\n";
print " <TH ALIGN=\"left\">Initial owner</TH>\n";
print " <TH ALIGN=\"left\">Initial QA contact</TH>\n"
if Param('useqacontact');
print " <TH ALIGN=\"left\">Bugs</TH>\n"
if $dobugcounts;
print " <TH ALIGN=\"left\">Delete</TH>\n";
print "</TR>";
while ( MoreSQLData() ) {
my ($component,$desc,$initialowner,$initialqacontact, $bugs) = FetchSQLData();
$desc ||= "<FONT COLOR=\"red\">missing</FONT>";
$initialowner ||= "<FONT COLOR=\"red\">missing</FONT>";
$initialqacontact ||= "<FONT COLOR=\"red\">none</FONT>";
print "<TR>\n";
print " <TD VALIGN=\"top\"><A HREF=\"editcomponents.cgi?product=", url_quote($product), "&component=", url_quote($component), "&action=edit\"><B>$component</B></A></TD>\n";
print " <TD VALIGN=\"top\">$desc</TD>\n";
print " <TD VALIGN=\"top\">$initialowner</TD>\n";
print " <TD VALIGN=\"top\">$initialqacontact</TD>\n"
if Param('useqacontact');
if ($dobugcounts) {
$bugs ||= 'none';
print " <TD VALIGN=\"top\">$bugs</TD>\n";
}
print " <TD VALIGN=\"top\"><A HREF=\"editcomponents.cgi?product=", url_quote($product), "&component=", url_quote($component), "&action=del\"><B>Delete</B></A></TD>\n";
print "</TR>";
}
print "<TR>\n";
my $span = 4;
$span++ if Param('useqacontact');
$span++ if $dobugcounts;
print " <TH VALIGN=\"top\" COLSPAN=$span><A HREF=\"editcomponents.cgi?product=", url_quote($product) . "&action=add\">";
print "Add a new component</A></TH>\n";
print "</TR></TABLE>\n";
PutTrailer();
exit;
}
$dobugcounts = 1; # Stupid hack to force further PutTrailer()
# calls to not offer a "bug count" option.
#
# action='add' -> present form for parameters for new component
#
# (next action will be 'new')
#
if ($action eq 'add') {
PutHeader("Add component", "Add component", $product);
CheckProduct($product);
#print "This page lets you add a new product to bugzilla.\n";
print "<FORM METHOD=POST ACTION=editcomponents.cgi>\n";
print "<TABLE BORDER=0 CELLPADDING=4 CELLSPACING=0 ALIGN=center><TR>\n";
EmitFormElements($product, '', '', '', '');
print "</TR></TABLE>\n";
print "<CENTER><INPUT TYPE=SUBMIT VALUE=\"Add\"></CENTER>\n";
print "<INPUT TYPE=HIDDEN NAME=\"action\" VALUE=\"new\">\n";
print "</FORM>";
my $other = $localtrailer;
$other =~ s/more/other/;
PutTrailer($other);
exit;
}
#
# action='new' -> add component entered in the 'action=add' screen
#
if ($action eq 'new') {
PutHeader("Adding new component", "Adding new component", $product);
CheckProduct($product);
# Cleanups and valididy checks
unless ($component) {
print "<CENTER>You must enter a name for the new component. Please press\n";
print "<b>Back</b> and try again.</CENTER>\n";
PutTrailer($localtrailer);
exit;
}
if (TestComponent($product,$component)) {
print "<CENTER>The component '$component' already exists. Please press\n";
print "<b>Back</b> and try again.</CENTER>\n";
PutTrailer($localtrailer);
exit;
}
my $description = trim($::FORM{description} || '');
if ($description eq '') {
print "<CENTER>You must enter a description for the component '$component'. Please press\n";
print "<b>Back</b> and try again.</CENTER>\n";
PutTrailer($localtrailer);
exit;
}
my $initialowner = trim($::FORM{initialowner} || '');
if ($initialowner eq '') {
print "<CENTER>You must enter an initial owner for the component '$component'. Please press\n";
print "<b>Back</b> and try again.</CENTER>\n";
PutTrailer($localtrailer);
exit;
}
#+++
#DBNameToIdAndCheck($initialowner, 0);
my $initialqacontact = trim($::FORM{initialqacontact} || '');
if (Param('useqacontact')) {
if ($initialqacontact eq '') {
print "<CENTER>You must enter an initial QA contact for the component '$component'. Please press\n";
print "<b>Back</b> and try again.</CENTER>\n";
PutTrailer($localtrailer);
exit;
}
#+++
#DBNameToIdAndCheck($initialqacontact, 0);
}
# Add the new component
SendSQL("INSERT INTO components ( " .
"program, value, description, initialowner, initialqacontact " .
" ) VALUES ( " .
SqlQuote($product) . "," .
SqlQuote($component) . "," .
SqlQuote($description) . "," .
SqlQuote($initialowner) . "," .
SqlQuote($initialqacontact) . ")");
# Make versioncache flush
unlink "data/versioncache";
print "<CENTER>OK, done.</CENTER><p>\n";
PutTrailer($localtrailer);
exit;
}
#
# action='del' -> ask if user really wants to delete
#
# (next action would be 'delete')
#
if ($action eq 'del') {
PutHeader("Delete component", "Delete component", $product);
CheckComponent($product, $component);
# display some data about the component
if ($::driver eq 'mysql') {
SendSQL("SELECT products.product, products.description,
products.milestoneurl, products.disallownew,
components.program, components.value, components.initialowner,
components.initialqacontact, components.description
FROM products
LEFT JOIN components on product=program
WHERE product = " . SqlQuote($product) . "
AND value = " . SqlQuote($component) );
} else {
SendSQL("SELECT products.product, products.description,
products.milestoneurl, products.disallownew,
components.program, components.value, components.initialowner,
components.initialqacontact, components.description
FROM products
WHERE products.product = components.program (+)
AND product = " . SqlQuote($product) . "
AND value = " . SqlQuote($component) );
}
my ($product,$pdesc,$milestoneurl,$disallownew,
$dummy,$component,$initialowner,$initialqacontact,$cdesc) = FetchSQLData();
$pdesc ||= "<FONT COLOR=\"red\">missing</FONT>";
$milestoneurl ||= "<FONT COLOR=\"red\">missing</FONT>";
$disallownew = $disallownew ? 'closed' : 'open';
$initialowner ||= "<FONT COLOR=\"red\">missing</FONT>";
$initialqacontact ||= "<FONT COLOR=\"red\">missing</FONT>";
$cdesc ||= "<FONT COLOR=\"red\">missing</FONT>";
print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0 ALIGN=center BGCOLOR=\"#ECECEC\">\n";
print "<TR BGCOLOR=\"#BFBFBF\">\n";
print " <TH VALIGN=\"top\" ALIGN=\"left\">Part</TH>\n";
print " <TH VALIGN=\"top\" ALIGN=\"left\">Value</TH>\n";
print "</TR><TR>\n";
print " <TD VALIGN=\"top\">Component:</TD>\n";
print " <TD VALIGN=\"top\">$component</TD>";
print "</TR><TR>\n";
print " <TD VALIGN=\"top\">Component description:</TD>\n";
print " <TD VALIGN=\"top\">$cdesc</TD>";
print "</TR><TR>\n";
print " <TD VALIGN=\"top\">Initial owner:</TD>\n";
print " <TD VALIGN=\"top\">$initialowner</TD>";
if (Param('useqacontact')) {
print "</TR><TR>\n";
print " <TD VALIGN=\"top\">Initial QA contact:</TD>\n";
print " <TD VALIGN=\"top\">$initialqacontact</TD>";
}
SendSQL("SELECT count(bug_id)
FROM bugs
WHERE product=" . SqlQuote($product) . "
AND component=" . SqlQuote($component));
print "</TR><TR>\n";
print " <TD VALIGN=\"top\">Component of product:</TD>\n";
print " <TD VALIGN=\"top\">$product</TD>\n";
print "</TR><TR>\n";
print " <TD VALIGN=\"top\">Description:</TD>\n";
print " <TD VALIGN=\"top\">$pdesc</TD>\n";
if (Param('usetargetmilestone')) {
print "</TR><TR>\n";
print " <TD VALIGN=\"top\">Milestone URL:</TD>\n";
print " <TD VALIGN=\"top\"><A HREF=\"$milestoneurl\">$milestoneurl</A></TD>\n";
}
print "</TR><TR>\n";
print " <TD VALIGN=\"top\">Closed for bugs:</TD>\n";
print " <TD VALIGN=\"top\">$disallownew</TD>\n";
print "</TR><TR>\n";
print " <TD VALIGN=\"top\">Bugs</TD>\n";
print " <TD VALIGN=\"top\">";
my $bugs = FetchOneColumn();
print $bugs || 'none';
print "</TD>\n</TR></TABLE>";
print "<CENTER><H2>Confirmation</H2></CENTER>\n";
if ($bugs) {
if (!Param("allowbugdeletion")) {
print "<CENTER>Sorry, there are $bugs bugs outstanding for this component.
You must reassign those bugs to another component before you can delete this
one.</CENTER>";
PutTrailer($localtrailer);
exit;
}
print "<TABLE BORDER=0 CELLPADDING=20 WIDTH=\"70%\" BGCOLOR=\"red\" ALIGN=center><TR><TD>\n",
"There are bugs entered for this component! When you delete this ",
"component, <B><BLINK>all</BLINK></B> stored bugs will be deleted, too. ",
"You could not even see the bug history for this component anymore!\n",
"</TD></TR></TABLE>\n";
}
print "<P><CENTER>Do you really want to delete this component?</CENTER><P>\n";
print "<FORM METHOD=POST ACTION=editcomponents.cgi>\n";
print "<CENTER><INPUT TYPE=SUBMIT VALUE=\"Yes, delete\"></CENTER>\n";
print "<INPUT TYPE=HIDDEN NAME=\"action\" VALUE=\"delete\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"product\" VALUE=\"" .
value_quote($product) . "\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"component\" VALUE=\"" .
value_quote($component) . "\">\n";
print "</FORM>";
PutTrailer($localtrailer);
exit;
}
#
# action='delete' -> really delete the component
#
if ($action eq 'delete') {
PutHeader("Deleting component", "Deleting component", $product);
CheckComponent($product,$component);
# lock the tables before we start to change everything:
if ($::driver eq 'mysql') {
SendSQL("LOCK TABLES attachments WRITE,
bugs WRITE,
bugs_activity WRITE,
components WRITE,
dependencies WRITE");
}
# According to MySQL doc I cannot do a DELETE x.* FROM x JOIN Y,
# so I have to iterate over bugs and delete all the indivial entries
# in bugs_activies and attachments.
if (Param("allowbugdeletion")) {
SendSQL("SELECT bug_id
FROM bugs
WHERE product = " . SqlQuote($product) . "
AND component = " . SqlQuote($component));
while (MoreSQLData()) {
my $bugid = FetchOneColumn();
my $query =
$::db->query("DELETE FROM attachments WHERE bug_id = $bugid")
or die "$::db_errstr";
$query =
$::db->query("DELETE FROM bugs_activity WHERE bug_id = $bugid")
or die "$::db_errstr";
$query =
$::db->query("DELETE FROM dependencies WHERE blocked = $bugid")
or die "$::db_errstr";
}
print "<CENTER>Attachments, bug activity and dependencies deleted.</CENTER><BR>\n";
# Deleting the rest is easier:
SendSQL("DELETE FROM bugs
WHERE product=" . SqlQuote($product) . "
AND component=" . SqlQuote($component));
print "<CENTER>Bugs deleted.</CENTER><BR>\n";
}
SendSQL("DELETE FROM components
WHERE program=" . SqlQuote($product) . "
AND value=" . SqlQuote($component));
print "<CENTER>Components deleted.<CENTER><P>\n";
SendSQL("UNLOCK TABLES");
unlink "data/versioncache";
PutTrailer($localtrailer);
exit;
}
#
# action='edit' -> present the edit component form
#
# (next action would be 'update')
#
if ($action eq 'edit') {
PutHeader("Edit component", "Edit component", $product);
CheckComponent($product,$component);
# get data of component
if ($::driver eq 'mysql') {
SendSQL("SELECT products.product, products.description,
products.milestoneurl, products.disallownew,
components.program, components.value, components.initialowner,
components.initialqacontact, components.description
FROM products
LEFT JOIN components on product = program
WHERE products.product = " . SqlQuote($product) . "
AND components.value = " . SqlQuote($component) );
} else {
SendSQL("SELECT products.product, products.description,
products.milestoneurl, products.disallownew,
components.program, components.value, components.initialowner,
components.initialqacontact, components.description
FROM products, components
WHERE components.program (+) = products.product
AND products.product = " . SqlQuote($product) . "
AND components.value = " . SqlQuote($component) );
}
my ($product,$pdesc,$milestoneurl,$disallownew,
$dummy,$component,$initialowner,$initialqacontact,$cdesc) = FetchSQLData();
print "<FORM METHOD=POST ACTION=editcomponents.cgi>\n";
print "<TABLE BORDER=0 CELLPADDING=4 CELLSPACING=0 ALIGN=center><TR>\n";
#+++ display product/product description
EmitFormElements($product, $component, $initialowner, $initialqacontact, $cdesc);
print "</TR><TR>\n";
print " <TH ALIGN=\"right\">Bugs:</TH>\n";
print " <TD>";
SendSQL("SELECT count(bug_id)
FROM bugs
WHERE product = " . SqlQuote($product) .
" and component = " . SqlQuote($component));
my $bugs = '';
$bugs = FetchOneColumn() if MoreSQLData();
print $bugs || 'none';
print "</TD>\n</TR></TABLE>\n";
print "<INPUT TYPE=HIDDEN NAME=\"componentold\" VALUE=\"" .
value_quote($component) . "\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"descriptionold\" VALUE=\"" .
value_quote($cdesc) . "\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"initialownerold\" VALUE=\"" .
value_quote($initialowner) . "\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"initialqacontactold\" VALUE=\"" .
value_quote($initialqacontact) . "\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"action\" VALUE=\"update\">\n";
print "<CENTER><INPUT TYPE=SUBMIT VALUE=\"Update\"></CENTER>\n";
print "</FORM>";
my $other = $localtrailer;
$other =~ s/more/other/;
PutTrailer($other);
exit;
}
#
# action='update' -> update the component
#
if ($action eq 'update') {
PutHeader("Update component", "Update component", $product);
my $componentold = trim($::FORM{componentold} || '');
my $description = trim($::FORM{description} || '');
my $descriptionold = trim($::FORM{descriptionold} || '');
my $initialowner = trim($::FORM{initialowner} || '');
my $initialownerold = trim($::FORM{initialownerold} || '');
my $initialqacontact = trim($::FORM{initialqacontact} || '');
my $initialqacontactold = trim($::FORM{initialqacontactold} || '');
CheckComponent($product,$componentold);
# Note that the order of this tests is important. If you change
# them, be sure to test for WHERE='$component' or WHERE='$componentold'
if ($::driver eq 'mysql') {
SendSQL("LOCK TABLES bugs WRITE,
components WRITE");
}
if ($description ne $descriptionold) {
unless ($description) {
print "Sorry, I can't delete the description.";
PutTrailer($localtrailer);
if ($::driver eq 'mysql') {
SendSQL("UNLOCK TABLES");
}
exit;
}
SendSQL("UPDATE components
SET description=" . SqlQuote($description) . "
WHERE program=" . SqlQuote($product) . "
AND value=" . SqlQuote($componentold));
print "<CENTER>Updated description.</CENTER><BR>\n";
}
if ($initialowner ne $initialownerold) {
unless ($initialowner) {
print "<CENTER>Sorry, I can't delete the initial owner.</CENTER>\n";
PutTrailer($localtrailer);
if ($::driver eq 'mysql') {
SendSQL("UNLOCK TABLES");
}
exit;
}
#+++
#DBNameToIdAndCheck($initialowner, 0);
SendSQL("UPDATE components
SET initialowner = " . SqlQuote($initialowner) . "
WHERE program = " . SqlQuote($product) . "
AND value = " . SqlQuote($componentold));
print "<CENTER>Updated initial owner.</CENTER><BR>\n";
}
if (Param('useqacontact') && $initialqacontact ne $initialqacontactold) {
unless ($initialqacontact) {
print "<CENTER>Sorry, I can't delete the initial QA contact.</CENTER>\n";
PutTrailer($localtrailer);
if ($::driver eq 'mysql') {
SendSQL("UNLOCK TABLES");
}
exit;
}
#+++
#DBNameToIdAndCheck($initialqacontact, 0);
SendSQL("UPDATE components
SET initialqacontact = " . SqlQuote($initialqacontact) . "
WHERE program = " . SqlQuote($product) . "
AND value = " . SqlQuote($componentold));
print "<CENTER>Updated initial QA contact.</CENTER><BR>\n";
}
if ($component ne $componentold) {
unless ($component) {
print "<CENTER>Sorry, I can't delete the product name.</CENTER>\n";
PutTrailer($localtrailer);
if ($::driver eq 'mysql') {
SendSQL("UNLOCK TABLES");
}
exit;
}
if (TestComponent($product,$component)) {
print "<CENTER>Sorry, component name '$component' is already in use.</CENTER>\n";
PutTrailer($localtrailer);
if ($::driver eq 'mysql') {
SendSQL("UNLOCK TABLES");
}
exit;
}
SendSQL("UPDATE bugs
SET component = " . SqlQuote($component) . "
WHERE component = " . SqlQuote($componentold) . "
AND product = " . SqlQuote($product));
SendSQL("UPDATE components
SET value = " . SqlQuote($component) . "
WHERE value = " . SqlQuote($componentold) . "
AND program = " . SqlQuote($product));
unlink "data/versioncache";
print "<CENTER>Updated product name.</CENTER><BR>\n";
}
if ($::driver eq 'mysql') {
SendSQL("UNLOCK TABLES");
}
PutTrailer($localtrailer);
exit;
}
#
# No valid action found
#
PutHeader("Error");
print "I don't have a clue what you want.<BR>\n";
foreach ( sort keys %::FORM) {
print "$_: $::FORM{$_}<BR>\n";
}

View File

@@ -1,451 +0,0 @@
#!/usr/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public License
# Version 1.0 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
#
# Direct any questions on this source code to
#
# Holger Schurig <holgerschurig@nikocity.de>
use diagnostics;
use strict;
require "CGI.pl";
require "globals.pl";
# TestGroup: just returns if the specified group does exists
# CheckGroup: same check, optionally emit an error text
sub TestGroup {
my $group = shift;
# does the group exist?
SendSQL("SELECT name
FROM groups
WHERE name = " . SqlQuote($group));
return FetchOneColumn();
}
sub CheckGroup {
my $group = shift;
# do we have a group?
unless ($group) {
print "Sorry, you haven't specified a group.";
PutTrailer();
exit;
}
unless (TestGroup($group)) {
print "Sorry, group '$group' does not exist.";
PutTrailer();
exit;
}
}
#
# Displays the form to edit a groups parameters
#
sub EmitFormElements {
my ($group, $description, $isbuggroup, $iscontract) = @_;
$isbuggroup = $isbuggroup ? " CHECKED " : "";
$iscontract = $iscontract ? " CHECKED " : "";
print qq{
<TH ALIGN="right">Group</TH>
<TD><INPUT SIZE=64 MAXLENGTH=64 NAME="group" VALUE="$group"></TD>
<TR><TR>
<TH ALIGN="right">Description</TH>
<TD><TEXTAREA ROWS=4 COLS=64 WRAP=VIRTUAL NAME="description">$description</TEXTAREA></TD>
<TR><TR>
<TH ALIGN="right">Is Bug Group</TH>
<TD><INPUT TYPE=CHECKBOX NAME="isbuggroup" VALUE="1" $isbuggroup></TD>
</TR><TR>
<TH ALIGN=right>Is Contract Group</TH>
<TD><INPUT TYPE=CHECKBOX NAME="iscontract" VALUE="1" $iscontract></TD>
};
}
#
# Displays a text like "a.", "a or b.", "a, b or c.", "a, b, c or d."
#
sub PutTrailer {
my (@links) = ("Back to the <A HREF=\"query.cgi\">query page</A>", @_);
my $count = $#links;
my $num = 0;
print "<P><CENTER>\n";
foreach (@links) {
print $_;
if ($num == $count) {
print ".\n";
}
elsif ($num == $count-1) {
print " or ";
}
else {
print ", ";
}
$num++;
}
print "</CENTER>\n";
}
#
# Preliminary checks:
#
confirm_login();
print "Content-type: text/html\n\n";
unless (UserInGroup("creategroups")) {
PutHeader("Not allowed");
print "Sorry, you aren't a member of the 'creategroups' group.\n";
print "And so, you aren't allowed to add, modify or delete groups.\n";
PutTrailer();
exit;
}
#
# often used variables
#
my $group = trim($::FORM{'group'} || '');
my $action = trim($::FORM{'action'} || '');
my $localtrailer = "<A HREF=\"editgroups.cgi\">edit</A> more groups";
#
# action='' -> Show nice list of groups
#
unless ($action) {
PutHeader("Select Group");
SendSQL("SELECT groupid, name, description, isbuggroup, contract
FROM groups
ORDER BY groupid");
print "<P>\n<TABLE ALIGN=center BORDER=1 CELLPADDING=4 CELLSPACING=0><TR BGCOLOR=\"#BFBFBF\">\n";
print " <TH ALIGN=\"left\">Name</TH>\n";
print " <TH ALIGN=\"left\">Description</TH>\n";
print " <TH ALIGN=\"left\">Bug Group</TH>\n";
print " <TH ALIGN=\"left\">Contract Group</TH>\n";
print " <TH ALIGN=\"left\">Action</TH>\n";
print "</TR>";
while ( MoreSQLData() ) {
my ($groupid, $name, $description, $isbuggroup, $iscontract) = FetchSQLData();
$description ||= "<FONT COLOR=\"red\">missing</FONT>";
$isbuggroup = $isbuggroup ? '<FONT COLOR=green>Yes</FONT>' : '<FONT COLOR=red>No</FONT>';
$iscontract = $iscontract ? '<FONT COLOR=green>Yes</FONT>' : '<FONT COLOR=red>No</FONT>';
print "<TR BGCOLOR=\"#ECECEC\">\n";
print " <TD ALIGN=\"left\"><A HREF=\"editgroups.cgi?action=edit&group=", url_quote($name), "\"><B>$name</B></A></TD>\n";
print " <TD ALIGN=\"left\">$description</TD>\n";
print " <TD ALIGN=\"left\">$isbuggroup</TD>\n";
print " <TD ALIGN=\"left\">$iscontract</TD>\n";
print " <TD ALIGN=\"left\"><A HREF=\"editgroups.cgi?action=del&group=", url_quote($name), "\">Delete</A></TD>\n";
print "</TR>";
}
print "<TR BGCOLOR=\"#ECECEC\">\n";
print " <TH COLSPAN=5><A HREF=\"editgroups.cgi?action=add\">Add a new group</A></TH>\n";
print "</TR></TABLE>\n";
PutTrailer();
PutFooter();
exit;
}
#
# action='add' -> present form for parameters for new group
#
# (next action will be 'new')
#
if ($action eq 'add') {
PutHeader("Add Group");
#print "This page lets you add a new group to bugzilla.\n";
print "<FORM METHOD=POST ACTION=editgroups.cgi>\n";
print "<TABLE ALIGN=center BORDER=0 CELLPADDING=4 CELLSPACING=0><TR>\n";
EmitFormElements('', '', '', 0);
print "</TR>\n</TABLE>\n";
print "<CENTER><INPUT TYPE=SUBMIT VALUE=\"Add\"></CENTER>\n";
print "<INPUT TYPE=HIDDEN NAME=\"action\" VALUE=\"new\">\n";
print "</FORM>";
my $other = $localtrailer;
$other =~ s/more/other/;
PutTrailer($other);
PutFooter();
exit;
}
#
# action='new' -> add group entered in the 'action=add' screen
#
if ($action eq 'new') {
PutHeader("Adding New Group");
# Cleanups and valididy checks
unless ($group) {
print "You must enter a name for the new group. Please press\n";
print "<b>Back</b> and try again.\n";
PutTrailer($localtrailer);
exit;
}
if (TestGroup($group)) {
print "The group '$group' already exists. Please press\n";
print "<b>Back</b> and try again.\n";
PutTrailer($localtrailer);
exit;
}
my $description = trim($::FORM{'description'} || '');
my $isbuggroup = 0;
$isbuggroup = 1 if $::FORM{'isbuggroup'};
my $iscontract = 0;
$iscontract = 1 if $::FORM{'iscontract'};
# Add the new group.
if ($::driver eq 'mysql') {
SendSQL("INSERT INTO groups ( " .
"name, description, isbuggroup, contract" .
" ) VALUES ( " .
SqlQuote($group) . "," .
SqlQuote($description) . "," .
SqlQuote($isbuggroup) . ", " .
SqlQuote($iscontract) . ")");
} else {
SendSQL("INSERT INTO groups ( " .
"groupid, name, description, isbuggroup, contract" .
" ) VALUES ( groups_seq.nextval, " .
SqlQuote($group) . "," .
SqlQuote($description) . "," .
SqlQuote($isbuggroup) . ", " .
SqlQuote($iscontract) . ")");
}
print "OK, done.<p>\n";
PutTrailer($localtrailer);
exit;
}
#
# action='del' -> ask if user really wants to delete
#
# (next action would be 'delete')
#
if ($action eq 'del') {
PutHeader("Delete Group");
CheckGroup($group);
# display some data about the group
SendSQL("SELECT groupid, name, description, isbuggroup, contract
FROM groups
WHERE name = " . SqlQuote($group));
my ($groupid, $name, $description, $isbuggroup, $iscontract) = FetchSQLData();
$description ||= "<FONT COLOR=\"red\">description missing</FONT>";
$isbuggroup = $isbuggroup ? '<FONT COLOR=green>Yes</FONT>' : '<FONT COLOR=red>No</FONT>';
$iscontract = $iscontract ? '<FONT COLOR=green>Yes</FONT>' : '<FONT COLOR=red>No</FONT>';
# Find out how many people are in this group
SendSQL("select count(userid) from user_group where groupid = $groupid");
my $members = FetchOneColumn();
$members = $members ? $members : 0;
print "<P>\n<TABLE ALIGN=center BORDER=1 CELLPADDING=4 CELLSPACING=0 BGCOLOR=\"#ECECEC\">\n";
print "<TR BGCOLOR=\"#BFBFBF\">\n";
print " <TH VALIGN=\"top\" ALIGN=\"left\">Part</TH>\n";
print " <TH VALIGN=\"top\" ALIGN=\"left\">Value</TH>\n";
print "</TR><TR>\n";
print " <TD VALIGN=\"top\">Group</TD>\n";
print " <TD VALIGN=\"top\">$name</TD>\n";
print "</TR><TR>\n";
print " <TD VALIGN=\"top\">Description</TD>\n";
print " <TD VALIGN=\"top\">$description</TD>\n";
print "</TR><TR>\n";
print " <TD VALIGN=\"top\">Is Bug Group</TD>\n";
print " <TD VALIGN=\"top\">$isbuggroup</TD>\n";
print "</TR><TR>\n";
print " <TD VALIGN=\"top\">Is Contract Group</TD>\n";
print " <TD VALIGN=\"top\">$iscontract</TD>\n";
print "</TR><TR>\n";
print " <TD VALIGN=\"top\">Members</TD>\n";
print " <TD VALIGN=\"top\">$members</TD>\n";
print "</TD>\n</TR></TABLE>";
print "<P>\n<CENTER><B>Current members will be removed from the group.</B>\n";
print "<H2>Confirmation</H2>\n";
print "<P>Do you really want to delete this group?<P>\n";
print "<FORM METHOD=POST ACTION=editgroups.cgi>\n";
print "<INPUT TYPE=SUBMIT VALUE=\"Yes, delete\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"action\" VALUE=\"delete\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"group\" VALUE=\"$group\">\n";
print "</FORM>\n</CENTER>\n";
PutTrailer($localtrailer);
PutFooter();
exit;
}
#
# action='delete' -> really delete the group
#
if ($action eq 'delete') {
PutHeader("Deleting Group");
CheckGroup($group);
SendSQL("select groupid from groups where name = " . SqlQuote($group));
my $groupid = FetchOneColumn();
SendSQL("DELETE FROM groups
WHERE name = " . SqlQuote($group));
print "Group deleted.<BR>\n";
SendSQL("delete from user_group where groupid = $groupid");
print "Members removed.<BR>\n";
PutTrailer($localtrailer);
PutFooter();
exit;
}
#
# action='edit' -> present the edit group
#
# (next action would be 'update')
#
if ($action eq 'edit') {
PutHeader("Edit Group");
CheckGroup($group);
# get data of group
SendSQL("SELECT groupid, name, description, isbuggroup, contract
FROM groups
WHERE name = " . SqlQuote($group));
my ($groupid, $name, $description, $isbuggroup, $iscontract) = FetchSQLData();
print "<FORM METHOD=POST ACTION=editgroups.cgi>\n";
print "<TABLE ALIGN=center BORDER=0 CELLPADDING=4 CELLSPACING=0><TR>\n";
EmitFormElements($group, $description, $isbuggroup, $iscontract);
print "</TR>\n";
print "</TABLE>\n";
print "<INPUT TYPE=HIDDEN NAME=\"nameold\" VALUE=\"$group\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"descriptionold\" VALUE=\"$description\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"isbuggroupold\" VALUE=\"$isbuggroup\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"iscontractold\" VALUE=\"$iscontract\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"action\" VALUE=\"update\">\n";
print "<CENTER><INPUT TYPE=SUBMIT VALUE=\"Update\"></CENTER>\n";
print "</FORM>";
my $x = $localtrailer;
$x =~ s/more/other/;
PutTrailer($x);
PutFooter();
exit;
}
#
# action='update' -> update the group
#
if ($action eq 'update') {
PutHeader("Update Group");
my $nameold = trim($::FORM{'nameold'} || '');
my $description = trim($::FORM{'description'} || '');
my $descriptionold = trim($::FORM{'descriptionold'} || '');
my $isbuggroup = trim($::FORM{'isbuggroup'} || '');
my $isbuggroupold = trim($::FORM{'isbuggroupold'} || '');
my $iscontract = trim($::FORM{'iscontract'} || '');
my $iscontractold = trim($::FORM{'iscontractold'} || '');
CheckGroup($nameold);
if ($isbuggroup != $isbuggroupold) {
$isbuggroup ||= 0;
SendSQL("UPDATE groups
SET isbuggroup = $isbuggroup
WHERE name = " . SqlQuote($nameold));
print "Updated bug group status.<BR>\n";
}
if ($iscontract != $iscontractold) {
$iscontract ||= 0;
SendSQL("UPDATE groups
SET contract = $iscontract
WHERE name = " . SqlQuote($nameold));
print "Updated contract group status.<BR>\n";
}
if ($description ne $descriptionold) {
unless ($description) {
print "Sorry, I can't delete the description.";
PutTrailer($localtrailer);
exit;
}
SendSQL("UPDATE groups
SET description=" . SqlQuote($description) . "
WHERE name =" . SqlQuote($nameold));
print "Updated description.<BR>\n";
}
if ($group ne $nameold) {
unless ($group) {
print "Sorry, I can't delete the group name.";
PutTrailer($localtrailer);
exit;
}
if (TestGroup($group)) {
print "Sorry, group name '$group' is already in use.";
PutTrailer($localtrailer);
exit;
}
SendSQL("UPDATE groups
SET name = " . SqlQuote($group) . "
WHERE name = " . SqlQuote($nameold));
print "Updated group name.<BR>\n";
}
PutTrailer($localtrailer);
exit;
}
#
# No valid action found
#
PutHeader("Error");
print "I don't have a clue what you want.<BR>\n";
foreach ( sort keys %::FORM) {
print "$_: $::FORM{$_}<BR>\n";
}

View File

@@ -1,409 +0,0 @@
#!/usr/bonsaitools/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Terry Weissman.
# Portions created by Terry Weissman are
# Copyright (C) 2000 Terry Weissman. All
# Rights Reserved.
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
use diagnostics;
use strict;
require "CGI.pl";
my $localtrailer = "<A HREF=\"editkeywords.cgi\">edit</A> more keywords";
#
# Displays a text like "a.", "a or b.", "a, b or c.", "a, b, c or d."
#
sub PutTrailer (@)
{
my (@links) = ("Back to the <A HREF=\"query.cgi\">query page</A>", @_);
my $count = $#links;
my $num = 0;
print "<P><CENTER>\n";
foreach (@links) {
print $_;
if ($num == $count) {
print ".\n";
}
elsif ($num == $count-1) {
print " or ";
}
else {
print ", ";
}
$num++;
}
print "</CENTER>\n";
PutFooter();
}
#
# Displays the form to edit a keyword's parameters
#
sub EmitFormElements ($$$)
{
my ($id, $name, $description) = @_;
$name = value_quote($name);
$description = value_quote($description);
print qq{<INPUT TYPE="HIDDEN" NAME=id VALUE=$id>};
print " <TR><TH ALIGN=\"right\">Name:</TH>\n";
print " <TD><INPUT SIZE=64 MAXLENGTH=64 NAME=\"name\" VALUE=\"$name\"></TD>\n";
print "</TR><TR>\n";
print " <TH ALIGN=\"right\">Description:</TH>\n";
print " <TD><TEXTAREA ROWS=4 COLS=64 WRAP=VIRTUAL NAME=\"description\">$description</TEXTAREA></TD>\n";
print "</TR>\n";
}
sub Validate ($$) {
my ($name, $description) = @_;
if ($name eq "") {
print "You must enter a non-blank name for the keyword. Please press\n";
print "<b>Back</b> and try again.\n";
PutTrailer($localtrailer);
exit;
}
if ($name =~ /[\s,]/) {
print "You may not use commas or whitespace in a keyword name.\n";
print "Please press <b>Back</b> and try again.\n";
PutTrailer($localtrailer);
exit;
}
if ($description eq "") {
print "You must enter a non-blank description of the keyword.\n";
print "Please press <b>Back</b> and try again.\n";
PutTrailer($localtrailer);
exit;
}
}
#
# Preliminary checks:
#
confirm_login();
print "Content-type: text/html\n\n";
unless (UserInGroup("editkeywords")) {
PutHeader("Not allowed");
print "Sorry, you aren't a member of the 'editkeywords' group.\n";
print "And so, you aren't allowed to add, modify or delete keywords.\n";
PutTrailer();
exit;
}
my $action = trim($::FORM{action} || '');
if ($action eq "") {
PutHeader("Select keyword");
my $tableheader = qq{
<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0 ALIGN=center>
<TR BGCOLOR="#BFBFBF">
<TH ALIGN="left">Edit keyword ...</TH>
<TH ALIGN="left">Description</TH>
<TH ALIGN="left">Bugs</TH>
<TH ALIGN="left">Action</TH>
</TR>
};
print $tableheader;
my $line_count = 0;
my $max_table_size = 50;
if ($::driver eq 'mysql') {
SendSQL("SELECT keyworddefs.id, keyworddefs.name, keyworddefs.description,
COUNT(keywords.bug_id), keywords.bug_id
FROM keyworddefs LEFT JOIN keywords ON keyworddefs.id = keywords.keywordid
GROUP BY keyworddefs.id
ORDER BY keyworddefs.name");
} else {
SendSQL("SELECT keyworddefs.id, keyworddefs.name, keyworddefs.description,
COUNT(keywords.keywordid), keywords.bug_id
FROM keyworddefs, keywords
WHERE keyworddefs.id = keywords.keywordid (+)
GROUP BY keyworddefs.id, keyworddefs.name,
keyworddefs.description, keywords.bug_id
ORDER BY keyworddefs.name");
}
while (MoreSQLData()) {
my ($id, $name, $description, $bugs, $onebug) = FetchSQLData();
$description ||= "<FONT COLOR=\"red\">missing</FONT>";
$bugs ||= 'none';
if (!$onebug) {
# This is silly hackery for old versions of MySQL that seem to
# return a count() of 1 even if there are no matching. So, we
# ask for an actual bug number. If it can't find any bugs that
# match the keyword, then we set the count to be zero, ignoring
# what it had responded.
$bugs = 'none';
}
if ($line_count == $max_table_size) {
print "</table>\n$tableheader";
$line_count = 0;
}
$line_count++;
print qq{
<TR BGCOLOR="#ECECEC">
<TH ALIGN="left"><A HREF="editkeywords.cgi?action=edit&id=$id">$name</TH>
<TD ALIGN="left">$description</TD>
<TD ALIGN="left" ALIGN="right">$bugs</TD>
<TH ALIGN="left"><A HREF="editkeywords.cgi?action=delete&id=$id">Delete</TH>
</TR>
};
}
print qq{
<TR BGCOLOR="#ECECEC">
<TH VALIGN="top" COLSPAN=4><A HREF="editkeywords.cgi?action=add">Add a new keyword</A></TH>
</TR>
</TABLE>
};
PutTrailer();
exit;
}
if ($action eq 'add') {
PutHeader("Add keyword");
print "<FORM METHOD=POST ACTION=editkeywords.cgi>\n";
print "<TABLE BORDER=0 CELLPADDING=4 CELLSPACING=0 ALIGN=center>\n";
EmitFormElements(-1, '', '');
print "</TABLE>\n<HR ALIGN=center WIDTH=800>\n";
print "<CENTER><INPUT TYPE=SUBMIT VALUE=\"Add\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"action\" VALUE=\"new\"></CENTER>\n";
print "</FORM>";
my $other = $localtrailer;
$other =~ s/more/other/;
PutTrailer($other);
exit;
}
#
# action='new' -> add keyword entered in the 'action=add' screen
#
if ($action eq 'new') {
PutHeader("Adding new keyword");
# Cleanups and valididy checks
my $name = trim($::FORM{name} || '');
my $description = trim($::FORM{description} || '');
Validate($name, $description);
SendSQL("SELECT id FROM keyworddefs WHERE name = " . SqlQuote($name));
if (FetchOneColumn()) {
print "<CENTER>The keyword '$name' already exists. Please press\n";
print "<b>Back</b> and try again.</CENTER>\n";
PutTrailer($localtrailer);
exit;
}
# Pick an unused number. Be sure to recycle numbers that may have been
# deleted in the past. This code is potentially slow, but it happens
# rarely enough, and there really aren't ever going to be that many
# keywords anyway.
SendSQL("SELECT id FROM keyworddefs ORDER BY id");
my $newid = 1;
while (MoreSQLData()) {
my $oldid = FetchOneColumn();
if ($oldid > $newid) {
last;
}
$newid = $oldid + 1;
}
# Add the new keyword.
SendSQL("INSERT INTO keyworddefs (id, name, description) VALUES ($newid, " .
SqlQuote($name) . "," .
SqlQuote($description) . ")");
# Make versioncache flush
unlink "data/versioncache";
print "<CENTER>OK, done.</CENTER><p>\n";
PutTrailer($localtrailer);
exit;
}
#
# action='edit' -> present the edit keywords from
#
# (next action would be 'update')
#
if ($action eq 'edit') {
PutHeader("Edit keyword");
my $id = trim($::FORM{id} || 0);
# get data of keyword
SendSQL("SELECT name,description
FROM keyworddefs
WHERE id=$id");
my ($name, $description) = FetchSQLData();
if (!$name) {
print "<CENTER>Something screwy is going on. Please try again.</CENTER>\n";
PutTrailer($localtrailer);
exit;
}
print "<FORM METHOD=POST ACTION=editkeywords.cgi>\n";
print "<TABLE BORDER=0 CELLPADDING=4 CELLSPACING=0 ALIGN=center>\n";
EmitFormElements($id, $name, $description);
print "<TR>\n";
print " <TH ALIGN=\"right\">Bugs:</TH>\n";
print " <TD>";
SendSQL("SELECT count(*)
FROM keywords
WHERE keywordid = $id");
my $bugs = '';
$bugs = FetchOneColumn() if MoreSQLData();
print $bugs || 'none';
print "</TD>\n</TR></TABLE>\n";
print "<CENTER><INPUT TYPE=HIDDEN NAME=\"action\" VALUE=\"update\">\n";
print "<INPUT TYPE=SUBMIT VALUE=\"Update\"></CENTER>\n";
print "</FORM>";
my $x = $localtrailer;
$x =~ s/more/other/;
PutTrailer($x);
exit;
}
#
# action='update' -> update the keyword
#
if ($action eq 'update') {
PutHeader("Update keyword");
my $id = $::FORM{id};
my $name = trim($::FORM{name} || '');
my $description = trim($::FORM{description} || '');
Validate($name, $description);
SendSQL("SELECT id FROM keyworddefs WHERE name = " . SqlQuote($name));
my $tmp = FetchOneColumn();
if ($tmp && $tmp != $id) {
print "The keyword '$name' already exists. Please press\n";
print "<b>Back</b> and try again.\n";
PutTrailer($localtrailer);
exit;
}
SendSQL("UPDATE keyworddefs SET name = " . SqlQuote($name) .
", description = " . SqlQuote($description) .
" WHERE id = $id");
print "<CENTER>Keyword updated.</CENTER><BR>\n";
# Make versioncache flush
unlink "data/versioncache";
PutTrailer($localtrailer);
exit;
}
if ($action eq 'delete') {
PutHeader("Delete keyword");
my $id = $::FORM{id};
SendSQL("SELECT name FROM keyworddefs WHERE id=$id");
my $name = FetchOneColumn();
if (!$::FORM{reallydelete}) {
SendSQL("SELECT count(*)
FROM keywords
WHERE keywordid = $id");
my $bugs = FetchOneColumn();
if ($bugs) {
print qq{
<CENTER>There are $bugs bugs which have this keyword set. Are you <b>sure</b> you want
to delete the <code>$name</code> keyword?
<FORM METHOD=POST ACTION=editkeywords.cgi>
<INPUT TYPE=HIDDEN NAME="id" VALUE="$id">
<INPUT TYPE=HIDDEN NAME="action" VALUE="delete">
<INPUT TYPE=HIDDEN NAME="reallydelete" VALUE="1">
<INPUT TYPE=SUBMIT VALUE="Yes, really delete the keyword">
</FORM></CENTER>
};
PutTrailer($localtrailer);
exit;
}
}
SendSQL("DELETE FROM keywords WHERE keywordid = $id");
SendSQL("DELETE FROM keyworddefs WHERE id = $id");
print "<CENTER>Keyword $name deleted.</CENTER>\n";
# Make versioncache flush
unlink "data/versioncache";
PutTrailer($localtrailer);
exit;
}
PutHeader("Error");
print "<CENTER>I don't have a clue what you want.</CENTER><BR>\n";
foreach ( sort keys %::FORM) {
print "$_: $::FORM{$_}<BR>\n";
}

View File

@@ -1,437 +0,0 @@
#!/usr/bonsaitools/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
# David Lawrence <dkl@redhat.com>
#
use diagnostics;
use strict;
require "CGI.pl";
require "globals.pl";
# print "Content-type: text/html\n\n";
# subroutine: PutGroupForm
# description: prints form for multiple choices
# params: none
# returns none
sub PutGroupForm {
my $query = "select groupid, description from groups order by groupid";
SendSQL($query);
my %grouplist;
while (my @row = FetchSQLData()) {
$grouplist{$row[0]} = $row[1];
}
print qq{
<P>
<B>1. Select members above that you want effected.<BR>
2. Check which groups below you wish the members to be in.<BR>
3. Click Update to commit the changes.</B><BR>
<P>
<TABLE ALIGN=center BORDER=1 CELLSPACING=0>
<TR>
<TD ALIGN=center><INPUT TYPE=radio NAME=group_type VALUE=add CHECKED>Add to checked groups</TD>
<TD ALIGN=center><INPUT TYPE=radio NAME=group_type VALUE=remove>Remove from checked groups</TD>
</TR>
</TABLE>
<P>
};
my $count = 0;
foreach my $i (keys %grouplist) {
print qq{<INPUT TYPE=checkbox NAME=group-$i>&nbsp;$grouplist{$i}<br>};
}
# print "
#<SCRIPT>
#numelements = document.changeform.elements.length;
#function SetCheckboxes(value) {
# for (var i=0 ; i<numelements ; i++) {
# item = document.changeform.elements\[i\];
# item.checked = value;
# }
#}
#document.write(\" <input type=button value=\\\"Uncheck All\\\" onclick=\\\"SetCheckboxes(false);\\\"> <input type=button value=\\\"Check All\\\" onclick=\\\"SetCheckboxes(true);\\\">\");
#</SCRIPT>\n";
print qq{
<P>
<HR>
<INPUT TYPE=hidden NAME=multiple VALUE=1>
<CENTER><INPUT TYPE=submit NAME=update VALUE=" Update! "></CENTER>
</FORM>
};
}
# subroutine: UpdateGroups
# description: updates member(s) group permissions
# params: none
# returns: none
sub UpdateGroups {
if (defined($::FORM{'multiple'}) && $::FORM{'multiple'} eq '1') {
foreach my $user (grep(/^user-.*$/, keys %::FORM)) {
$user =~ s/^user-//g;
foreach my $i (grep (/^group-.*$/, keys %::FORM)) {
$i =~ s/^group-//g;
SendSQL("select userid from user_group where userid = $user and groupid = $i");
my $result = FetchOneColumn();
if (!$result && $::FORM{'group_type'} eq 'add') {
SendSQL("insert into user_group values ($user, $i)");
} elsif ($result && $::FORM{'group_type'} eq 'remove') {
SendSQL("delete from user_group where userid = $user and groupid = $i");
}
}
}
} else {
SendSQL("delete from user_group where userid = " . $::FORM{'userid'});
foreach my $i (grep (/^group-.*$/, keys %::FORM)) {
$i =~ s/^group-//g;
SendSQL("insert into user_group values (" .
$::FORM{'userid'} . ", $i)");
}
}
return 1;
}
# subroutine: SortPopup
# description: generate popup for sorting results list by group
# params: none
# returns: $popup = string containing html to generate group sort popup (scalar)
sub SortPopup {
my $popup = "";
my $query = "select groupid, name from groups order by groupid";
SendSQL($query);
my %groups;
while (my @row = FetchSQLData()) {
$groups{$row[1]} = $row[0];
}
$popup .= qq{
<FORM METHOD=get ACTION=editmembers.cgi>
<B>Sort by group</B>
<SELECT NAME=sort>
<OPTION VALUE="all">All
};
my @sorted_ids = sort keys %groups;
foreach my $group (@sorted_ids) {
my $selected = $::FORM{'sort'} eq $groups{$group} ? " SELECTED" : "";
$popup .= "<OPTION VALUE=\"$groups{$group}\" $selected>$group";
}
$popup .= qq{
</SELECT>
<INPUT TYPE=submit NAME= do_sort VALUE="Sort">
<INPUT TYPE=hidden NAME=login_name VALUE="$::FORM{'login_name'}">
<INPUT TYPE=hidden NAME=real_name VALUE="$::FORM{'real_name'}">
<INPUT TYPE=hidden NAME=multiple VALUE="$::FORM{'multiple'}">
</FORM>
};
return $popup;
}
confirm_login();
print "Content-type: text/html\n\n";
if (!UserInGroup("editgroupmembers")) {
PutHeader("Not Allowed");
PutError("Sorry, you aren't a member of the 'editgroupmembers' group.<BR>" .
"And so, you aren't allowed to edit the members.");
}
PutHeader("Edit Members");
if ($::FORM{'submit'} || $::FORM{'sort'}) {
my $sort_popup = SortPopup();
print "<CENTER><H2>Results for search on ";
if ($::FORM{'login_name'}) {
print "$::FORM{'login_name'} ";
}
if ($::FORM{'login_name'} && $::FORM{'realname'}) {
print " and ";
}
if ($::FORM{'realname'}) {
print "$::FORM{'realname'} ";
}
print "</H2></CENTER>\n";
# User didnt enter anything
if (!$::FORM{'login_name'} && !$::FORM{'realname'}) {
PutError("<P>Illegal values - Back up and try again.");
}
# Form the Query
my $query = "";
if (defined($::FORM{'sort'}) && $::FORM{'sort'} ne 'all' && $::FORM{'sort'} ne '') {
$query = "select profiles.userid, profiles.login_name, profiles.realname " .
"from profiles, user_group " .
"where user_group.userid = profiles.userid and " .
"user_group.groupid = $::FORM{'sort'} and ";
} else {
$query = "select profiles.userid, profiles.login_name, profiles.realname " .
"from profiles where ";
}
if ($::FORM{'login_name'}) {
$query .= " profiles.login_name like \'%$::FORM{'login_name'}%\'";
}
if ($::FORM{'login_name'} && $::FORM{'realname'}) {
$query .= " or ";
}
if ($::FORM{'realname'}) {
$query .= " profiles.realname like \'%$::FORM{'realname'}%\'";
}
$query .= " order by profiles.userid";
SendSQL($query);
my @row = ();
# Print the results
print qq{
<CENTER>$sort_popup</CENTER>
<FORM NAME=changeform METHOD=get ACTION=editmembers.cgi>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=4 ALIGN=center>
<TR BGCOLOR="#BFBFBF">
};
if ($::FORM{'multiple'}) {
print "<TH ALIGN=left>Select</TH>\n";
}
print qq{
<TH ALIGN=left>User ID</TH>
<TH ALIGN=left>Email Address</TH>
<TH ALIGN=left>Real Name</TH>
</TR>
};
my $count = 0;
while (@row = FetchSQLData()) {
print qq{
<TR BGCOLOR="#ECECEC">
};
if ($::FORM{'multiple'}) {
print "<TD ALIGN=center><INPUT TYPE=checkbox NAME=\"user-$row[0]\"></TD>\n";
}
print qq{
<TD ALIGN=center><A HREF="editmembers.cgi?\&userid=$row[0]">$row[0]</A>&nbsp;</TD>
<TD ALIGN=left>$row[1]</TD>
};
# For some reason netscape was choking when this value was NULL
if (!$row[2]) {
$row[2] = "&nbsp;";
}
print qq{
<TD ALIGN=left>$row[2]</TD>
</TR>
};
}
print qq{</TABLE>\n};
if ($::FORM{'multiple'}) {
print "<P><TABLE ALIGN=center>\n<TR>\n<TD ALIGN=left>\n";
PutGroupForm();
print "</TD>\n</TR>\n</TABLE>\n";
}
print qq{
<P>
<CENTER>
<A HREF="editmembers.cgi?submit=1&login_name=$::FORM{'login_name'}&realname=$::FORM{'realname'}&multiple=1&sort=$::FORM{'sort'}">
[Edit multiple members at once]</A> &nbsp;
<A HREF="editmembers.cgi">[Find another member]</A>
</CENTER>
};
PutFooter();
exit;
}
# single member selected so display information for changing
if ($::FORM{'userid'}) {
# we made changes to a single member
if ($::FORM{'update'}) {
if ($::FORM{'password'} ne "" && $::FORM{'retype'} ne "") {
if ($::FORM{'password'} ne $::FORM{'retype'}) {
print qq{
<FONT SIZE=+1 COLOR=red>Sorry.</FONT><B>The passwords you entered were not the same.
Please click BACK and correct the error.</B>
};
exit;
}
my $password = $::FORM{'password'};
my $encrypted = crypt($password, substr($password, 0, 2));
SendSQL("update profiles set password = " . SqlQuote($password) .
", cryptpassword = " . SqlQuote($encrypted) .
" where login_name = " . SqlQuote($::FORM{'login_name'}));
MailPassword($::FORM{'login_name'}, $password, 1);
print "<CENTER><B>Password changed and member notified.</B></CENTER><BR>\n";
}
SendSQL("update profiles set login_name = " . SqlQuote($::FORM{'login_name'}) .
" where userid = " . $::FORM{'userid'});
print "<CENTER><B>Login name updated.</B></CENTER><BR>\n";
SendSQL("update profiles set realname = " . SqlQuote($::FORM{'realname'}) .
" where userid = " . $::FORM{'userid'});
print "<CENTER><B>Real name updated.</B></CENTER><BR>\n";
if (UpdateGroups()) {
print "<CENTER><B>Group membership updated.</B></CENTER><P>\n";
}
}
SendSQL("select login_name, realname from profiles where userid = " . $::FORM{'userid'});
my @user_info = FetchSQLData();
SendSQL("select groupid, description from groups order by groupid");
my %grouplist;
my @row;
while (@row = FetchSQLData()) {
$grouplist{$row[0]} = $row[1];
}
SendSQL("select groupid from user_group where userid = " . $::FORM{'userid'});
my @groupbelong;
while (@row = FetchSQLData()) {
push (@groupbelong, $row[0]);
}
print qq{
<CENTER><H1>Information for <FONT COLOR=blue>$user_info[0]</FONT></H1></CENTER>
<P>
<FORM NAME=changeform METHOD=post ACTION=editmembers.cgi>
<TABLE ALIGN=center CELLSPACING=0 CELLPADDING=4>
<TR>
<TD ALIGN=right><B>User ID#: </B></TD>
<TD ALIGN=left><B><FONT COLOR=blue>$::FORM{'userid'}</FONT></B></TD>
</TR><TR>
<TD ALIGN=right><B>Email Address: </B></TD>
<TD ALIGN=left><INPUT TYPE=text SIZE=40 MAXLENGTH=60 NAME=login_name VALUE="$user_info[0]"></TD>
</TR><TR>
<TD ALIGN=right><B>Real Name: </B></TD>
<TD ALIGN=left><INPUT TYPE=text SIZE=40 MAXLENGTH=60 NAME=realname VALUE="$user_info[1]"></TD>
</TR><TR>
<TD ALIGN=right><B>New Password (8 chars.): </B></TD>
<TD ALIGN=left><INPUT TYPE=password NAME=password></TD>
</TR><TR>
<TD ALIGN=right><B>Retype New Password (8 chars.): </TD>
<TD ALIGN=left><INPUT TYPE=password NAME=retype></TD>
</TR>
</TABLE>
<CENTER><B><FONT SIZE=+1 COLOR=red>Note:</FONT> If the current password is changed, it will be automatically
mailed out to the member.</B></CENTER>
<P>
<HR WIDTH=800>
<TABLE ALIGN=center CELLSPACING=0 CELLPADDING=4>
<TR>
<TH>Check which groups you wish this member to be in.</TH>
</TR><TR>
<TD ALIGN=left>
<INPUT TYPE=HIDDEN NAME=userid VALUE="$::FORM{'userid'}">
};
my $count = 0;
foreach my $i (keys %grouplist) {
my $c;
if (lsearch(\@groupbelong, $i) >= 0) {
$c = 'CHECKED';
} else {
$c = '';
}
print qq{
<INPUT TYPE=checkbox NAME=group-$i $c> $grouplist{$i}<br>
};
}
print "
<P>
<SCRIPT>
numelements = document.changeform.elements.length;
function SetCheckboxes(value) {
for (var i=0 ; i<numelements ; i++) {
item = document.changeform.elements\[i\];
item.checked = value;
}
}
document.write(\" <input type=button value=\\\"Uncheck All\\\" onclick=\\\"SetCheckboxes(false);\\\"> <input type=button value=\\\"Check All\\\" onclick=\\\"SetCheckboxes(true);\\\">\");
</SCRIPT>\n";
print qq{
</TD>
</TR>
</TABLE>
<P>
<CENTER>
<HR WIDTH=800>
<INPUT TYPE=submit NAME=update VALUE=" Update! ">
</FORM>
<A HREF="editmembers.cgi">[Edit another member]</A>
</CENTER>
};
PutFooter();
exit;
}
# we made group changes to multiple members
if ($::FORM{'update'} && $::FORM{'multiple'} eq '1') {
if (UpdateGroups()) {
print "<CENTER><B>Member group permissions successfully updated.</B></CENTER>\n";
exit;
} else {
print "<CENTER><B>Member group updated unsuccessful!</B></CENTER>\n";
exit;
}
}
print qq{
<FORM <METHOD=post ACTION=editmembers.cgi>
<TABLE ALIGN=center>
<TR>
<TD COLSPAN=2><U><B>Enter email address or partial real name of member you want to edit</B></U></TD>
</TR><TR>
<TD ALIGN=right><B>Email Address: </B></TD>
<TD ALIGN=left><INPUT TYPE=text SIZE=30 MAXLENGTH=40 NAME=login_name></TD>
</TR><TR>
<TD ALIGN=right><B>Full Name: </B></TD>
<TD ALIGN=left><INPUT TYPE=text SIZE=30 MAXLENGTH=40 NAME=realname></TD>
</TR><TR>
<TD COLSPAN=2 ALIGN=center><INPUT TYPE=submit NAME=submit VALUE=Find></TD>
</TR>
</TABLE>
</FORM>
};
PutFooter();
exit;

View File

@@ -1,568 +0,0 @@
#!/usr/bonsaitools/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# This is a script to edit the target milestones. It is largely a copy of
# the editversions.cgi script, since the two fields were set up in a
# very similar fashion.
#
# (basically replace each occurance of 'milestone' with 'version', and
# you'll have the original script)
#
# Matt Masson <matthew@zeroknowledge.com>
#
use diagnostics;
use strict;
require "CGI.pl";
require "globals.pl";
# TestProduct: just returns if the specified product does exists
# CheckProduct: same check, optionally emit an error text
# TestMilestone: just returns if the specified product/version combination exists
# CheckMilestone: same check, optionally emit an error text
sub TestProduct ($)
{
my $prod = shift;
# does the product exist?
SendSQL("SELECT product
FROM products
WHERE product=" . SqlQuote($prod));
return FetchOneColumn();
}
sub CheckProduct ($)
{
my $prod = shift;
# do we have a product?
unless ($prod) {
print "Sorry, you haven't specified a product.";
PutTrailer();
exit;
}
unless (TestProduct $prod) {
print "Sorry, product '$prod' does not exist.";
PutTrailer();
exit;
}
}
sub TestMilestone ($$)
{
my ($prod,$mile) = @_;
# does the product exist?
SendSQL("SELECT product,value
FROM milestones
WHERE product=" . SqlQuote($prod) . " and value=" . SqlQuote($mile));
return FetchOneColumn();
}
sub CheckMilestone ($$)
{
my ($prod,$mile) = @_;
# do we have the milestone?
unless ($mile) {
print "Sorry, you haven't specified a milestone.";
PutTrailer();
exit;
}
CheckProduct($prod);
unless (TestMilestone $prod,$mile) {
print "Sorry, milestone '$mile' for product '$prod' does not exist.";
PutTrailer();
exit;
}
}
#
# Displays the form to edit a milestone
#
sub EmitFormElements ($$$)
{
my ($product, $milestone, $sortkey) = @_;
print " <TH ALIGN=\"right\">Milestone:</TH>\n";
print " <TD><INPUT SIZE=64 MAXLENGTH=64 NAME=\"milestone\" VALUE=\"" .
value_quote($milestone) . "\">\n";
print "</TR><TR>\n";
print " <TH ALIGN=\"right\">Sortkey:</TH>\n";
print " <TD><INPUT SIZE=64 MAXLENGTH=64 NAME=\"sortkey\" VALUE=\"" .
value_quote($sortkey) . "\">\n";
print " <INPUT TYPE=HIDDEN NAME=\"product\" VALUE=\"" .
value_quote($product) . "\"></TD>\n";
}
#
# Displays a text like "a.", "a or b.", "a, b or c.", "a, b, c or d."
#
sub PutTrailer (@)
{
my (@links) = ("Back to the <A HREF=\"query.cgi\">query page</A>", @_);
my $count = $#links;
my $num = 0;
print "<P>\n";
foreach (@links) {
print $_;
if ($num == $count) {
print ".\n";
}
elsif ($num == $count-1) {
print " or ";
}
else {
print ", ";
}
$num++;
}
PutFooter();
}
#
# Preliminary checks:
#
confirm_login();
print "Content-type: text/html\n\n";
unless (UserInGroup("editcomponents")) {
PutHeader("Not allowed");
print "Sorry, you aren't a member of the 'editcomponents' group.\n";
print "And so, you aren't allowed to add, modify or delete milestones.\n";
PutTrailer();
exit;
}
#
# often used variables
#
my $product = trim($::FORM{product} || '');
my $milestone = trim($::FORM{milestone} || '');
my $sortkey = trim($::FORM{sortkey} || '0');
my $action = trim($::FORM{action} || '');
my $localtrailer;
if ($milestone) {
$localtrailer = "<A HREF=\"editmilestones.cgi?product=" . url_quote($product) . "\">edit</A> more milestones";
} else {
$localtrailer = "<A HREF=\"editmilestones.cgi\">edit</A> more milestones";
}
#
# product = '' -> Show nice list of milestones
#
unless ($product) {
PutHeader("Select product");
SendSQL("SELECT products.product,products.description,'xyzzy'
FROM products
GROUP BY products.product
ORDER BY products.product");
print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0><TR BGCOLOR=\"#6666FF\">\n";
print " <TH ALIGN=\"left\">Edit milestones of ...</TH>\n";
print " <TH ALIGN=\"left\">Description</TH>\n";
print " <TH ALIGN=\"left\">Bugs</TH>\n";
print "</TR>";
while ( MoreSQLData() ) {
my ($product, $description, $bugs) = FetchSQLData();
$description ||= "<FONT COLOR=\"red\">missing</FONT>";
$bugs ||= "none";
print "<TR>\n";
print " <TD VALIGN=\"top\"><A HREF=\"editmilestones.cgi?product=", url_quote($product), "\"><B>$product</B></A></TD>\n";
print " <TD VALIGN=\"top\">$description</TD>\n";
print " <TD VALIGN=\"top\">$bugs</TD>\n";
}
print "</TR></TABLE>\n";
PutTrailer();
exit;
}
#
# action='' -> Show nice list of milestones
#
unless ($action) {
PutHeader("Select milestone");
CheckProduct($product);
SendSQL("SELECT value,sortkey
FROM milestones
WHERE product=" . SqlQuote($product) . "
ORDER BY sortkey,value");
print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0><TR BGCOLOR=\"#6666FF\">\n";
print " <TH ALIGN=\"left\">Edit milestone ...</TH>\n";
#print " <TH ALIGN=\"left\">Bugs</TH>\n";
print " <TH ALIGN=\"left\">Sortkey</TH>\n";
print " <TH ALIGN=\"left\">Action</TH>\n";
print "</TR>";
while ( MoreSQLData() ) {
my ($milestone,$sortkey,$bugs) = FetchSQLData();
$bugs ||= 'none';
print "<TR>\n";
print " <TD VALIGN=\"top\"><A HREF=\"editmilestones.cgi?product=", url_quote($product), "&milestone=", url_quote($milestone), "&action=edit\"><B>$milestone</B></A></TD>\n";
#print " <TD VALIGN=\"top\">$bugs</TD>\n";
print " <TD VALIGN=\"top\" ALIGN=\"right\">$sortkey</TD>\n";
print " <TD VALIGN=\"top\"><A HREF=\"editmilestones.cgi?product=", url_quote($product), "&milestone=", url_quote($milestone), "&action=del\"><B>Delete</B></A></TD>\n";
print "</TR>";
}
print "<TR>\n";
print " <TD VALIGN=\"top\" COLSPAN=\"2\">Add a new milestone</TD>\n";
print " <TD VALIGN=\"top\" ALIGN=\"middle\"><A HREF=\"editmilestones.cgi?product=", url_quote($product) . "&action=add\">Add</A></TD>\n";
print "</TR></TABLE>\n";
PutTrailer();
exit;
}
#
# action='add' -> present form for parameters for new milestone
#
# (next action will be 'new')
#
if ($action eq 'add') {
PutHeader("Add milestone");
CheckProduct($product);
#print "This page lets you add a new milestone to a $::bugzilla_name tracked product.\n";
print "<FORM METHOD=POST ACTION=editmilestones.cgi>\n";
print "<TABLE BORDER=0 CELLPADDING=4 CELLSPACING=0><TR>\n";
EmitFormElements($product, $milestone, 0);
print "</TABLE>\n<HR>\n";
print "<INPUT TYPE=SUBMIT VALUE=\"Add\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"action\" VALUE=\"new\">\n";
print "</FORM>";
my $other = $localtrailer;
$other =~ s/more/other/;
PutTrailer($other);
exit;
}
#
# action='new' -> add milestone entered in the 'action=add' screen
#
if ($action eq 'new') {
PutHeader("Adding new milestone");
CheckProduct($product);
# Cleanups and valididy checks
unless ($milestone) {
print "You must enter a text for the new milestone. Please press\n";
print "<b>Back</b> and try again.\n";
PutTrailer($localtrailer);
exit;
}
if (TestMilestone($product,$milestone)) {
print "The milestone '$milestone' already exists. Please press\n";
print "<b>Back</b> and try again.\n";
PutTrailer($localtrailer);
exit;
}
# Add the new milestone
SendSQL("INSERT INTO milestones ( " .
"value, product, sortkey" .
" ) VALUES ( " .
SqlQuote($milestone) . "," .
SqlQuote($product) . ", $sortkey)");
# Make versioncache flush
unlink "data/versioncache";
print "OK, done.<p>\n";
PutTrailer($localtrailer);
exit;
}
#
# action='del' -> ask if user really wants to delete
#
# (next action would be 'delete')
#
if ($action eq 'del') {
PutHeader("Delete milestone");
CheckMilestone($product, $milestone);
SendSQL("SELECT count(bug_id),product,target_milestone
FROM bugs
GROUP BY product,target_milestone
HAVING product=" . SqlQuote($product) . "
AND target_milestone=" . SqlQuote($milestone));
my $bugs = FetchOneColumn();
SendSQL("SELECT defaultmilestone FROM products " .
"WHERE product=" . SqlQuote($product));
my $defaultmilestone = FetchOneColumn();
print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0>\n";
print "<TR BGCOLOR=\"#6666FF\">\n";
print " <TH VALIGN=\"top\" ALIGN=\"left\">Part</TH>\n";
print " <TH VALIGN=\"top\" ALIGN=\"left\">Value</TH>\n";
print "</TR><TR>\n";
print " <TH ALIGN=\"left\" VALIGN=\"top\">Product:</TH>\n";
print " <TD VALIGN=\"top\">$product</TD>\n";
print "</TR><TR>\n";
print " <TH ALIGN=\"left\" VALIGN=\"top\">Milestone:</TH>\n";
print " <TD VALIGN=\"top\">$milestone</TD>\n";
print "</TR><TR>\n";
print " <TH ALIGN=\"left\" VALIGN=\"top\">Bugs:</TH>\n";
print " <TD VALIGN=\"top\">", $bugs || 'none' , "</TD>\n";
print "</TR></TABLE>\n";
print "<H2>Confirmation</H2>\n";
if ($bugs) {
if (!Param("allowbugdeletion")) {
print "Sorry, there are $bugs bugs outstanding for this milestone.
You must reassign those bugs to another milestone before you can delete this
one.";
PutTrailer($localtrailer);
exit;
}
print "<TABLE BORDER=0 CELLPADDING=20 WIDTH=\"70%\" BGCOLOR=\"red\"><TR><TD>\n",
"There are bugs entered for this milestone! When you delete this ",
"milestone, <B><BLINK>all</BLINK></B> stored bugs will be deleted, too. ",
"You could not even see the bug history for this milestone anymore!\n",
"</TD></TR></TABLE>\n";
}
if ($defaultmilestone eq $milestone) {
print "Sorry; this is the default milestone for this product, and " .
"so it can not be deleted.";
PutTrailer($localtrailer);
exit;
}
print "<P>Do you really want to delete this milestone?<P>\n";
print "<FORM METHOD=POST ACTION=editmilestones.cgi>\n";
print "<INPUT TYPE=SUBMIT VALUE=\"Yes, delete\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"action\" VALUE=\"delete\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"product\" VALUE=\"" .
value_quote($product) . "\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"milestone\" VALUE=\"" .
value_quote($milestone) . "\">\n";
print "</FORM>";
PutTrailer($localtrailer);
exit;
}
#
# action='delete' -> really delete the milestone
#
if ($action eq 'delete') {
PutHeader("Deleting milestone");
CheckMilestone($product,$milestone);
# lock the tables before we start to change everything:
SendSQL("LOCK TABLES attachments WRITE,
bugs WRITE,
bugs_activity WRITE,
milestones WRITE,
dependencies WRITE");
# According to MySQL doc I cannot do a DELETE x.* FROM x JOIN Y,
# so I have to iterate over bugs and delete all the indivial entries
# in bugs_activies and attachments.
if (Param("allowbugdeletion")) {
SendSQL("SELECT bug_id
FROM bugs
WHERE product=" . SqlQuote($product) . "
AND target_milestone=" . SqlQuote($milestone));
while (MoreSQLData()) {
my $bugid = FetchOneColumn();
my $query =
$::db->query("DELETE FROM attachments WHERE bug_id=$bugid")
or die "$::db_errstr";
$query =
$::db->query("DELETE FROM bugs_activity WHERE bug_id=$bugid")
or die "$::db_errstr";
$query =
$::db->query("DELETE FROM dependencies WHERE blocked=$bugid")
or die "$::db_errstr";
}
print "Attachments, bug activity and dependencies deleted.<BR>\n";
# Deleting the rest is easier:
SendSQL("DELETE FROM bugs
WHERE product=" . SqlQuote($product) . "
AND target_milestone=" . SqlQuote($milestone));
print "Bugs deleted.<BR>\n";
}
SendSQL("DELETE FROM milestones
WHERE product=" . SqlQuote($product) . "
AND value=" . SqlQuote($milestone));
print "Milestone deleted.<P>\n";
SendSQL("UNLOCK TABLES");
unlink "data/versioncache";
PutTrailer($localtrailer);
exit;
}
#
# action='edit' -> present the edit milestone form
#
# (next action would be 'update')
#
if ($action eq 'edit') {
PutHeader("Edit milestone");
CheckMilestone($product,$milestone);
SendSQL("SELECT sortkey FROM milestones WHERE product=" .
SqlQuote($product) . " AND value = " . SqlQuote($milestone));
my $sortkey = FetchOneColumn();
print "<FORM METHOD=POST ACTION=editmilestones.cgi>\n";
print "<TABLE BORDER=0 CELLPADDING=4 CELLSPACING=0><TR>\n";
EmitFormElements($product, $milestone, $sortkey);
print "</TR></TABLE>\n";
print "<INPUT TYPE=HIDDEN NAME=\"milestoneold\" VALUE=\"" .
value_quote($milestone) . "\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"sortkeyold\" VALUE=\"" .
value_quote($sortkey) . "\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"action\" VALUE=\"update\">\n";
print "<INPUT TYPE=SUBMIT VALUE=\"Update\">\n";
print "</FORM>";
my $other = $localtrailer;
$other =~ s/more/other/;
PutTrailer($other);
exit;
}
#
# action='update' -> update the milestone
#
if ($action eq 'update') {
PutHeader("Update milestone");
my $milestoneold = trim($::FORM{milestoneold} || '');
my $sortkeyold = trim($::FORM{sortkeyold} || '0');
CheckMilestone($product,$milestoneold);
SendSQL("LOCK TABLES bugs WRITE,
milestones WRITE,
products WRITE");
if ($milestone ne $milestoneold) {
unless ($milestone) {
print "Sorry, I can't delete the milestone text.";
PutTrailer($localtrailer);
SendSQL("UNLOCK TABLES");
exit;
}
if (TestMilestone($product,$milestone)) {
print "Sorry, milestone '$milestone' is already in use.";
PutTrailer($localtrailer);
SendSQL("UNLOCK TABLES");
exit;
}
SendSQL("UPDATE bugs
SET target_milestone=" . SqlQuote($milestone) . "
WHERE target_milestone=" . SqlQuote($milestoneold) . "
AND product=" . SqlQuote($product));
SendSQL("UPDATE milestones
SET value=" . SqlQuote($milestone) . "
WHERE product=" . SqlQuote($product) . "
AND value=" . SqlQuote($milestoneold));
SendSQL("UPDATE products " .
"SET defaultmilestone = " . SqlQuote($milestone) .
"WHERE product = " . SqlQuote($product) .
" AND defaultmilestone = " . SqlQuote($milestoneold));
unlink "data/versioncache";
print "Updated milestone.<BR>\n";
}
if ($sortkey != $sortkeyold) {
SendSQL("UPDATE milestones SET sortkey=$sortkey
WHERE product=" . SqlQuote($product) . "
AND value=" . SqlQuote($milestoneold));
unlink "data/versioncache";
print "Updated sortkey.<BR>\n";
}
SendSQL("UNLOCK TABLES");
PutTrailer($localtrailer);
exit;
}
#
# No valid action found
#
PutHeader("Error");
print "I don't have a clue what you want.<BR>\n";
foreach ( sort keys %::FORM) {
print "$_: $::FORM{$_}<BR>\n";
}

View File

@@ -1,369 +0,0 @@
#!/usr/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public License
# Version 1.0 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
#
# Direct any questions on this source code to
#
# Holger Schurig <holgerschurig@nikocity.de>
# David Lawrence <dkl@redhat.com>
use diagnostics;
use strict;
require "CGI.pl";
require "globals.pl";
#
# Displays the form to edit news articles
#
sub EmitFormElements {
my ($id, $add_date, $headline, $story) = (@_);
print qq{
<TH ALIGN="right">Headline</TH>
<TD><INPUT SIZE=64 MAXLENGTH=64 NAME=headline VALUE="$headline"></TD>
</TR><TR>
<TH ALIGN="right">Story</TH>
<TD><TEXTAREA ROWS=4 COLS=64 WRAP=VIRTUAL NAME=story>$$story</TEXTAREA></TD>
</TR>
};
}
#
# Displays a text like "a.", "a or b.", "a, b or c.", "a, b, c or d."
#
sub PutTrailer {
my (@links) = ("Back to the <A HREF=\"query.cgi\">query page</A>", @_);
my $count = $#links;
my $num = 0;
print "<P>\n";
print "<CENTER>";
foreach (@links) {
print $_;
if ($num == $count) {
print ".\n";
}
elsif ($num == $count-1) {
print " or ";
}
else {
print ", ";
}
$num++;
}
print "</CENTER>\n";
}
#
# Preliminary checks:
#
confirm_login();
print "Content-type: text/html\n\n";
unless (UserInGroup("addnews")) {
PutHeader("Not allowed");
PutError("Sorry, you aren't a member of the 'addnews' group.<BR>" .
"And so, you aren't allowed to add, modify or delete news items.");
}
#
# often used variables
#
my $id = trim($::FORM{'id'} || '');
my $action = trim($::FORM{'action'} || '');
my $localtrailer = "<A HREF=\"editnews.cgi\">edit</A> more news items";
#
# action='' -> Show nice list of groups
#
unless ($action) {
PutHeader("Select News Item");
if ($::driver eq 'mysql') {
SendSQL("SELECT id, DATE_FORMAT(add_date, '\%b \%d, \%Y \%l:\%i'), headline " .
"FROM news " .
"ORDER BY id");
} else {
SendSQL("SELECT id, TO_CHAR(add_date, 'MON DD, YYYY HH:MI'), headline, story " .
"FROM news " .
"ORDER BY id");
}
print "<P>\n<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0 ALIGN=center><TR BGCOLOR=\"#BFBFBF\">\n";
print " <TH ALIGN=left>ID</TH>\n";
print " <TH ALIGN=left>Date</TH>\n";
print " <TH ALIGN=left>Headline</TH>\n";
print " <TH ALIGN=left>Action</TH>\n";
print "</TR>";
while ( MoreSQLData() ) {
my ($id, $add_date, $headline) = FetchSQLData();
print "<TR BGCOLOR=\"#ECECEC\">\n";
print " <TD ALIGN=left><A HREF=\"editnews.cgi?id=$id&action=edit\">$id</A></TD>\n";
print " <TD ALIGN=left>$add_date</TD>\n";
print " <TD ALIGN=left>$headline</TD>\n";
print " <TD ALIGN=left><A HREF=\"editnews.cgi?id=$id&action=del\">Delete</A></TD>\n";
print "</TR>";
}
print "<TR BGCOLOR=\"#ECECEC\">\n";
print " <TH COLSPAN=4><A HREF=\"editnews.cgi?action=add\">Add a new item</A></TH>\n";
print "</TR></TABLE>\n";
PutTrailer();
PutFooter();
exit;
}
#
# action='add' -> present form for parameters for new item
#
# (next action will be 'new')
#
if ($action eq 'add') {
PutHeader("Add News Item");
#print "This page lets you add a news item to bugzilla.\n";
print "<FORM METHOD=POST ACTION=editnews.cgi>\n";
print "<TABLE BORDER=0 CELLPADDING=4 CELLSPACING=0 ALIGN=center><TR>\n";
EmitFormElements('', '', '<Place headline here>', \'<Place story here>');
print "</TR>\n</TABLE>\n";
print "<CENTER><INPUT TYPE=SUBMIT VALUE=\"Add\"></CENTER>\n";
print "<INPUT TYPE=HIDDEN NAME=\"action\" VALUE=\"new\">\n";
print "</FORM>";
my $other = $localtrailer;
$other =~ s/more/other/;
PutTrailer($other);
PutFooter();
exit;
}
#
# action='new' -> add news item entered in the 'action=add' screen
#
if ($action eq 'new') {
PutHeader("Adding News Item");
my $headline = trim($::FORM{'headline'} || '');
my $story = trim($::FORM{'story'} || '');
# Cleanups and valididy checks
unless ($headline) {
print "You must enter a headline for the news item. Please press\n";
print "<b>Back</b> and try again.\n";
PutTrailer($localtrailer);
exit;
}
SendSQL("select id from news where headline = " . SqlQuote($headline));
my $result = FetchOneColumn();
if ($result) {
print "The news item '$headline' already exists. Please press\n";
print "<b>Back</b> and try again.\n";
PutTrailer($localtrailer);
exit;
}
# Add the new group.
if ($::driver eq 'mysql') {
SendSQL("INSERT INTO news ( " .
"add_date, headline, story" .
") VALUES ( " .
"now(), " .
SqlQuote($headline) . "," .
SqlQuote($story) . ")");
} else {
SendSQL("INSERT INTO news ( " .
"id, add_date, headline, story" .
") VALUES ( " .
"news_seq.nextval, sysdate, " .
SqlQuote($headline) . "," .
SqlQuote($story) . ")");
}
print "<CENTER>OK, done.</CENTER><P>\n";
PutTrailer($localtrailer);
exit;
}
#
# action='del' -> ask if user really wants to delete
#
# (next action would be 'delete')
#
if ($action eq 'del') {
PutHeader("Delete News Item");
# display some data about the news item
if ($::driver eq 'mysql') {
SendSQL("SELECT id, DATE_FORMAT(add_date, '\%b \%d, \%Y \%l:\%i'), headline, story " .
"FROM news " .
"WHERE id = " . $::FORM{'id'});
} else {
SendSQL("SELECT id, TO_CHAR(add_date, 'MON DD, YYYY HH:MI'), headline, story " .
"FROM news " .
"WHERE id = " . $::FORM{'id'});
}
my ($id, $add_date, $headline, $story) = FetchSQLData();
print qq{
<P>
<TABLE ALIGN=center WIDTH=700 BORDER=1 CELLSPACING=0 CELLPADDING=3>
<TR BGCOLOR="#BFBFBF">
<TD ALIGN=left>
<FONT SIZE=+2><B>$headline</B></FONT><BR>
<FONT SIZE=-1>Added on</FONT> <I>$add_date</I>
</TD>
</TR><TR BGCOLOR="#ECECEC">
<TD ALIGN=left>
$story
</TD>
</TR>
</TABLE>
<P>
};
print "<CENTER><H2>Confirmation</H2>\n";
print "</TD>\n</TR></TABLE>";
print "<P>Do you really want to delete this news item?<P>\n";
print "<FORM METHOD=POST ACTION=editnews.cgi>\n";
print "<INPUT TYPE=SUBMIT VALUE=\"Yes, delete\">\n";
print "<INPUT TYPE=HIDDEN NAME=action VALUE=delete>\n";
print "<INPUT TYPE=HIDDEN NAME=id VALUE=$id>\n";
print "</FORM></CENTER>";
PutTrailer($localtrailer);
PutFooter();
exit;
}
#
# action='delete' -> really delete the news item
#
if ($action eq 'delete') {
PutHeader("Deleting News Item");
SendSQL("DELETE FROM news " .
"WHERE id = " . $::FORM{'id'});
print "<CENTER>Item deleted.<BR></CENTER>\n";
PutTrailer($localtrailer);
PutFooter();
exit;
}
#
# action='edit' -> present the edit news item
#
# (next action would be 'update')
#
if ($action eq 'edit') {
PutHeader("Edit News Item");
# get data of group
SendSQL("SELECT id, add_date, headline, story " .
"FROM news " .
"WHERE id = " . $::FORM{'id'});
my ($id, $add_date, $headline, $story) = FetchSQLData();
print "<FORM METHOD=POST ACTION=editnews.cgi>\n";
print "<TABLE BORDER=0 CELLPADDING=4 CELLSPACING=0 ALIGN=center><TR>\n";
EmitFormElements($id, $add_date, $headline, \$story);
print "</TR>\n";
print "</TABLE>\n";
print "<INPUT TYPE=hidden NAME=id VALUE=$id>\n";
print "<INPUT TYPE=hidden NAME=headlineold VALUE=\"$headline\">\n";
print "<INPUT TYPE=hidden NAME=storyold VALUE=\"$story\">\n";
print "<INPUT TYPE=hidden NAME=action VALUE=update>\n";
print "<CENTER><INPUT TYPE=submit VALUE=\"Update\"></CENTER>\n";
print "</FORM>";
my $x = $localtrailer;
$x =~ s/more/other/;
PutTrailer($x);
PutFooter();
exit;
}
#
# action='update' -> update the news item
#
if ($action eq 'update') {
PutHeader("Update News Item");
my $id = trim($::FORM{'id'});
my $headlineold = trim($::FORM{'headlineold'} || '');
my $storyold = trim($::FORM{'storyold'} || '');
my $headline = trim($::FORM{'headline'} || '');
my $story = trim($::FORM{'story'} || '');
if ($headline ne $headlineold) {
unless ($headline ne "") {
print "Sorry, I can't delete the headline.";
PutTrailer($localtrailer);
exit;
}
SendSQL("UPDATE news " .
"SET headline = " . SqlQuote($headline) .
" WHERE id = $id");
print "Updated headline.<BR>\n";
}
if ($story ne $storyold) {
unless ($story ne "") {
print "Sorry, I can't delete the story.";
PutTrailer($localtrailer);
exit;
}
SendSQL("UPDATE news " .
"SET story = " . SqlQuote($story) .
" WHERE id = $id");
print "Updated story.<BR>\n";
}
PutTrailer($localtrailer);
exit;
}
#
# No valid action found
#
PutHeader("Error");
print "I don't have a clue what you want.<BR>\n";
foreach ( sort keys %::FORM) {
print "$_: $::FORM{$_}<BR>\n";
}

View File

@@ -1,69 +0,0 @@
#!/usr/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public License
# Version 1.0 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are Copyright (C) 1998
# Netscape Communications Corporation. All Rights Reserved.
#
# Contributor(s): Sam Ziegler <sam@ziegler.org>
# Code derived from editparams.cgi
use diagnostics;
use strict;
require "CGI.pl";
confirm_login();
print "Content-type: text/html\n\n";
if (!UserInGroup("editcomponents")) {
print "<H1>Sorry, you aren't a member of the 'editcomponents' group.</H1>\n";
print "And so, you aren't allowed to edit the owners.\n";
exit;
}
PutHeader("Edit Component Owners");
print "This lets you edit the owners of the program components of bugzilla.\n";
print "<form method=post action=doeditowners.cgi><table>\n";
my $rowbreak = "<tr><td colspan=2><hr></td></tr>";
SendSQL("select program, value, initialowner from components order by program, value");
my @line;
my $curProgram = "";
while (@line = FetchSQLData()) {
if ($line[0] ne $curProgram) {
print $rowbreak;
print "<tr><th align=right valign=top>$line[0]:</th><td></td></tr>\n";
$curProgram = $line[0];
}
print "<tr><td valign = top>$line[1]</td><td><input size=80 ";
print "name=\"$line[0]_$line[1]\" value=\"$line[2]\"></td></tr>\n";
}
print "</table>\n";
print "<input type=submit value=\"Submit changes\">\n";
print "</form>\n";
print "<p><a href=query.cgi>Skip all this, and go back to the query page</a>\n";

View File

@@ -1,110 +0,0 @@
#!/usr/bonsaitools/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
use diagnostics;
use strict;
require "CGI.pl";
require "defparams.pl";
# Shut up misguided -w warnings about "used only once":
use vars @::param_desc,
@::param_list;
confirm_login();
print "Content-type: text/html\n\n";
if (!UserInGroup("tweakparams")) {
PutHeader("Not Allowed");
PutError("Sorry, you aren't a member of the 'tweakparams' group.<BR>\n" .
"And so, you aren't allowed to edit the parameters.\n");
exit;
}
PutHeader("Edit parameters", undef, undef, undef, 1);
print "<CENTER>This lets you edit the basic operating parameters of bugzilla.\n";
print "Be careful!\n";
print "<p>\n";
print "Any item you check Reset on will get reset to its default value.</CENTER>\n";
print "<FORM METHOD=post ACTION=doeditparams.cgi>\n<TABLE ALIGN=center WIDTH=800>\n";
my $rowbreak = "<TR><TD COLSPAN=2><HR></TD></TR>";
print $rowbreak;
foreach my $i (@::param_list) {
print "<TR><TH ALIGN=right VALIGN=top>$i:</TH><TD>$::param_desc{$i}</TD></TR>\n";
print "<TR><TD VALIGN=top><INPUT TYPE=checkbox NAME=reset-$i>Reset</TD><TD>\n";
my $value = Param($i);
SWITCH: for ($::param_type{$i}) {
/^t$/ && do {
print "<INPUT SIZE=60 MAXSIZE=80 NAME=$i VALUE=\"" .
value_quote($value) . "\">\n";
last SWITCH;
};
/^l$/ && do {
print "<TEXTAREA WRAP=hard NAME=$i ROWS=10 COLS=60>" .
value_quote($value) . "</TEXTAREA>\n";
last SWITCH;
};
/^b$/ && do {
my $on;
my $off;
if ($value) {
$on = "checked";
$off = "";
} else {
$on = "";
$off = "checked";
}
print "<INPUT TYPE=radio NAME=$i VALUE=1 $on>On\n";
print "<INPUT TYPE=radio NAME=$i VALUE=0 $off>Off\n";
last SWITCH;
};
# DEFAULT
print "<FONT COLOR=red><BLINK>Unknown param type $::param_type{$i}!!!</BLINK></FONT>\n";
}
print "</TD></TR>\n";
print $rowbreak;
}
print "<TR><TH ALIGN=right VALIGN=top>version:</TH><TD>
What version of Bugzilla this is. This can't be modified here, but
<TT>%version%</TT> can be used as a parameter in places that understand
such parameters</TD></TR>
<TR><TD></TD><TD>" . Param('version') . "</TD></TR>";
print "</TABLE>\n";
print "<CENTER><INPUT TYPE=reset VALUE=\"Reset form\">\n";
print "<INPUT TYPE=submit VALUE=\"Submit changes\"></CENTER>\n";
print "</FORM>\n";
print "<P><CENTER><A HREF=query.cgi>Skip all this, and go back to the query page</A></CENTER>\n";
PutFooter();
exit;

View File

@@ -1,667 +0,0 @@
#!/usr/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public License
# Version 1.0 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
#
# Direct any questions on this source code to
#
# Holger Schurig <holgerschurig@nikocity.de>
use diagnostics;
use strict;
require "CGI.pl";
require "globals.pl";
# TestProduct: just returns if the specified product does exists
# CheckProduct: same check, optionally emit an error text
sub TestProduct ($) {
my $prod = shift;
# does the product exist?
SendSQL("SELECT product
FROM products
WHERE product=" . SqlQuote($prod));
return FetchOneColumn();
}
sub CheckProduct ($) {
my $prod = shift;
# do we have a product?
unless ($prod) {
print "Sorry, you haven't specified a product.";
PutTrailer();
exit;
}
unless (TestProduct $prod) {
print "Sorry, product '$prod' does not exist.";
PutTrailer();
exit;
}
}
#
# Displays the form to edit a products parameters
#
sub EmitFormElements ($$$$) {
my ($product, $description, $milestoneurl, $disallownew) = @_;
print " <TH ALIGN=\"right\">Product:</TH>\n";
print " <TD><INPUT SIZE=64 MAXLENGTH=64 NAME=\"product\" VALUE=\"$product\"></TD>\n";
print "</TR><TR>\n";
print " <TH ALIGN=\"right\">Description:</TH>\n";
print " <TD><TEXTAREA ROWS=4 COLS=64 WRAP=VIRTUAL NAME=\"description\">$description</TEXTAREA></TD>\n";
if (Param('usetargetmilestone')) {
print "</TR><TR>\n";
print " <TH ALIGN=\"right\">Milestone URL:</TH>\n";
print " <TD><INPUT TYPE=TEXT SIZE=64 MAXLENGTH=255 NAME=\"milestoneurl\" VALUE=\"$milestoneurl\"></TD>\n";
}
print "</TR><TR>\n";
print " <TH ALIGN=\"right\">Closed for bug entry:</TH>\n";
my $closed = $disallownew ? "CHECKED" : "";
print " <TD><INPUT TYPE=CHECKBOX NAME=\"disallownew\" $closed VALUE=\"1\"></TD>\n";
}
#
# Displays a text like "a.", "a or b.", "a, b or c.", "a, b, c or d."
#
sub PutTrailer (@) {
my (@links) = ("Back to the <A HREF=\"query.cgi\">query page</A>", @_);
print "<CENTER>\n";
my $count = $#links;
my $num = 0;
print "<P>\n";
foreach (@links) {
print $_;
if ($num == $count) {
print ".\n";
}
elsif ($num == $count-1) {
print " or ";
}
else {
print ", ";
}
$num++;
}
print "</CENTER>\n";
}
#
# Preliminary checks:
#
confirm_login();
print "Content-type: text/html\n\n";
unless (UserInGroup("editcomponents")) {
PutHeader("Not allowed");
PutError("Sorry, you aren't a member of the 'editcomponents' group.<BR>\n" .
"And so, you aren't allowed to add, modify or delete products.<BR>\n");
PutTrailer();
exit;
}
#
# often used variables
#
my $product = trim($::FORM{product} || '');
my $action = trim($::FORM{action} || '');
my $localtrailer = "<A HREF=\"editproducts.cgi\">edit</A> more products";
#
# action='' -> Show nice list of products
#
unless ($action) {
PutHeader("Select product");
SendSQL("SELECT product, description, disallownew
FROM products
ORDER BY product");
print "<P>\n<TABLE BORDER=1 CELLPADDING=3 CELLSPACING=0 ALIGN=center><TR BGCOLOR=\"#BFBFBF\">\n";
print " <TH ALIGN=\"left\">Product</TH>\n";
print " <TH ALIGN=\"left\">Description</TH>\n";
print " <TH ALIGN=\"left\">Status</TH>\n";
print " <TH ALIGN=\"left\">Action</TH>\n";
print "</TR>";
while ( MoreSQLData() ) {
my ($product, $description, $disallownew) = FetchSQLData();
$description ||= "<FONT COLOR=\"red\">missing</FONT>";
$disallownew = $disallownew ? 'closed' : 'open';
print "<TR BGCOLOR=\"#ECECEC\">\n";
print " <TD VALIGN=\"top\"><A HREF=\"editproducts.cgi?action=edit&product=", url_quote($product), "\"><B>$product</B></A></TD>\n";
print " <TD VALIGN=\"top\">$description</TD>\n";
print " <TD VALIGN=\"top\">$disallownew</TD>\n";
print " <TD VALIGN=\"top\"><A HREF=\"editproducts.cgi?action=del&product=", url_quote($product), "\">Delete</A></TD>\n";
print "</TR>";
}
print "<TR BGCOLOR=\"#ECECEC\">\n";
print " <TH VALIGN=\"top\" COLSPAN=4><A HREF=\"editproducts.cgi?action=add\">Add a new product</A></TH>\n";
print "</TR></TABLE>\n";
PutTrailer();
PutFooter();
exit;
}
#
# action='add' -> present form for parameters for new product
#
# (next action will be 'new')
#
if ($action eq 'add') {
PutHeader("Add product");
#print "This page lets you add a new product to bugzilla.\n";
print "<FORM METHOD=POST ACTION=editproducts.cgi>\n";
print "<TABLE BORDER=0 CELLPADDING=4 CELLSPACING=0 ALIGN=center><TR>\n";
EmitFormElements('', '', '', 0);
print "</TR><TR>\n";
print " <TH ALIGN=\"right\">Version:</TH>\n";
print " <TD><INPUT SIZE=64 MAXLENGTH=255 NAME=\"version\" VALUE=\"unspecified\"></TD>\n";
print "</TABLE>\n";
print "<CENTER><INPUT TYPE=SUBMIT VALUE=\"Add\"></CENTER>\n";
print "<INPUT TYPE=HIDDEN NAME=\"action\" VALUE=\"new\">\n";
print "</FORM>";
my $other = $localtrailer;
$other =~ s/more/other/;
PutTrailer($other);
PutFooter();
exit;
}
#
# action='new' -> add product entered in the 'action=add' screen
#
if ($action eq 'new') {
PutHeader("Adding new product");
# Cleanups and valididy checks
unless ($product) {
print "You must enter a name for the new product. Please press\n";
print "<b>Back</b> and try again.\n";
PutTrailer($localtrailer);
exit;
}
if (TestProduct($product)) {
print "The product '$product' already exists. Please press\n";
print "<b>Back</b> and try again.\n";
PutTrailer($localtrailer);
exit;
}
my $version = trim($::FORM{version} || '');
if ($version eq '') {
print "You must enter a version for product '$product'. Please press\n";
print "<b>Back</b> and try again.\n";
PutTrailer($localtrailer);
exit;
}
my $description = trim($::FORM{description} || '');
my $milestoneurl = trim($::FORM{milestoneurl} || '');
my $disallownew = 0;
$disallownew = 1 if $::FORM{disallownew};
# Add the new product.
if ($::driver eq "mysql") {
SendSQL("INSERT INTO products ( " .
"product, description, milestoneurl, disallownew" .
" ) VALUES ( " .
SqlQuote($product) . "," .
SqlQuote($description) . "," .
SqlQuote($milestoneurl) . "," .
$disallownew . ")" );
} else {
SendSQL("INSERT INTO products ( " .
"product, description, milestoneurl, disallownew, id" .
" ) VALUES ( " .
SqlQuote($product) . "," .
SqlQuote($description) . "," .
SqlQuote($milestoneurl) . "," .
$disallownew . ", products_seq.nextval)" );
}
SendSQL("INSERT INTO versions ( " .
"value, program" .
" ) VALUES ( " .
SqlQuote($version) . "," .
SqlQuote($product) . ")" );
# Make versioncache flush
unlink "data/versioncache";
print "<CENTER>OK, done.</CENTER><p>\n";
PutTrailer($localtrailer, "<a href=\"editcomponents.cgi?action=add&product=" . url_quote($product) . "\">add</a> components to this new product.");
PutFooter();
exit;
}
#
# action='del' -> ask if user really wants to delete
#
# (next action would be 'delete')
#
if ($action eq 'del') {
PutHeader("Delete product");
CheckProduct($product);
# display some data about the product
SendSQL("SELECT description, milestoneurl, disallownew
FROM products
WHERE product=" . SqlQuote($product));
my ($description, $milestoneurl, $disallownew) = FetchSQLData();
$description ||= "<FONT COLOR=\"red\">description missing</FONT>";
$disallownew = $disallownew ? 'closed' : 'open';
print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0 ALIGN=center BGCOLOR=\"#ECECEC\">\n";
print "<TR BGCOLOR=\"#BFBFBF\">\n";
print " <TH VALIGN=\"top\" ALIGN=\"left\">Part</TH>\n";
print " <TH VALIGN=\"top\" ALIGN=\"left\">Value</TH>\n";
print "</TR><TR>\n";
print " <TH VALIGN=\"top\" ALIGN=left>Product</TH>\n";
print " <TD VALIGN=\"top\">$product</TD>\n";
print "</TR><TR>\n";
print " <TH VALIGN=\"top\" ALIGN=left>Description</TH>\n";
print " <TD VALIGN=\"top\">$description</TD>\n";
if (Param('usetargetmilestone')) {
print "</TR><TR>\n";
print " <TH VALIGN=\"top\" ALIGN=left>Milestone URL</TH>\n";
print " <TD VALIGN=\"top\"><A HREF=\"$milestoneurl\">$milestoneurl</A></TD>\n";
}
print "</TR><TR>\n";
print " <TH VALIGN=\"top\" ALIGN=left>Closed for bugs</TH>\n";
print " <TD VALIGN=\"top\">$disallownew</TD>\n";
print "</TR><TR>\n";
print " <TH VALIGN=\"top\" ALIGN=left>Components</TH>\n";
print " <TD VALIGN=\"top\">";
SendSQL("SELECT value,description
FROM components
WHERE program=" . SqlQuote($product));
if (MoreSQLData()) {
print "<TABLE>";
while ( MoreSQLData() ) {
my ($component, $description) = FetchSQLData();
$description ||= "<FONT COLOR=\"red\">description missing</FONT>";
print "<TR><TH ALIGN=right VALIGN=top>$component:</TH>";
print "<TD VALIGN=top>$description</TD></TR>\n";
}
print "</TABLE>\n";
} else {
print "<FONT COLOR=\"red\">missing</FONT>";
}
print "</TD>\n</TR><TR>\n";
print " <TH VALIGN=\"top\" ALIGN=left>Versions</TH>\n";
print " <TD VALIGN=\"top\">";
SendSQL("SELECT value
FROM versions
WHERE program=" . SqlQuote($product) . "
ORDER BY value");
if (MoreSQLData()) {
my $br = 0;
while ( MoreSQLData() ) {
my ($version) = FetchSQLData();
print "<BR>" if $br;
print $version;
$br = 1;
}
} else {
print "<FONT COLOR=\"red\">missing</FONT>";
}
print "</TD>\n</TR><TR>\n";
print " <TH VALIGN=\"top\" ALIGN=left>Bugs</TH>\n";
print " <TD VALIGN=\"top\">";
SendSQL("SELECT count(bug_id),product
FROM bugs
GROUP BY product
HAVING product=" . SqlQuote($product));
my $bugs = FetchOneColumn();
print $bugs || 'none';
print "</TD>\n</TR></TABLE>";
print "<CENTER><H2>Confirmation</H2>\n";
if ($bugs) {
if (!Param("allowbugdeletion")) {
print "Sorry, there are $bugs bugs outstanding for this product.
You must reassign those bugs to another product before you can delete this
one.</CENTER><P>\n";
PutTrailer($localtrailer);
exit;
}
print "<TABLE BORDER=0 CELLPADDING=20 WIDTH=\"70%\" BGCOLOR=\"red\" ALIGN=center><TR><TD>\n",
"There are bugs entered for this product! When you delete this ",
"product, <B><BLINK>all</BLINK><B> stored bugs will be deleted, too. ",
"You could not even see a bug history anymore!\n",
"</TD></TR></TABLE>\n";
}
print "<P>Do you really want to delete this product?<P>\n";
print "<FORM METHOD=POST ACTION=editproducts.cgi>\n";
print "<INPUT TYPE=SUBMIT VALUE=\"Yes, delete\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"action\" VALUE=\"delete\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"product\" VALUE=\"$product\">\n";
print "</FORM>\n</CENTER>\n";
PutTrailer($localtrailer);
PutFooter();
exit;
}
#
# action='delete' -> really delete the product
#
if ($action eq 'delete') {
PutHeader("Deleting product");
CheckProduct($product);
# lock the tables before we start to change everything:
if ($::driver eq 'mysql') {
SendSQL("LOCK TABLES attachments WRITE,
bugs WRITE,
bugs_activity WRITE,
components WRITE,
dependencies WRITE,
versions WRITE,
products WRITE");
}
# According to MySQL doc I cannot do a DELETE x.* FROM x JOIN Y,
# so I have to iterate over bugs and delete all the indivial entries
# in bugs_activies and attachments.
SendSQL("SELECT bug_id
FROM bugs
WHERE product=" . SqlQuote($product));
while (MoreSQLData()) {
my $bugid = FetchOneColumn();
my $query = $::db->query("DELETE FROM attachments WHERE bug_id=$bugid")
or die "$::db_errstr";
$query = $::db->query("DELETE FROM bugs_activity WHERE bug_id=$bugid")
or die "$::db_errstr";
$query = $::db->query("DELETE FROM dependencies WHERE blocked=$bugid")
or die "$::db_errstr";
}
print "Attachments, bug activity and dependencies deleted.<BR>\n";
# Deleting the rest is easier:
SendSQL("DELETE FROM bugs
WHERE product=" . SqlQuote($product));
print "Bugs deleted.<BR>\n";
SendSQL("DELETE FROM components
WHERE program=" . SqlQuote($product));
print "Components deleted.<BR>\n";
SendSQL("DELETE FROM versions
WHERE program=" . SqlQuote($product));
print "Versions deleted.<P>\n";
SendSQL("DELETE FROM products
WHERE product=" . SqlQuote($product));
print "Product '$product' deleted.<BR>\n";
if ($::driver eq 'mysql') {
SendSQL("UNLOCK TABLES");
}
unlink "data/versioncache";
PutTrailer($localtrailer);
PutFooter();
exit;
}
#
# action='edit' -> present the edit products from
#
# (next action would be 'update')
#
if ($action eq 'edit') {
PutHeader("Edit product");
CheckProduct($product);
# get data of product
SendSQL("SELECT description,milestoneurl,disallownew
FROM products
WHERE product=" . SqlQuote($product));
my ($description, $milestoneurl, $disallownew) = FetchSQLData();
print "<FORM METHOD=POST ACTION=editproducts.cgi>\n";
print "<TABLE BORDER=0 CELLPADDING=4 CELLSPACING=0 ALIGN=center><TR>\n";
EmitFormElements($product, $description, $milestoneurl, $disallownew);
print "</TR><TR>\n";
print "<TH ALIGN=right VALIGN=center>Other:</TH>\n";
print "<TH ALIGN=left><A HREF=\"editcomponents.cgi?product=", url_quote($product), "\">";
print "Edit components for $product</A><BR>\n";
print "<A HREF=\"editversions.cgi?product=", url_quote($product), "\">Edit versions for $product</A></TH>\n";
print "</TR><TR>\n";
print " <TH ALIGN=\"right\">Bugs:</TH>\n";
print " <TD>";
SendSQL("SELECT count(bug_id), product " .
"FROM bugs " .
"GROUP BY product " .
"HAVING product = " . SqlQuote($product));
my $bugs = '';
$bugs = FetchOneColumn() if MoreSQLData();
print $bugs || 'none';
print "</TD>\n</TR>\n";
# begin new group stuff
SendSQL("select id from products where product = " . SqlQuote($product));
my $productid = FetchOneColumn();
SendSQL("select groupid, description from groups order by groupid");
my %grouplist;
my @row;
while (@row = FetchSQLData()) {
$grouplist{$row[0]} = $row[1];
}
SendSQL("select groupid from product_group where productid = $productid");
my @groupbelong;
while (@row = FetchSQLData()) {
push (@groupbelong, $row[0]);
}
print qq{
<TR>
<TH ALIGN=right VALIGN=center>Product can<BR>seen by:</TH>
<TD ALIGN=left>
<U>All <B>unchecked</B> same as <B>everyone</B></U><BR>
<INPUT TYPE=HIDDEN NAME=productid VALUE="$productid">
};
my $count = 0;
foreach my $i (keys %grouplist) {
my $c;
if (lsearch(\@groupbelong, $i) >= 0) {
$c = 'CHECKED';
} else {
$c = '';
}
print qq{
<INPUT TYPE=checkbox NAME=group-$i $c> $grouplist{$i}<br>
};
}
print "</TD>\n</TR></TABLE>\n";
print "<CENTER>\n";
print "<INPUT TYPE=HIDDEN NAME=\"productold\" VALUE=\"$product\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"descriptionold\" VALUE=\"$description\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"milestoneurlold\" VALUE=\"$milestoneurl\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"disallownewold\" VALUE=\"$disallownew\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"action\" VALUE=\"update\">\n";
print "<INPUT TYPE=SUBMIT VALUE=\"Update\">\n";
print "</FORM>\n</CENTER>\n";
my $x = $localtrailer;
$x =~ s/more/other/;
PutTrailer($x);
PutFooter();
exit;
}
#
# action='update' -> update the product
#
if ($action eq 'update') {
PutHeader("Update product");
my $productold = trim($::FORM{productold} || '');
my $description = trim($::FORM{description} || '');
my $descriptionold = trim($::FORM{descriptionold} || '');
my $disallownew = trim($::FORM{disallownew} || '');
my $disallownewold = trim($::FORM{disallownewold} || '');
my $milestoneurl = trim($::FORM{milestoneurl} || '');
my $milestoneurlold = trim($::FORM{milestoneurlold} || '');
CheckProduct($productold);
# Note that the order of this tests is important. If you change
# them, be sure to test for WHERE='$product' or WHERE='$productold'
if ($::driver eq 'mysql') {
SendSQL("LOCK TABLES bugs WRITE,
components WRITE,
products WRITE,
versions WRITE,
product_group WRITE");
}
if ($disallownew != $disallownewold) {
$disallownew ||= 0;
SendSQL("UPDATE products
SET disallownew=$disallownew
WHERE product=" . SqlQuote($productold));
print "Updated bug submit status.<BR>\n";
}
if ($description ne $descriptionold) {
unless ($description) {
print "Sorry, I can't delete the description.";
PutTrailer($localtrailer);
if ($::driver eq 'mysql') {
SendSQL("UNLOCK TABLES");
}
exit;
}
SendSQL("UPDATE products
SET description=" . SqlQuote($description) . "
WHERE product=" . SqlQuote($productold));
print "Updated description.<BR>\n";
}
if (Param('usetargetmilestone') && $milestoneurl ne $milestoneurlold) {
SendSQL("UPDATE products
SET milestoneurl=" . SqlQuote($milestoneurl) . "
WHERE product=" . SqlQuote($productold));
print "Updated mile stone URL.<BR>\n";
}
if ($product ne $productold) {
unless ($product) {
print "Sorry, I can't delete the product name.";
PutTrailer($localtrailer);
if ($::driver eq 'mysql') {
SendSQL("UNLOCK TABLES");
}
exit;
}
if (TestProduct($product)) {
print "Sorry, product name '$product' is already in use.";
PutTrailer($localtrailer);
if ($::driver eq 'mysql') {
SendSQL("UNLOCK TABLES");
}
exit;
}
SendSQL("UPDATE bugs
SET product=" . SqlQuote($product) . "
WHERE product=" . SqlQuote($productold));
SendSQL("UPDATE components
SET program=" . SqlQuote($product) . "
WHERE program=" . SqlQuote($productold));
SendSQL("UPDATE products
SET product=" . SqlQuote($product) . "
WHERE product=" . SqlQuote($productold));
SendSQL("UPDATE versions
SET program='$product'
WHERE program=" . SqlQuote($productold));
unlink "data/versioncache";
print "Updated product name.<BR>\n";
}
# Update product_group table
my $productid = $::FORM{'productid'};
my $flag = 0;
SendSQL("delete from product_group where productid = $productid");
foreach my $groupid (grep(/^group-.*$/, keys %::FORM)) {
if ($::FORM{$groupid}) {
$groupid =~ s/^group-//;
SendSQL("insert into product_group values ($productid, $groupid)");
$flag = 1;
}
}
if ($flag) { print "Updated group permissions.<BR>\n"; }
if ($::driver eq 'mysql') {
SendSQL("UNLOCK TABLES");
}
PutTrailer($localtrailer);
exit;
}
#
# No valid action found
#
PutHeader("Error");
print "I don't have a clue what you want.<BR>\n";
foreach ( sort keys %::FORM) {
print "$_: $::FORM{$_}<BR>\n";
}

View File

@@ -1,783 +0,0 @@
#!/usr/bonsaitools/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Holger
# Schurig. Portions created by Holger Schurig are
# Copyright (C) 1999 Holger Schurig. All
# Rights Reserved.
#
# Contributor(s): Holger Schurig <holgerschurig@nikocity.de>
#
#
# Direct any questions on this source code to
#
# Holger Schurig <holgerschurig@nikocity.de>
use diagnostics;
use strict;
require "CGI.pl";
require "globals.pl";
# Shut up misguided -w warnings about "used only once". "use vars" just
# doesn't work for me.
sub sillyness {
my $zz;
$zz = $::userid;
}
my $editall;
my $opblessgroupset = '9223372036854775807'; # This is all 64 bits.
# TestUser: just returns if the specified user does exists
# CheckUser: same check, optionally emit an error text
sub TestUser ($)
{
my $user = shift;
# does the product exist?
SendSQL("SELECT login_name
FROM profiles
WHERE login_name=" . SqlQuote($user));
return FetchOneColumn();
}
sub CheckUser ($)
{
my $user = shift;
# do we have a product?
unless ($user) {
print "Sorry, you haven't specified a user.";
PutTrailer();
exit;
}
unless (TestUser $user) {
print "Sorry, user '$user' does not exist.";
PutTrailer();
exit;
}
}
sub EmitElement ($$)
{
my ($name, $value) = (@_);
$value = value_quote($value);
if ($editall) {
print qq{<TD><INPUT SIZE=64 MAXLENGTH=255 NAME="$name" VALUE="$value"></TD>\n};
} else {
print qq{<TD>$value</TD>\n};
}
}
#
# Displays the form to edit a user parameters
#
sub EmitFormElements ($$$$$$$)
{
my ($user, $password, $realname, $groupset, $blessgroupset,
$emailnotification, $disabledtext) = @_;
print " <TH ALIGN=\"right\">Login name:</TH>\n";
EmitElement("user", $user);
print "</TR><TR>\n";
print " <TH ALIGN=\"right\">Real name:</TH>\n";
EmitElement("realname", $realname);
if ($editall) {
print "</TR><TR>\n";
print " <TH ALIGN=\"right\">Password:</TH>\n";
print " <TD><INPUT SIZE=16 MAXLENGTH=16 NAME=\"password\" VALUE=\"$password\"></TD>\n";
print "</TR><TR>\n";
print " <TH ALIGN=\"right\">Email notification:</TH>\n";
print qq{<TD><SELECT NAME="emailnotification">};
foreach my $i (["ExcludeSelfChanges", "All qualifying bugs except those which I change"],
["CConly", "Only those bugs which I am listed on the CC line"],
["All", "All qualifying bugs"]) {
my ($tag, $desc) = (@$i);
my $selectpart = "";
if ($tag eq $emailnotification) {
$selectpart = " SELECTED";
}
print qq{<OPTION$selectpart VALUE="$tag">$desc\n};
}
print "</SELECT></TD>\n";
print "</TR><TR>\n";
print " <TH ALIGN=\"right\">Disable text:</TH>\n";
print " <TD ROWSPAN=2><TEXTAREA NAME=\"disabledtext\" ROWS=10 COLS=60>" .
value_quote($disabledtext) . "</TEXTAREA>\n";
print " </TD>\n";
print "</TR><TR>\n";
print " <TD VALIGN=\"top\">If non-empty, then the account will\n";
print "be disabled, and this text should explain why.</TD>\n";
}
SendSQL("SELECT bit,name,description,bit & $groupset != 0, " .
" bit & $blessgroupset " .
"FROM groups " .
"WHERE bit & $opblessgroupset != 0 " .
"ORDER BY name");
while (MoreSQLData()) {
my ($bit,$name,$description,$checked,$blchecked) = FetchSQLData();
print "</TR><TR>\n";
print " <TH ALIGN=\"right\">", ucfirst($name), ":</TH>\n";
$checked = ($checked) ? "CHECKED" : "";
print " <TD><INPUT TYPE=CHECKBOX NAME=\"bit_$name\" $checked VALUE=\"$bit\"> $description</TD>\n";
if ($editall) {
print "</TR><TR>\n";
print "<TH></TH>";
$blchecked = ($blchecked) ? "CHECKED" : "";
print "<TD><INPUT TYPE=CHECKBOX NAME=\"blbit_$name\" $blchecked VALUE=\"$bit\"> Can turn this bit on for other users</TD>\n";
}
}
}
#
# Displays a text like "a.", "a or b.", "a, b or c.", "a, b, c or d."
#
sub PutTrailer (@)
{
my (@links) = ("Back to the <A HREF=\"index.html\">index</A>", @_);
my $count = $#links;
my $num = 0;
print "<P>\n";
foreach (@links) {
print $_;
if ($num == $count) {
print ".\n";
}
elsif ($num == $count-1) {
print " or ";
}
else {
print ", ";
}
$num++;
}
PutFooter();
}
#
# Preliminary checks:
#
confirm_login();
print "Content-type: text/html\n\n";
$editall = UserInGroup("editusers");
if (!$editall) {
SendSQL("SELECT blessgroupset FROM profiles WHERE userid = $::userid");
$opblessgroupset = FetchOneColumn();
if (!$opblessgroupset) {
PutHeader("Not allowed");
print "Sorry, you aren't a member of the 'editusers' group, and you\n";
print "don't have permissions to put people in or out of any group.\n";
print "And so, you aren't allowed to add, modify or delete users.\n";
PutTrailer();
exit;
}
}
#
# often used variables
#
my $user = trim($::FORM{user} || '');
my $action = trim($::FORM{action} || '');
my $localtrailer = "<A HREF=\"editusers.cgi\">edit</A> more users";
my $candelete = Param('allowuserdeletion');
#
# action='' -> Ask for match string for users.
#
unless ($action) {
PutHeader("Select match string");
print qq{
<FORM METHOD=GET ACTION="editusers.cgi">
<INPUT TYPE=HIDDEN NAME="action" VALUE="list">
List users with login name matching:
<INPUT SIZE=32 NAME="matchstr">
<SELECT NAME="matchtype">
<OPTION VALUE="substr" SELECTED>case-insensitive substring
<OPTION VALUE="regexp">case-sensitive regexp
<OPTION VALUE="notregexp">not (case-sensitive regexp)
</SELECT>
<BR>
<INPUT TYPE=SUBMIT VALUE="Submit">
};
PutTrailer();
exit;
}
#
# action='list' -> Show nice list of matching users
#
if ($action eq 'list') {
PutHeader("Select user");
my $query = "SELECT login_name,realname,disabledtext " .
"FROM profiles WHERE login_name ";
if ($::FORM{'matchtype'} eq 'substr') {
$query .= "like";
$::FORM{'matchstr'} = '%' . $::FORM{'matchstr'} . '%';
} elsif ($::FORM{'matchtype'} eq 'regexp') {
$query .= "regexp";
} elsif ($::FORM{'matchtype'} eq 'notregexp') {
$query .= "not regexp";
} else {
die "Unknown match type";
}
$query .= SqlQuote($::FORM{'matchstr'}) . " ORDER BY login_name";
SendSQL($query);
my $count = 0;
my $header = "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0><TR BGCOLOR=\"#6666FF\">
<TH ALIGN=\"left\">Edit user ...</TH>
<TH ALIGN=\"left\">Real name</TH>
";
if ($candelete) {
$header .= "<TH ALIGN=\"left\">Action</TH>\n";
}
$header .= "</TR>\n";
print $header;
while ( MoreSQLData() ) {
$count++;
if ($count % 100 == 0) {
print "</table>$header";
}
my ($user, $realname, $disabledtext) = FetchSQLData();
my $s = "";
my $e = "";
if ($disabledtext) {
$s = "<STRIKE>";
$e = "</STRIKE>";
}
$realname ||= "<FONT COLOR=\"red\">missing</FONT>";
print "<TR>\n";
print " <TD VALIGN=\"top\"><A HREF=\"editusers.cgi?action=edit&user=", url_quote($user), "\"><B>$s$user$e</B></A></TD>\n";
print " <TD VALIGN=\"top\">$s$realname$e</TD>\n";
if ($candelete) {
print " <TD VALIGN=\"top\"><A HREF=\"editusers.cgi?action=del&user=", url_quote($user), "\">Delete</A></TD>\n";
}
print "</TR>";
}
if ($editall) {
print "<TR>\n";
my $span = $candelete ? 3 : 2;
print qq{
<TD VALIGN="top" COLSPAN=$span ALIGN="right">
<A HREF=\"editusers.cgi?action=add\">Add a new user</A>
</TD>
};
print "</TR>";
}
print "</TABLE>\n";
print "$count users found.\n";
PutTrailer($localtrailer);
exit;
}
#
# action='add' -> present form for parameters for new user
#
# (next action will be 'new')
#
if ($action eq 'add') {
PutHeader("Add user");
if (!$editall) {
print "Sorry, you don't have permissions to add new users.";
PutTrailer();
exit;
}
print "<FORM METHOD=POST ACTION=editusers.cgi>\n";
print "<TABLE BORDER=0 CELLPADDING=4 CELLSPACING=0><TR>\n";
EmitFormElements('', '', '', 0, 0, 'ExcludeSelfChanges', '');
print "</TR></TABLE>\n<HR>\n";
print "<INPUT TYPE=SUBMIT VALUE=\"Add\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"action\" VALUE=\"new\">\n";
print "</FORM>";
my $other = $localtrailer;
$other =~ s/more/other/;
PutTrailer($other);
exit;
}
#
# action='new' -> add user entered in the 'action=add' screen
#
if ($action eq 'new') {
PutHeader("Adding new user");
if (!$editall) {
print "Sorry, you don't have permissions to add new users.";
PutTrailer();
exit;
}
# Cleanups and valididy checks
my $realname = trim($::FORM{realname} || '');
my $password = trim($::FORM{password} || '');
my $disabledtext = trim($::FORM{disabledtext} || '');
unless ($user) {
print "You must enter a name for the new user. Please press\n";
print "<b>Back</b> and try again.\n";
PutTrailer($localtrailer);
exit;
}
unless ($user =~ /^[^\@]+\@[^\@]+$/) {
print "The user name entered must be a valid e-mail address. Please press\n";
print "<b>Back</b> and try again.\n";
PutTrailer($localtrailer);
exit;
}
if (TestUser($user)) {
print "The user '$user' does already exist. Please press\n";
print "<b>Back</b> and try again.\n";
PutTrailer($localtrailer);
exit;
}
if ($password !~ /^[a-zA-Z0-9-_]*$/ || length($password) < 3 || length($password) > 16) {
print "The new user must have a password. The password must be between ",
"3 and 16 characters long and must contain only numbers, letters, ",
"hyphens and underlines. Press <b>Back</b> and try again.\n";
PutTrailer($localtrailer);
exit;
}
my $bits = "0";
foreach (keys %::FORM) {
next unless /^bit_/;
#print "$_=$::FORM{$_}<br>\n";
$bits .= "+ $::FORM{$_}";
}
# Add the new user
SendSQL("INSERT INTO profiles ( " .
"login_name, password, cryptpassword, realname, groupset, " .
"disabledtext" .
" ) VALUES ( " .
SqlQuote($user) . "," .
SqlQuote($password) . "," .
"encrypt(" . SqlQuote($password) . ")," .
SqlQuote($realname) . "," .
$bits . "," .
SqlQuote($disabledtext) . ")" );
#+++ send e-mail away
print "OK, done.<p>\n";
PutTrailer($localtrailer,
"<a href=\"editusers.cgi?action=add\">add</a> another user.");
exit;
}
#
# action='del' -> ask if user really wants to delete
#
# (next action would be 'delete')
#
if ($action eq 'del') {
PutHeader("Delete user");
if (!$candelete) {
print "Sorry, deleting users isn't allowed.";
PutTrailer();
}
if (!$editall) {
print "Sorry, you don't have permissions to delete users.";
PutTrailer();
exit;
}
CheckUser($user);
# display some data about the user
SendSQL("SELECT realname, groupset, emailnotification, login_name
FROM profiles
WHERE login_name=" . SqlQuote($user));
my ($realname, $groupset, $emailnotification) = FetchSQLData();
$realname ||= "<FONT COLOR=\"red\">missing</FONT>";
print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0>\n";
print "<TR BGCOLOR=\"#6666FF\">\n";
print " <TH VALIGN=\"top\" ALIGN=\"left\">Part</TH>\n";
print " <TH VALIGN=\"top\" ALIGN=\"left\">Value</TH>\n";
print "</TR><TR>\n";
print " <TD VALIGN=\"top\">Login name:</TD>\n";
print " <TD VALIGN=\"top\">$user</TD>\n";
print "</TR><TR>\n";
print " <TD VALIGN=\"top\">Real name:</TD>\n";
print " <TD VALIGN=\"top\">$realname</TD>\n";
print "</TR><TR>\n";
print " <TD VALIGN=\"top\">E-Mail notification:</TD>\n";
print " <TD VALIGN=\"top\">$emailnotification</TD>\n";
print "</TR><TR>\n";
print " <TD VALIGN=\"top\">Group set:</TD>\n";
print " <TD VALIGN=\"top\">";
SendSQL("SELECT bit, name
FROM groups
ORDER BY name");
my $found = 0;
while ( MoreSQLData() ) {
my ($bit,$name) = FetchSQLData();
if ($bit & $groupset) {
print "<br>\n" if $found;
print ucfirst $name;
$found = 1;
}
}
print "none" unless $found;
print "</TD>\n</TR>";
# Check if the user is an initialowner
my $nodelete = '';
SendSQL("SELECT program, value
FROM components
WHERE initialowner=" . SqlQuote($user));
$found = 0;
while (MoreSQLData()) {
if ($found) {
print "<BR>\n";
} else {
print "<TR>\n";
print " <TD VALIGN=\"top\">Initial owner:</TD>\n";
print " <TD VALIGN=\"top\">";
}
my ($product, $component) = FetchSQLData();
print "<a href=\"editcomponents.cgi?product=", url_quote($product),
"&component=", url_quote($component),
"&action=edit\">$product: $component</a>";
$found = 1;
$nodelete = 'initial bug owner';
}
print "</TD>\n</TR>" if $found;
# Check if the user is an initialqacontact
SendSQL("SELECT program, value
FROM components
WHERE initialqacontact=" . SqlQuote($user));
$found = 0;
while (MoreSQLData()) {
if ($found) {
print "<BR>\n";
} else {
print "<TR>\n";
print " <TD VALIGN=\"top\">Initial QA contact:</TD>\n";
print " <TD VALIGN=\"top\">";
}
my ($product, $component) = FetchSQLData();
print "<a href=\"editcomponents.cgi?product=", url_quote($product),
"&component=", url_quote($component),
"&action=edit\">$product: $component</a>";
$found = 1;
$nodelete = 'initial QA contact';
}
print "</TD>\n</TR>" if $found;
print "</TABLE>\n";
if ($nodelete) {
print "<P>You can't delete this user because '$user' is an $nodelete ",
"for at least one product.";
PutTrailer($localtrailer);
exit;
}
print "<H2>Confirmation</H2>\n";
print "<P>Do you really want to delete this user?<P>\n";
print "<FORM METHOD=POST ACTION=editusers.cgi>\n";
print "<INPUT TYPE=SUBMIT VALUE=\"Yes, delete\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"action\" VALUE=\"delete\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"user\" VALUE=\"$user\">\n";
print "</FORM>";
PutTrailer($localtrailer);
exit;
}
#
# action='delete' -> really delete the user
#
if ($action eq 'delete') {
PutHeader("Deleting user");
if (!$candelete) {
print "Sorry, deleting users isn't allowed.";
PutTrailer();
}
if (!$editall) {
print "Sorry, you don't have permissions to delete users.";
PutTrailer();
exit;
}
CheckUser($user);
SendSQL("SELECT userid
FROM profiles
WHERE login_name=" . SqlQuote($user));
my $userid = FetchOneColumn();
SendSQL("DELETE FROM profiles
WHERE login_name=" . SqlQuote($user));
SendSQL("DELETE FROM logincookies
WHERE userid=" . $userid);
print "User deleted.<BR>\n";
PutTrailer($localtrailer);
exit;
}
#
# action='edit' -> present the user edit from
#
# (next action would be 'update')
#
if ($action eq 'edit') {
PutHeader("Edit user");
CheckUser($user);
# get data of user
SendSQL("SELECT password, realname, groupset, blessgroupset,
emailnotification, disabledtext
FROM profiles
WHERE login_name=" . SqlQuote($user));
my ($password, $realname, $groupset, $blessgroupset, $emailnotification,
$disabledtext) = FetchSQLData();
print "<FORM METHOD=POST ACTION=editusers.cgi>\n";
print "<TABLE BORDER=0 CELLPADDING=4 CELLSPACING=0><TR>\n";
EmitFormElements($user, $password, $realname, $groupset, $blessgroupset,
$emailnotification, $disabledtext);
print "</TR></TABLE>\n";
print "<INPUT TYPE=HIDDEN NAME=\"userold\" VALUE=\"$user\">\n";
if ($editall) {
print "<INPUT TYPE=HIDDEN NAME=\"passwordold\" VALUE=\"$password\">\n";
}
print "<INPUT TYPE=HIDDEN NAME=\"realnameold\" VALUE=\"$realname\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"groupsetold\" VALUE=\"$groupset\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"blessgroupsetold\" VALUE=\"$blessgroupset\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"emailnotificationold\" VALUE=\"$emailnotification\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"disabledtextold\" VALUE=\"" .
value_quote($disabledtext) . "\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"action\" VALUE=\"update\">\n";
print "<INPUT TYPE=SUBMIT VALUE=\"Update\">\n";
print "</FORM>";
my $x = $localtrailer;
$x =~ s/more/other/;
PutTrailer($x);
exit;
}
#
# action='update' -> update the user
#
if ($action eq 'update') {
PutHeader("Updated user");
my $userold = trim($::FORM{userold} || '');
my $realname = trim($::FORM{realname} || '');
my $realnameold = trim($::FORM{realnameold} || '');
my $password = trim($::FORM{password} || '');
my $passwordold = trim($::FORM{passwordold} || '');
my $emailnotification = trim($::FORM{emailnotification} || '');
my $emailnotificationold = trim($::FORM{emailnotificationold} || '');
my $disabledtext = trim($::FORM{disabledtext} || '');
my $disabledtextold = trim($::FORM{disabledtextold} || '');
my $groupsetold = trim($::FORM{groupsetold} || '0');
my $blessgroupsetold = trim($::FORM{blessgroupsetold} || '0');
my $groupset = "0";
foreach (keys %::FORM) {
next unless /^bit_/;
#print "$_=$::FORM{$_}<br>\n";
$groupset .= " + $::FORM{$_}";
}
my $blessgroupset = "0";
foreach (keys %::FORM) {
next unless /^blbit_/;
#print "$_=$::FORM{$_}<br>\n";
$blessgroupset .= " + $::FORM{$_}";
}
CheckUser($userold);
# Note that the order of this tests is important. If you change
# them, be sure to test for WHERE='$product' or WHERE='$productold'
if ($groupset ne $groupsetold) {
SendSQL("SELECT groupset FROM profiles WHERE login_name=" .
SqlQuote($userold));
$groupsetold = FetchOneColumn();
SendSQL("UPDATE profiles
SET groupset =
groupset - (groupset & $opblessgroupset) + $groupset
WHERE login_name=" . SqlQuote($userold));
# I'm paranoid that someone who I give the ability to bless people
# will start misusing it. Let's log who blesses who (even though
# nothing actually uses this log right now).
my $fieldid = GetFieldID("groupset");
SendSQL("SELECT userid, groupset FROM profiles WHERE login_name=" .
SqlQuote($userold));
my $u;
($u, $groupset) = (FetchSQLData());
if ($groupset ne $groupsetold) {
SendSQL("INSERT INTO profiles_activity " .
"(userid,who,profiles_when,fieldid,oldvalue,newvalue) " .
"VALUES " .
"($u, $::userid, now(), $fieldid, " .
" $groupsetold, $groupset)");
}
print "Updated permissions.\n";
}
if ($editall && $blessgroupset ne $blessgroupsetold) {
SendSQL("UPDATE profiles
SET blessgroupset=" . $blessgroupset . "
WHERE login_name=" . SqlQuote($userold));
print "Updated ability to tweak permissions of other users.\n";
}
if ($editall && $emailnotification ne $emailnotificationold) {
SendSQL("UPDATE profiles
SET emailnotification=" . SqlQuote($emailnotification) . "
WHERE login_name=" . SqlQuote($userold));
print "Updated email notification.<BR>\n";
}
if ($editall && $password ne $passwordold) {
my $q = SqlQuote($password);
SendSQL("UPDATE profiles
SET password= $q, cryptpassword = ENCRYPT($q)
WHERE login_name=" . SqlQuote($userold));
print "Updated password.<BR>\n";
}
if ($editall && $realname ne $realnameold) {
SendSQL("UPDATE profiles
SET realname=" . SqlQuote($realname) . "
WHERE login_name=" . SqlQuote($userold));
print "Updated real name.<BR>\n";
}
if ($editall && $disabledtext ne $disabledtextold) {
SendSQL("UPDATE profiles
SET disabledtext=" . SqlQuote($disabledtext) . "
WHERE login_name=" . SqlQuote($userold));
SendSQL("SELECT userid
FROM profiles
WHERE login_name=" . SqlQuote($user));
my $userid = FetchOneColumn();
SendSQL("DELETE FROM logincookies
WHERE userid=" . $userid);
print "Updated disabled text.<BR>\n";
}
if ($editall && $user ne $userold) {
unless ($user) {
print "Sorry, I can't delete the user's name.";
PutTrailer($localtrailer);
exit;
}
if (TestUser($user)) {
print "Sorry, user name '$user' is already in use.";
PutTrailer($localtrailer);
exit;
}
SendSQL("UPDATE profiles
SET login_name=" . SqlQuote($user) . "
WHERE login_name=" . SqlQuote($userold));
print "Updated user's name.<BR>\n";
}
PutTrailer($localtrailer);
exit;
}
#
# No valid action found
#
PutHeader("Error");
print "I don't have a clue what you want.<BR>\n";
foreach ( sort keys %::FORM) {
print "$_: $::FORM{$_}<BR>\n";
}

View File

@@ -1,515 +0,0 @@
#!/usr/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public License
# Version 1.0 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
#
# Direct any questions on this source code to
#
# Holger Schurig <holgerschurig@nikocity.de>
use diagnostics;
use strict;
require "CGI.pl";
require "globals.pl";
# TestProduct: just returns if the specified product does exists
# CheckProduct: same check, optionally emit an error text
# TestVersion: just returns if the specified product/version combination exists
# CheckVersion: same check, optionally emit an error text
sub TestProduct ($) {
my $prod = shift;
# does the product exist?
SendSQL("SELECT product
FROM products
WHERE product=" . SqlQuote($prod));
return FetchOneColumn();
}
sub CheckProduct ($) {
my $prod = shift;
# do we have a product?
unless ($prod) {
print "Sorry, you haven't specified a product.";
PutTrailer();
exit;
}
unless (TestProduct $prod) {
print "Sorry, product '$prod' does not exist.";
PutTrailer();
exit;
}
}
sub TestVersion ($$) {
my ($prod,$ver) = @_;
# does the product exist?
SendSQL("SELECT program,value
FROM versions
WHERE program=" . SqlQuote($prod) . " and value=" . SqlQuote($ver));
return FetchOneColumn();
}
sub CheckVersion ($$) {
my ($prod,$ver) = @_;
# do we have the version?
unless ($ver) {
print "Sorry, you haven't specified a version.";
PutTrailer();
exit;
}
CheckProduct($prod);
unless (TestVersion $prod,$ver) {
print "Sorry, version '$ver' for product '$prod' does not exist.";
PutTrailer();
exit;
}
}
#
# Displays the form to edit a version
#
sub EmitFormElements ($$) {
my ($product, $version) = @_;
print " <TH ALIGN=\"right\">Version:</TH>\n";
print " <TD><INPUT SIZE=64 MAXLENGTH=64 NAME=\"version\" VALUE=\"$version\">\n";
print " <INPUT TYPE=HIDDEN NAME=\"product\" VALUE=\"$product\"></TD>\n";
}
#
# Displays a text like "a.", "a or b.", "a, b or c.", "a, b, c or d."
#
sub PutTrailer (@) {
my (@links) = ("Back to the <A HREF=\"query.cgi\">query page</A>", @_);
my $count = $#links;
my $num = 0;
print "<P>\n<CENTER>";
foreach (@links) {
print $_;
if ($num == $count) {
print ".\n";
}
elsif ($num == $count-1) {
print " or ";
}
else {
print ", ";
}
$num++;
}
print "</CENTER>\n</BODY>\n</HTML>\n";
}
#
# Preliminary checks:
#
confirm_login();
print "Content-type: text/html\n\n";
unless (UserInGroup("editcomponents")) {
PutHeader("Not allowed");
print "Sorry, you aren't a member of the 'editproducts' group.\n";
print "And so, you aren't allowed to add, modify or delete versions.\n";
PutTrailer();
exit;
}
#
# often used variables
#
my $product = trim($::FORM{product} || '');
my $version = trim($::FORM{version} || '');
my $action = trim($::FORM{action} || '');
my $localtrailer;
if ($version) {
$localtrailer = "<A HREF=\"editversions.cgi?product=" . url_quote($product) . "\">edit</A> more versions";
} else {
$localtrailer = "<A HREF=\"editversions.cgi\">edit</A> more versions";
}
#
# product = '' -> Show nice list of versions
#
unless ($product) {
PutHeader("Select product");
print "<CENTER><H2>Edit Product Versions</H2></CENTER>\n";
SendSQL("SELECT product, description FROM products " .
"ORDER BY products.product");
print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0 ALIGN=center><TR BGCOLOR=\"#BFBFBF\">\n";
print " <TH ALIGN=\"left\">Edit versions of ...</TH>\n";
print " <TH ALIGN=\"left\">Description</TH>\n";
print "</TR>";
while ( MoreSQLData() ) {
my ($product, $description) = FetchSQLData();
$description ||= "<FONT COLOR=\"red\">missing</FONT>";
print "<TR BGCOLOR=\"#ECECEC\">\n";
print " <TH VALIGN=\"top\" ALIGN=left><A HREF=\"editversions.cgi?product=", url_quote($product), "\">$product</A></TH>\n";
print " <TD VALIGN=\"top\" ALIGN=left>$description</TD>\n";
}
print "</TR></TABLE>\n";
PutFooter();
exit;
}
#
# action='' -> Show nice list of versions
#
unless ($action) {
PutHeader("Select version");
print "<CENTER><H2>Edit $product Versions</H2></CENTER>\n";
CheckProduct($product);
=for me
# Das geht nicht wie vermutet. Ich bekomme nicht alle Versionen
# angezeigt! Schade. Ich würde gerne sehen, wieviel Bugs pro
# Version angegeben sind ...
=cut
SendSQL("SELECT value,program
FROM versions
WHERE program=" . SqlQuote($product) . "
ORDER BY value");
print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0 ALIGN=center><TR BGCOLOR=\"#BFBFBF\">\n";
print " <TH ALIGN=\"left\">Edit version ...</TH>\n";
#print " <TH ALIGN=\"left\">Bugs</TH>\n";
print " <TH ALIGN=\"left\">Action</TH>\n";
print "</TR>";
while ( MoreSQLData() ) {
my ($version,$dummy,$bugs) = FetchSQLData();
$bugs ||= 'none';
print "<TR BGCOLOR=\"#ECECEC\">\n";
print " <TD VALIGN=\"top\"><A HREF=\"editversions.cgi?product=", url_quote($product), "&version=", url_quote($version), "&action=edit\"><B>$version</B></A></TD>\n";
#print " <TD VALIGN=\"top\">$bugs</TD>\n";
print " <TD VALIGN=\"top\"><A HREF=\"editversions.cgi?product=", url_quote($product), "&version=", url_quote($version), "&action=del\"><B>Delete</B></A></TD>\n";
print "</TR>";
}
print "<TR BGCOLOR=\"#ECECEC\">\n";
print " <TH VALIGN=\"top\" COLSPAN=2><A HREF=\"editversions.cgi?product=", url_quote($product) . "&action=add\">";
print"Add a new version</A></TH>\n";
print "</TR></TABLE>\n";
PutFooter();
exit;
}
#
# action='add' -> present form for parameters for new version
#
# (next action will be 'new')
#
if ($action eq 'add') {
PutHeader("Add version");
CheckProduct($product);
#print "This page lets you add a new version to a bugzilla-tracked product.\n";
print "<FORM METHOD=POST ACTION=editversions.cgi>\n";
print "<TABLE BORDER=0 CELLPADDING=4 CELLSPACING=0 ALIGN=center><TR>\n";
EmitFormElements($product, $version);
print "</TABLE>\n";
print "<CENTER>\n";
print "<INPUT TYPE=SUBMIT VALUE=\"Add\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"action\" VALUE=\"new\">\n";
print "</FORM>\n</CENTER>\n";
my $other = $localtrailer;
$other =~ s/more/other/;
PutTrailer($other);
PutFooter();
exit;
}
#
# action='new' -> add version entered in the 'action=add' screen
#
if ($action eq 'new') {
PutHeader("Adding new version");
CheckProduct($product);
# Cleanups and valididy checks
unless ($version) {
print "You must enter a text for the new version. Please press\n";
print "<b>Back</b> and try again.\n";
PutTrailer($localtrailer);
exit;
}
if (TestVersion($product,$version)) {
print "The version '$version' already exists. Please press\n";
print "<b>Back</b> and try again.\n";
PutTrailer($localtrailer);
exit;
}
# Add the new version
SendSQL("INSERT INTO versions ( " .
"value, program" .
" ) VALUES ( " .
SqlQuote($version) . "," .
SqlQuote($product) . ")");
# Make versioncache flush
unlink "data/versioncache";
print "<CENTER>OK, done.</CENTER><P>\n";
PutTrailer($localtrailer);
exit;
}
#
# action='del' -> ask if user really wants to delete
#
# (next action would be 'delete')
#
if ($action eq 'del') {
PutHeader("Delete version");
CheckVersion($product, $version);
SendSQL("SELECT count(bug_id),product,version
FROM bugs
GROUP BY product,version
HAVING product=" . SqlQuote($product) . "
AND version=" . SqlQuote($version));
my $bugs = FetchOneColumn();
print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0>\n";
print "<TR BGCOLOR=\"#BFBFBF\">\n";
print " <TH VALIGN=\"top\" ALIGN=\"left\">Part</TH>\n";
print " <TH VALIGN=\"top\" ALIGN=\"left\">Value</TH>\n";
print "</TR><TR>\n";
print " <TH ALIGN=\"left\" VALIGN=\"top\">Product:</TH>\n";
print " <TD VALIGN=\"top\">$product</TD>\n";
print "</TR><TR>\n";
print " <TH ALIGN=\"left\" VALIGN=\"top\">Version:</TH>\n";
print " <TD VALIGN=\"top\">$version</TD>\n";
print "</TR><TR>\n";
print " <TH ALIGN=\"left\" VALIGN=\"top\">Bugs:</TH>\n";
print " <TD VALIGN=\"top\">", $bugs || 'none' , "</TD>\n";
print "</TR></TABLE>\n";
print "<H2>Confirmation</H2>\n";
print "<P>Do you really want to delete this version?<P>\n";
if ($bugs) {
print "<TABLE BORDER=0 CELLPADDING=20 WIDTH=\"70%\" BGCOLOR=\"red\"><TR><TD>\n",
"There are bugs entered for this version! When you delete this ",
"version, <B><BLINK>all</BLINK></B> stored bugs will be deleted, too. ",
"You could not even see the bug history for this version anymore!\n",
"</TD></TR></TABLE>\n";
}
print "<FORM METHOD=POST ACTION=editversions.cgi>\n";
print "<INPUT TYPE=SUBMIT VALUE=\"Yes, delete\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"action\" VALUE=\"delete\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"product\" VALUE=\"$product\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"version\" VALUE=\"$version\">\n";
print "</FORM>";
PutTrailer($localtrailer);
exit;
}
#
# action='delete' -> really delete the version
#
if ($action eq 'delete') {
PutHeader("Deleting version");
CheckVersion($product,$version);
# lock the tables before we start to change everything:
SendSQL("LOCK TABLES attachments WRITE,
bugs WRITE,
bugs_activity WRITE,
versions WRITE,
dependencies WRITE");
# According to MySQL doc I cannot do a DELETE x.* FROM x JOIN Y,
# so I have to iterate over bugs and delete all the indivial entries
# in bugs_activies and attachments.
SendSQL("SELECT bug_id
FROM bugs
WHERE product=" . SqlQuote($product) . "
AND version=" . SqlQuote($version));
while (MoreSQLData()) {
my $bugid = FetchOneColumn();
my $query = $::db->query("DELETE FROM attachments WHERE bug_id=$bugid")
or die "$::db_errstr";
$query = $::db->query("DELETE FROM bugs_activity WHERE bug_id=$bugid")
or die "$::db_errstr";
$query = $::db->query("DELETE FROM dependencies WHERE blocked=$bugid")
or die "$::db_errstr";
}
print "Attachments, bug activity and dependencies deleted.<BR>\n";
# Deleting the rest is easier:
SendSQL("DELETE FROM bugs
WHERE product=" . SqlQuote($product) . "
AND version=" . SqlQuote($version));
print "Bugs deleted.<BR>\n";
SendSQL("DELETE FROM versions
WHERE program=" . SqlQuote($product) . "
AND value=" . SqlQuote($version));
print "Version deleted.<P>\n";
SendSQL("UNLOCK TABLES");
unlink "data/versioncache";
PutTrailer($localtrailer);
exit;
}
#
# action='edit' -> present the edit version form
#
# (next action would be 'update')
#
if ($action eq 'edit') {
PutHeader("Edit version");
CheckVersion($product,$version);
print "<FORM METHOD=POST ACTION=editversions.cgi>\n";
print "<TABLE BORDER=0 CELLPADDING=4 CELLSPACING=0 ALIGN=center><TR>\n";
EmitFormElements($product, $version);
print "</TR></TABLE>\n";
print "<INPUT TYPE=HIDDEN NAME=\"versionold\" VALUE=\"$version\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"action\" VALUE=\"update\">\n";
print "<CENTER><INPUT TYPE=SUBMIT VALUE=\"Update\"></CENTER>\n";
print "</FORM>";
my $other = $localtrailer;
$other =~ s/more/other/;
PutTrailer($other);
PutFooter();
exit;
}
#
# action='update' -> update the version
#
if ($action eq 'update') {
PutHeader("Update version");
my $versionold = trim($::FORM{versionold} || '');
CheckVersion($product,$versionold);
# Note that the order of this tests is important. If you change
# them, be sure to test for WHERE='$version' or WHERE='$versionold'
SendSQL("LOCK TABLES bugs WRITE,
versions WRITE");
if ($version ne $versionold) {
unless ($version) {
print "Sorry, I can't delete the version text.";
PutTrailer($localtrailer);
SendSQL("UNLOCK TABLES");
exit;
}
if (TestVersion($product,$version)) {
print "Sorry, version '$version' is already in use.";
PutTrailer($localtrailer);
SendSQL("UNLOCK TABLES");
exit;
}
SendSQL("UPDATE bugs
SET version=" . SqlQuote($version) . "
WHERE version=" . SqlQuote($versionold) . "
AND product=" . SqlQuote($product));
SendSQL("UPDATE versions
SET value=" . SqlQuote($version) . "
WHERE program=" . SqlQuote($product) . "
AND value=" . SqlQuote($versionold));
unlink "data/versioncache";
print "Updated version.<BR>\n";
}
SendSQL("UNLOCK TABLES");
PutTrailer($localtrailer);
exit;
}
#
# No valid action found
#
PutHeader("Error");
print "I don't have a clue what you want.<BR>\n";
foreach ( sort keys %::FORM) {
print "$_: $::FORM{$_}<BR>\n";
}

View File

@@ -1,424 +0,0 @@
#!/usr/bonsaitools/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are Copyright (C) 1998
# Netscape Communications Corporation. All Rights Reserved.
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
# Dave Miller <dave@intrec.com>
# Joe Robins <jmrobins@tgix.com>
# David Lawrence <dkl@redhat.com>
########################################################################
#
# enter_bug.cgi
# -------------
# Displays bug entry form. Bug fields are specified through popup menus,
# drop-down lists, or text fields. Default for these values can be passed
# in as parameters to the cgi.
#
########################################################################
use diagnostics;
use strict;
require "CGI.pl";
# Shut up misguided -w warnings about "used only once". "use vars" just
# doesn't work for me.
sub sillyness {
my $zz;
$zz = $::unconfirmedstate;
$zz = @::legal_opsys;
$zz = @::legal_platform;
$zz = @::legal_priority;
$zz = @::legal_severity;
}
# hash to hold values to be passed to the html fill in template
my %enter_bug;
confirm_login();
my $userid = 0;
if (defined ($::COOKIE{'Bugzilla_login'})) {
$userid = DBname_to_id($::COOKIE{'Bugzilla_login'});
}
if (!defined $::FORM{'product'}) {
GetVersionTable();
my @prodlist = GenProductList($userid, keys %::versions);
if (1 != @prodlist) {
print "Content-type: text/html\n\n";
PutHeader("Enter Bug");
print "<CENTER><H3>First, did you <A HREF=\"query.cgi\">query</A> the current database of bugs";
print "to see if your problem has already been reported?<P>";
print "Also, have you checked to see if your problem has been fixed in a latest ";
print "<A HREF=\"http://www.redhat.com/support/updates.html\">errata</A> updates?<P>";
print "If it has not then pick a product or category on which to enter a bug.</H3></CENTER>";
print "<TABLE ALIGN=center BORDER=1 CELLSPACING=0 CELLPADDING=3>\n";
print "<TR BGCOLOR=\"#BFBFBF\">\n<TH ALIGN=left>Product</TH>\n";
print "<TH ALIGN=left>Description</TH>\n</TR>\n";
foreach my $p (sort (@prodlist)) {
if (defined $::proddesc{$p} && $::proddesc{$p} eq '0') {
# Special hack. If we stuffed a "0" into proddesc, that means
# that disallownew was set for this bug, and so we don't want
# to allow people to specify that product here.
next;
}
if(Param("usebuggroupsentry")
&& GroupExists($p)
&& !UserInGroup($p)) {
# If we're using bug groups to restrict entry on products, and
# this product has a bug group, and the user is not in that
# group, we don't want to include that product in this list.
next;
}
print "<TR BGCOLOR=\"#ECECEC\">";
print "<TH ALIGN=left VALIGN=center><A HREF=\"enter_bug.cgi?product=" . url_quote($p);
print "\">$p</A></TH>\n";
if (defined $::proddesc{$p}) {
print "<TD VALIGN=center ALIGN=left>$::proddesc{$p}</TD>\n";
}
print "</TR>";
}
print "</TABLE>\n";
PutFooter();
exit;
}
$::FORM{'product'} = $prodlist[0];
}
my $product = $::FORM{'product'};
print "Content-type: text/html\n\n";
sub formvalue {
my ($name, $default) = (@_);
if (exists $::FORM{$name}) {
return $::FORM{$name};
}
if (defined $default) {
return $default;
}
return "";
}
sub pickplatform {
my $value = formvalue("rep_platform");
if ($value ne "") {
return $value;
}
if ( Param('usebrowserinfo') ) {
for ($ENV{'HTTP_USER_AGENT'}) {
/Mozilla.*\(Windows/ && do { return "PC";};
/Mozilla.*\(Macintosh/ && do {return "Macintosh";};
/Mozilla.*\(Win/ && do {return "PC";};
/Mozilla.*Windows NT/ && do {return "PC";};
/Mozilla.*Linux.*86/ && do {return "i386";};
/Mozilla.*Linux.*alpha/ && do {return "alpha";};
/Mozilla.*OSF/ && do {return "DEC";};
/Mozilla.*HP-UX/ && do {return "HP";};
/Mozilla.*IRIX/ && do {return "SGI";};
/Mozilla.*(SunOS|Solaris)/ && do {return "Sun";};
}
}
# default
return "i386";
}
sub pickversion {
my $version = formvalue('version');
if ( Param('usebrowserinfo') ) {
if ($version eq "") {
if ($ENV{'HTTP_USER_AGENT'} =~ m@Mozilla[ /]([^ ]*)@) {
$version = $1;
}
}
}
if (lsearch($::versions{$product}, $version) >= 0) {
return $version;
} else {
if (defined $::COOKIE{"VERSION-$product"}) {
if (lsearch($::versions{$product},
$::COOKIE{"VERSION-$product"}) >= 0) {
return $::COOKIE{"VERSION-$product"};
}
}
}
return $::versions{$product}->[0];
}
sub pickcomponent {
my $result = formvalue('component');
if ($result ne "" && lsearch($::components{$product}, $result) < 0) {
$result = "";
}
return $result;
}
sub pickos {
if (formvalue('op_sys') ne "") {
return formvalue('op_sys');
}
if ( Param('usebrowserinfo') ) {
for ($ENV{'HTTP_USER_AGENT'}) {
/Mozilla.*\(.*;.*; IRIX.*\)/ && do {return "IRIX";};
/Mozilla.*\(.*;.*; 32bit.*\)/ && do {return "Windows 95";};
/Mozilla.*\(.*;.*; 16bit.*\)/ && do {return "Windows 3.1";};
/Mozilla.*\(.*;.*; 68K.*\)/ && do {return "Mac System 8.5";};
/Mozilla.*\(.*;.*; PPC.*\)/ && do {return "Mac System 8.5";};
/Mozilla.*\(.*;.*; OSF.*\)/ && do {return "OSF/1";};
/Mozilla.*\(.*;.*; Linux.*\)/ && do {return "Linux";};
/Mozilla.*\(.*;.*; SunOS 5.*\)/ && do {return "Solaris";};
/Mozilla.*\(.*;.*; SunOS.*\)/ && do {return "SunOS";};
/Mozilla.*\(.*;.*; SunOS.*\)/ && do {return "SunOS";};
/Mozilla.*\(.*;.*; BSD\/OS.*\)/ && do {return "BSDI";};
/Mozilla.*\(Win16.*\)/ && do {return "Windows 3.1";};
/Mozilla.*\(Win95.*\)/ && do {return "Windows 95";};
/Mozilla.*\(Win98.*\)/ && do {return "Windows 98";};
/Mozilla.*\(WinNT.*\)/ && do {return "Windows NT";};
}
}
# default
return "Linux";
}
GetVersionTable();
$enter_bug{'assign_element'} = "<A HREF=\"bug_status.cgi#assigned_to\"><B>Assigned To:</B></A></TD><TD>" .
GeneratePeopleInput('assigned_to', formvalue('assigned_to'));
$enter_bug{'cc_element'} = "<B>Cc:</B></TD><TD>" .
GeneratePeopleInput('cc', formvalue('cc'));
my $priority = Param('defaultpriority');
$enter_bug{'severity_popup'} = "<A HREF=\"bug_status.cgi#bug_severity\"><B>Severity:</B></A></TD><TD>" .
make_popup('bug_severity', \@::legal_severity,
formvalue('bug_severity', 'normal'), 0);
$enter_bug{'platform_popup'} = "<A HREF=\"bug_status.cgi#rep_platform\"><B>Platform:<B></A></TD><TD>" .
make_popup('rep_platform', \@::legal_platform,
pickplatform(), 0) ;
# $enter_bug{'opsys_popup'} = "<A HREF=\"bug_status.cgi#op_sys\"><B>OpSys:</B></A></TD><TD>" .
make_popup('op_sys', \@::legal_opsys, pickos(), 0);
$enter_bug{'opsys_popup'} = "<INPUT TYPE=hidden NAME=op_sys VALUE=\"" . value_quote(pickos()) ."\"></TD><TD>\n";
if (1 == @{$::components{$product}}) {
# Only one component; just pick it.
$::FORM{'component'} = $::components{$product}->[0];
}
$enter_bug{'component_popup'} = "<A HREF=\"describecomponents.cgi?product=" . value_quote($product) . "\">" .
"<B>Component:</B></A></TD><TD>" .
make_popup('component', $::components{$product},
formvalue('component'), 1);
$enter_bug{'component_text'} = "<A HREF=\"bug_status.cgi#component\"><B>Component Text:</B></A></TD><TD>" .
GeneratePeopleInput('component_text', formvalue('component_text'));
PutHeader ("Enter Bug", "Enter Bug");
# PutHeader ("Enter Bug","Enter Bug","This page lets you enter a new bug into Bugzilla.");
# Modified, -JMR, 2/24,00
# If the usebuggroupsentry parameter is set, we need to check and make sure
# that the user has permission to enter a bug against this product.
if(Param("usebuggroupsentry")) {
if(!UserInGroup($product)) {
print "<H1>Permission denied.</H1>\n";
print "Sorry; you do not have the permissions necessary to enter\n";
print "a bug against this product.\n";
print "<P>\n";
PutFooter();
exit;
}
}
# Modified, -JMR, 2/18/00
# I'm putting in a select box in order to select whether to restrict this bug to
# the product's bug group or not, if the usebuggroups parameter is set, and if
# this product has a bug group. This box will default to selected, but can be
# turned off if this bug should be world-viewable for some reason.
#
# To do this, I need to (1) get the bit and description for the bug group from
# the database, (2) insert the select box in the giant print statements below,
# and (3) update post_bug.cgi to process the additional input field.
# First we get the bit and description for the group.
my $group_bit=0;
my $group_desc;
if(Param("usebuggroups") && GroupExists($product)) {
SendSQL("select bit, description from groups ".
"where name = ".SqlQuote($product)." ".
"and isbuggroup != 0");
($group_bit, $group_desc) = FetchSQLData();
}
if (Param("entryheaderhtml")){
$enter_bug{'entryheaderhtml'} = Param("entryheaderhtml");
}
$enter_bug{'version_element'} = "<B>Version:</B></TD><TD>" .
Version_element(pickversion(), $product);
$enter_bug{'component_describe'} = url_quote($product);
if (Param('letsubmitterchoosepriority')) {
$enter_bug{'priority_popup'} = "<B><A HREF=\"bug_status.cgi#priority\">Priority</A>:</B></TD><TD>" .
make_popup('priority', \@::legal_priority,
formvalue('priority', $priority), 0);
} else {
$enter_bug{'priority_popup'} = "<INPUT TYPE=HIDDEN NAME=priority VALUE=\"" .
value_quote($priority) . "\"></TD><TD>\n";
}
$enter_bug{'url_element'} = "<B>URL:</B></TD><TD>" .
GeneratePeopleInput('bug_file_loc', formvalue('bug_file_loc'));
$enter_bug{'summary_element'} = "<B>Summary:</B></TD><TD>" .
GeneratePeopleInput('short_desc', formvalue('short_desc'));
$enter_bug{'comment'} = value_quote(formvalue('comment'));
if (UserInGroup("editbugs") || UserInGroup("canconfirm")) {
SendSQL("SELECT votestoconfirm FROM products WHERE product = " .
SqlQuote($product));
if (FetchOneColumn()) {
$enter_bug{'initialstate_popup'} = qq{
<B><A HREF="bug_status.html#status">Initial state:</B></A></TD>
<TD>
};
$enter_bug{'initialstate_popup'} = BuildPulldown("bug_status",
[[$::unconfirmedstate], ["NEW"]],
"NEW");
}
} else {
$enter_bug{'initialstate_popup'} = "<INPUT TYPE=hidden NAME=bug_status VALUE=\"NEW\">\n";
}
# Red Hat contract bug support
if (Param('contract') && UserInGroup('setcontract')) {
$enter_bug{'contract_checkbox'} = qq{
<INPUT TYPE="checkbox" NAME="iscontract" VALUE="1">&nbsp;<B>This is a contract bug</B></TD>
};
}
# In between the Description field and the Submit buttons, we'll put in the
# select box for the bug group, if necessary.
# Rather than waste time with another Param check and another database access,
# $group_bit will only have a non-zero value if we're using bug groups and have
# one for this product, so I'll check on that instead here. -JMR, 2/18/00
if($group_bit && $::driver eq 'mysql') {
# In addition, we need to handle the possibility that we're coming from
# a bookmark template. We'll simply check if we've got a parameter called
# groupset passed with a value other than the current bit. If so, then we're
# coming from a template, and we don't have group_bit set, so turn it off.
my $check0 = (formvalue("groupset",$group_bit) == $group_bit) ? "" : " SELECTED";
my $check1 = ($check0 eq "") ? " SELECTED" : "";
$enter_bug{'group_select'} = "
<table>
<tr>
<td align=right><B>Access:</td>
<td colspan=5>
<select name=\"groupset\">
<option value=0$check0>
People not in the \"$group_desc\" group can see this bug
</option>
<option value=$group_bit$check1>
Only people in the \"$group_desc\" group can see this bug
</option>
</select>
</td>
</tr>
</table>";
} else {
# Find out which groups we are a member of and form radio buttons
SendSQL("select user_group.groupid, groups.description, groups.isbuggroup " .
"from user_group, groups " .
"where user_group.groupid = groups.groupid " .
"and user_group.userid = $userid order by groups.groupid");
my %grouplist;
my @buggrouplist;
my @row;
my $flag = 0;
while (@row = FetchSQLData()) {
if ($row[2] == 0) {
next;
}
$grouplist{$row[0]} = $row[1];
$flag = 1;
}
if ($flag) {
$enter_bug{'group_select'} = qq{
<TABLE CELLSPACING=0 CELLPADDING=3 BORDER=1>
<TR BGCOLOR="#CFCFCF">
<TD ALIGN=left><B>Groups that can see this bug.</B><BR>
(If all unchecked then same as everyone)</TD>
</TR><TR>
<TD ALIGN=left>
};
foreach my $group (keys %grouplist) {
$enter_bug{'group_select'} .= "<INPUT TYPE=checkbox NAME=group-$group VALUE=1>\n";
$enter_bug{'group_select'} .= "<B>$grouplist{$group}</B> can only see this bug.<BR>\n";
}
$enter_bug{'group_select'} .= qq{
</TD>
</TR>
</TABLE>
};
}
}
if ( Param('usebrowserinfo') ) {
$enter_bug{'browserinfo'} = "
Some fields initialized from your user-agent,
<B>$ENV{'HTTP_USER_AGENT'}</B>. If you think it got it wrong,
please tell " . Param('maintainer') . " what it should have been.
";
}
foreach my $key (keys %::FORM) {
$enter_bug{$key} = $::FORM{$key};
}
# we should have enough now to fill in the template
print LoadTemplate('enterbug_redhat.tmpl', \%enter_bug);
PutFooter();

File diff suppressed because it is too large Load Diff

View File

@@ -1,76 +0,0 @@
#!/usr/bonsaitools/bin/perl -w
#
# The contents of this file are subject to the Mozilla Public License
# Version 1.0 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are Copyright (C) 1998
# Netscape Communications Corporation. All Rights Reserved.
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
# David Lawrence <dkl@redhat.com>
use diagnostics;
use strict;
require 'CGI.pl';
print "Content-type:text/html\n\n";
PutHeader("Clue Page");
print "
<TABLE WIDTH=800 ALIGN=center>
<TR>
<TD>
<H1>A Clue</H1>
This form will allow you to call up a subset of the bug list.
You should be able to add the URL of the resulting list to
your bookmark file in order to preserve queries.
<P>
The way the query works, if you have nothing checked in a box,
then all values for that field are legal, for example if you checked nothing
in any of the boxes, you would get the entire bug list.
<P>
The default value of this form should correspond roughly to a <I>personal</I>
bug list.
<HR>
<H2>Running queries not supported by the pretty boxes</H2>
There is a hacky way to do some searches that aren't supported by the
form. The buglist script will build queries based on the URL, so
you can add other criteria.
<P>
For example, if you wanted to see all bugs reported against the X platform
and assigned to jwz, you could ask for all bugs assign to jwz, then
edit the URL in the \"Location\" box, adding the clause \"&rep_platform=X-Windows\"
to the URL.
<P>
Here is a list of some of the field names you could use for additional
unsupported searches ...
<PRE>
version
rep_platform
op_sys
bug_file_loc
short_desc
</PRE>
</TD>
</TR>
</TABLE>
";
PutFooter();

View File

@@ -1,66 +0,0 @@
<HTML>
<!--
The contents of this file are subject to the Mozilla Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is the Bugzilla Bug Tracking System.
The Initial Developer of the Original Code is Netscape Communications
Corporation. Portions created by Netscape are
Copyright (C) 1998 Netscape Communications Corporation. All
Rights Reserved.
Contributor(s):
Contributor(s): Terry Weissman <terry@mozilla.org>
-->
<TITLE>Clue</TITLE>
<H1>A Clue</H1>
This form will allow you to call up a subset of the bug list.
You should be able to add the URL of the resulting list to
your bookmark file in order to preserve queries.
<p>
The way the query works, if you have nothing checked in a box,
then all values for that field are legal, for example if you checked nothing
in any of the boxes, you would get the entire bug list.
<p>
The default value of this form should correspond roughly to a "personal"
bug list.
<HR>
<H2>Running queries not supported by the pretty boxes</H2>
There is a hacky way to do some searches that aren't supported by the
form. The buglist script will build queries based on the URL, so
you can add other criteria.
<P>
For example, if you wanted to see all bugs reported against the X platform
and assigned to jwz, you could ask for all bugs assign to jwz, then
edit the URL in the "Location" box, adding the clause "&rep_platform=X-Windows"
to the URL.
<P>
Here is a list of some of the field names you could use for additional
unsupported searches ...
<PRE>
version
rep_platform
op_sys
reporter area
bug_file_loc
short_desc
</PRE>
<HR>
<H1>Browser Notes</H1>
<P>Bugzilla uses several non-standard Netscape extentions, but this does not seem
to case any problem with other browsers. The lynx browser does work, but lynx
seems to cache results of a .cgi. You'll sometimes need to press CONTROL-R to reload
the screen to see an update.
</html>

View File

@@ -1,67 +0,0 @@
#!/usr/bonsaitools/bin/perl -w
#
# The contents of this file are subject to the Mozilla Public License
# Version 1.0 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are Copyright (C) 1998
# Netscape Communications Corporation. All Rights Reserved.
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
# David Lawrence <dkl@redhat.com>
use diagnostics;
use strict;
require 'CGI.pl';
print "Content-type:text/html\n\n";
PutHeader("Email Help");
print "
<TABLE WIDTH=800>
<TR>
<TD>
<h1>Help on searching by email address.</h1>
This used to be simpler, but not very powerful. Now it's really
powerful and useful, but it may not be obvious how to use it...
<p>
To search for bugs associated with an email address:
<ul>
<li> Type a portion of an email address into the text field.
<li> Select which fields of the bug you expect that address to be in
the bugs you're looking for.
</ul>
<p>
You can look for up to two different email addresses; if you specify
both, then only bugs which match both will show up. This is useful to
find bugs that were, for example, created by Ralph and assigned to
Fred.
<p>
You can also use the drop down menus to specify whether you want to
match addresses by doing a substring match, by using regular
expressions, or by exactly matching a fully specified email address.
</TD>
</TR>
</TABLE>
";
PutFooter();

View File

@@ -1,36 +0,0 @@
<html> <head>
<title>Help on searching by email address.</title>
</head>
<body>
<h1>Help on searching by email address.</h1>
This used to be simpler, but not very powerful. Now it's really
powerful and useful, but it may not be obvious how to use it...
<p>
To search for bugs associated with an email address:
<ul>
<li> Type a portion of an email address into the text field.
<li> Select which fields of the bug you expect that address to be in
the bugs you're looking for.
</ul>
<p>
You can look for up to two different email addresses; if you specify
both, then only bugs which match both will show up. This is useful to
find bugs that were, for example, created by Ralph and assigned to
Fred.
<p>
You can also use the drop down menus to specify whether you want to
match addresses by doing a substring match, by using regular
expressions, or by exactly matching a fully specified email address.
</body> </html>

View File

@@ -1,83 +0,0 @@
<HTML>
<!--
The contents of this file are subject to the Mozilla Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is the Bugzilla Bug Tracking System.
The Initial Developer of the Original Code is Netscape Communications
Corporation. Portions created by Netscape are
Copyright (C) 1998 Netscape Communications Corporation. All
Rights Reserved.
Contributor(s):
Contributor(s): Terry Weissman <terry@mozilla.org>
-->
<TITLE>How to Mail to bugzilla</TITLE>
<H1>THIS DOESN'T WORK RIGHT NOW. Coming someday.</H1>
Mailing to "bugzilla" will be piped through a script which examines
your message, stripping out control lines, and passing the rest of the
message in as the description of a new bug. The control lines look like: <P>
<PRE>
@FIELD-LABEL VALUE
LABEL Legal Values
Priority critical major normal minor trivial
Type BUG RFE
Product Cheddar
Platform PC X-Windows Macintosh All
Area CODE JAVA TEST BUILD UI PERF
Version version 2.0b1 2.0b2 2.0b2 2.0b4 2.1a0 2.1a1 2.1b0 2.1b1 2.1b2
OS Windows 3.1 Windows 95 Windows NT System 7 System 7.5
AIX BSDI HP-UX IRIX Linux OSF/1 Solaris SunOS other
Summary -anything-
URL -anything-
Assign someone in eng
and
@description
This tells the bug parse to stop looking for control lines,
allowing the bug description to contain lines which start with @
</PRE>
There are default values for all these fields. If you don't specify a
Summary, the subject of the mail message is used. <P>
If you specify an illegal value, the default value is used, the
bug is assigned to you, and the answerback message will describe
the error. <P>
After the bug is posted, you will get mail verifying the posting
and informing you of the bug number if you wish to fix any
mistakes made by the auto-processor. <P>
EXAMPLE: <P>
<PRE>
% Mail bugzilla
Subject: WinFE crashes with GPF when I pour beer on my keyboard
@priority critical
@platform PC
@assign troy
After the beer bash I emptied the rest of the keg onto my keyboard
and my sharp build of Navigator got a GPF.
.
</PRE>

View File

@@ -1,54 +0,0 @@
#!/usr/bonsaitools/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public License
# Version 1.0 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are Copyright (C) 1998
# Netscape Communications Corporation. All Rights Reserved.
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
# David Lawrence <dkl@redhat.com>
use diagnostics;
use strict;
use Text::Template;
require 'CGI.pl';
ConnectToDatabase();
print "Content-type:text/html\n\n";
PutHeader("Main Page");
print qq{
<TABLE ALIGN=center WIDTH=800 BORDER=1 CELLPADDING=0 CELLSPACING=0>
<TR BGCOLOR="#BFBFBF">
<TD>
<TABLE ALIGN=center WIDTH=100%>
<TR>
<TH ALIGN=left>Bugzilla News</TH>
<TH ALIGN=right><A HREF=news.cgi>Old news...</A></TH>
</TR>
</TABLE>
</TD>
</TR><TR>
<TD>
};
print GetHeadlines();
print "</TD>\n</TR>\n</TABLE><P>\n";
print LoadTemplate('index_redhat.tmpl');
PutFooter();

View File

@@ -1,86 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<!--
The contents of this file are subject to the Mozilla Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is the Bugzilla Bug Tracking System.
The Initial Developer of the Original Code is Netscape Communications
Corporation. Portions created by Netscape are
Copyright (C) 1998 Netscape Communications Corporation. All
Rights Reserved.
Contributor(s):
Contributor(s): Terry Weissman <terry@mozilla.org>
-->
<HEAD><TITLE>Bugzilla Main Page</TITLE></HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000"
LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000">
<TABLE BGCOLOR="#000000" WIDTH="100%" BORDER=0 CELLPADDING=0 CELLSPACING=0>
<TR><TD><A HREF="http://www.mozilla.org/"><IMG
SRC="http://www.mozilla.org/images/mozilla-banner.gif" ALT=""
BORDER=0 WIDTH=600 HEIGHT=58></A></TD></TR></TABLE>
<TABLE BORDER=0 CELLPADDING=12 CELLSPACING=0 WIDTH="100%">
<TR>
<TD>
<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=2>
<TR><TD VALIGN=TOP ALIGN=CENTER NOWRAP>
<FONT SIZE="+3"><B><NOBR>Main Page</NOBR></B></FONT>
</TD></TR><TR><TD VALIGN=TOP ALIGN=CENTER>
<B></B>
</TD></TR>
</TABLE>
</TD>
<TD>
This is <B>Bugzilla</B>: the Mozilla bug system. For more
information about what Bugzilla is and what it can do, see
<A HREF="http://www.mozilla.org/">mozilla.org</A>'s
<A HREF="http://www.mozilla.org/bugs/"><B>bug pages</B></A>.
</TD></TR></TABLE>
<img align=right width=329 height=220 src=ant.jpg border=2>
This is where we put in lots of nifty words explaining all about
bugzilla.
<p>
But it all boils down to a choice of:
<br>
<a href="query.cgi">Query existing bug reports</a><br>
<a href="enter_bug.cgi">Enter a new bug report</a><br>
<a href="reports.cgi">Get summary reports</a><br>
<p>
<a href="createaccount.cgi">Open a new Bugzilla account</a><br>
<a href="relogin.cgi">Forget the currently stored login</a><br>
<a href="userprefs.cgi">Change password or user preferences</a><br>
<FORM METHOD=GET ACTION="show_bug.cgi">
<INPUT TYPE=SUBMIT VALUE="Find"> bug # <INPUT NAME=id SIZE=6></FORM>
<SCRIPT LANGUAGE="JavaScript">
document.forms[0].id.focus()
</SCRIPT>
</BODY>
</HTML>

View File

@@ -1,115 +0,0 @@
#!/usr/bonsaitools/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public License
# Version 1.0 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are Copyright (C) 1998
# Netscape Communications Corporation. All Rights Reserved.
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
use diagnostics;
use strict;
require "CGI.pl";
# Shut up misguided -w warnings about "used only once":
use vars %::FORM;
print "Content-type: text/html\n\n";
ConnectToDatabase();
quietly_check_login();
my $userid = 0;
if (defined($::COOKIE{'Bugzilla_login'})) {
$userid = DBname_to_id($::COOKIE{'Bugzilla_login'});
}
my $generic_query = "
select
bugs.bug_id,
bugs.product,
bugs.version,
bugs.rep_platform,
bugs.op_sys,
bugs.bug_status,
bugs.bug_severity,
bugs.priority,
bugs.resolution,
assign.login_name,
report.login_name,
bugs.component,
bugs.bug_file_loc,
bugs.short_desc,
bugs.target_milestone,
bugs.qa_contact,
bugs.status_whiteboard
from bugs,profiles assign,profiles report
where assign.userid = bugs.assigned_to and report.userid = bugs.reporter and ";
foreach my $bug (split(/:/, $::FORM{'buglist'})) {
if (!CanISee($bug, $userid)) {
next;
}
SendSQL("$generic_query bugs.bug_id = $bug");
my @row;
if (@row = FetchSQLData()) {
my ($id, $product, $version, $platform, $opsys, $status, $severity,
$priority, $resolution, $assigned, $reporter, $component, $url,
$shortdesc, $target_milestone, $qa_contact,
$status_whiteboard) = (@row);
print "<HTML><HEAD><TITLE>Bug # $id</TITLE></HEAD><BODY BGCOLOR=white>\n";
print "<TABLE CELLSPACING=4 CELLPADDING=4>\n";
print "<TR><TD COLSPAN=4 ALIGN=center><B><FONT =\"+3\">" .
html_quote($shortdesc) .
"</B></FONT></TD></TR>\n";
print "<TR><TD><B>Bug#:</B> <A HREF=\"show_bug.cgi?id=$id\">$id</A>\n";
print "<TD><B>Product:</B> $product\n";
print "<TD><B>Version:</B> $version\n";
print "<TD><B>Platform:</B> $platform\n";
print "<TR><TD><B>OS/Version:</B> $opsys\n";
print "<TD><B>Status:</B> $status\n";
print "<TD><B>Severity:</B> $severity\n";
print "<TD><B>Priority:</B> $priority\n";
print "<TR><TD><B>Resolution:</B> $resolution</TD>\n";
print "<TD><B>Assigned To:</B> $assigned\n";
print "<TD><B>Reported By:</B> $reporter\n";
if (Param("useqacontact")) {
my $name = "";
if ($qa_contact > 0) {
$name = DBID_to_name($qa_contact);
}
print "<TD><B>QA Contact:</B> $name\n";
}
print "<TR><TD><B>Component:</B> $component\n";
if (Param("usetargetmilestone")) {
print "<TD><B>Target milestone:</B>$target_milestone\n";
}
print "<TR><TD COLSPAN=6><B>URL:</B>&nbsp;";
print "<A HREF=\"" . $url . "\">" . html_quote($url) . "</A>\n";
print "<TR><TD COLSPAN=6><B>Summary:</B> " . html_quote($shortdesc) . "\n";
if (Param("usestatuswhiteboard")) {
print "<TR><TD COLSPAN=6><B>Status Whiteboard:" .
html_quote($status_whiteboard) . "\n";
}
print "<TR><TD><B>Description:</B></TD></TR>\n";
print "<TR><TD ALIGN=left COLSPAN=4><PRE>" . html_quote(GetLongDescriptionAsText($bug)) . "</PRE></TD>\n";
print "</TR></TABLE></BODY></HTML>\n";
}
}

View File

@@ -1,41 +0,0 @@
#!/usr/bonsaitools/bin/perl
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public License
# Version 1.0 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are Copyright (C) 1998
# Netscape Communications Corporation. All Rights Reserved.
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
if ($ENV{'REQUEST_METHOD'} eq "GET") { $buffer = $ENV{'QUERY_STRING'}; }
else { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); }
# Split the name-value pairs
@pairs = split(/&/, $buffer);
foreach $pair (@pairs)
{
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$FORM{$name} = $value;
}
open(COMMENTS, ">>data/comments");
$c=$FORM{"comment"};
print COMMENTS $FORM{"comment"} . "\n";
close(COMMENTS);
print "Content-type: text/html\n\n";
print "<TITLE>The Word Of Confirmation</TITLE>";
print "<H1>Done</H1>";
print $c;

View File

@@ -1,93 +0,0 @@
#!/usr/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public License
# Version 1.0 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are Copyright (C) 1998
# Netscape Communications Corporation. All Rights Reserved.
#
# $Id: new_mail.pl,v 1.1.2.4 2000-05-31 22:22:19 dkl%redhat.com Exp $
#
# Contributor(s): Andrew Anderson <andrew@redhat.com>
use diagnostics;
use strict;
use English;
require "globals.pl";
my $basedir = '/home/httpd/html/bugzilla/';
my $bug_id = shift;
if(!$bug_id) {
die "No Bug ID supplied";
}
my @message = ();
while(<>) {
push(@message,$_);
}
my $i = 0;
my $header = "";
while ($message[$i] ne "\n") {
$header .= $message[$i];
$i++;
}
my @body = ();
while(defined($message[$i])) {
push(@body, $message[$i++]);
}
$header =~ s/\n\s+/ /g;
my %head = ('FRONTSTUFF', split /^([-\w]+):/m, $header);
#print "HEADER:\n";
foreach my $item (keys %head) {
chomp($head{$item});
#print "\t$item: $head{$item}\n";
}
#print "BODY:\n";
#print "@body\n";
# Here we make the assumption that the last mail received
# was indeed the message in question -- given the message
# load, this should be a valid assumption.
umask 0777;
opendir MAILDIR, "$basedir/data/maildir/$bug_id" or
die "Couldn't open mail directory: $ERRNO";
my @mail = readdir MAILDIR;
closedir MAILDIR;
#print "MAIL: $mail[$#mail]\n";
my $maillink = "data/maildir/$bug_id/$mail[$#mail]";
&ConnectToDatabase;
my $query = "SELECT long_desc FROM bugs WHERE bug_id = '$bug_id'";
#print "QUERY: $query\n";
SendSQL($query);
my $desc = FetchOneColumn();
my $now = time2str("%D %H:%M", time());
$desc .= "\n\n------- Email From $head{'From'} $now -------\n";
$desc .= "Attached to Bug # $bug_id.\n";
$query = "UPDATE bugs SET long_desc = " . SqlQuote($desc) .
" WHERE bug_id = '$bug_id'";
#print "UPDATE: $query\n";
SendSQL($query);
chdir($basedir);
system("$basedir/processmail", "$bug_id");

View File

@@ -1,37 +0,0 @@
<HTML>
<!--
The contents of this file are subject to the Mozilla Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is the Bugzilla Bug Tracking System.
The Initial Developer of the Original Code is Netscape Communications
Corporation. Portions created by Netscape are
Copyright (C) 1998 Netscape Communications Corporation. All
Rights Reserved.
Contributor(s):
Contributor(s): Terry Weissman <terry@mozilla.org>
-->
<TITLE>I'm So Pretty and Witty And Wise</TITLE>
<H2>Add your own clever headline.</h2>
The buglist picks a random quip for the headline, and
you can extend the quip list. Type in something clever or
funny or boring and bonk on the button.
<HR>
<FORM METHOD=POST ACTION="new_comment.cgi">
<INPUT SIZE=80 NAME="comment"><BR>
<INPUT TYPE="submit" VALUE="Add This Quip"></FORM>
</HR>
For the impatient, you can
<A HREF="data/comments">view the whole quip list</A>.

View File

@@ -1,68 +0,0 @@
#!/usr/bin/perl -w
#
# news.cgi
#
# Contributor(s) David Lawrence <dkl@redhat.com>
require 'CGI.pl';
require 'globals.pl';
print "Content-type: text/html\n\n";
PutHeader("Bugzilla News");
# subroutine: PutStory
# description: outputs story in table html format
# params: $headline = headline of news article (scalar)
# $date = date news article was created (scalar)
# $story = actual large text of the story (scalar)
# returns: none
sub PutStory {
my ($add_date, $headline, $story) = (@_);
print qq{
<P>
<TABLE ALIGN=center WIDTH=700 BORDER=1 CELLSPACING=0 CELLPADDING=3>
<TR BGCOLOR="#BFBFBF">
<TD ALIGN=left>
<FONT SIZE=+2><B>$headline</B></FONT><BR>
<FONT SIZE=-1>Added on</FONT> <I>$add_date</I>
</TD>
</TR><TR BGCOLOR="#ECECEC">
<TD ALIGN=left>
$$story
</TD>
</TR>
</TABLE>
<P>
};
}
my $query = "";
if (defined($::FORM{'id'}) && $::FORM{'id'} ne '') {
# Show an individual news article
$query = "select " . SqlDate('add_date') . ", headline, story from news where id = " . $::FORM{'id'};
SendSQL($query);
my ($add_date, $headline, $story) = FetchSQLData();
if ($headline eq "") {
PutError("News item not found.");
}
PutStory($add_date, $headline, \$story);
} else {
# Show all the news
print "<CENTER><H2>All the News...</H2></CENTER>\n";
$query = "select id, " . SqlDate('add_date') . ", headline, story from news order by id";
SendSQL($query);
while (my @row = FetchSQLData()) {
my ($id, $add_date, $headline, $story) = (@row);
PutStory($add_date, $headline, \$story);
}
}
PutFooter();
exit;

View File

@@ -1,10 +0,0 @@
<html> <head>
<title>No target milestones.</title>
</head>
<body>
<h1>No target milestones.</h1>
No target milestones have been defined for this product. You can set
the Target Milestone field to things, but there is not currently any
agreed definition of what the milestones are.

View File

@@ -1,44 +0,0 @@
rem Drops all tables in bugzilla
rem Contributed by David Lawrence
drop table bugs_activity;
drop table attachments;
drop sequence attachments_seq;
drop table bug_group;
drop table bug_status cascade constraints;
drop table bugs;
drop sequence bugs_seq;
drop table cc;
drop table components;
drop table dependencies;
drop table emailnotification cascade constraints;
drop table errata;
drop sequence errata_seq;
drop table fielddefs;
drop sequence fielddefs_seq;
drop table groups;
drop sequence groups_seq;
drop table keyworddefs;
drop table keywords;
drop table logincookies;
drop sequence logincookies_seq;
drop table longdescs;
drop table milestones;
drop table namedqueries ;
drop table news;
drop sequence news_seq;
drop table op_sys cascade constraints;
drop table priority cascade constraints;
drop table product_group;
drop table products;
drop sequence products_seq;
drop table profiles;
drop sequence profiles_seq;
drop table rep_platform cascade constraints;
drop table resolution cascade constraints;
drop table bug_severity cascade constraints;
drop table user_group;
drop table versions;
drop table votes;
exit;

View File

@@ -1,167 +0,0 @@
#!/usr/bin/perl -w
#
# filename: longdescs_convert.pl
# description: 2000-01-20 Added a new "longdescs" table, which is supposed to have all the
# long descriptions in it, replacing the old long_desc field in the bugs
# table. The below hideous code populates this new table with things from
# the old field, with ugly parsing and heuristics.
# exceptions: Oracle Only!
# contributors: Holger Schurig <holgerschurig@nikocity.de>
# David Lawrence <dkl@redhat.com>
#
use DBI;
use Date::Parse;
use Date::Format;
# database setup
# Connect to Oracle Database
$ENV{'ORACLE_HOME'} = "/opt/oracle/product/805/";
$ENV{'ORACLE_SID'} = "bugzilla";
$ENV{'TWO_TASK'} = "bugzilla";
$ENV{'ORACLE_USERID'} = "bugzilla/bugzilla";
my $oracle_name = "bugzilla";
my $oracle_user = "bugzilla/bugzilla";
my $oracle_date = "SYSDATE";
my $oracle_dsn = "DBI:Oracle:$oracle_name";
my $dbh = DBI->connect($oracle_dsn, $oracle_user, '', { RaiseError => 1 })
|| die "Can't connect to database server: " . $DBI::errstr .
" for $oracle_dsn, $oracle_user";
print "\n\nConnected to Oracle database.\n";
$dbh->{LongReadLen} = 1000 * 1024; # large object to read in
$dbh->{LongTruncOk} = 0; # do not truncate
# subroutine: WriteOneDesc
# description: Inserts a comment into the new longdescs comments table
# params: $id = current bug number (scalar)
# $who = userid of who created the comment (scalar)
# $when = date when the comment was created (scalar)
# $buffer = the actual text of the comment (scalar)
# returns: none
sub WriteOneDesc {
my ($id, $who, $when, $buffer) = (@_);
$buffer = trim($buffer);
if ($buffer eq '') {
return;
}
my $query = "INSERT INTO longdescs (bug_id, who, bug_when, thetext) VALUES " .
"($id, $who, TO_DATE(" .
$dbh->quote( time2str('%Y/%m/%d %H:%M:%S', $when) ) . ", 'YYYY-MM-DD HH24:MI:SS'), :1)";
my $sth = $dbh->prepare($query);
$sth->bind_param(1, $buffer, { SQL_LONGVARCHAR => 1 });
$sth->execute();
}
# subroutine: trim
# description: Trim whitespace from front and back.
# params: $_ = string to trim whitespace (scalar)
# returns: $_ = string with whitespace removed (scalar)
sub trim {
($_) = (@_);
s/^\s+//g;
s/\s+$//g;
return $_;
}
my $sth = $dbh->prepare("SELECT count(bug_id) FROM bugs");
$sth->execute();
my ($total) = ($sth->fetchrow_array);
print "Populating new long_desc table. This is slow. There are $total\n";
print "bugs to process; a line of dots will be printed for each 50.\n\n";
$| = 1;
$dbh->do('DELETE FROM longdescs');
$sth = $dbh->prepare("SELECT bug_id, TO_CHAR(creation_ts, 'YYYY-MM-DD HH24:MI:SS'), reporter, long_desc " .
"FROM bugs ORDER BY bug_id");
$sth->execute();
my $count = 0;
while (1) {
my ($id, $createtime, $reporterid, $desc) = ($sth->fetchrow_array());
if (!$id) {
last;
}
print ".";
$count++;
if ($count % 10 == 0) {
print " ";
if ($count % 50 == 0) {
print "$count/$total (" . int($count * 100 / $total) . "%)\n";
}
}
$desc =~ s/\r//g;
my $who = $reporterid;
my $when = str2time($createtime);
my $buffer = "";
foreach my $line (split(/\n/, $desc)) {
$line =~ s/\s+$//g; # Trim trailing whitespace.
if ($line =~ /^------- Additional Comments From ([^\s]+)\s+(\d.+\d)\s+-------$/) {
my $name = $1;
my $date = str2time($2);
$date += 59; # Oy, what a hack. The creation time is
# accurate to the second. But we the long
# text only contains things accurate to the
# minute. And so, if someone makes a comment
# within a minute of the original bug creation,
# then the comment can come *before* the
# bug creation. So, we add 59 seconds to
# the time of all comments, so that they
# are always considered to have happened at
# the *end* of the given minute, not the
# beginning.
if ($date >= $when) {
WriteOneDesc($id, $who, $when, $buffer);
$buffer = "";
$when = $date;
my $s2 = $dbh->prepare("SELECT userid FROM profiles " .
"WHERE login_name = " .
$dbh->quote($name));
$s2->execute();
($who) = ($s2->fetchrow_array());
if (!$who) {
# This username doesn't exist. Try a special
# netscape-only hack (sorry about that, but I don't
# think it will hurt any other installations). We
# have many entries in the bugsystem from an ancient
# world where the "@netscape.com" part of the loginname
# was omitted. So, look up the user again with that
# appended, and use it if it's there.
if ($name !~ /\@/) {
my $nsname = $name . "\@netscape.com";
$s2 =
$dbh->prepare("SELECT userid FROM profiles " .
"WHERE login_name = " .
$dbh->quote($nsname));
$s2->execute();
($who) = ($s2->fetchrow_array());
}
}
if (!$who) {
# This username doesn't exist. Maybe someone renamed
# him or something. Use a summy profile (Anonymous)
# since we used to allow anonymous comments.
($who) = '4424'; # userid of user 'Anonymous'
}
next;
} else {
# print "\nDecided this line of bug $id has a date of " .
# time2str("'%Y/%m/%d %H:%M:%S'", $date) .
# "\nwhich is less than previous line:\n$line\n\n";
}
}
$buffer .= $line . "\n";
}
WriteOneDesc($id, $who, $when, $buffer);
}

View File

@@ -1,18 +0,0 @@
rem Creates the bug activity table
rem Contributed by David Lawrence <dkl@redhat.com>
drop table bugs_activity;
create table bugs_activity (
bug_id INTEGER CONSTRAINT ACT_NN_BUGID NOT NULL,
who INTEGER CONSTRAINT ACT_NN_WHO NOT NULL,
field VARCHAR2(64),
fieldid INTEGER,
bug_when DATE CONSTRAINT ACT_NN_WHEN NOT NULL,
oldvalue VARCHAR2(400),
newvalue VARCHAR2(400)
);
create index bugact_index on bugs_activity (bug_id, bug_when);
exit;

View File

@@ -1,24 +0,0 @@
rem Table to hold attachements to bugs
rem Contributed by David Lawrence <dkl@redhat.com>
drop table attachments;
create table attachments (
attach_id INTEGER CONSTRAINT ATTACH_PK_ATTACHID PRIMARY KEY NOT NULL,
bug_id INTEGER CONSTRAINT ATTACH_NN_BUGID NOT NULL,
creation_ts DATE CONSTRAINT ATTACH_NN_CREATION NOT NULL,
description VARCHAR2(2000) CONSTRAINT ATTACH_NN_DESC NOT NULL,
mimetype VARCHAR2(255) CONSTRAINT ATTACH_NN_MIME NOT NULL,
ispatch INTEGER ,
filename VARCHAR2(255) CONSTRAINT ATTACH_NN_FILE NOT NULL,
thedata BLOB CONSTRAINT ATTACH_NN_DATA NOT NULL,
submitter_id INTEGER CONSTRAINT ATTACH_NN_SUBMIT NOT NULL
);
create index attach_index on attachments (bug_id, creation_ts);
drop sequence attachments_seq;
create sequence attachments_seq NOCACHE START WITH 1 INCREMENT BY 1;
exit;

View File

@@ -1,13 +0,0 @@
rem * Table to hold valid bug class values in bugzilla
rem * Contributed by David Lawrence <dkl@redhat.com>
drop table bug_group;
create table bug_group (
bugid INTEGER CONSTRAINT BUGGROUP_NN_BUGID NOT NULL,
groupid INTEGER CONSTRAINT BUGGROUP_NN_GROUPID NOT NULL
);
create index buggroup_index on bug_group (bugid, groupid);
exit;

View File

@@ -1,17 +0,0 @@
rem * Table to hold valid bug status values in bugzilla
rem * Contributed by David Lawrence <dkl@redhat.com>
drop table bug_status cascade constraints;
create table bug_status (
value VARCHAR(255) CONSTRAINT STATUS_PK_VALUE PRIMARY KEY NOT NULL
);
rem insert into bug_status (value) values ('NEW');
rem insert into bug_status (value) values ('VERIFIED');
rem insert into bug_status (value) values ('ASSIGNED');
rem insert into bug_status (value) values ('REOPENED');
rem insert into bug_status (value) values ('RESOLVED');
rem insert into bug_status (value) values ('CLOSED');
exit;

View File

@@ -1,59 +0,0 @@
rem The big bugs table
rem Contributed by David Lawrence <dkl@redhat.com>
drop table bugs;
drop index bugs_index;
drop sequence bugs_seq;
create table bugs (
bug_id INTEGER CONSTRAINT BUGS_NN_BUGID NOT NULL,
groupset INTEGER DEFAULT('0'),
group_id INTEGER DEFAULT('0'),
assigned_to INTEGER CONSTRAINT BUGS_NN_ASSITO NOT NULL,
bug_file_loc VARCHAR2(255) DEFAULT(''),
patch_file_loc VARCHAR2(255) DEFAULT(''),
bug_severity VARCHAR2(64) CONSTRAINT BUGS_NN_SEVRTY NOT NULL,
bug_status VARCHAR2(64) CONSTRAINT BUGS_NN_STATUS NOT NULL,
bug_view INTEGER DEFAULT('0'),
creation_ts DATE CONSTRAINT BUGS_NN_CRTETS NOT NULL,
delta_ts DATE,
short_desc VARCHAR2(4000) CONSTRAINT BUGS_NN_SHORT NOT NULL,
op_sys VARCHAR2(64) DEFAULT('Linux'),
priority VARCHAR2(64) CONSTRAINT BUGS_NN_PRIRTY NOT NULL,
product VARCHAR2(256) CONSTRAINT BUGS_NN_PRODCT NOT NULL,
rep_platform VARCHAR2(64) CONSTRAINT BUGS_NN_PLATFM NOT NULL,
reporter INTEGER CONSTRAINT BUGS_NN_REPRTR NOT NULL,
version VARCHAR2(64) CONSTRAINT BUGS_NN_VERSN NOT NULL,
release VARCHAR2(64) DEFAULT(''),
component VARCHAR2(64) CONSTRAINT BUGS_NN_COMPNT NOT NULL,
resolution VARCHAR2(64) DEFAULT(''),
class VARCHAR2(255) DEFAULT(''),
target_milestone VARCHAR2(64) DEFAULT(''),
qa_contact VARCHAR2(255) DEFAULT(''),
status_whiteboard VARCHAR2(4000) DEFAULT(''),
votes INTEGER DEFAULT(''),
keywords VARCHAR(255) DEFAULT(''),
lastdiffed DATE
);
alter table bugs add constraint BUGS_PK_BUGID primary key (bug_id);
create sequence bugs_seq NOCACHE START WITH 1 INCREMENT BY 1;
create index bugs_index on bugs (bug_id,
assigned_to,
creation_ts,
delta_ts,
bug_severity,
bug_status,
op_sys,
priority,
product,
reporter,
version,
component,
resolution,
target_milestone,
qa_contact);
exit;

View File

@@ -1,14 +0,0 @@
rem Table to hold list of cc persons for particular bug
rem Contributed by David Lawrence <dkl@redhat.com>
drop table cc;
create table cc (
bug_id INTEGER CONSTRAINT CC_NN_BUGID NOT NULL,
who INTEGER CONSTRAINT CC_NN_WHO NOT NULL
);
create index cc_index on cc (bug_id, who);
exit;

View File

@@ -1,16 +0,0 @@
rem * Table to hold valid bug class values in bugzilla
rem * Contributed by David Lawrence <dkl@redhat.com>
drop table class cascade constraints;
create table class (
value VARCHAR(255) CONSTRAINT CLASS_PK_VALUE PRIMARY KEY NOT NULL
);
rem insert into class (value) values ('install/upgrade');
rem insert into class (value) values ('packaging');
rem insert into class (value) values ('functionality');
rem insert into class (value) values ('security');
rem insert into class (value) values ('documentation');
exit;

View File

@@ -1,19 +0,0 @@
rem Table to hold component information divided by product
rem Contributed by David Lawrence <dkl@redhat.com>
drop table components;
create table components (
value VARCHAR2(255) CONSTRAINT COMP_NN_VALUE NOT NULL,
program VARCHAR2(255) CONSTRAINT COMP_NN_PROGRM NOT NULL,
initialowner VARCHAR2(64) CONSTRAINT COMP_NN_INTOWN NOT NULL,
devowner VARCHAR2(64),
initialqacontact VARCHAR2(64),
description VARCHAR2(2000)
);
rem insert into components (value, program, initialowner, description)
rem values ('TestComponent', 'TestProduct', 'dkl@redhat.com',
rem 'This is a test component in the test product database. This ought to be blown away and replaced with real stuffrem in a finished installation of bugzilla.');
exit;

View File

@@ -1,13 +0,0 @@
rem Table to hold bug report dependency information
rem Contributed by David Lawrence <dkl@redhat.com>
drop table dependencies;
create table dependencies (
blocked INTEGER CONSTRAINT DEPEND_NN_BLOCKED NOT NULL,
dependson INTEGER CONSTRAINT DEPEND_NN_DPNDSON NOT NULL
);
create index depend_index on dependencies (blocked, dependson);
exit;

View File

@@ -1,14 +0,0 @@
rem * Table to hold valid email choices values in bugzilla
rem * Contributed by David Lawrence <dkl@redhat.com>
drop table emailnotification cascade constraints;
create table emailnotification (
value VARCHAR(255) CONSTRAINT EMAIL_PK_VALUE PRIMARY KEY NOT NULL
);
rem insert into emailnotification (value) values ('ExcludeSelfChanges');
rem insert into emailnotification (value) values ('CConly');
rem insert into emailnotification (value) values ('All');
exit;

View File

@@ -1,23 +0,0 @@
rem Create table for storing errata information
rem Contributed by David Lawrence <dkl@redhat.com>
drop table errata;
create table errata (
revision INTEGER DEFAULT('0'),
type VARCHAR2(10) CONSTRAINT ERRATA_NN_TYPE NOT NULL,
issue_date DATE CONSTRAINT ERRATA_NN_ISSUE NOT NULL,
updated_on DATE ,
id INTEGER CONSTRAINT ERRATA_PK_ID PRIMARY KEY NOT NULL,
synopsis VARCHAR2(2000) CONSTRAINT ERRATA_NN_SYNOP NOT NULL,
mail INTEGER DEFAULT('0'),
files INTEGER DEFAULT('0'),
valid INTEGER
);
drop sequence errata_seq;
create sequence errata_seq START WITH 1 INCREMENT BY 1;
exit;

View File

@@ -1,24 +0,0 @@
rem create script for fielddefs table
rem Cotributed by David Lawrence <dkl@redhat.com>
drop table fielddefs;
create table fielddefs (
fieldid INTEGER CONSTRAINT FIELDDEF_PK_ID PRIMARY KEY NOT NULL,
name VARCHAR2(64) CONSTRAINT FIELDDEF_NN_NAME NOT NULL,
description VARCHAR2(255) CONSTRAINT FIELDDEF_NN_DESC NOT NULL,
mailhead INTEGER DEFAULT ('0'),
sortkey INTEGER CONSTRAINT FIELDDEF_NN_SORT NOT NULL
);
drop index fielddefs_index;
create index fielddefs_index on fielddefs (sortkey);
drop sequence fielddefs_seq;
create sequence fielddefs_seq START WITH 1 INCREMENT BY 1;
exit;

View File

@@ -1,33 +0,0 @@
rem Table to hold bugzilla group information
rem Contributed by David Lawrence <dkl@redhat.com>
drop table groups;
create table groups (
bit INTEGER DEFAULT('0'),
groupid INTEGER CONSTRAINT GROUPS_PK_GROUPID PRIMARY KEY NOT NULL,
name VARCHAR2(255) CONSTRAINT GROUPS_NN_NAME NOT NULL,
description VARCHAR2(2000) CONSTRAINT GROUPS_NN_DESC NOT NULL,
isbuggroup INTEGER CONSTRAINT GROUPS_NN_BUGGRP NOT NULL,
userregexp VARCHAR2(255) DEFAULT(''),
contract INTEGER DEFAULT(0)
);
drop sequence groups_seq;
create sequence groups_seq start with 1 increment by 1;
rem insert into groups (bit, groupid, name, description, isbuggroup, userregexp, contract) values (1, groups_seq.nextval, 'tweakparams', 'Can tweak operating parameters', 0, '', 0);
rem insert into groups (bit, groupid, name, description, isbuggroup, userregexp, contract) values (2, groups_seq.nextval, 'editgroupmembers', 'Can put people in and out of groups that they are members of.', 0, '', 0);
rem insert into groups (bit, groupid, name, description, isbuggroup, userregexp, contract) values (4, groups_seq.nextval, 'creategroups', 'Can create and destroy groups.', 0, '', 0);
rem insert into groups (bit, groupid, name, description, isbuggroup, userregexp, contract) values (8, groups_seq.nextval, 'editcomponents', 'Can create, destroy, and edit components.', 0, '', 0);
rem insert into groups (bit, groupid, name, description, isbuggroup, userregexp, contract) values (16, groups_seq.nextval, 'support', 'Red Hat Technical Supprt', 1, '', 0);
rem insert into groups (bit, groupid, name, description, isbuggroup, userregexp, contract) values (32, groups_seq.nextval, 'qa', 'Red Hat Quality Assurance', 1, '', 0);
rem insert into groups (bit, groupid, name, description, isbuggroup, userregexp, contract) values (64, groups_seq.nextval, 'devel', 'Red Hat Development', 1, '', 0);
rem insert into groups (bit, groupid, name, description, isbuggroup, userregexp, contract) values (128, groups_seq.nextval, 'marketing', 'Red Hat Marketing', 1, '', 0);
rem insert into groups (bit, groupid, name, description, isbuggroup, userregexp, contract) values (256, groups_seq.nextval, 'web', 'Red Hat Web Group', 1, '', 0);
rem insert into groups (bit, groupid, name, description, isbuggroup, userregexp, contract) values (512, groups_seq.nextval, 'beta', 'Red Hat Beta Program', 1, '', 0);
rem insert into groups (bit, groupid, name, description, isbuggroup, userregexp, contract) values (1024, groups_seq.nextval, 'intel', 'Intel Confidential Group', 1, '', 1);
rem insert into groups (bit, groupid, name, description, isbuggroup, userregexp, contract) values (2048, groups_seq.nextval, 'errata', 'Red Hat Errata Group', 1, '', 0);
rem insert into groups (bit, groupid, name, description, isbuggroup, userregexp, contract) values (4096, groups_seq.nextval, 'setcontract', 'Can set a bug report to contract priority', 1, '', 0);
exit;

View File

@@ -1,12 +0,0 @@
rem table to hold keyword definitions
rem Contributed by David Lawrence <dkl@redhat.com>
drop table keyworddefs;
create table keyworddefs (
id INTEGER CONSTRAINT KEYDEF_PK_ID PRIMARY KEY NOT NULL,
name VARCHAR2(64) CONSTRAINT KEYDEF_NN_NAME NOT NULL,
description VARCHAR2(2000)
);
exit;

View File

@@ -1,13 +0,0 @@
rem table to hold keywords
rem Contributed by David Lawrence <dkl@redhat.com>
drop table keywords;
create table keywords (
bug_id INTEGER CONSTRAINT KEYWORDS_NN_BUGID NOT NULL,
keywordid INTEGER CONSTRAINT KEYWORDS_NN_KEYID NOT NULL
);
create index keywords_index on keywords (bug_id, keywordid);
exit;

View File

@@ -1,20 +0,0 @@
rem * Table to hold login cookie information for user authentification
rem * Contributed by David Lawrence <dkl@redhat.com>
drop table logincookies;
create table logincookies (
cookie INTEGER CONSTRAINT LOGIN_PK_COOKIE PRIMARY KEY,
userid INTEGER CONSTRAINT LOGIN_NN_USERID NOT NULL,
cryptpassword VARCHAR2(64),
hostname VARCHAR2(128),
lastused DATE
);
create index logincookies_index on logincookies (lastused);
drop sequence logincookies_seq;
create sequence logincookies_seq NOCACHE START WITH 1 INCREMENT BY 1;
exit;

View File

@@ -1,15 +0,0 @@
rem * Table to hold valid bug class values in bugzilla
rem * Contributed by David Lawrence <dkl@redhat.com>
drop table longdescs;
create table longdescs (
bug_id INTEGER CONSTRAINT LONG_NN_BUGID NOT NULL,
who INTEGER CONSTRAINT LONG_NN_WHO NOT NULL,
bug_when DATE CONSTRAINT LONG_NN_WHEN NOT NULL,
thetext LONG
);
create index longdescs_index on longdescs (bug_id, bug_when);
exit;

View File

@@ -1,13 +0,0 @@
rem Create table for storing milestone information
rem Contributed by David Lawrence <dkl@redhat.com>
drop table milestones;
create table milestones (
value VARCHAR2(20) CONSTRAINT MILE_NN_VALUE NOT NULL,
product VARCHAR(64) CONSTRAINT MILE_NN_PRODUCT NOT NULL,
sortkey INTEGER CONSTRAINT MILE_NN_SORTKEY NOT NULL
);
exit;

View File

@@ -1,17 +0,0 @@
rem Creates news table for articles
rem Contributed by David Lawrence
drop table news;
create table news (
id INTEGER CONSTRAINT NEWS_PK_ID PRIMARY KEY NOT NULL,
add_date DATE CONSTRAINT NEWS_NN_DATE NOT NULL,
headline VARCHAR2(2000) CONSTRAINT NEWS_NN_HEAD NOT NULL,
story LONG CONSTRAINT NEWS_NN_STORY NOT NULL
);
drop sequence news_seq;
create sequence news_seq START WITH 1 INCREMENT BY 1;
exit;

View File

@@ -1,17 +0,0 @@
rem Creates news table for articles
rem Contributed by David Lawrence
drop table news;
create table news (
id INTEGER CONSTRAINT NEWS_PK_ID PRIMARY KEY NOT NULL,
add_date DATE CONSTRAINT NEWS_NN_DATE NOT NULL,
headline VARCHAR2(2000) CONSTRAINT NEWS_NN_HEAD NOT NULL,
story LONG CONSTRAINT NEWS_NN_STORY NOT NULL
);
drop sequence news_seq;
create sequence news_seq START WITH 1 INCREMENT BY 1;
exit;

View File

@@ -1,12 +0,0 @@
rem * Table to hold valid op sys values in bugzilla
rem * Contributed by David Lawrence <dkl@redhat.com>
drop table op_sys cascade constraints;
create table op_sys (
value VARCHAR2(255) CONSTRAINT OPSYS_PK_VALUE PRIMARY KEY NOT NULL
);
rem insert into op_sys (value) values ('Linux');
exit;

View File

@@ -1,15 +0,0 @@
rem * Table to hold valid priority values in bugzilla
rem * Contributed by David Lawrence <dkl@redhat.com>
drop table priority cascade constraints;
create table priority (
value VARCHAR(255) CONSTRAINT PRIORITY_PK_VALUE PRIMARY KEY NOT NULL
);
rem insert into priority (value) values ('high');
rem insert into priority (value) values ('normal');
rem insert into priority (value) values ('low');
rem insert into priority (value) values ('contract');
exit;

View File

@@ -1,14 +0,0 @@
rem * Table to hold valid bug class values in bugzilla
rem * Contributed by David Lawrence <dkl@redhat.com>
drop table product_group;
create table product_group (
productid INTEGER CONSTRAINT PRODGROUP_NN_PRODID NOT NULL,
groupid INTEGER CONSTRAINT PRODGROUP_NN_GROUPID NOT NULL
);
create index prodgroup_index on product_group (productid, groupid);
exit;

View File

@@ -1,21 +0,0 @@
rem * Table to hold the current list of products in bugzilla
rem * Contributed by David Lawrence <dkl@redhat.com>
drop table products;
create table products (
product VARCHAR2(255) CONSTRAINT PRODUCT_NN_PRODUCT NOT NULL,
description VARCHAR2(2000) CONSTRAINT PRODUCT_NN_DESC NOT NULL,
milestoneurl VARCHAR2(255),
disallownew VARCHAR2(255),
votesperuser INTEGER,
id INTEGER CONSTRAINT PRODUCT_PK_ID PRIMARY KEY NOT NULL
);
drop sequence products_seq;
create sequence products_seq NOCACHE START WITH 1 INCREMENT BY 1;
rem insert into products(product, description, id) values ('TestProduct', 'This is a test product. This ought to be blown away and replaced with real stuff in a finished installation of bugzilla.', product_seq.nextval);
exit;

View File

@@ -1,26 +0,0 @@
rem * Table to hold all the valid members of bugzilla and their information
rem * Contributed by David Lawrence <dkl@redhat.com>
drop table profiles;
create table profiles (
userid INTEGER CONSTRAINT PROFILE_PK_USRID PRIMARY KEY,
login_name VARCHAR2(255) CONSTRAINT PROFILE_NN_LOGIN NOT NULL,
password VARCHAR2(16) CONSTRAINT PROFILE_NN_PASSWD NOT NULL,
cryptpassword VARCHAR2(64) CONSTRAINT PROFILE_NN_CRYPT NOT NULL,
realname VARCHAR2(255) DEFAULT(''),
groupid INTEGER DEFAULT(0),
groupset INTEGER DEFAULT(0),
emailnotification VARCHAR2(30) CONSTRAINT PROFILE_NN_EMAIL NOT NULL,
disabledtext VARCHAR2(255) DEFAULT(''),
newemailtech INTEGER DEFAULT('0'),
mybugslink INTEGER DEFAULT('1')
);
create index profiles_index on profiles (login_name);
drop sequence profiles_seq;
create sequence profiles_seq NOCACHE START WITH 1 INCREMENT BY 1;
exit;

View File

@@ -1,16 +0,0 @@
rem * Table to hold valid member queries in bugzilla
rem * Contributed by David Lawrence <dkl@redhat.com>
drop table namedqueries ;
create table namedqueries (
userid INTEGER CONSTRAINT NAMED_NN_USRID not null,
name VARCHAR2(255) CONSTRAINT NAMED_NN_NAME not null,
watchfordiffs INTEGER DEFAULT(0) not null,
linkinfooter INTEGER DEFAULT(0) not null,
query LONG CONSTRAINT NAMED_NN_QUERY not null
);
create index queries_index on namedqueries (name);
exit;

View File

@@ -1,16 +0,0 @@
rem * Table to hold valid rep platform values in bugzilla
rem * Contributed by David Lawrence <dkl@redhat.com>
drop table rep_platform cascade constraints;
create table rep_platform (
value VARCHAR(255) CONSTRAINT PLATFM_PK_VALUE PRIMARY KEY NOT NULL
);
rem insert into rep_platform (value) values ('All');
rem insert into rep_platform (value) values ('i386');
rem insert into rep_platform (value) values ('alpha');
rem insert into rep_platform (value) values ('sparc');
rem insert into rep_platform (value) values ('noarch');
exit;

View File

@@ -1,19 +0,0 @@
rem * Table to hold valid bug resolution values in bugzilla
rem * Contributed by David Lawrence <dkl@redhat.com>
drop table resolution cascade constraints;
create table resolution (
value VARCHAR2(255) CONSTRAINT RESOL_PK_VALUE PRIMARY KEY NOT NULL
);
rem insert into resolution (value) values ('NOTABUG');
rem insert into resolution (value) values ('WONTFIX');
rem insert into resolution (value) values ('DEFERRED');
rem insert into resolution (value) values ('WORKSFORME');
rem insert into resolution (value) values ('CURRENTRELEASE');
rem insert into resolution (value) values ('RAWHIDE');
rem insert into resolution (value) values ('ERRATA');
rem insert into resolution (value) values ('DUPLICATE');
exit;

View File

@@ -1,16 +0,0 @@
rem * Table to hold valid bug severity values in bugzilla
rem * Contributed by David Lawrence <dkl@redhat.com>
drop table bug_severity cascade constraints;
create table bug_severity (
value VARCHAR(255) CONSTRAINT SEVERE_PK_VALUE PRIMARY KEY NOT NULL
);
rem insert into bug_severity (value) values ('security');
rem insert into bug_severity (value) values ('high');
rem insert into bug_severity (value) values ('normal');
rem insert into bug_severity (value) values ('low');
rem insert into bug_severity (value) values ('enhancement');
exit;

View File

@@ -1,29 +0,0 @@
rem * Table to hold valid user group values in bugzilla
rem * Contributed by David Lawrence <dkl@redhat.com>
drop table user_group;
create table user_group (
userid INTEGER CONSTRAINT USERGROUP_NN_BUGID NOT NULL,
groupid INTEGER CONSTRAINT USERGROUP_NN_GROUPID NOT NULL
);
drop index usergroup_index;
create index usergroup_index on user_group (userid, groupid);
rem insert into user_group values (1, 1);
rem insert into user_group values (1, 2);
rem insert into user_group values (1, 3);
rem insert into user_group values (1, 4);
rem insert into user_group values (1, 5);
rem insert into user_group values (1, 6);
rem insert into user_group values (1, 7);
rem insert into user_group values (1, 8);
rem insert into user_group values (1, 9);
rem insert into user_group values (1, 10);
rem insert into user_group values (1, 11);
rem insert into user_group values (1, 12);
rem insert into user_group values (1, 13);
exit;

View File

@@ -1,13 +0,0 @@
rem * Table to hold valid product versions in bugzilla
rem * Contributed by David Lawrence <dkl@redhat.com>
drop table versions;
create table versions (
value VARCHAR2(255) CONSTRAINT VERS_NN_VALUE NOT NULL,
program VARCHAR2(255) CONSTRAINT VERS_NN_PROGM NOT NULL
);
rem insert into versions (value, program) values ('other', 'TestProduct');
exit;

View File

@@ -1,12 +0,0 @@
rem * Table to hold bug vote information in bugzilla
rem * Contributed by David Lawrence <dkl@redhat.com>
drop table votes;
create table votes (
who INTEGER CONSTRAINT VOTE_NN_WHO NOT NULL,
bug_id INTEGER CONSTRAINT VOTE_NN_BUGID NOT NULL,
count INTEGER CONSTRAINT VOTE_NN_COUNT NOT NULL
);
exit;

Some files were not shown because too many files have changed in this diff Show More