Compare commits

..

10 Commits

Author SHA1 Message Date
ssu%netscape.com
5015e62d91 updated comment
git-svn-id: svn://10.0.0.236/branches/SSU_PERSONAL_M16@65907 18797224-902f-48f8-a5cc-f745e15eee43
2000-04-14 01:42:39 +00:00
ssu%netscape.com
2a627a36b7 trying to fix shortcut creation routines and add uninstall feature
git-svn-id: svn://10.0.0.236/branches/SSU_PERSONAL_M16@65906 18797224-902f-48f8-a5cc-f745e15eee43
2000-04-14 00:15:05 +00:00
ssu%netscape.com
a69924abd2 fixed pr2 string
git-svn-id: svn://10.0.0.236/branches/SSU_PERSONAL_M16@65747 18797224-902f-48f8-a5cc-f745e15eee43
2000-04-13 01:21:11 +00:00
ssu%netscape.com
9746b6018a added creation of shortcuts code
git-svn-id: svn://10.0.0.236/branches/SSU_PERSONAL_M16@65746 18797224-902f-48f8-a5cc-f745e15eee43
2000-04-13 01:14:10 +00:00
ssu%netscape.com
ee45cb13fa changed beta version from b1 to b2
git-svn-id: svn://10.0.0.236/branches/SSU_PERSONAL_M16@65745 18797224-902f-48f8-a5cc-f745e15eee43
2000-04-13 01:12:33 +00:00
ssu%netscape.com
b928df1b00 changed logging string to be more similar to the other logging string format
git-svn-id: svn://10.0.0.236/branches/SSU_PERSONAL_M16@65744 18797224-902f-48f8-a5cc-f745e15eee43
2000-04-13 00:58:03 +00:00
ssu%netscape.com
3324619a2d added code to dereference the NetscapeInstantMessenger key
git-svn-id: svn://10.0.0.236/branches/SSU_PERSONAL_M16@65578 18797224-902f-48f8-a5cc-f745e15eee43
2000-04-10 23:02:48 +00:00
ssu%netscape.com
59e5e73bdf fixing bugs 27598, 18563, 23240, 33348
git-svn-id: svn://10.0.0.236/branches/SSU_PERSONAL_M16@65545 18797224-902f-48f8-a5cc-f745e15eee43
2000-04-10 02:56:55 +00:00
ssu%netscape.com
c96b32104d fixing bugs 16068, 25595, 21034, 34664
git-svn-id: svn://10.0.0.236/branches/SSU_PERSONAL_M16@65526 18797224-902f-48f8-a5cc-f745e15eee43
2000-04-08 02:28:10 +00:00
(no author)
e4ccec7149 This commit was manufactured by cvs2svn to create branch 'SSU_PERSONAL_M16'.
git-svn-id: svn://10.0.0.236/branches/SSU_PERSONAL_M16@65364 18797224-902f-48f8-a5cc-f745e15eee43
2000-04-05 06:58:58 +00:00
176 changed files with 41540 additions and 11656 deletions

View File

@@ -1,135 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY % myents SYSTEM "bugzilla.ent">
%myents;
]>
<!-- Coding standards for this document
* Other than the GFDL, please use the "section" tag instead of "sect1",
"sect2", etc.
* Use Entities to include files for new chapters in Bugzilla-Guide.xml.
* Try to use Entities for frequently-used passages of text as well.
* Ensure all documents compile cleanly to HTML after modification.
The warning, "DTDDECL catalog types not supported" is normal.
* Try to index important terms wherever possible.
* Use "glossterm" whenever you introduce a new term.
* Follow coding standards at http://www.tldp.org, and
check out the KDE guidelines (they are nice, too)
http://i18n.kde.org/doc/markup.html
* All tags should be lowercase.
* Please use sensible spacing. The comments at the very end of each
file define reasonable defaults for PSGML mode in EMACS.
* Double-indent tags, use double spacing whenever possible, and
try to avoid clutter and feel free to waste space in the code to make it
more readable.
-->
<book id="index">
<!-- Header -->
<bookinfo>
<title>The Bugzilla Guide - &bz-ver;
<!-- BZ-DEVEL -->Development <!-- /BZ-DEVEL -->
Release</title>
<authorgroup>
<corpauthor>The Bugzilla Team</corpauthor>
</authorgroup>
<pubdate>&bz-date;</pubdate>
<abstract>
<para>
This is the documentation for Bugzilla, a
bug-tracking system from mozilla.org.
Bugzilla is an enterprise-class piece of software
that tracks millions of bugs and issues for hundreds of
organizations around the world.
</para>
<para>
The most current version of this document can always be found on the
<ulink url="http://www.bugzilla.org/docs/">Bugzilla
Documentation Page</ulink>.
</para>
</abstract>
<keywordset>
<keyword>Bugzilla</keyword>
<keyword>Guide</keyword>
<keyword>installation</keyword>
<keyword>FAQ</keyword>
<keyword>administration</keyword>
<keyword>integration</keyword>
<keyword>MySQL</keyword>
<keyword>Mozilla</keyword>
<keyword>webtools</keyword>
</keywordset>
</bookinfo>
<!-- About This Guide -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="about.xml" />
<!-- Installing Bugzilla -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="installation.xml" />
<!-- Administering Bugzilla -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="administration.xml" />
<!-- Securing Bugzilla -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="security.xml" />
<!-- Customizing Bugzilla -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="customization.xml" />
<!-- Using Bugzilla -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="using.xml" />
<!-- Appendix: Troubleshooting -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="troubleshooting.xml" />
<!-- Appendix: Custom Patches -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="patches.xml" />
<!-- Appendix: Manually Installing Perl Modules -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="modules.xml" />
<!-- Appendix: GNU Free Documentation License -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="gfdl.xml" />
<!-- Glossary -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="glossary.xml" />
<!-- Index -->
<!--xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="index.xml" /-->
</book>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-always-quote-attributes:t
sgml-auto-insert-required-elements:t
sgml-balanced-tag-edit:t
sgml-exposed-tags:nil
sgml-general-insert-case:lower
sgml-indent-data:t
sgml-indent-step:2
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
sgml-minimize-attributes:nil
sgml-namecase-general:t
sgml-omittag:t
sgml-parent-document:("Bugzilla-Guide.xml" "book" "chapter")
sgml-shorttag:t
sgml-tag-region-if-active:t
End:
-->

View File

@@ -1,246 +0,0 @@
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY % myents SYSTEM "bugzilla.ent">
%myents;
]>
<!-- $Id: about.xml,v 1.26.4.1 2008-07-13 16:44:28 mozilla%colinogilvie.co.uk Exp $ -->
<chapter id="about">
<title>About This Guide</title>
<section id="copyright">
<title>Copyright Information</title>
<para>This document is copyright (c) 2000-&current-year; by the various
Bugzilla contributors who wrote it.</para>
<blockquote>
<para>
Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU Free Documentation
License, Version 1.1 or any later version published by the
Free Software Foundation; with no Invariant Sections, no
Front-Cover Texts, and with no Back-Cover Texts. A copy of
the license is included in <xref linkend="gfdl"/>.
</para>
</blockquote>
<para>
If you have any questions regarding this document, its
copyright, or publishing this document in non-electronic form,
please contact the Bugzilla Team.
</para>
</section>
<section id="disclaimer">
<title>Disclaimer</title>
<para>
No liability for the contents of this document can be accepted.
Follow the instructions herein at your own risk.
This document may contain errors
and inaccuracies that may damage your system, cause your partner
to leave you, your boss to fire you, your cats to
pee on your furniture and clothing, and global thermonuclear
war. Proceed with caution.
</para>
<para>
Naming of particular products or brands should not be seen as
endorsements, with the exception of the term "GNU/Linux". We
wholeheartedly endorse the use of GNU/Linux; it is an extremely
versatile, stable,
and robust operating system that offers an ideal operating
environment for Bugzilla.
</para>
<para>
Although the Bugzilla development team has taken great care to
ensure that all exploitable bugs have been fixed, security holes surely
exist in any piece of code. Great care should be taken both in
the installation and usage of this software. The Bugzilla development
team members assume no liability for your use of Bugzilla. You have
the source code, and are responsible for auditing it yourself to ensure
your security needs are met.
</para>
</section>
<!-- Section 2: New Versions -->
<section id="newversions">
<title>New Versions</title>
<para>
This is the &bz-ver; version of The Bugzilla Guide. It is so named
to match the current version of Bugzilla.
<!-- BZ-DEVEL --> This version of the guide, like its associated Bugzilla version, is a
development version.<!-- /BZ-DEVEL -->
</para>
<para>
The latest version of this guide can always be found at <ulink
url="http://www.bugzilla.org"/>, or checked out via CVS by
following the <ulink url="http://www.mozilla.org/cvs.html">Mozilla
CVS</ulink> instructions and check out the
<filename>mozilla/webtools/bugzilla/docs/</filename>
subtree. However, you should read the version
which came with the Bugzilla release you are using.
</para>
<para>
The Bugzilla Guide, or a section of it, is also available in
the following languages:
<ulink url="http://www.traduc.org/docs/guides/lecture/bugzilla/">French</ulink>,
<ulink url="http://bugzilla-de.sourceforge.net/docs/html/">German</ulink>,
<ulink url="http://www.bugzilla.jp/docs/2.18/">Japanese</ulink>.
Note that these may be outdated or not up to date.
</para>
<para>
In addition, there are Bugzilla template localization projects in
the following languages. They may have translated documentation
available:
<ulink url="http://sourceforge.net/projects/bugzilla-ar/">Arabic</ulink>,
<ulink url="http://sourceforge.net/projects/bugzilla-be/">Belarusian</ulink>,
<ulink url="http://openfmi.net/projects/mozilla-bg/">Bulgarian</ulink>,
<ulink url="http://sourceforge.net/projects/bugzilla-br/">Brazilian Portuguese</ulink>,
<ulink url="http://sourceforge.net/projects/bugzilla-cn/">Chinese</ulink>,
<ulink url="http://sourceforge.net/projects/bugzilla-fr/">French</ulink>,
<ulink url="http://germzilla.ganderbay.net/">German</ulink>,
<ulink url="http://sourceforge.net/projects/bugzilla-it/">Italian</ulink>,
<ulink url="http://www.bugzilla.jp/about/jp.html">Japanese</ulink>,
<ulink url="http://sourceforge.net/projects/bugzilla-kr/">Korean</ulink>,
<ulink url="http://sourceforge.net/projects/bugzilla-ru/">Russian</ulink> and
<ulink url="http://sourceforge.net/projects/bugzilla-es/">Spanish</ulink>.
</para>
<para>
If you would like to volunteer to translate the Guide into additional
languages, please contact
<ulink url="mailto:justdave@bugzilla.org">Dave Miller</ulink>.
</para>
</section>
<section id="credits">
<title>Credits</title>
<para>
The people listed below have made enormous contributions to the
creation of this Guide, through their writing, dedicated hacking efforts,
numerous e-mail and IRC support sessions, and overall excellent
contribution to the Bugzilla community:
</para>
<!-- TODO: This is evil... there has to be a valid way to get this look -->
<variablelist>
<varlistentry>
<term>Matthew P. Barnson <email>mbarnson@sisna.com</email></term>
<listitem>
<para>for the Herculean task of pulling together the Bugzilla Guide
and shepherding it to 2.14.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Terry Weissman <email>terry@mozilla.org</email></term>
<listitem>
<para>for initially writing Bugzilla and creating the README upon
which the UNIX installation documentation is largely based.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Tara Hernandez <email>tara@tequilarists.org</email></term>
<listitem>
<para>for keeping Bugzilla development going strong after Terry left
mozilla.org and for running landfill.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Dave Lawrence <email>dkl@redhat.com</email></term>
<listitem>
<para>for providing insight into the key differences between Red
Hat's customized Bugzilla.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Dawn Endico <email>endico@mozilla.org</email></term>
<listitem>
<para>for being a hacker extraordinaire and putting up with Matthew's
incessant questions and arguments on irc.mozilla.org in #mozwebtools
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Jacob Steenhagen <email>jake@bugzilla.org</email></term>
<listitem>
<para>for taking over documentation during the 2.17 development
period.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Dave Miller <email>justdave@bugzilla.org</email></term>
<listitem>
<para>for taking over as project lead when Tara stepped down and
continually pushing for the documentation to be the best it can be.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
Thanks also go to the following people for significant contributions
to this documentation:
<simplelist type="inline">
<member>Kevin Brannen</member>
<member>Vlad Dascalu</member>
<member>Ben FrantzDale</member>
<member>Eric Hanson</member>
<member>Zach Lipton</member>
<member>Gervase Markham</member>
<member>Andrew Pearson</member>
<member>Joe Robins</member>
<member>Spencer Smith</member>
<member>Ron Teitelbaum</member>
<member>Shane Travis</member>
<member>Martin Wulffeld</member>
</simplelist>.
</para>
<para>
Also, thanks are due to the members of the
<ulink url="news://news.mozilla.org/mozilla.support.bugzilla">
mozilla.support.bugzilla</ulink>
newsgroup (and its predecessor, netscape.public.mozilla.webtools).
Without your discussions, insight, suggestions, and patches,
this could never have happened.
</para>
</section>
<!-- conventions used here (didn't want to give it a chapter of its own) -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="conventions.xml" />
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-always-quote-attributes:t
sgml-auto-insert-required-elements:t
sgml-balanced-tag-edit:t
sgml-exposed-tags:nil
sgml-general-insert-case:lower
sgml-indent-data:t
sgml-indent-step:2
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
sgml-minimize-attributes:nil
sgml-namecase-general:t
sgml-omittag:t
sgml-parent-document:("Bugzilla-Guide.xml" "book" "chapter")
sgml-shorttag:t
sgml-tag-region-if-active:t
End: -->

File diff suppressed because it is too large Load Diff

View File

@@ -1,168 +0,0 @@
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY % myents SYSTEM "bugzilla.ent">
%myents;
]>
<section id="conventions">
<title>Document Conventions</title>
<indexterm zone="conventions">
<primary>conventions</primary>
</indexterm>
<para>This document uses the following conventions:</para>
<informaltable frame="none">
<tgroup cols="2">
<thead>
<row>
<entry>Descriptions</entry>
<entry>Appearance</entry>
</row>
</thead>
<tbody>
<row>
<entry>Caution</entry>
<entry>
<caution>
<para>Don't run with scissors!</para>
</caution>
</entry>
</row>
<row>
<entry>Hint or Tip</entry>
<entry>
<tip>
<para>For best results... </para>
</tip>
</entry>
</row>
<row>
<entry>Note</entry>
<entry>
<note>
<para>Dear John...</para>
</note>
</entry>
</row>
<row>
<entry>Warning</entry>
<entry>
<warning>
<para>Read this or the cat gets it.</para>
</warning>
</entry>
</row>
<row>
<entry>File or directory name</entry>
<entry>
<filename>filename</filename>
</entry>
</row>
<row>
<entry>Command to be typed</entry>
<entry>
<command>command</command>
</entry>
</row>
<row>
<entry>Application name</entry>
<entry>
<application>application</application>
</entry>
</row>
<row>
<entry>
Normal user's prompt under bash shell</entry>
<entry>bash$</entry>
</row>
<row>
<entry>
Root user's prompt under bash shell</entry>
<entry>bash#</entry>
</row>
<row>
<entry>
Normal user's prompt under tcsh shell</entry>
<entry>tcsh$</entry>
</row>
<row>
<entry>Environment variables</entry>
<entry>
<envar>VARIABLE</envar>
</entry>
</row>
<row>
<entry>Term found in the glossary</entry>
<entry>
<glossterm linkend="gloss-bugzilla">Bugzilla</glossterm>
</entry>
</row>
<row>
<entry>Code example</entry>
<entry>
<programlisting><sgmltag class="starttag">para</sgmltag>
Beginning and end of paragraph
<sgmltag class="endtag">para</sgmltag></programlisting>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>
This documentation is maintained in DocBook 4.1.2 XML format.
Changes are best submitted as plain text or XML diffs, attached
to a bug filed in the &bzg-bugs; component.
</para>
</section>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-always-quote-attributes:t
sgml-auto-insert-required-elements:t
sgml-balanced-tag-edit:t
sgml-exposed-tags:nil
sgml-general-insert-case:lower
sgml-indent-data:t
sgml-indent-step:2
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
sgml-minimize-attributes:nil
sgml-namecase-general:t
sgml-omittag:t
sgml-parent-document:("Bugzilla-Guide.xml" "book" "chapter")
sgml-shorttag:t
sgml-tag-region-if-active:t
End:
-->

View File

@@ -1,821 +0,0 @@
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY % myents SYSTEM "bugzilla.ent">
%myents;
]>
<chapter id="customization">
<title>Customizing Bugzilla</title>
<section id="cust-skins">
<title>Custom Skins</title>
<para>
Bugzilla allows you to have multiple skins. These are custom CSS and possibly
also custom images for Bugzilla. To create a new custom skin, you have two
choices:
<itemizedlist>
<listitem>
<para>
Make a single CSS file, and put it in the
<filename>skins/contrib</filename> directory.
</para>
</listitem>
<listitem>
<para>
Make a directory that contains all the same CSS file
names as <filename>skins/standard/</filename>, and put
your directory in <filename>skins/contrib/</filename>.
</para>
</listitem>
</itemizedlist>
</para>
<para>
After you put the file or the directory there, make sure to run checksetup.pl
so that it can reset the file permissions correctly.
</para>
<para>
After you have installed the new skin, it will show up as an option in the
user's General Preferences. If you would like to force a particular skin on all
users, just select it in the Default Preferences and then uncheck "Enabled" on
the preference.
</para>
</section>
<section id="cust-templates">
<title>Template Customization</title>
<para>
Administrators can configure the look and feel of Bugzilla without
having to edit Perl files or face the nightmare of massive merge
conflicts when they upgrade to a newer version in the future.
</para>
<para>
Templatization also makes localized versions of Bugzilla possible,
for the first time. It's possible to have Bugzilla's UI language
determined by the user's browser. More information is available in
<xref linkend="template-http-accept"/>.
</para>
<section id="template-directory">
<title>Template Directory Structure</title>
<para>
The template directory structure starts with top level directory
named <filename>template</filename>, which contains a directory
for each installed localization. The next level defines the
language used in the templates. Bugzilla comes with English
templates, so the directory name is <filename>en</filename>,
and we will discuss <filename>template/en</filename> throughout
the documentation. Below <filename>template/en</filename> is the
<filename>default</filename> directory, which contains all the
standard templates shipped with Bugzilla.
</para>
<warning>
<para>
A directory <filename>data/templates</filename> also exists;
this is where Template Toolkit puts the compiled versions of
the templates from either the default or custom directories.
<emphasis>Do not</emphasis> directly edit the files in this
directory, or all your changes will be lost the next time
Template Toolkit recompiles the templates.
</para>
</warning>
</section>
<section id="template-method">
<title>Choosing a Customization Method</title>
<para>
If you want to edit Bugzilla's templates, the first decision
you must make is how you want to go about doing so. There are two
choices, and which you use depends mainly on the scope of your
modifications, and the method you plan to use to upgrade Bugzilla.
</para>
<para>
The first method of making customizations is to directly edit the
templates found in <filename>template/en/default</filename>.
This is probably the best way to go about it if you are going to
be upgrading Bugzilla through CVS, because if you then execute
a <command>cvs update</command>, any changes you have made will
be merged automagically with the updated versions.
</para>
<note>
<para>
If you use this method, and CVS conflicts occur during an
update, the conflicted templates (and possibly other parts
of your installation) will not work until they are resolved.
</para>
</note>
<para>
The second method is to copy the templates to be modified
into a mirrored directory structure under
<filename>template/en/custom</filename>. Templates in this
directory structure automatically override any identically-named
and identically-located templates in the
<filename>default</filename> directory.
</para>
<note>
<para>
The <filename>custom</filename> directory does not exist
at first and must be created if you want to use it.
</para>
</note>
<para>
The second method of customization should be used if you
use the overwriting method of upgrade, because otherwise
your changes will be lost. This method may also be better if
you are using the CVS method of upgrading and are going to make major
changes, because it is guaranteed that the contents of this directory
will not be touched during an upgrade, and you can then decide whether
to continue using your own templates, or make the effort to merge your
changes into the new versions by hand.
</para>
<para>
Using this method, your installation may break if incompatible
changes are made to the template interface. Such changes should
be documented in the release notes, provided you are using a
stable release of Bugzilla. If you use using unstable code, you will
need to deal with this one yourself, although if possible the changes
will be mentioned before they occur in the deprecations section of the
previous stable release's release notes.
</para>
<note>
<para>
Regardless of which method you choose, it is recommended that
you run <command>./checksetup.pl</command> after creating or
editing any templates in the <filename>template/en/default</filename>
directory, and after editing any templates in the
<filename>custom</filename> directory.
</para>
</note>
<warning>
<para>
It is <emphasis>required</emphasis> that you run
<command>./checksetup.pl</command> after creating a new
template in the <filename>custom</filename> directory. Failure
to do so will raise an incomprehensible error message.
</para>
</warning>
</section>
<section id="template-edit">
<title>How To Edit Templates</title>
<note>
<para>
If you are making template changes that you intend on submitting back
for inclusion in standard Bugzilla, you should read the relevant
sections of the
<ulink url="http://www.bugzilla.org/docs/developer.html">Developers'
Guide</ulink>.
</para>
</note>
<para>
The syntax of the Template Toolkit language is beyond the scope of
this guide. It's reasonably easy to pick up by looking at the current
templates; or, you can read the manual, available on the
<ulink url="http://www.template-toolkit.org">Template Toolkit home
page</ulink>.
</para>
<para>
One thing you should take particular care about is the need
to properly HTML filter data that has been passed into the template.
This means that if the data can possibly contain special HTML characters
such as &lt;, and the data was not intended to be HTML, they need to be
converted to entity form, i.e. &amp;lt;. You use the 'html' filter in the
Template Toolkit to do this. If you forget, you may open up
your installation to cross-site scripting attacks.
</para>
<para>
Also note that Bugzilla adds a few filters of its own, that are not
in standard Template Toolkit. In particular, the 'url_quote' filter
can convert characters that are illegal or have special meaning in URLs,
such as &amp;, to the encoded form, i.e. %26. This actually encodes most
characters (but not the common ones such as letters and numbers and so
on), including the HTML-special characters, so there's never a need to
HTML filter afterwards.
</para>
<para>
Editing templates is a good way of doing a <quote>poor man's custom
fields</quote>.
For example, if you don't use the Status Whiteboard, but want to have
a free-form text entry box for <quote>Build Identifier</quote>,
then you can just
edit the templates to change the field labels. It's still be called
status_whiteboard internally, but your users don't need to know that.
</para>
</section>
<section id="template-formats">
<title>Template Formats and Types</title>
<para>
Some CGI's have the ability to use more than one template. For example,
<filename>buglist.cgi</filename> can output itself as RDF, or as two
formats of HTML (complex and simple). The mechanism that provides this
feature is extensible.
</para>
<para>
Bugzilla can support different types of output, which again can have
multiple formats. In order to request a certain type, you can append
the &amp;ctype=&lt;contenttype&gt; (such as rdf or html) to the
<filename>&lt;cginame&gt;.cgi</filename> URL. If you would like to
retrieve a certain format, you can use the &amp;format=&lt;format&gt;
(such as simple or complex) in the URL.
</para>
<para>
To see if a CGI supports multiple output formats and types, grep the
CGI for <quote>get_format</quote>. If it's not present, adding
multiple format/type support isn't too hard - see how it's done in
other CGIs, e.g. config.cgi.
</para>
<para>
To make a new format template for a CGI which supports this,
open a current template for
that CGI and take note of the INTERFACE comment (if present.) This
comment defines what variables are passed into this template. If
there isn't one, I'm afraid you'll have to read the template and
the code to find out what information you get.
</para>
<para>
Write your template in whatever markup or text style is appropriate.
</para>
<para>
You now need to decide what content type you want your template
served as. The content types are defined in the
<filename>Bugzilla/Constants.pm</filename> file in the
<filename>contenttypes</filename>
constant. If your content type is not there, add it. Remember
the three- or four-letter tag assigned to your content type.
This tag will be part of the template filename.
</para>
<note>
<para>
After adding or changing a content type, it's suitable to edit
<filename>Bugzilla/Constants.pm</filename> in order to reflect
the changes. Also, the file should be kept up to date after an
upgrade if content types have been customized in the past.
</para>
</note>
<para>
Save the template as <filename>&lt;stubname&gt;-&lt;formatname&gt;.&lt;contenttypetag&gt;.tmpl</filename>.
Try out the template by calling the CGI as
<filename>&lt;cginame&gt;.cgi?format=&lt;formatname&gt;&amp;ctype=&lt;type&gt;</filename> .
</para>
</section>
<section id="template-specific">
<title>Particular Templates</title>
<para>
There are a few templates you may be particularly interested in
customizing for your installation.
</para>
<para>
<command>index.html.tmpl</command>:
This is the Bugzilla front page.
</para>
<para>
<command>global/header.html.tmpl</command>:
This defines the header that goes on all Bugzilla pages.
The header includes the banner, which is what appears to users
and is probably what you want to edit instead. However the
header also includes the HTML HEAD section, so you could for
example add a stylesheet or META tag by editing the header.
</para>
<para>
<command>global/banner.html.tmpl</command>:
This contains the <quote>banner</quote>, the part of the header
that appears
at the top of all Bugzilla pages. The default banner is reasonably
barren, so you'll probably want to customize this to give your
installation a distinctive look and feel. It is recommended you
preserve the Bugzilla version number in some form so the version
you are running can be determined, and users know what docs to read.
</para>
<para>
<command>global/footer.html.tmpl</command>:
This defines the footer that goes on all Bugzilla pages. Editing
this is another way to quickly get a distinctive look and feel for
your Bugzilla installation.
</para>
<para>
<command>global/variables.none.tmpl</command>:
This defines a list of terms that may be changed in order to
<quote>brand</quote> the Bugzilla instance In this way, terms
like <quote>bugs</quote> can be replaced with <quote>issues</quote>
across the whole Bugzilla installation. The name
<quote>Bugzilla</quote> and other words can be customized as well.
</para>
<para>
<command>list/table.html.tmpl</command>:
This template controls the appearance of the bug lists created
by Bugzilla. Editing this template allows per-column control of
the width and title of a column, the maximum display length of
each entry, and the wrap behaviour of long entries.
For long bug lists, Bugzilla inserts a 'break' every 100 bugs by
default; this behaviour is also controlled by this template, and
that value can be modified here.
</para>
<para>
<command>bug/create/user-message.html.tmpl</command>:
This is a message that appears near the top of the bug reporting page.
By modifying this, you can tell your users how they should report
bugs.
</para>
<para>
<command>bug/process/midair.html.tmpl</command>:
This is the page used if two people submit simultaneous changes to the
same bug. The second person to submit their changes will get this page
to tell them what the first person did, and ask if they wish to
overwrite those changes or go back and revisit the bug. The default
title and header on this page read "Mid-air collision detected!" If
you work in the aviation industry, or other environment where this
might be found offensive (yes, we have true stories of this happening)
you'll want to change this to something more appropriate for your
environment.
</para>
<para>
<command>bug/create/create.html.tmpl</command> and
<command>bug/create/comment.txt.tmpl</command>:
You may not wish to go to the effort of creating custom fields in
Bugzilla, yet you want to make sure that each bug report contains
a number of pieces of important information for which there is not
a special field. The bug entry system has been designed in an
extensible fashion to enable you to add arbitrary HTML widgets,
such as drop-down lists or textboxes, to the bug entry page
and have their values appear formatted in the initial comment.
A hidden field that indicates the format should be added inside
the form in order to make the template functional. Its value should
be the suffix of the template filename. For example, if the file
is called <filename>create-cust.html.tmpl</filename>, then
<programlisting>&lt;input type="hidden" name="format" value="cust"&gt;</programlisting>
should be used inside the form.
</para>
<para>
An example of this is the mozilla.org
<ulink url="http://landfill.bugzilla.org/bugzilla-tip/enter_bug.cgi?product=WorldControl&amp;format=guided">guided
bug submission form</ulink>. The code for this comes with the Bugzilla
distribution as an example for you to copy. It can be found in the
files
<filename>create-guided.html.tmpl</filename> and
<filename>comment-guided.html.tmpl</filename>.
</para>
<para>
So to use this feature, create a custom template for
<filename>enter_bug.cgi</filename>. The default template, on which you
could base it, is
<filename>custom/bug/create/create.html.tmpl</filename>.
Call it <filename>create-&lt;formatname&gt;.html.tmpl</filename>, and
in it, add widgets for each piece of information you'd like
collected - such as a build number, or set of steps to reproduce.
</para>
<para>
Then, create a template like
<filename>custom/bug/create/comment.txt.tmpl</filename>, and call it
<filename>comment-&lt;formatname&gt;.txt.tmpl</filename>. This
template should reference the form fields you have created using
the syntax <filename>[% form.&lt;fieldname&gt; %]</filename>. When a
bug report is
submitted, the initial comment attached to the bug report will be
formatted according to the layout of this template.
</para>
<para>
For example, if your custom enter_bug template had a field
<programlisting>&lt;input type="text" name="buildid" size="30"&gt;</programlisting>
and then your comment.txt.tmpl had
<programlisting>BuildID: [% form.buildid %]</programlisting>
then something like
<programlisting>BuildID: 20020303</programlisting>
would appear in the initial comment.
</para>
</section>
<section id="template-http-accept">
<title>Configuring Bugzilla to Detect the User's Language</title>
<para>Bugzilla honours the user's Accept: HTTP header. You can install
templates in other languages, and Bugzilla will pick the most appropriate
according to a priority order defined by you. Many
language templates can be obtained from <ulink
url="http://www.bugzilla.org/download.html#localizations"/>. Instructions
for submitting new languages are also available from that location.
</para>
</section>
</section>
<section id="cust-hooks">
<title>The Bugzilla Extension Mechanism</title>
<warning>
<para>
Note that the below paths are inconsistent and confusing. They will
likely be changed in Bugzilla 4.0.
</para>
</warning>
<para>
Extensions are a way for extensions to Bugzilla to insert code
into the standard Bugzilla templates and source files
without modifying these files themselves. The extension mechanism
defines a consistent API for extending the standard templates and source files
in a way that cleanly separates standard code from extension code.
Hooks reduce merge conflicts and make it easier to write extensions that work
across multiple versions of Bugzilla, making upgrading a Bugzilla installation
with installed extensions easier. Furthermore, they make it easy to install
and remove extensions as each extension is nothing more than a
simple directory structure.
</para>
<para>
There are two main types of hooks: code hooks and template hooks. Code
hooks allow extensions to invoke code at specific points in various
source files, while template hooks allow extensions to add elements to
the Bugzilla user interface.
</para>
<para>
A hook is just a named place in a standard source or template file
where extension source code or template files for that hook get processed.
Each extension has a corresponding directory in the Bugzilla directory
tree (<filename>BUGZILLA_ROOT/extensions/extension_name</filename>). Hooking
an extension source file or template to a hook is as simple as putting
the extension file into extension's template or code directory.
When Bugzilla processes the source file or template and reaches the hook,
it will process all extension files in the hook's directory.
The hooks themselves can be added into any source file or standard template
upon request by extension authors.
</para>
<para>
To use hooks to extend Bugzilla, first make sure there is
a hook at the appropriate place within the source file or template you
want to extend. The exact appearance of a hook depends on if the hook
is a code hook or a template hook.
</para>
<para>
Code hooks appear in Bugzilla source files as a single method call
in the format <literal role="code">Bugzilla::Hook->process("<varname>name</varname>");</literal>.
For instance, <filename>enter_bug.cgi</filename> may invoke the hook
"<varname>enter_bug-entrydefaultvars</varname>". Thus, a source file at
<filename>BUGZILLA_ROOT/extensions/EXTENSION_NAME/code/enter_bug-entrydefaultvars.pl</filename>
will be automatically invoked when the code hook is reached.
</para>
<para>
Template hooks appear in the standard Bugzilla templates as a
single directive in the format
<literal role="code">[% Hook.process("<varname>name</varname>") %]</literal>,
where <varname>name</varname> is the unique name of the hook.
</para>
<para>
If you aren't sure what you want to extend or just want to browse the
available hooks, either use your favorite multi-file search
tool (e.g. <command>grep</command>) to search the standard templates
for occurrences of <methodname>Hook.process</methodname> or the source
files for occurrences of <methodname>Bugzilla::Hook::process</methodname>.
</para>
<para>
If there is no hook at the appropriate place within the Bugzilla
source file or template you want to extend,
<ulink url="http://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla&amp;component=User%20Interface">file
a bug requesting one</ulink>, specifying:
</para>
<simplelist>
<member>the source or template file for which you are
requesting a hook;</member>
<member>
where in the file you would like the hook to be placed
(line number/position for latest version of the file in CVS
or description of location);
</member>
<member>the purpose of the hook;</member>
<member>a link to information about your extension, if any.</member>
</simplelist>
<para>
The Bugzilla reviewers will promptly review each hook request,
name the hook, add it to the template or source file, and check
the new version of the template into CVS.
</para>
<para>
You may optionally attach a patch to the bug which implements the hook
and check it in yourself after receiving approval from a Bugzilla
reviewer. The developers may suggest changes to the location of the
hook based on their analysis of your needs or so the hook can satisfy
the needs of multiple extensions, but the process of getting hooks
approved and checked in is not as stringent as the process for general
changes to Bugzilla, and any extension, whether released or still in
development, can have hooks added to meet their needs.
</para>
<para>
After making sure the hook you need exists (or getting it added if not),
add your extension to the directory within the Bugzilla
extensions tree corresponding to the hook.
</para>
<para>
That's it! Now, when the source file or template containing the hook
is processed, your extension file will be processed at the point
where the hook appears.
</para>
<para>
For example, let's say you have an extension named Projman that adds
project management capabilities to Bugzilla. Projman has an
administration interface <filename>edit-projects.cgi</filename>,
and you want to add a link to it into the navigation bar at the bottom
of every Bugzilla page for those users who are authorized
to administer projects.
</para>
<para>
The navigation bar is generated by the template file
<filename>useful-links.html.tmpl</filename>, which is located in
the <filename>global/</filename> subdirectory on the standard Bugzilla
template path
<filename>BUGZILLA_ROOT/template/en/default/</filename>.
Looking in <filename>useful-links.html.tmpl</filename>, you find
the following hook at the end of the list of standard Bugzilla
administration links:
</para>
<programlisting><![CDATA[...
[% ', <a href="editkeywords.cgi">keywords</a>'
IF user.groups.editkeywords %]
[% Hook.process("edit") %]
...]]></programlisting>
<para>
The corresponding extension file for this hook is
<filename>BUGZILLA_ROOT/extensions/projman/template/en/global/useful-links-edit.html.tmpl</filename>.
You then create that template file and add the following constant:
</para>
<programlisting><![CDATA[...[% ', <a href="edit-projects.cgi">projects</a>' IF user.groups.projman_admins %]]]></programlisting>
<para>
Voila! The link now appears after the other administration links in the
navigation bar for users in the <literal>projman_admins</literal> group.
</para>
<para>
Now, let us say your extension adds a custom "project_manager" field
to enter_bug.cgi. You want to modify the CGI script to set the default
project manager to be productname@company.com. Looking at
<filename>enter_bug.cgi</filename>, you see the enter_bug-entrydefaultvars
hook near the bottom of the file before the default form values are set.
The corresponding extension source file for this hook is located at
<filename>BUGZILLA_ROOT/extensions/projman/code/enter_bug-entrydefaultvars.pl</filename>.
You then create that file and add the following:
</para>
<programlisting>$default{'project_manager'} = $product.'@company.com';</programlisting>
<para>
This code will be invoked whenever enter_bug.cgi is executed.
Assuming that the rest of the customization was completed (e.g. the
custom field was added to the enter_bug template and the required hooks
were used in process_bug.cgi), the new field will now have this
default value.
</para>
<para>
Notes:
</para>
<itemizedlist>
<listitem>
<para>
If your extension includes entirely new templates in addition to
extensions of standard templates, it should store those new
templates in its
<filename>BUGZILLA_ROOT/extensions/template/en/</filename>
directory. Extension template directories, like the
<filename>default/</filename> and <filename>custom/</filename>
directories, are part of the template search path, so putting templates
there enables them to be found by the template processor.
</para>
<para>
The template processor looks for templates first in the
<filename>custom/</filename> directory (i.e. templates added by the
specific installation), then in the <filename>extensions/</filename>
directory (i.e. templates added by extensions), and finally in the
<filename>default/</filename> directory (i.e. the standard Bugzilla
templates). Thus, installation-specific templates override both
default and extension templates.
</para>
</listitem>
<listitem>
<para>
If you are looking to customize Bugzilla, you can also take advantage
of template hooks. To do so, create a directory in
<filename>BUGZILLA_ROOT/template/en/custom/hook/</filename>
that corresponds to the hook you wish to use, then place your
customization templates into those directories. For example,
if you wanted to use the hook "end" in
<filename>global/useful-links.html.tmpl</filename>, you would
create the directory <filename>BUGZILLA_ROOT/template/en/custom/hook/
global/useful-links.html.tmpl/end/</filename> and add your customization
template to this directory.
</para>
<para>
Obviously this method of customizing Bugzilla only lets you add code
to the standard source files and templates; you cannot change the
existing code. Nevertheless, for those customizations that only add
code, this method can reduce conflicts when merging changes,
making upgrading your customized Bugzilla installation easier.
</para>
</listitem>
</itemizedlist>
</section>
<section id="cust-change-permissions">
<title>Customizing Who Can Change What</title>
<warning>
<para>
This feature should be considered experimental; the Bugzilla code you
will be changing is not stable, and could change or move between
versions. Be aware that if you make modifications as outlined here,
you may have
to re-make them or port them if Bugzilla changes internally between
versions, and you upgrade.
</para>
</warning>
<para>
Companies often have rules about which employees, or classes of employees,
are allowed to change certain things in the bug system. For example,
only the bug's designated QA Contact may be allowed to VERIFY the bug.
Bugzilla has been
designed to make it easy for you to write your own custom rules to define
who is allowed to make what sorts of value transition.
</para>
<para>
By default, assignees, QA owners and users
with <emphasis>editbugs</emphasis> privileges can edit all fields of bugs,
except group restrictions (unless they are members of the groups they
are trying to change). Bug reporters also have the ability to edit some
fields, but in a more restrictive manner. Other users, without
<emphasis>editbugs</emphasis> privileges, can not edit
bugs, except to comment and add themselves to the CC list.
</para>
<para>
For maximum flexibility, customizing this means editing Bugzilla's Perl
code. This gives the administrator complete control over exactly who is
allowed to do what. The relevant method is called
<filename>check_can_change_field()</filename>,
and is found in <filename>Bug.pm</filename> in your
Bugzilla/ directory. If you open that file and search for
<quote>sub check_can_change_field</quote>, you'll find it.
</para>
<para>
This function has been carefully commented to allow you to see exactly
how it works, and give you an idea of how to make changes to it.
Certain marked sections should not be changed - these are
the <quote>plumbing</quote> which makes the rest of the function work.
In between those sections, you'll find snippets of code like:
<programlisting> # Allow the assignee to change anything.
if ($ownerid eq $whoid) {
return 1;
}</programlisting>
It's fairly obvious what this piece of code does.
</para>
<para>
So, how does one go about changing this function? Well, simple changes
can be made just by removing pieces - for example, if you wanted to
prevent any user adding a comment to a bug, just remove the lines marked
<quote>Allow anyone to change comments.</quote> If you don't want the
Reporter to have any special rights on bugs they have filed, just
remove the entire section that deals with the Reporter.
</para>
<para>
More complex customizations are not much harder. Basically, you add
a check in the right place in the function, i.e. after all the variables
you are using have been set up. So, don't look at $ownerid before
$ownerid has been obtained from the database. You can either add a
positive check, which returns 1 (allow) if certain conditions are true,
or a negative check, which returns 0 (deny.) E.g.:
<programlisting> if ($field eq "qacontact") {
if (Bugzilla->user->groups("quality_assurance")) {
return 1;
}
else {
return 0;
}
}</programlisting>
This says that only users in the group "quality_assurance" can change
the QA Contact field of a bug.
</para>
<para>
Getting more weird:
<programlisting><![CDATA[ if (($field eq "priority") &&
(Bugzilla->user->email =~ /.*\@example\.com$/))
{
if ($oldvalue eq "P1") {
return 1;
}
else {
return 0;
}
}]]></programlisting>
This says that if the user is trying to change the priority field,
and their email address is @example.com, they can only do so if the
old value of the field was "P1". Not very useful, but illustrative.
</para>
<warning>
<para>
If you are modifying <filename>process_bug.cgi</filename> in any
way, do not change the code that is bounded by DO_NOT_CHANGE blocks.
Doing so could compromise security, or cause your installation to
stop working entirely.
</para>
</warning>
<para>
For a list of possible field names, look at the bugs table in the
database. If you need help writing custom rules for your organization,
ask in the newsgroup.
</para>
</section>
<!-- Integrating Bugzilla with Third-Party Tools -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="integration.xml" />
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-always-quote-attributes:t
sgml-auto-insert-required-elements:t
sgml-balanced-tag-edit:t
sgml-exposed-tags:nil
sgml-general-insert-case:lower
sgml-indent-data:t
sgml-indent-step:2
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
sgml-minimize-attributes:nil
sgml-namecase-general:t
sgml-omittag:t
sgml-parent-document:("Bugzilla-Guide.xml" "book" "chapter")
sgml-shorttag:t
sgml-tag-region-if-active:t
End:
-->

View File

@@ -1,449 +0,0 @@
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY % myents SYSTEM "bugzilla.ent">
%myents;
]>
<appendix id="gfdl">
<title>GNU Free Documentation License</title>
<!-- - GNU Project - Free Software Foundation (FSF) -->
<!-- LINK REV="made" HREF="mailto:webmasters@gnu.org" -->
<!-- section>
<title>GNU Free Documentation License</title -->
<para>Version 1.1, March 2000</para>
<blockquote>
<para>Copyright (C) 2000 Free Software Foundation, Inc. 59 Temple Place,
Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and
distribute verbatim copies of this license document, but changing it is
not allowed.</para>
</blockquote>
<section label="0" id="gfdl-0">
<title>Preamble</title>
<para>The purpose of this License is to make a manual, textbook, or other
written document "free" in the sense of freedom: to assure everyone the
effective freedom to copy and redistribute it, with or without modifying
it, either commercially or noncommercially. Secondarily, this License
preserves for the author and publisher a way to get credit for their
work, while not being considered responsible for modifications made by
others.</para>
<para>This License is a kind of "copyleft", which means that derivative
works of the document must themselves be free in the same sense. It
complements the GNU General Public License, which is a copyleft license
designed for free software.</para>
<para>We have designed this License in order to use it for manuals for
free software, because free software needs free documentation: a free
program should come with manuals providing the same freedoms that the
software does. But this License is not limited to software manuals; it
can be used for any textual work, regardless of subject matter or whether
it is published as a printed book. We recommend this License principally
for works whose purpose is instruction or reference.</para>
</section>
<section label="1" id="gfdl-1">
<title>Applicability and Definition</title>
<para>This License applies to any manual or other work that contains a
notice placed by the copyright holder saying it can be distributed under
the terms of this License. The "Document", below, refers to any such
manual or work. Any member of the public is a licensee, and is addressed
as "you".</para>
<para>A "Modified Version" of the Document means any work containing the
Document or a portion of it, either copied verbatim, or with
modifications and/or translated into another language.</para>
<para>A "Secondary Section" is a named appendix or a front-matter section
of the Document that deals exclusively with the relationship of the
publishers or authors of the Document to the Document's overall subject
(or to related matters) and contains nothing that could fall directly
within that overall subject. (For example, if the Document is in part a
textbook of mathematics, a Secondary Section may not explain any
mathematics.) The relationship could be a matter of historical connection
with the subject or with related matters, or of legal, commercial,
philosophical, ethical or political position regarding them.</para>
<para>The "Invariant Sections" are certain Secondary Sections whose
titles are designated, as being those of Invariant Sections, in the
notice that says that the Document is released under this License.</para>
<para>The "Cover Texts" are certain short passages of text that are
listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says
that the Document is released under this License.</para>
<para>A "Transparent" copy of the Document means a machine-readable copy,
represented in a format whose specification is available to the general
public, whose contents can be viewed and edited directly and
straightforwardly with generic text editors or (for images composed of
pixels) generic paint programs or (for drawings) some widely available
drawing editor, and that is suitable for input to text formatters or for
automatic translation to a variety of formats suitable for input to text
formatters. A copy made in an otherwise Transparent file format whose
markup has been designed to thwart or discourage subsequent modification
by readers is not Transparent. A copy that is not "Transparent" is called
"Opaque".</para>
<para>Examples of suitable formats for Transparent copies include plain
ASCII without markup, Texinfo input format, LaTeX input format, SGML or
XML using a publicly available DTD, and standard-conforming simple HTML
designed for human modification. Opaque formats include PostScript, PDF,
proprietary formats that can be read and edited only by proprietary word
processors, SGML or XML for which the DTD and/or processing tools are not
generally available, and the machine-generated HTML produced by some word
processors for output purposes only.</para>
<para>The "Title Page" means, for a printed book, the title page itself,
plus such following pages as are needed to hold, legibly, the material
this License requires to appear in the title page. For works in formats
which do not have any title page as such, "Title Page" means the text
near the most prominent appearance of the work's title, preceding the
beginning of the body of the text.</para>
</section>
<section label="2" id="gfdl-2">
<title>Verbatim Copying</title>
<para>You may copy and distribute the Document in any medium, either
commercially or noncommercially, provided that this License, the
copyright notices, and the license notice saying this License applies to
the Document are reproduced in all copies, and that you add no other
conditions whatsoever to those of this License. You may not use technical
measures to obstruct or control the reading or further copying of the
copies you make or distribute. However, you may accept compensation in
exchange for copies. If you distribute a large enough number of copies
you must also follow the conditions in section 3.</para>
<para>You may also lend copies, under the same conditions stated above,
and you may publicly display copies.</para>
</section>
<section label="3" id="gfdl-3">
<title>Copying in Quantity</title>
<para>If you publish printed copies of the Document numbering more than
100, and the Document's license notice requires Cover Texts, you must
enclose the copies in covers that carry, clearly and legibly, all these
Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts
on the back cover. Both covers must also clearly and legibly identify you
as the publisher of these copies. The front cover must present the full
title with all words of the title equally prominent and visible. You may
add other material on the covers in addition. Copying with changes
limited to the covers, as long as they preserve the title of the Document
and satisfy these conditions, can be treated as verbatim copying in other
respects.</para>
<para>If the required texts for either cover are too voluminous to fit
legibly, you should put the first ones listed (as many as fit reasonably)
on the actual cover, and continue the rest onto adjacent pages.</para>
<para>If you publish or distribute Opaque copies of the Document
numbering more than 100, you must either include a machine-readable
Transparent copy along with each Opaque copy, or state in or with each
Opaque copy a publicly-accessible computer-network location containing a
complete Transparent copy of the Document, free of added material, which
the general network-using public has access to download anonymously at no
charge using public-standard network protocols. If you use the latter
option, you must take reasonably prudent steps, when you begin
distribution of Opaque copies in quantity, to ensure that this
Transparent copy will remain thus accessible at the stated location until
at least one year after the last time you distribute an Opaque copy
(directly or through your agents or retailers) of that edition to the
public.</para>
<para>It is requested, but not required, that you contact the authors of
the Document well before redistributing any large number of copies, to
give them a chance to provide you with an updated version of the
Document.</para>
</section>
<section label="4" id="gfdl-4">
<title>Modifications</title>
<para>You may copy and distribute a Modified Version of the Document
under the conditions of sections 2 and 3 above, provided that you release
the Modified Version under precisely this License, with the Modified
Version filling the role of the Document, thus licensing distribution and
modification of the Modified Version to whoever possesses a copy of it.
In addition, you must do these things in the Modified Version:</para>
<orderedlist numeration="upperalpha">
<listitem>
<para>Use in the Title Page (and on the covers, if any) a title
distinct from that of the Document, and from those of previous
versions (which should, if there were any, be listed in the History
section of the Document). You may use the same title as a previous
version if the original publisher of that version gives
permission.</para>
</listitem>
<listitem>
<para>List on the Title Page, as authors, one or more persons or
entities responsible for authorship of the modifications in the
Modified Version, together with at least five of the principal
authors of the Document (all of its principal authors, if it has less
than five).</para>
</listitem>
<listitem>
<para>State on the Title page the name of the publisher of the
Modified Version, as the publisher.</para>
</listitem>
<listitem>
<para>Preserve all the copyright notices of the Document.</para>
</listitem>
<listitem>
<para>Add an appropriate copyright notice for your modifications
adjacent to the other copyright notices.</para>
</listitem>
<listitem>
<para>Include, immediately after the copyright notices, a license
notice giving the public permission to use the Modified Version under
the terms of this License, in the form shown in the Addendum
below.</para>
</listitem>
<listitem>
<para>Preserve in that license notice the full lists of Invariant
Sections and required Cover Texts given in the Document's license
notice.</para>
</listitem>
<listitem>
<para>Include an unaltered copy of this License.</para>
</listitem>
<listitem>
<para>Preserve the section entitled "History", and its title, and add
to it an item stating at least the title, year, new authors, and
publisher of the Modified Version as given on the Title Page. If
there is no section entitled "History" in the Document, create one
stating the title, year, authors, and publisher of the Document as
given on its Title Page, then add an item describing the Modified
Version as stated in the previous sentence.</para>
</listitem>
<listitem>
<para>Preserve the network location, if any, given in the Document
for public access to a Transparent copy of the Document, and likewise
the network locations given in the Document for previous versions it
was based on. These may be placed in the "History" section. You may
omit a network location for a work that was published at least four
years before the Document itself, or if the original publisher of the
version it refers to gives permission.</para>
</listitem>
<listitem>
<para>In any section entitled "Acknowledgements" or "Dedications",
preserve the section's title, and preserve in the section all the
substance and tone of each of the contributor acknowledgements and/or
dedications given therein.</para>
</listitem>
<listitem>
<para>Preserve all the Invariant Sections of the Document, unaltered
in their text and in their titles. Section numbers or the equivalent
are not considered part of the section titles.</para>
</listitem>
<listitem>
<para>Delete any section entitled "Endorsements". Such a section may
not be included in the Modified Version.</para>
</listitem>
<listitem>
<para>Do not retitle any existing section as "Endorsements" or to
conflict in title with any Invariant Section.</para>
</listitem>
</orderedlist>
<para>If the Modified Version includes new front-matter sections or
appendices that qualify as Secondary Sections and contain no material
copied from the Document, you may at your option designate some or all of
these sections as invariant. To do this, add their titles to the list of
Invariant Sections in the Modified Version's license notice. These titles
must be distinct from any other section titles.</para>
<para>You may add a section entitled "Endorsements", provided it contains
nothing but endorsements of your Modified Version by various parties--for
example, statements of peer review or that the text has been approved by
an organization as the authoritative definition of a standard.</para>
<para>You may add a passage of up to five words as a Front-Cover Text,
and a passage of up to 25 words as a Back-Cover Text, to the end of the
list of Cover Texts in the Modified Version. Only one passage of
Front-Cover Text and one of Back-Cover Text may be added by (or through
arrangements made by) any one entity. If the Document already includes a
cover text for the same cover, previously added by you or by arrangement
made by the same entity you are acting on behalf of, you may not add
another; but you may replace the old one, on explicit permission from the
previous publisher that added the old one.</para>
<para>The author(s) and publisher(s) of the Document do not by this
License give permission to use their names for publicity for or to assert
or imply endorsement of any Modified Version.</para>
</section>
<section label="5" id="gfdl-5">
<title>Combining Documents</title>
<para>You may combine the Document with other documents released under
this License, under the terms defined in section 4 above for modified
versions, provided that you include in the combination all of the
Invariant Sections of all of the original documents, unmodified, and list
them all as Invariant Sections of your combined work in its license
notice.</para>
<para>The combined work need only contain one copy of this License, and
multiple identical Invariant Sections may be replaced with a single copy.
If there are multiple Invariant Sections with the same name but different
contents, make the title of each such section unique by adding at the end
of it, in parentheses, the name of the original author or publisher of
that section if known, or else a unique number. Make the same adjustment
to the section titles in the list of Invariant Sections in the license
notice of the combined work.</para>
<para>In the combination, you must combine any sections entitled
"History" in the various original documents, forming one section entitled
"History"; likewise combine any sections entitled "Acknowledgements", and
any sections entitled "Dedications". You must delete all sections
entitled "Endorsements."</para>
</section>
<section label="6" id="gfdl-6">
<title>Collections of Documents</title>
<para>You may make a collection consisting of the Document and other
documents released under this License, and replace the individual copies
of this License in the various documents with a single copy that is
included in the collection, provided that you follow the rules of this
License for verbatim copying of each of the documents in all other
respects.</para>
<para>You may extract a single document from such a collection, and
distribute it individually under this License, provided you insert a copy
of this License into the extracted document, and follow this License in
all other respects regarding verbatim copying of that document.</para>
</section>
<section label="7" id="gfdl-7">
<title>Aggregation with Independent Works</title>
<para>A compilation of the Document or its derivatives with other
separate and independent documents or works, in or on a volume of a
storage or distribution medium, does not as a whole count as a Modified
Version of the Document, provided no compilation copyright is claimed for
the compilation. Such a compilation is called an "aggregate", and this
License does not apply to the other self-contained works thus compiled
with the Document, on account of their being thus compiled, if they are
not themselves derivative works of the Document.</para>
<para>If the Cover Text requirement of section 3 is applicable to these
copies of the Document, then if the Document is less than one quarter of
the entire aggregate, the Document's Cover Texts may be placed on covers
that surround only the Document within the aggregate. Otherwise they must
appear on covers around the whole aggregate.</para>
</section>
<section label="8" id="gfdl-8">
<title>Translation</title>
<para>Translation is considered a kind of modification, so you may
distribute translations of the Document under the terms of section 4.
Replacing Invariant Sections with translations requires special
permission from their copyright holders, but you may include translations
of some or all Invariant Sections in addition to the original versions of
these Invariant Sections. You may include a translation of this License
provided that you also include the original English version of this
License. In case of a disagreement between the translation and the
original English version of this License, the original English version
will prevail.</para>
</section>
<section label="9" id="gfdl-9">
<title>Termination</title>
<para>You may not copy, modify, sublicense, or distribute the Document
except as expressly provided for under this License. Any other attempt to
copy, modify, sublicense or distribute the Document is void, and will
automatically terminate your rights under this License. However, parties
who have received copies, or rights, from you under this License will not
have their licenses terminated so long as such parties remain in full
compliance.</para>
</section>
<section label="10" id="gfdl-10">
<title>Future Revisions of this License</title>
<para>The Free Software Foundation may publish new, revised versions of
the GNU Free Documentation License from time to time. Such new versions
will be similar in spirit to the present version, but may differ in
detail to address new problems or concerns. See
<ulink url="http://www.gnu.org/copyleft/"/>.</para>
<para>Each version of the License is given a distinguishing version
number. If the Document specifies that a particular numbered version of
this License "or any later version" applies to it, you have the option of
following the terms and conditions either of that specified version or of
any later version that has been published (not as a draft) by the Free
Software Foundation. If the Document does not specify a version number of
this License, you may choose any version ever published (not as a draft)
by the Free Software Foundation.</para>
</section>
<section label="" id="gfdl-howto">
<title>How to use this License for your documents</title>
<para>To use this License in a document you have written, include a copy
of the License in the document and put the following copyright and
license notices just after the title page:</para>
<blockquote>
<para>Copyright (c) YEAR YOUR NAME. Permission is granted to copy,
distribute and/or modify this document under the terms of the GNU Free
Documentation License, Version 1.1 or any later version published by
the Free Software Foundation; with the Invariant Sections being LIST
THEIR TITLES, with the Front-Cover Texts being LIST, and with the
Back-Cover Texts being LIST. A copy of the license is included in the
section entitled "GNU Free Documentation License".</para>
</blockquote>
<para>If you have no Invariant Sections, write "with no Invariant
Sections" instead of saying which ones are invariant. If you have no
Front-Cover Texts, write "no Front-Cover Texts" instead of "Front-Cover
Texts being LIST"; likewise for Back-Cover Texts.</para>
<para>If your document contains nontrivial examples of program code, we
recommend releasing these examples in parallel under your choice of free
software license, such as the GNU General Public License, to permit their
use in free software.</para>
</section>
</appendix>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-always-quote-attributes:t
sgml-auto-insert-required-elements:t
sgml-balanced-tag-edit:t
sgml-exposed-tags:nil
sgml-general-insert-case:lower
sgml-indent-data:t
sgml-indent-step:2
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
sgml-minimize-attributes:nil
sgml-namecase-general:t
sgml-omittag:t
sgml-parent-document:("Bugzilla-Guide.xml" "book" "chapter")
sgml-shorttag:t
sgml-tag-region-if-active:t
End:
-->

View File

@@ -1,555 +0,0 @@
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY % myents SYSTEM "bugzilla.ent">
%myents;
]>
<glossary id="glossary">
<glossdiv>
<title>0-9, high ascii</title>
<glossentry id="gloss-htaccess">
<glossterm>.htaccess</glossterm>
<glossdef>
<para>Apache web server, and other NCSA-compliant web servers,
observe the convention of using files in directories called
<filename>.htaccess</filename>
to restrict access to certain files. In Bugzilla, they are used
to keep secret files which would otherwise
compromise your installation - e.g. the
<filename>localconfig</filename>
file contains the password to your database.
curious.</para>
</glossdef>
</glossentry>
</glossdiv>
<glossdiv id="gloss-a">
<title>A</title>
<glossentry id="gloss-apache">
<glossterm>Apache</glossterm>
<glossdef>
<para>In this context, Apache is the web server most commonly used
for serving up Bugzilla
pages. Contrary to popular belief, the apache web server has nothing
to do with the ancient and noble Native American tribe, but instead
derived its name from the fact that it was
<quote>a patchy</quote>
version of the original
<acronym>NCSA</acronym>
world-wide-web server.</para>
<variablelist>
<title>Useful Directives when configuring Bugzilla</title>
<varlistentry>
<term><computeroutput><ulink url="http://httpd.apache.org/docs-2.0/mod/core.html#addhandler">AddHandler</ulink></computeroutput></term>
<listitem>
<para>Tell Apache that it's OK to run CGI scripts.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><computeroutput><ulink url="http://httpd.apache.org/docs-2.0/mod/core.html#allowoverride">AllowOverride</ulink></computeroutput></term>
<term><computeroutput><ulink url="http://httpd.apache.org/docs-2.0/mod/core.html#options">Options</ulink></computeroutput></term>
<listitem>
<para>These directives are used to tell Apache many things about
the directory they apply to. For Bugzilla's purposes, we need
them to allow script execution and <filename>.htaccess</filename>
overrides.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><computeroutput><ulink url="http://httpd.apache.org/docs-2.0/mod/mod_dir.html#directoryindex">DirectoryIndex</ulink></computeroutput></term>
<listitem>
<para>Used to tell Apache what files are indexes. If you can
not add <filename>index.cgi</filename> to the list of valid files,
you'll need to set <computeroutput>$index_html</computeroutput> to
1 in <filename>localconfig</filename> so
<command>./checksetup.pl</command> will create an
<filename>index.html</filename> that redirects to
<filename>index.cgi</filename>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><computeroutput><ulink url="http://httpd.apache.org/docs-2.0/mod/core.html#scriptinterpretersource">ScriptInterpreterSource</ulink></computeroutput></term>
<listitem>
<para>Used when running Apache on windows so the shebang line
doesn't have to be changed in every Bugzilla script.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>For more information about how to configure Apache for Bugzilla,
see <xref linkend="http-apache"/>.
</para>
</glossdef>
</glossentry>
</glossdiv>
<glossdiv id="gloss-b">
<title>B</title>
<glossentry>
<glossterm>Bug</glossterm>
<glossdef>
<para>A
<quote>bug</quote>
in Bugzilla refers to an issue entered into the database which has an
associated number, assignments, comments, etc. Some also refer to a
<quote>tickets</quote>
or
<quote>issues</quote>;
in the context of Bugzilla, they are synonymous.</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm>Bug Number</glossterm>
<glossdef>
<para>Each Bugzilla bug is assigned a number that uniquely identifies
that bug. The bug associated with a bug number can be pulled up via a
query, or easily from the very front page by typing the number in the
"Find" box.</para>
</glossdef>
</glossentry>
<glossentry id="gloss-bugzilla">
<glossterm>Bugzilla</glossterm>
<glossdef>
<para>Bugzilla is the world-leading free software bug tracking system.
</para>
</glossdef>
</glossentry>
</glossdiv>
<glossdiv id="gloss-c">
<title>C</title>
<glossentry id="gloss-cgi">
<glossterm>Common Gateway Interface</glossterm>
<acronym>CGI</acronym>
<glossdef>
<para><acronym>CGI</acronym> is an acronym for Common Gateway Interface. This is
a standard for interfacing an external application with a web server. Bugzilla
is an example of a <acronym>CGI</acronym> application.
</para>
</glossdef>
</glossentry>
<glossentry id="gloss-component">
<glossterm>Component</glossterm>
<glossdef>
<para>A Component is a subsection of a Product. It should be a narrow
category, tailored to your organization. All Products must contain at
least one Component (and, as a matter of fact, creating a Product
with no Components will create an error in Bugzilla).</para>
</glossdef>
</glossentry>
<glossentry id="gloss-cpan">
<glossterm>Comprehensive Perl Archive Network</glossterm>
<acronym>CPAN</acronym>
<!-- TODO: Rewrite def for CPAN -->
<glossdef>
<para>
<acronym>CPAN</acronym>
stands for the
<quote>Comprehensive Perl Archive Network</quote>.
CPAN maintains a large number of extremely useful
<glossterm>Perl</glossterm>
modules - encapsulated chunks of code for performing a
particular task.</para>
</glossdef>
</glossentry>
<glossentry id="gloss-contrib">
<glossterm><filename class="directory">contrib</filename></glossterm>
<glossdef>
<para>The <filename class="directory">contrib</filename> directory is
a location to put scripts that have been contributed to Bugzilla but
are not a part of the official distribution. These scripts are written
by third parties and may be in languages other than perl. For those
that are in perl, there may be additional modules or other requirements
than those of the official distribution.
<note>
<para>Scripts in the <filename class="directory">contrib</filename>
directory are not officially supported by the Bugzilla team and may
break in between versions.
</para>
</note>
</para>
</glossdef>
</glossentry>
</glossdiv>
<glossdiv id="gloss-d">
<title>D</title>
<glossentry id="gloss-daemon">
<glossterm>daemon</glossterm>
<glossdef>
<para>A daemon is a computer program which runs in the background. In
general, most daemons are started at boot time via System V init
scripts, or through RC scripts on BSD-based systems.
<glossterm>mysqld</glossterm>,
the MySQL server, and
<glossterm>apache</glossterm>,
a web server, are generally run as daemons.</para>
</glossdef>
</glossentry>
<glossentry id="gloss-dos">
<glossterm>DOS Attack</glossterm>
<glossdef>
<para>A DOS, or Denial of Service attack, is when a user attempts to
deny access to a web server by repeatedly accessing a page or sending
malformed requests to a webserver. A D-DOS, or
Distributed Denial of Service attack, is when these requests come
from multiple sources at the same time. Unfortunately, these are much
more difficult to defend against.
</para>
</glossdef>
</glossentry>
</glossdiv>
<glossdiv id="gloss-g">
<title>G</title>
<glossentry id="gloss-groups">
<glossterm>Groups</glossterm>
<glossdef>
<para>The word
<quote>Groups</quote>
has a very special meaning to Bugzilla. Bugzilla's main security
mechanism comes by placing users in groups, and assigning those
groups certain privileges to view bugs in particular
<glossterm>Products</glossterm>
in the
<glossterm>Bugzilla</glossterm>
database.</para>
</glossdef>
</glossentry>
</glossdiv>
<glossdiv id="gloss-j">
<title>J</title>
<glossentry id="gloss-javascript">
<glossterm>JavaScript</glossterm>
<glossdef>
<para>JavaScript is cool, we should talk about it.
</para>
</glossdef>
</glossentry>
</glossdiv>
<glossdiv id="gloss-m">
<title>M</title>
<glossentry id="gloss-mta">
<glossterm>Message Transport Agent</glossterm>
<acronym>MTA</acronym>
<glossdef>
<para>A Message Transport Agent is used to control the flow of email on a system.
The <ulink url="http://search.cpan.org/dist/Email-Send/lib/Email/Send.pm">Email::Send</ulink>
Perl module, which Bugzilla uses to send email, can be configured to
use many different underlying implementations for actually sending the
mail using the <option>mail_delivery_method</option> parameter.
Implementations other than <literal>sendmail</literal> require that the
<option>sendmailnow</option> param be set to <literal>on</literal>.
</para>
</glossdef>
</glossentry>
<glossentry id="gloss-mysql">
<glossterm>MySQL</glossterm>
<glossdef>
<para>MySQL is currently the required
<glossterm linkend="gloss-rdbms">RDBMS</glossterm> for Bugzilla. MySQL
can be downloaded from <ulink url="http://www.mysql.com"/>. While you
should familiarize yourself with all of the documentation, some high
points are:
</para>
<variablelist>
<varlistentry>
<term><ulink url="http://www.mysql.com/doc/en/Backup.html">Backup</ulink></term>
<listitem>
<para>Methods for backing up your Bugzilla database.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><ulink url="http://www.mysql.com/doc/en/Option_files.html">Option Files</ulink></term>
<listitem>
<para>Information about how to configure MySQL using
<filename>my.cnf</filename>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><ulink url="http://www.mysql.com/doc/en/Privilege_system.html">Privilege System</ulink></term>
<listitem>
<para>Much more detailed information about the suggestions in
<xref linkend="security-mysql"/>.
</para>
</listitem>
</varlistentry>
</variablelist>
</glossdef>
</glossentry>
</glossdiv>
<glossdiv id="gloss-p">
<title>P</title>
<glossentry id="gloss-ppm">
<glossterm>Perl Package Manager</glossterm>
<acronym>PPM</acronym>
<glossdef>
<para><ulink url="http://aspn.activestate.com/ASPN/Downloads/ActivePerl/PPM/"/>
</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm id="gloss-product">Product</glossterm>
<glossdef>
<para>A Product is a broad category of types of bugs, normally
representing a single piece of software or entity. In general,
there are several Components to a Product. A Product may define a
group (used for security) for all bugs entered into
its Components.</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm>Perl</glossterm>
<glossdef>
<para>First written by Larry Wall, Perl is a remarkable program
language. It has the benefits of the flexibility of an interpreted
scripting language (such as shell script), combined with the speed
and power of a compiled language, such as C.
<glossterm>Bugzilla</glossterm>
is maintained in Perl.</para>
</glossdef>
</glossentry>
</glossdiv>
<glossdiv id="gloss-q">
<title>Q</title>
<glossentry>
<glossterm>QA</glossterm>
<glossdef>
<para>
<quote>QA</quote>,
<quote>Q/A</quote>, and
<quote>Q.A.</quote>
are short for
<quote>Quality Assurance</quote>.
In most large software development organizations, there is a team
devoted to ensuring the product meets minimum standards before
shipping. This team will also generally want to track the progress of
bugs over their life cycle, thus the need for the
<quote>QA Contact</quote>
field in a bug.</para>
</glossdef>
</glossentry>
</glossdiv>
<glossdiv id="gloss-r">
<title>R</title>
<glossentry id="gloss-rdbms">
<glossterm>Relational DataBase Management System</glossterm>
<acronym>RDBMS</acronym>
<glossdef>
<para>A relational database management system is a database system
that stores information in tables that are related to each other.
</para>
</glossdef>
</glossentry>
<glossentry id="gloss-regexp">
<glossterm>Regular Expression</glossterm>
<acronym>regexp</acronym>
<glossdef>
<para>A regular expression is an expression used for pattern matching.
<ulink url="http://perldoc.com/perl5.6/pod/perlre.html#Regular-Expressions">Documentation</ulink>
</para>
</glossdef>
</glossentry>
</glossdiv>
<glossdiv id="gloss-s">
<title>S</title>
<glossentry id="gloss-service">
<glossterm>Service</glossterm>
<glossdef>
<para>In Windows NT environment, a boot-time background application
is referred to as a service. These are generally managed through the
control panel while logged in as an account with
<quote>Administrator</quote> level capabilities. For more
information, consult your Windows manual or the MSKB.
</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm>
<acronym>SGML</acronym>
</glossterm>
<glossdef>
<para>
<acronym>SGML</acronym>
stands for
<quote>Standard Generalized Markup Language</quote>.
Created in the 1980's to provide an extensible means to maintain
documentation based upon content instead of presentation,
<acronym>SGML</acronym>
has withstood the test of time as a robust, powerful language.
<glossterm>
<acronym>XML</acronym>
</glossterm>
is the
<quote>baby brother</quote>
of SGML; any valid
<acronym>XML</acronym>
document it, by definition, a valid
<acronym>SGML</acronym>
document. The document you are reading is written and maintained in
<acronym>SGML</acronym>,
and is also valid
<acronym>XML</acronym>
if you modify the Document Type Definition.</para>
</glossdef>
</glossentry>
</glossdiv>
<glossdiv id="gloss-t">
<title>T</title>
<glossentry id="gloss-target-milestone" xreflabel="Target Milestone">
<glossterm>Target Milestone</glossterm>
<glossdef>
<para>Target Milestones are Product goals. They are configurable on a
per-Product basis. Most software development houses have a concept of
<quote>milestones</quote>
where the people funding a project expect certain functionality on
certain dates. Bugzilla facilitates meeting these milestones by
giving you the ability to declare by which milestone a bug will be
fixed, or an enhancement will be implemented.</para>
</glossdef>
</glossentry>
<glossentry id="gloss-tcl">
<glossterm>Tool Command Language</glossterm>
<acronym>TCL</acronym>
<glossdef>
<para>TCL is an open source scripting language available for Windows,
Macintosh, and Unix based systems. Bugzilla 1.0 was written in TCL but
never released. The first release of Bugzilla was 2.0, which was when
it was ported to perl.
</para>
</glossdef>
</glossentry>
</glossdiv>
<glossdiv id="gloss-z">
<title>Z</title>
<glossentry id="gloss-zarro">
<glossterm>Zarro Boogs Found</glossterm>
<glossdef>
<para>This is just a goofy way of saying that there were no bugs
found matching your query. When asked to explain this message,
Terry had the following to say:
</para>
<blockquote>
<attribution>Terry Weissman</attribution>
<para>I've been asked to explain this ... way back when, when
Netscape released version 4.0 of its browser, we had a release
party. Naturally, there had been a big push to try and fix every
known bug before the release. Naturally, that hadn't actually
happened. (This is not unique to Netscape or to 4.0; the same thing
has happened with every software project I've ever seen.) Anyway,
at the release party, T-shirts were handed out that said something
like "Netscape 4.0: Zarro Boogs". Just like the software, the
T-shirt had no known bugs. Uh-huh.
</para>
<para>So, when you query for a list of bugs, and it gets no results,
you can think of this as a friendly reminder. Of *course* there are
bugs matching your query, they just aren't in the bugsystem yet...
</para>
</blockquote>
</glossdef>
</glossentry>
</glossdiv>
</glossary>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-always-quote-attributes:t
sgml-auto-insert-required-elements:t
sgml-balanced-tag-edit:t
sgml-exposed-tags:nil
sgml-general-insert-case:lower
sgml-indent-data:t
sgml-indent-step:2
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
sgml-minimize-attributes:nil
sgml-namecase-general:t
sgml-omittag:t
sgml-parent-document:("Bugzilla-Guide.xml" "book" "chapter")
sgml-shorttag:t
sgml-tag-region-if-active:t
End:
-->

View File

@@ -1,21 +0,0 @@
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-always-quote-attributes:t
sgml-auto-insert-required-elements:t
sgml-balanced-tag-edit:t
sgml-exposed-tags:nil
sgml-general-insert-case:lower
sgml-indent-data:t
sgml-indent-step:2
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
sgml-minimize-attributes:nil
sgml-namecase-general:t
sgml-omittag:t
sgml-parent-document:("Bugzilla-Guide.xml" "book" "chapter")
sgml-shorttag:t
sgml-tag-region-if-active:t
End:
-->

File diff suppressed because it is too large Load Diff

View File

@@ -1,124 +0,0 @@
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY % myents SYSTEM "bugzilla.ent">
%myents;
]>
<!-- Keep these tools listings in alphabetical order please. -MPB -->
<section id="integration">
<title>Integrating Bugzilla with Third-Party Tools</title>
<section id="bonsai"
xreflabel="Bonsai, the Mozilla automated CVS management system">
<title>Bonsai</title>
<para>Bonsai is a web-based tool for managing
<xref linkend="cvs" />
. Using Bonsai, administrators can control open/closed status of trees,
query a fast relational database back-end for change, branch, and comment
information, and view changes made since the last time the tree was
closed. Bonsai
also integrates with
<xref linkend="tinderbox" />.
</para>
</section>
<section id="cvs" xreflabel="CVS, the Concurrent Versioning System">
<title>CVS</title>
<para>CVS integration is best accomplished, at this point, using the
Bugzilla Email Gateway.</para>
<para>Follow the instructions in this Guide for enabling Bugzilla e-mail
integration. Ensure that your check-in script sends an email to your
Bugzilla e-mail gateway with the subject of
<quote>[Bug XXXX]</quote>,
and you can have CVS check-in comments append to your Bugzilla bug. If
you want to have the bug be closed automatically, you'll have to modify
the <filename>contrib/bugzilla_email_append.pl</filename> script.
</para>
<para>There is also a CVSZilla project, based upon somewhat dated
Bugzilla code, to integrate CVS and Bugzilla through CVS' ability to
email. Check it out at: <ulink url="http://www.cvszilla.org/"/>.
</para>
<para>Another system capable of CVS integration with Bugzilla is
Scmbug. This system provides generic integration of Source code
Configuration Management with Bugtracking. Check it out at: <ulink
url="http://freshmeat.net/projects/scmbug/"/>.
</para>
</section>
<section id="scm"
xreflabel="Perforce SCM (Fast Software Configuration Management System, a powerful commercial alternative to CVS">
<title>Perforce SCM</title>
<para>You can find the project page for Bugzilla and Teamtrack Perforce
integration (p4dti) at:
<ulink url="http://www.ravenbrook.com/project/p4dti/"/>
.
<quote>p4dti</quote>
is now an officially supported product from Perforce, and you can find
the "Perforce Public Depot" p4dti page at
<ulink url="http://public.perforce.com/public/perforce/p4dti/index.html"/>
.</para>
<para>Integration of Perforce with Bugzilla, once patches are applied, is
seamless. Perforce replication information will appear below the comments
of each bug. Be certain you have a matching set of patches for the
Bugzilla version you are installing. p4dti is designed to support
multiple defect trackers, and maintains its own documentation for it.
Please consult the pages linked above for further information.</para>
</section>
<section id="svn"
xreflabel="Subversion, a compelling replacement for CVS">
<title>Subversion</title>
<para>Subversion is a free/open-source version control system,
designed to overcome various limitations of CVS. Integration of
Subversion with Bugzilla is possible using Scmbug, a system
providing generic integration of Source Code Configuration
Management with Bugtracking. Scmbug is available at <ulink
url="http://freshmeat.net/projects/scmbug/"/>.</para>
</section>
<section id="tinderbox"
xreflabel="Tinderbox, the Mozilla automated build management system">
<title>Tinderbox/Tinderbox2</title>
<para>Tinderbox is a continuous-build system which can integrate with
Bugzilla - see
<ulink url="http://www.mozilla.org/projects/tinderbox"/> for details
of Tinderbox, and
<ulink url="http://tinderbox.mozilla.org/showbuilds.cgi"/> to see it
in action.</para>
</section>
</section>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-always-quote-attributes:t
sgml-auto-insert-required-elements:t
sgml-balanced-tag-edit:t
sgml-exposed-tags:nil
sgml-general-insert-case:lower
sgml-indent-data:t
sgml-indent-step:2
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
sgml-minimize-attributes:nil
sgml-namecase-general:t
sgml-omittag:t
sgml-parent-document:("Bugzilla-Guide.xml" "book" "chapter")
sgml-shorttag:t
sgml-tag-region-if-active:t
End:
-->

View File

@@ -1,121 +0,0 @@
<chapter id="introduction">
<title>Introduction</title>
<section id="what-is-bugzilla">
<title>What is Bugzilla?</title>
<para>
Bugzilla is a bug- or issue-tracking system. Bug-tracking
systems allow individual or groups of developers effectively to keep track
of outstanding problems with their products.
</para>
<para><emphasis>Do we need more here?</emphasis></para>
</section>
<section id="why-tracking">
<title>Why use a bug-tracking system?</title>
<para>Those who do not use a bug-tracking system tend to rely on
shared lists, email, spreadsheets and/or Post-It notes to monitor the
status of defects. This procedure
is usually error-prone and tends to cause those bugs judged least
significant by developers to be dropped or ignored.</para>
<para>Integrated defect-tracking systems make sure that nothing gets
swept under the carpet; they provide a method of creating, storing,
arranging and processing defect reports and enhancement requests.</para>
</section>
<section id="why-bugzilla">
<title>Why use Bugzilla?</title>
<para>Bugzilla is the leading open-source/free software bug tracking
system. It boasts many advanced features, including:
<itemizedlist>
<listitem>
<para>Powerful searching</para>
</listitem>
<listitem>
<para>User-configurable email notifications of bug changes</para>
</listitem>
<listitem>
<para>Full change history</para>
</listitem>
<listitem>
<para>Inter-bug dependency tracking and graphing</para>
</listitem>
<listitem>
<para>Excellent attachment management</para>
</listitem>
<listitem>
<para>Integrated, product-based, granular security schema</para>
</listitem>
<listitem>
<para>Fully security-audited, and runs under Perl's taint mode</para>
</listitem>
<listitem>
<para>A robust, stable RDBMS back-end</para>
</listitem>
<listitem>
<para>Completely customizable and/or localizable web user
interface</para>
</listitem>
<listitem>
<para>Additional XML, email and console interfaces</para>
</listitem>
<listitem>
<para>Extensive configurability</para>
</listitem>
<listitem>
<para>Smooth upgrade pathway between versions</para>
</listitem>
</itemizedlist>
</para>
<para>Bugzilla is very adaptable to various situations. Known uses
currently include IT support queues, Systems Administration deployment
management, chip design and development problem tracking (both
pre-and-post fabrication), and software and hardware bug tracking for
luminaries such as Redhat, NASA, Linux-Mandrake, and VA Systems.
Combined with systems such as
<ulink url="http://www.cvshome.org">CVS</ulink>,
<ulink url="http://www.mozilla.org/bonsai.html">Bonsai</ulink>, or
<ulink url="http://www.perforce.com">Perforce SCM</ulink>, Bugzilla
provides a powerful, easy-to-use configuration management solution.</para>
</section>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-always-quote-attributes:t
sgml-auto-insert-required-elements:t
sgml-balanced-tag-edit:t
sgml-exposed-tags:nil
sgml-general-insert-case:lower
sgml-indent-data:t
sgml-indent-step:2
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
sgml-minimize-attributes:nil
sgml-namecase-general:t
sgml-omittag:t
sgml-parent-document:("Bugzilla-Guide.xml" "book" "chapter")
sgml-shorttag:t
sgml-tag-region-if-active:t
End:
-->

View File

@@ -1,197 +0,0 @@
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY % myents SYSTEM "bugzilla.ent">
%myents;
]>
<appendix id="install-perlmodules-manual">
<title>Manual Installation of Perl Modules</title>
<section id="modules-manual-instructions">
<title>Instructions</title>
<para>
If you need to install Perl modules manually, here's how it's done.
Download the module using the link given in the next section, and then
apply this magic incantation, as root:
</para>
<para>
<screen><prompt>bash#</prompt> tar -xzvf &lt;module&gt;.tar.gz
<prompt>bash#</prompt> cd &lt;module&gt;
<prompt>bash#</prompt> perl Makefile.PL
<prompt>bash#</prompt> make
<prompt>bash#</prompt> make test
<prompt>bash#</prompt> make install</screen>
</para>
<note>
<para>
In order to compile source code under Windows you will need to obtain
a 'make' utility. The <command>nmake</command> utility provided with
Microsoft Visual C++ may be used. As an alternative, there is a
utility called <command>dmake</command> available from CPAN which is
written entirely in Perl.
</para>
<para>
As described in <xref linkend="modules-manual-download" />, however, most
packages already exist and are available from ActiveState or theory58S.
We highly recommend that you install them using the ppm GUI available with
ActiveState and to add the theory58S repository to your list of repositories.
</para>
</note>
</section>
<section id="modules-manual-download">
<title>Download Locations</title>
<note>
<para>
Running Bugzilla on Windows requires the use of ActiveState
Perl 5.8.1 or higher. Many modules already exist in the core
distribution of ActiveState Perl. Additional modules can be downloaded
from <ulink url="http://theoryx5.uwinnipeg.ca/ppms/" /> if you use
Perl 5.8.x or from <ulink url="http://cpan.uwinnipeg.ca/PPMPackages/10xx/" />
if you use Perl 5.10.x.
</para>
</note>
<para>
CGI:
<literallayout>
CPAN Download Page: <ulink url="http://search.cpan.org/dist/CGI.pm/"/>
Documentation: <ulink url="http://perldoc.perl.org/CGI.html"/>
</literallayout>
</para>
<para>
Data-Dumper:
<literallayout>
CPAN Download Page: <ulink url="http://search.cpan.org/dist/Data-Dumper/"/>
Documentation: <ulink url="http://search.cpan.org/dist/Data-Dumper/Dumper.pm"/>
</literallayout>
</para>
<para>
Date::Format (part of TimeDate):
<literallayout>
CPAN Download Page: <ulink url="http://search.cpan.org/dist/TimeDate/"/>
Documentation: <ulink url="http://search.cpan.org/dist/TimeDate/lib/Date/Format.pm"/>
</literallayout>
</para>
<para>
DBI:
<literallayout>
CPAN Download Page: <ulink url="http://search.cpan.org/dist/DBI/"/>
Documentation: <ulink url="http://dbi.perl.org/docs/"/>
</literallayout>
</para>
<para>
DBD::mysql:
<literallayout>
CPAN Download Page: <ulink url="http://search.cpan.org/dist/DBD-mysql/"/>
Documentation: <ulink url="http://search.cpan.org/dist/DBD-mysql/lib/DBD/mysql.pm"/>
</literallayout>
</para>
<para>
DBD::Pg:
<literallayout>
CPAN Download Page: <ulink url="http://search.cpan.org/dist/DBD-Pg/"/>
Documentation: <ulink url="http://search.cpan.org/dist/DBD-Pg/Pg.pm"/>
</literallayout>
</para>
<para>
File::Spec:
<literallayout>
CPAN Download Page: <ulink url="http://search.cpan.org/dist/File-Spec/"/>
Documentation: <ulink url="http://perldoc.perl.org/File/Spec.html"/>
</literallayout>
</para>
<para>
Template-Toolkit:
<literallayout>
CPAN Download Page: <ulink url="http://search.cpan.org/dist/Template-Toolkit/"/>
Documentation: <ulink url="http://www.template-toolkit.org/docs.html"/>
</literallayout>
</para>
<para>
GD:
<literallayout>
CPAN Download Page: <ulink url="http://search.cpan.org/dist/GD/"/>
Documentation: <ulink url="http://search.cpan.org/dist/GD/GD.pm"/>
</literallayout>
</para>
<para>
Template::Plugin::GD:
<literallayout>
CPAN Download Page: <ulink url="http://search.cpan.org/dist/Template-GD/" />
Documentation: <ulink url="http://www.template-toolkit.org/docs/aqua/Modules/index.html" />
</literallayout>
</para>
<para>
MIME::Parser (part of MIME-tools):
<literallayout>
CPAN Download Page: <ulink url="http://search.cpan.org/dist/MIME-tools/"/>
Documentation: <ulink url="http://search.cpan.org/dist/MIME-tools/lib/MIME/Parser.pm"/>
</literallayout>
</para>
</section>
<section id="modules-manual-optional">
<title>Optional Modules</title>
<para>
Chart::Base:
<literallayout>
CPAN Download Page: <ulink url="http://search.cpan.org/dist/Chart/"/>
Documentation: <ulink url="http://search.cpan.org/dist/Chart/Chart.pod"/>
</literallayout>
</para>
<para>
GD::Graph:
<literallayout>
CPAN Download Page: <ulink url="http://search.cpan.org/dist/GDGraph/"/>
Documentation: <ulink url="http://search.cpan.org/dist/GDGraph/Graph.pm"/>
</literallayout>
</para>
<para>
GD::Text::Align (part of GD::Text::Util):
<literallayout>
CPAN Download Page: <ulink url="http://search.cpan.org/dist/GDTextUtil/"/>
Documentation: <ulink url="http://search.cpan.org/dist/GDTextUtil/Text/Align.pm"/>
</literallayout>
</para>
<para>
XML::Twig:
<literallayout>
CPAN Download Page: <ulink url="http://search.cpan.org/dist/XML-Twig/"/>
Documentation: <ulink url="http://standards.ieee.org/resources/spasystem/twig/twig_stable.html"/>
</literallayout>
</para>
<para>
PatchReader:
<literallayout>
CPAN Download Page: <ulink url="http://search.cpan.org/author/JKEISER/PatchReader/"/>
Documentation: <ulink url="http://www.johnkeiser.com/mozilla/Patch_Viewer.html"/>
</literallayout>
</para>
<para>
Image::Magick:
<literallayout>
CPAN Download Page: <ulink url="http://search.cpan.org/dist/PerlMagick/"/>
Documentation: <ulink url="http://www.imagemagick.org/script/resources.php"/>
</literallayout>
</para>
</section>
</appendix>

View File

@@ -1,135 +0,0 @@
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY % myents SYSTEM "bugzilla.ent">
%myents;
]>
<appendix id="patches" xreflabel="Useful Patches and Utilities for Bugzilla">
<title>Contrib</title>
<para>
There are a number of unofficial Bugzilla add-ons in the
<filename class="directory">$BUGZILLA_ROOT/contrib/</filename>
directory. This section documents them.
</para>
<section id="cmdline">
<title>Command-line Search Interface</title>
<para>
There are a suite of Unix utilities for searching Bugzilla from the
command line. They live in the
<filename class="directory">contrib/cmdline</filename> directory.
There are three files - <filename>query.conf</filename>,
<filename>buglist</filename> and <filename>bugs</filename>.
</para>
<warning>
<para>
These files pre-date the templatization work done as part of the
2.16 release, and have not been updated.
</para>
</warning>
<para>
<filename>query.conf</filename> contains the mapping from
options to field names and comparison types. Quoted option names
are <quote>grepped</quote> for, so it should be easy to edit this
file. Comments (#) have no effect; you must make sure these lines
do not contain any quoted <quote>option</quote>.
</para>
<para>
<filename>buglist</filename> is a shell script that submits a
Bugzilla query and writes the resulting HTML page to stdout.
It supports both short options, (such as <quote>-Afoo</quote>
or <quote>-Rbar</quote>) and long options (such
as <quote>--assignedto=foo</quote> or <quote>--reporter=bar</quote>).
If the first character of an option is not <quote>-</quote>, it is
treated as if it were prefixed with <quote>--default=</quote>.
</para>
<para>
The column list is taken from the COLUMNLIST environment variable.
This is equivalent to the <quote>Change Columns</quote> option
that is available when you list bugs in buglist.cgi. If you have
already used Bugzilla, grep for COLUMNLIST in your cookies file
to see your current COLUMNLIST setting.
</para>
<para>
<filename>bugs</filename> is a simple shell script which calls
<filename>buglist</filename> and extracts the
bug numbers from the output. Adding the prefix
<quote>http://bugzilla.mozilla.org/buglist.cgi?bug_id=</quote>
turns the bug list into a working link if any bugs are found.
Counting bugs is easy. Pipe the results through
<command>sed -e 's/,/ /g' | wc | awk '{printf $2 "\n"}'</command>
</para>
<para>
Akkana Peck says she has good results piping
<filename>buglist</filename> output through
<command>w3m -T text/html -dump</command>
</para>
</section>
<section id="cmdline-bugmail">
<title>Command-line 'Send Unsent Bug-mail' tool</title>
<para>
Within the <filename class="directory">contrib</filename> directory
exists a utility with the descriptive (if compact) name
of <filename>sendunsentbugmail.pl</filename>. The purpose of this
script is, simply, to send out any bug-related mail that should
have been sent by now, but for one reason or another has not.
</para>
<para>
To accomplish this task, <filename>sendunsentbugmail.pl</filename> uses
the same mechanism as the <filename>sanitycheck.cgi</filename> script;
it scans through the entire database looking for bugs with changes that
were made more than 30 minutes ago, but where there is no record of
anyone related to that bug having been sent mail. Having compiled a list,
it then uses the standard rules to determine who gets mail, and sends it
out.
</para>
<para>
As the script runs, it indicates the bug for which it is currently
sending mail; when it has finished, it gives a numerical count of how
many mails were sent and how many people were excluded. (Individual
user names are not recorded or displayed.) If the script produces
no output, that means no unsent mail was detected.
</para>
<para>
<emphasis>Usage</emphasis>: move the sendunsentbugmail.pl script
up into the main directory, ensure it has execute permission, and run it
from the command line (or from a cron job) with no parameters.
</para>
</section>
</appendix>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-always-quote-attributes:t
sgml-auto-insert-required-elements:t
sgml-balanced-tag-edit:t
sgml-exposed-tags:nil
sgml-general-insert-case:lower
sgml-indent-data:t
sgml-indent-step:2
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
sgml-minimize-attributes:nil
sgml-namecase-general:t
sgml-omittag:t
sgml-parent-document:("Bugzilla-Guide.xml" "book" "chapter")
sgml-shorttag:t
sgml-tag-region-if-active:t
End:
-->

View File

@@ -1,77 +0,0 @@
<!-- <!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook V4.1//EN"> -->
<appendix id="downloadlinks">
<title>Software Download Links</title>
<para>All of these sites are current as of April, 2001. Hopefully they'll
stay current for a while.</para>
<para>Apache Web Server:
<ulink url="http://www.apache.org/"/>
Optional web server for Bugzilla, but recommended because of broad user
base and support.</para>
<para>Bugzilla:
<ulink url="http://www.bugzilla.org/"/>
</para>
<para>MySQL:
<ulink url="http://www.mysql.com/"/>
</para>
<para>Perl:
<ulink url="http://www.perl.org/"/>
</para>
<para>CPAN:
<ulink url="http://www.cpan.org/"/>
</para>
<para>DBI Perl module:
<ulink url="http://www.cpan.org/modules/by-module/DBI/"/>
</para>
<para>MySQL related Perl modules:
<ulink url="http://www.cpan.org/modules/by-module/Mysql/"/>
</para>
<para>TimeDate Perl module collection:
<ulink url="http://www.cpan.org/modules/by-module/Date/"/>
</para>
<para>GD Perl module:
<ulink url="http://www.cpan.org/modules/by-module/GD/"/>
Alternately, you should be able to find the latest version of GD at
<ulink url="http://www.boutell.com/gd/"/>
</para>
<para>Chart::Base module:
<ulink url="http://www.cpan.org/modules/by-module/Chart/"/>
</para>
<para>(But remember, Bundle::Bugzilla will install all the modules for you.)
</para>
</appendix>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-always-quote-attributes:t
sgml-auto-insert-required-elements:t
sgml-balanced-tag-edit:t
sgml-exposed-tags:nil
sgml-general-insert-case:lower
sgml-indent-data:t
sgml-indent-step:2
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
sgml-minimize-attributes:nil
sgml-namecase-general:t
sgml-omittag:t
sgml-parent-document:("Bugzilla-Guide.xml" "book" "chapter")
sgml-shorttag:t
sgml-tag-region-if-active:t
End:
-->

View File

@@ -1,364 +0,0 @@
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY % myents SYSTEM "bugzilla.ent">
%myents;
]>
<!-- $Id: security.xml,v 1.19.2.1 2008-07-13 16:44:28 mozilla%colinogilvie.co.uk Exp $ -->
<chapter id="security">
<title>Bugzilla Security</title>
<para>While some of the items in this chapter are related to the operating
system Bugzilla is running on or some of the support software required to
run Bugzilla, it is all related to protecting your data. This is not
intended to be a comprehensive guide to securing Linux, Apache, MySQL, or
any other piece of software mentioned. There is no substitute for active
administration and monitoring of a machine. The key to good security is
actually right in the middle of the word: <emphasis>U R It</emphasis>.
</para>
<para>While programmers in general always strive to write secure code,
accidents can and do happen. The best approach to security is to always
assume that the program you are working with isn't 100% secure and restrict
its access to other parts of your machine as much as possible.
</para>
<section id="security-os">
<title>Operating System</title>
<section id="security-os-ports">
<title>TCP/IP Ports</title>
<!-- TODO: Get exact number of ports -->
<para>The TCP/IP standard defines more than 65,000 ports for sending
and receiving traffic. Of those, Bugzilla needs exactly one to operate
(different configurations and options may require up to 3). You should
audit your server and make sure that you aren't listening on any ports
you don't need to be. It's also highly recommended that the server
Bugzilla resides on, along with any other machines you administer, be
placed behind some kind of firewall.
</para>
</section>
<section id="security-os-accounts">
<title>System User Accounts</title>
<para>Many <glossterm linkend="gloss-daemon">daemons</glossterm>, such
as Apache's <filename>httpd</filename> or MySQL's
<filename>mysqld</filename>, run as either <quote>root</quote> or
<quote>nobody</quote>. This is even worse on Windows machines where the
majority of <glossterm linkend="gloss-service">services</glossterm>
run as <quote>SYSTEM</quote>. While running as <quote>root</quote> or
<quote>SYSTEM</quote> introduces obvious security concerns, the
problems introduced by running everything as <quote>nobody</quote> may
not be so obvious. Basically, if you run every daemon as
<quote>nobody</quote> and one of them gets compromised it can
compromise every other daemon running as <quote>nobody</quote> on your
machine. For this reason, it is recommended that you create a user
account for each daemon.
</para>
<note>
<para>You will need to set the <option>webservergroup</option> option
in <filename>localconfig</filename> to the group your web server runs
as. This will allow <filename>./checksetup.pl</filename> to set file
permissions on Unix systems so that nothing is world-writable.
</para>
</note>
</section>
<section id="security-os-chroot">
<title>The <filename>chroot</filename> Jail</title>
<para>
If your system supports it, you may wish to consider running
Bugzilla inside of a <filename>chroot</filename> jail. This option
provides unprecedented security by restricting anything running
inside the jail from accessing any information outside of it. If you
wish to use this option, please consult the documentation that came
with your system.
</para>
</section>
</section>
<section id="security-mysql">
<title>MySQL</title>
<section id="security-mysql-account">
<title>The MySQL System Account</title>
<para>As mentioned in <xref linkend="security-os-accounts"/>, the MySQL
daemon should run as a non-privileged, unique user. Be sure to consult
the MySQL documentation or the documentation that came with your system
for instructions.
</para>
</section>
<section id="security-mysql-root">
<title>The MySQL <quote>root</quote> and <quote>anonymous</quote> Users</title>
<para>By default, MySQL comes with a <quote>root</quote> user with a
blank password and an <quote>anonymous</quote> user, also with a blank
password. In order to protect your data, the <quote>root</quote> user
should be given a password and the anonymous user should be disabled.
</para>
<example id="security-mysql-account-root">
<title>Assigning the MySQL <quote>root</quote> User a Password</title>
<screen>
<prompt>bash$</prompt> mysql mysql
<prompt>mysql&gt;</prompt> UPDATE user SET password = password('<replaceable>new_password</replaceable>') WHERE user = 'root';
<prompt>mysql&gt;</prompt> FLUSH PRIVILEGES;
</screen>
</example>
<example id="security-mysql-account-anonymous">
<title>Disabling the MySQL <quote>anonymous</quote> User</title>
<screen>
<prompt>bash$</prompt> mysql -u root -p mysql <co id="security-mysql-account-anonymous-mysql"/>
<prompt>Enter Password:</prompt> <replaceable>new_password</replaceable>
<prompt>mysql&gt;</prompt> DELETE FROM user WHERE user = '';
<prompt>mysql&gt;</prompt> FLUSH PRIVILEGES;
</screen>
<calloutlist>
<callout arearefs="security-mysql-account-anonymous-mysql">
<para>This command assumes that you have already completed
<xref linkend="security-mysql-account-root"/>.
</para>
</callout>
</calloutlist>
</example>
</section>
<section id="security-mysql-network">
<title>Network Access</title>
<para>If MySQL and your web server both run on the same machine and you
have no other reason to access MySQL remotely, then you should disable
the network access. This, along with the suggestion in
<xref linkend="security-os-ports"/>, will help protect your system from
any remote vulnerabilities in MySQL.
</para>
<example id="security-mysql-network-ex">
<title>Disabling Networking in MySQL</title>
<para>Simply enter the following in <filename>/etc/my.cnf</filename>:
<screen>
[mysqld]
# Prevent network access to MySQL.
skip-networking
</screen>
</para>
</example>
</section>
<!-- For possible addition in the future: How to better control the bugs user
<section id="security-mysql-bugs">
<title>The bugs User</title>
</section>
-->
</section>
<section id="security-webserver">
<title>Web server</title>
<section id="security-webserver-access">
<title>Disabling Remote Access to Bugzilla Configuration Files</title>
<para>
There are many files that are placed in the Bugzilla directory
area that should not be accessible from the web server. Because of the way
Bugzilla is currently layed out, the list of what should and should not
be accessible is rather complicated. A quick way is to run
<filename>testserver.pl</filename> to check if your web server serves
Bugzilla files as expected. If not, you may want to follow the few
steps below.
</para>
<tip>
<para>Bugzilla ships with the ability to create
<glossterm linkend="gloss-htaccess"><filename>.htaccess</filename></glossterm>
files that enforce these rules. Instructions for enabling these
directives in Apache can be found in <xref linkend="http-apache"/>
</para>
</tip>
<itemizedlist spacing="compact">
<listitem>
<para>In the main Bugzilla directory, you should:</para>
<itemizedlist spacing="compact">
<listitem>
<para>Block:
<simplelist type="inline">
<member><filename>*.pl</filename></member>
<member><filename>*localconfig*</filename></member>
</simplelist>
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para>In <filename class="directory">data</filename>:</para>
<itemizedlist spacing="compact">
<listitem>
<para>Block everything</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para>In <filename class="directory">data/webdot</filename>:</para>
<itemizedlist spacing="compact">
<listitem>
<para>If you use a remote webdot server:</para>
<itemizedlist spacing="compact">
<listitem>
<para>Block everything</para>
</listitem>
<listitem>
<para>But allow
<simplelist type="inline">
<member><filename>*.dot</filename></member>
</simplelist>
only for the remote webdot server</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para>Otherwise, if you use a local GraphViz:</para>
<itemizedlist spacing="compact">
<listitem>
<para>Block everything</para>
</listitem>
<listitem>
<para>But allow:
<simplelist type="inline">
<member><filename>*.png</filename></member>
<member><filename>*.gif</filename></member>
<member><filename>*.jpg</filename></member>
<member><filename>*.map</filename></member>
</simplelist>
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para>And if you don't use any dot:</para>
<itemizedlist spacing="compact">
<listitem>
<para>Block everything</para>
</listitem>
</itemizedlist>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para>In <filename class="directory">Bugzilla</filename>:</para>
<itemizedlist spacing="compact">
<listitem>
<para>Block everything</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para>In <filename class="directory">template</filename>:</para>
<itemizedlist spacing="compact">
<listitem>
<para>Block everything</para>
</listitem>
</itemizedlist>
</listitem>
</itemizedlist>
<para>Be sure to test that data that should not be accessed remotely is
properly blocked. Of particular interest is the localconfig file which
contains your database password. Also, be aware that many editors
create temporary and backup files in the working directory and that
those should also not be accessible. For more information, see
<ulink url="http://bugzilla.mozilla.org/show_bug.cgi?id=186383">bug 186383</ulink>
or
<ulink url="http://online.securityfocus.com/bid/6501">Bugtraq ID 6501</ulink>.
To test, simply run <filename>testserver.pl</filename>, as said above.
</para>
<tip>
<para>Be sure to check <xref linkend="http"/> for instructions
specific to the web server you use.
</para>
</tip>
</section>
</section>
<section id="security-bugzilla">
<title>Bugzilla</title>
<section id="security-bugzilla-charset">
<title>Prevent users injecting malicious Javascript</title>
<para>If you installed Bugzilla version 2.22 or later from scratch,
then the <emphasis>utf8</emphasis> parameter is switched on by default.
This makes Bugzilla explicitly set the character encoding, following
<ulink
url="http://www.cert.org/tech_tips/malicious_code_mitigation.html#3">a
CERT advisory</ulink> recommending exactly this.
The following therefore does not apply to you; just keep
<emphasis>utf8</emphasis> turned on.
</para>
<para>If you've upgraded from an older version, then it may be possible
for a Bugzilla user to take advantage of character set encoding
ambiguities to inject HTML into Bugzilla comments.
This could include malicious scripts.
This is because due to internationalization concerns, we are unable to
turn the <emphasis>utf8</emphasis> parameter on by default for upgraded
installations.
Turning it on manually will prevent this problem.
</para>
</section>
</section>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-always-quote-attributes:t
sgml-auto-insert-required-elements:t
sgml-balanced-tag-edit:t
sgml-exposed-tags:nil
sgml-general-insert-case:lower
sgml-indent-data:t
sgml-indent-step:2
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
sgml-minimize-attributes:nil
sgml-namecase-general:t
sgml-omittag:t
sgml-parent-document:("Bugzilla-Guide.xml" "book" "chapter")
sgml-shorttag:t
sgml-tag-region-if-active:t
End: -->

View File

@@ -1,311 +0,0 @@
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY % myents SYSTEM "bugzilla.ent">
%myents;
]>
<!-- $Id: troubleshooting.xml,v 1.13.4.1 2008-07-13 16:44:28 mozilla%colinogilvie.co.uk Exp $ -->
<appendix id="troubleshooting">
<title>Troubleshooting</title>
<para>This section gives solutions to common Bugzilla installation
problems. If none of the section headings seems to match your
problem, read the general advice.
</para>
<section id="general-advice">
<title>General Advice</title>
<para>If you can't get <filename>checksetup.pl</filename> to run to
completion, it normally explains what's wrong and how to fix it.
If you can't work it out, or if it's being uncommunicative, post
the errors in the
<ulink url="news://news.mozilla.org/mozilla.support.bugzilla">mozilla.support.bugzilla</ulink>
newsgroup.
</para>
<para>If you have made it all the way through
<xref linkend="installation"/> (Installation) and
<xref linkend="configuration"/> (Configuration) but accessing the Bugzilla
URL doesn't work, the first thing to do is to check your web server error
log. For Apache, this is often located at
<filename>/etc/logs/httpd/error_log</filename>. The error messages
you see may be self-explanatory enough to enable you to diagnose and
fix the problem. If not, see below for some commonly-encountered
errors. If that doesn't help, post the errors to the newsgroup.
</para>
<para>
Bugzilla can also log all user-based errors (and many code-based errors)
that occur, without polluting the web server's error log. To enable
Bugzilla error logging, create a file that Bugzilla can write to, named
<filename>errorlog</filename>, in the Bugzilla <filename>data</filename>
directory. Errors will be logged as they occur, and will include the type
of the error, the IP address and username (if available) of the user who
triggered the error, and the values of all environment variables; if a
form was being submitted, the data in the form will also be included.
To disable error logging, delete or rename the
<filename>errorlog</filename> file.
</para>
</section>
<section id="trbl-testserver">
<title>The Apache web server is not serving Bugzilla pages</title>
<para>After you have run <command>checksetup.pl</command> twice,
run <command>testserver.pl http://yoursite.yourdomain/yoururl</command>
to confirm that your web server is configured properly for
Bugzilla.
</para>
<programlisting>
<prompt>bash$</prompt> ./testserver.pl http://landfill.bugzilla.org/bugzilla-tip
TEST-OK Webserver is running under group id in $webservergroup.
TEST-OK Got ant picture.
TEST-OK Webserver is executing CGIs.
TEST-OK Webserver is preventing fetch of http://landfill.bugzilla.org/bugzilla-tip/localconfig.
</programlisting>
</section>
<section id="trbl-perlmodule">
<title>I installed a Perl module, but
<filename>checksetup.pl</filename> claims it's not installed!</title>
<para>This could be caused by one of two things:</para>
<orderedlist>
<listitem>
<para>You have two versions of Perl on your machine. You are installing
modules into one, and Bugzilla is using the other. Rerun the CPAN
commands (or manual compile) using the full path to Perl from the
top of <filename>checksetup.pl</filename>. This will make sure you
are installing the modules in the right place.
</para>
</listitem>
<listitem>
<para>The permissions on your library directories are set incorrectly.
They must, at the very least, be readable by the web server user or
group. It is recommended that they be world readable.
</para>
</listitem>
</orderedlist>
</section>
<section id="trbl-dbdSponge">
<title>DBD::Sponge::db prepare failed</title>
<para>The following error message may appear due to a bug in DBD::mysql
(over which the Bugzilla team have no control):
</para>
<programlisting><![CDATA[ DBD::Sponge::db prepare failed: Cannot determine NUM_OF_FIELDS at D:/Perl/site/lib/DBD/mysql.pm line 248.
SV = NULL(0x0) at 0x20fc444
REFCNT = 1
FLAGS = (PADBUSY,PADMY)
]]></programlisting>
<para>To fix this, go to
<filename>&lt;path-to-perl&gt;/lib/DBD/sponge.pm</filename>
in your Perl installation and replace
</para>
<programlisting><![CDATA[ my $numFields;
if ($attribs->{'NUM_OF_FIELDS'}) {
$numFields = $attribs->{'NUM_OF_FIELDS'};
} elsif ($attribs->{'NAME'}) {
$numFields = @{$attribs->{NAME}};
]]></programlisting>
<para>with</para>
<programlisting><![CDATA[ my $numFields;
if ($attribs->{'NUM_OF_FIELDS'}) {
$numFields = $attribs->{'NUM_OF_FIELDS'};
} elsif ($attribs->{'NAMES'}) {
$numFields = @{$attribs->{NAMES}};
]]></programlisting>
<para>(note the S added to NAME.)</para>
</section>
<section id="paranoid-security">
<title>cannot chdir(/var/spool/mqueue)</title>
<para>If you are installing Bugzilla on SuSE Linux, or some other
distributions with <quote>paranoid</quote> security options, it is
possible that the checksetup.pl script may fail with the error:
<programlisting><![CDATA[cannot chdir(/var/spool/mqueue): Permission denied
]]></programlisting>
</para>
<para>This is because your <filename>/var/spool/mqueue</filename>
directory has a mode of <computeroutput>drwx------</computeroutput>.
Type <command>chmod 755 <filename>/var/spool/mqueue</filename></command>
as root to fix this problem. This will allow any process running on your
machine the ability to <emphasis>read</emphasis> the
<filename>/var/spool/mqueue</filename> directory.
</para>
</section>
<section id="trbl-relogin-everyone">
<title>Everybody is constantly being forced to relogin</title>
<para>The most-likely cause is that the <quote>cookiepath</quote> parameter
is not set correctly in the Bugzilla configuration. You can change this (if
you're a Bugzilla administrator) from the editparams.cgi page via the web interface.
</para>
<para>The value of the cookiepath parameter should be the actual directory
containing your Bugzilla installation, <emphasis>as seen by the end-user's
web browser</emphasis>. Leading and trailing slashes are mandatory. You can
also set the cookiepath to any directory which is a parent of the Bugzilla
directory (such as '/', the root directory). But you can't put something
that isn't at least a partial match or it won't work. What you're actually
doing is restricting the end-user's browser to sending the cookies back only
to that directory.
</para>
<para>How do you know if you want your specific Bugzilla directory or the
whole site?
</para>
<para>If you have only one Bugzilla running on the server, and you don't
mind having other applications on the same server with it being able to see
the cookies (you might be doing this on purpose if you have other things on
your site that share authentication with Bugzilla), then you'll want to have
the cookiepath set to "/", or to a sufficiently-high enough directory that
all of the involved apps can see the cookies.
</para>
<example id="trbl-relogin-everyone-share">
<title>Examples of urlbase/cookiepath pairs for sharing login cookies</title>
<blockquote>
<literallayout>
urlbase is <ulink url="http://bugzilla.mozilla.org/"/>
cookiepath is /
urlbase is <ulink url="http://tools.mysite.tld/bugzilla/"/>
but you have http://tools.mysite.tld/someotherapp/ which shares
authentication with your Bugzilla
cookiepath is /
</literallayout>
</blockquote>
</example>
<para>On the other hand, if you have more than one Bugzilla running on the
server (some people do - we do on landfill) then you need to have the
cookiepath restricted enough so that the different Bugzillas don't
confuse their cookies with one another.
</para>
<example id="trbl-relogin-everyone-restrict">
<title>Examples of urlbase/cookiepath pairs to restrict the login cookie</title>
<blockquote>
<literallayout>
urlbase is <ulink url="http://landfill.bugzilla.org/bugzilla-tip/"/>
cookiepath is /bugzilla-tip/
urlbase is <ulink url="http://landfill.bugzilla.org/bugzilla-2.16-branch/"/>
cookiepath is /bugzilla-2.16-branch/
</literallayout>
</blockquote>
</example>
<para>If you had cookiepath set to <quote>/</quote> at any point in the
past and need to set it to something more restrictive
(i.e. <quote>/bugzilla/</quote>), you can safely do this without
requiring users to delete their Bugzilla-related cookies in their
browser (this is true starting with Bugzilla 2.18 and Bugzilla 2.16.5).
</para>
</section>
<section id="trbl-relogin-some">
<title>Some users are constantly being forced to relogin</title>
<para>First, make sure cookies are enabled in the user's browser.
</para>
<para>If that doesn't fix the problem, it may be that the user's ISP
implements a rotating proxy server. This causes the user's effective IP
address (the address which the Bugzilla server perceives him coming from)
to change periodically. Since Bugzilla cookies are tied to a specific IP
address, each time the effective address changes, the user will have to
log in again.
</para>
<para>If you are using 2.18 (or later), there is a
parameter called <quote>loginnetmask</quote>, which you can use to set
the number of bits of the user's IP address to require to be matched when
authenticating the cookies. If you set this to something less than 32,
then the user will be given a checkbox for <quote>Restrict this login to
my IP address</quote> on the login screen, which defaults to checked. If
they leave the box checked, Bugzilla will behave the same as it did
before, requiring an exact match on their IP address to remain logged in.
If they uncheck the box, then only the left side of their IP address (up
to the number of bits you specified in the parameter) has to match to
remain logged in.
</para>
</section>
<section id="trbl-index">
<title><filename>index.cgi</filename> doesn't show up unless specified in the URL</title>
<para>
You probably need to set up your web server in such a way that it
will serve the index.cgi page as an index page.
</para>
<para>
If you are using Apache, you can do this by adding
<filename>index.cgi</filename> to the end of the
<computeroutput>DirectoryIndex</computeroutput> line
as mentioned in <xref linkend="http-apache"/>.
</para>
</section>
<section id="trbl-passwd-encryption">
<title>
checksetup.pl reports "Client does not support authentication protocol
requested by server..."
</title>
<para>
This error is occurring because you are using the new password
encryption that comes with MySQL 4.1, while your
<filename>DBD::mysql</filename> module was compiled against an
older version of MySQL. If you recompile <filename>DBD::mysql</filename>
against the current MySQL libraries (or just obtain a newer version
of this module) then the error may go away.
</para>
<para>
If that does not fix the problem, or if you cannot recompile the
existing module (e.g. you're running Windows) and/or don't want to
replace it (e.g. you want to keep using a packaged version), then a
workaround is available from the MySQL docs:
<ulink url="http://dev.mysql.com/doc/mysql/en/Old_client.html"/>
</para>
</section>
</appendix>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-always-quote-attributes:t
sgml-auto-insert-required-elements:t
sgml-balanced-tag-edit:t
sgml-exposed-tags:nil
sgml-general-insert-case:lower
sgml-indent-data:t
sgml-indent-step:2
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
sgml-minimize-attributes:nil
sgml-namecase-general:t
sgml-omittag:t
sgml-parent-document:("Bugzilla-Guide.xml" "book" "chapter")
sgml-shorttag:t
sgml-tag-region-if-active:t
End: -->

File diff suppressed because it is too large Load Diff

View File

@@ -1,217 +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 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): Matthew Tuck <matty@chariot.net.au>
# Jacob Steenhagen <jake@bugzilla.org>
# Colin Ogilvie <colin.ogilvie@gmail.com>
# Max Kanat-Alexander <mkanat@bugzilla.org>
# This script compiles all the documentation.
use strict;
use Cwd;
# We need to be in this directory to use our libraries.
BEGIN {
require File::Basename;
import File::Basename qw(dirname);
chdir dirname($0);
}
use lib qw(.. ../lib lib);
# We only compile our POD if Pod::Simple is installed. We do the checks
# this way so that if there's a compile error in Pod::Simple::HTML::Bugzilla,
# makedocs doesn't just silently fail, but instead actually tells us there's
# a compile error.
my $pod_simple;
if (eval { require Pod::Simple }) {
require Pod::Simple::HTMLBatch::Bugzilla;
require Pod::Simple::HTML::Bugzilla;
$pod_simple = 1;
};
use Bugzilla::Install::Requirements
qw(REQUIRED_MODULES OPTIONAL_MODULES);
use Bugzilla::Constants qw(DB_MODULE BUGZILLA_VERSION);
###############################################################################
# Generate minimum version list
###############################################################################
my $modules = REQUIRED_MODULES;
my $opt_modules = OPTIONAL_MODULES;
open(ENTITIES, '>', 'bugzilla.ent') or die('Could not open bugzilla.ent: ' . $!);
print ENTITIES <<END_ENTITIES;
<?xml version="1.0" encoding="UTF-8" ?>
<!ENTITY bz-ver "3.3">
<!ENTITY bz-nextver "4.0">
<!ENTITY bz-date "2008-05-20">
<!ENTITY current-year "2008">
<!ENTITY landfillbase "http://landfill.bugzilla.org/bugzilla-tip/">
<!ENTITY bz "http://www.bugzilla.org/">
<!ENTITY bzg-bugs "<ulink url='https://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla&amp;component=Documentation'>Bugzilla Documentation</ulink>">
<!ENTITY mysql "http://www.mysql.com/">
<!ENTITY min-perl-ver "5.8.1">
<!-- Module Versions -->
END_ENTITIES
foreach my $module (@$modules, @$opt_modules)
{
my $name = $module->{'module'};
$name =~ s/::/-/g;
$name = lc($name);
#This needs to be a string comparison, due to the modules having
#version numbers like 0.9.4
my $version = $module->{'version'} eq 0 ? 'any' : $module->{'version'};
print ENTITIES '<!ENTITY min-' . $name . '-ver "'.$version.'">' . "\n";
}
# CGI is a special case, because for Perl versions below 5.10, it has an
# optional version *and* a required version.
# We check @opt_modules first, then @modules, and pick the first we get.
# We'll get the optional one then, if it is given, otherwise the required one.
my ($cgi_opt) = grep($_->{module} eq 'CGI', @$opt_modules, @$modules);
print ENTITIES '<!ENTITY min-mp-cgi-ver "' . $cgi_opt->{version} . '">' . "\n";
print ENTITIES "\n <!-- Database Versions --> \n";
my $db_modules = DB_MODULE;
foreach my $db (keys %$db_modules) {
my $dbd = $db_modules->{$db}->{dbd};
my $name = $dbd->{module};
$name =~ s/::/-/g;
$name = lc($name);
my $version = $dbd->{version} || 'any';
my $db_version = $db_modules->{$db}->{'db_version'};
print ENTITIES '<!ENTITY min-' . $name . '-ver "'.$version.'">' . "\n";
print ENTITIES '<!ENTITY min-' . lc($db) . '-ver "'.$db_version.'">' . "\n";
}
close(ENTITIES);
###############################################################################
# Subs
###############################################################################
sub MakeDocs {
my ($name, $cmdline) = @_;
print "Creating $name documentation ...\n" if defined $name;
print "$cmdline\n\n";
system $cmdline;
print "\n";
}
sub make_pod {
print "Creating API documentation...\n";
my $converter = Pod::Simple::HTMLBatch::Bugzilla->new;
# Don't output progress information.
$converter->verbose(0);
$converter->html_render_class('Pod::Simple::HTML::Bugzilla');
my $doctype = Pod::Simple::HTML::Bugzilla->DOCTYPE;
my $content_type = Pod::Simple::HTML::Bugzilla->META_CT;
my $bz_version = BUGZILLA_VERSION;
my $contents_start = <<END_HTML;
$doctype
<html>
<head>
$content_type
<title>Bugzilla $bz_version API Documentation</title>
</head>
<body class="contentspage">
<h1>Bugzilla $bz_version API Documentation</h1>
END_HTML
$converter->contents_page_start($contents_start);
$converter->contents_page_end("</body></html>");
$converter->add_css('./../../../style.css');
$converter->javascript_flurry(0);
$converter->css_flurry(0);
$converter->batch_convert(['../../'], 'html/api/');
print "\n";
}
###############################################################################
# Make the docs ...
###############################################################################
my @langs;
# search for sub directories which have a 'xml' sub-directory
opendir(LANGS, './');
foreach my $dir (readdir(LANGS)) {
next if (($dir eq '.') || ($dir eq '..') || (! -d $dir));
if (-d "$dir/xml") {
push(@langs, $dir);
}
}
closedir(LANGS);
my $docparent = getcwd();
foreach my $lang (@langs) {
chdir "$docparent/$lang";
MakeDocs(undef, 'cp ../bugzilla.ent ./xml/');
if (!-d 'txt') {
unlink 'txt';
mkdir 'txt', 0755;
}
if (!-d 'pdf') {
unlink 'pdf';
mkdir 'pdf', 0755;
}
if (!-d 'html') {
unlink 'html';
mkdir 'html', 0755;
}
if (!-d 'html/api') {
unlink 'html/api';
mkdir 'html/api', 0755;
}
MakeDocs(undef, 'cp ../style.css html/api/');
make_pod() if $pod_simple;
MakeDocs('separate HTML', 'xmlto -m ../xsl/chunks.xsl -o html html ' .
'xml/Bugzilla-Guide.xml');
MakeDocs('big HTML', 'xmlto -m ../xsl/nochunks.xsl -o html html-nochunks ' .
'xml/Bugzilla-Guide.xml');
MakeDocs('big text', "lynx -dump -justify=off -nolist html/Bugzilla-Guide.html " .
"> txt/Bugzilla-Guide.txt");
if (! grep($_ eq "--with-pdf", @ARGV)) {
next;
}
MakeDocs('PDF', 'xmlto -m ../xsl/pdf.xsl -o pdf pdf xml/Bugzilla-Guide.xml');
}

View File

@@ -1,112 +0,0 @@
/* 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 Everything Solved.
* Portions created by Everything Solved are Copyright (C) 2006
* Everything Solved. All Rights Reserved.
*
* Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org>
*/
body {
background: white;
color: #111;
padding: 0 1em;
margin: 0;
font-family: Verdana, Arial, sans-serif;
font-size: small;
}
td, th {
font-family: Verdana, Arial, sans-serif;
font-size: small;
}
a:link, a:active { color: #36415c; }
a:visited { color: #666; }
a:hover { color: #888; }
h1 {
font-size: 150%;
font-weight: bold;
border-bottom: 2px solid #ccc;
}
h2 {
font-size: 125%;
font-weight: bold;
border-bottom: 1px solid #ccc;
margin-bottom: 8px;
}
h3 {
font-size: 115%;
font-weight: bold;
margin-bottom: 0;
padding-bottom: 0;
}
/* This makes Description/Params/Returns look nice. */
dd { margin-top: .2em; }
dd p { margin-top: 0; }
dl { margin-bottom: 1em; }
/* This makes the names of functions slightly larger, in Gecko. */
body > dl > dt code { font-size: 1.35em; }
#pod h1 a, #pod h2 a, #pod h3 a {
color: #36415c;
text-decoration: none;
}
pre, code, tt, kbd, samp {
/* Unfortunately, the default monospace fonts on most browsers
look odd with relative sizing. */
font-size: 12px;
}
.code {
background: #eed;
border: 1px solid #ccc;
}
pre.code {
margin-left: 10px;
width: 90%;
padding: 10px;
}
/* Special styles for the Contents page */
.contentspage dt {
font-size: large;
font-weight: bold;
}
.pod_desc_table {
border-collapse: collapse;
table-layout: auto;
border: 1px solid #ccc;
}
.pod_desc_table th {
text-align: left;
}
.pod_desc_table td, .pod_desc_table th {
padding: .25em;
border-top: 1px solid #ccc;
}
.pod_desc_table .odd th, .pod_desc_table .odd td {
background-color: #eee;
}
.pod_desc_table

View File

@@ -1,102 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- Nicer Filenames -->
<xsl:param name="use.id.as.filename" select="1"/>
<!-- Label sections if they aren't automatically labeled -->
<xsl:param name="section.autolabel" select="1"/>
<!-- Table of Contents Depth -->
<xsl:param name="toc.section.depth">1</xsl:param>
<!-- Set chunk parameters -->
<xsl:param name="chunk.section.depth" select="1"/>
<xsl:param name="chunk.first.sections" select="1"/>
<xsl:param name="chunker.output.encoding" select="UTF-8"/>
<!-- Show titles of next/previous page -->
<xsl:param name="navig.showtitles">1</xsl:param>
<!-- Tidy up the HTML a bit... -->
<xsl:param name="html.cleanup" select="1"/>
<xsl:param name="make.valid.html" select="1"/>
<xsl:param name="html.stylesheet">api/style.css</xsl:param>
<!-- make links nicer... -->
<xsl:param name="refentry.generate.title" select="1"/>
<xsl:param name="refentry.generate.name" select="0"/>
<!-- Use Graphics, specify their Path and Extension -->
<xsl:param name="admon.graphics" select="1"/>
<xsl:param name="admon.graphics.path">../images/</xsl:param>
<xsl:param name="admon.graphics.extension">.gif</xsl:param>
<xsl:param name="qanda.inherit.numeration" select="0" />
<!--
****
CODE BELOW HERE IS EXTRACTED AND EDITED FROM THE DOCBOOK XSL SOURCES
****
-->
<xsl:template match="simplelist[@type='inline']/member">
<xsl:apply-templates/>
</xsl:template>
<!--
To generate valid HTML, we need to redefine this section... Code extracted from
http://cvs.sourceforge.net/viewcvs.py/docbook/xsl/html/qandaset.xsl?rev=1.19&view=log
and modified below. Basic change: Remove the colspan attribute of the tr tags - no
other changes have been made to the document.
-->
<xsl:template match="qandadiv">
<xsl:variable name="preamble" select="*[name(.) != 'title'
and name(.) != 'titleabbrev'
and name(.) != 'qandadiv'
and name(.) != 'qandaentry']"/>
<xsl:if test="blockinfo/title|title">
<tr class="qandadiv">
<td align="left" valign="top" colspan="2">
<xsl:call-template name="anchor">
<xsl:with-param name="conditional" select="0"/>
</xsl:call-template>
<xsl:apply-templates select="(blockinfo/title|title)[1]"/>
</td>
</tr>
</xsl:if>
<xsl:variable name="toc">
<xsl:call-template name="dbhtml-attribute">
<xsl:with-param name="pis"
select="processing-instruction('dbhtml')"/>
<xsl:with-param name="attribute" select="'toc'"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="toc.params">
<xsl:call-template name="find.path.params">
<xsl:with-param name="table" select="normalize-space($generate.toc)"/>
</xsl:call-template>
</xsl:variable>
<xsl:if test="(contains($toc.params, 'toc') and $toc != '0') or $toc = '1'">
<tr class="toc">
<td align="left" valign="top" colspan="2">
<xsl:call-template name="process.qanda.toc"/>
</td>
</tr>
</xsl:if>
<xsl:if test="$preamble">
<tr class="toc" >
<td align="left" valign="top" colspan="2">
<xsl:apply-templates select="$preamble"/>
</td>
</tr>
</xsl:if>
<xsl:apply-templates select="qandadiv|qandaentry"/>
</xsl:template>
</xsl:stylesheet>

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- Include default bugzilla XSL -->
<xsl:include href="bugzilla-docs.xsl"/>
<!-- Set Chunk Specific XSL Params -->
<xsl:param name="chunker.output.doctype-public">-//W3C//DTD HTML 4.01 Transitional//EN</xsl:param>
<xsl:param name="chunker.output.doctype-system">http://www.w3.org/TR/html4/loose.dtd</xsl:param>
<xsl:param name="chunk.section.depth" select="1"/>
<xsl:param name="chunk.first.sections" select="1"/>
<!-- Don't output filename list - mimic old behaviour-->
<xsl:param name="chunk.quietly" select="0" />
</xsl:stylesheet>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- Include default bugzilla XSL -->
<xsl:include href="bugzilla-docs.xsl"/>
<!-- No other params necessary -->
</xsl:stylesheet>

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" version="1.0">
<!-- Enable passivetex extensions -->
<xsl:param name="passivetex.extensions" select="1"/>
<xsl:param name="tablecolumns.extensions" select="1"/>
<!-- Show <ulink>s as footnotes -->
<xsl:param name="ulink.footnotes" select="1" />
<xsl:param name="ulink.show" select="1" />
<!-- Don't use Graphics -->
<xsl:param name="admon.graphics" select="0"/>
<xsl:param name="callout.graphics" select="'0'"/>
<xsl:template match="simplelist[@type='inline']/member">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>

View File

@@ -0,0 +1,239 @@
function createShortcuts()
{
var subkey;
var valname;
var szStartMenuPrograms;
var szStartMenu;
var szFolderDesktop;
var szFolderQuickLaunch;
var szFolderSendTo;
var winreg;
var fWindows;
var fTemp;
var fCommunicator;
var fileExe;
var scExeDesc;
var scProfileDesc;
var scProfileDescParam;
var scFolderName;
var fFolderPath;
var fFolderPathStr;
var is_winnt;
var szCurrentVersion;
winreg = getWinRegistry();
fWindows = getFolder("Windows");
fCommunicator = getFolder("Communicator");
fTemp = fCommunicator + "\\mozilla.exe";
fileExe = getFolder("file:///", fTemp);
scExeDesc = "Mozilla Seamonkey";
scProfileDesc = "Profile Manager";
scProfileDescParam = "-ProfileManager";
scFolderName = "Mozilla Seamonkey";
if(winreg != null)
{
winreg.setRootKey(winreg.HKEY_LOCAL_MACHINE);
subkey = "SOFTWARE\\Mozilla\\Mozilla Seamonkey\\$UserAgent$\\Main";
valname = "Program Folder Path";
fFolderPathStr = winreg.getValueString(subkey, valname);
if((fFolderPathStr == "") || (fFolderPathStr == null))
{
/* determine if the script is running under NT or not */
winreg.setRootKey(winreg.HKEY_LOCAL_MACHINE);
subkey = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";
valname = "CurrentVersion";
szCurrentVersion = winreg.getValueString(subkey, valname);
logComment("szCurrentVersion: " + szCurrentVersion);
if((szCurrentVersion == "") || (szCurrentVersion == null))
{
is_winnt = false;
}
else
{
is_winnt = true;
}
if(is_winnt == false)
{
logComment("is_winnt is false: " + is_winnt);
winreg.setRootKey(winreg.HKEY_CURRENT_USER);
subkey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
valname = "Programs";
szStartMenuPrograms = winreg.getValueString(subkey, valname);
valname = "Start Menu";
szStartMenu = winreg.getValueString(subkey, valname);
valname = "Desktop";
szFolderDesktop = winreg.getValueString(subkey, valname);
}
else
{
logComment("is_winnt is true: " + is_winnt);
winreg.setRootKey(winreg.HKEY_LOCAL_MACHINE);
subkey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
valname = "Common Programs";
szStartMenuPrograms = winreg.getValueString(subkey, valname);
valname = "Common Start Menu";
szStartMenu = winreg.getValueString(subkey, valname);
valname = "Common Desktop";
szFolderDesktop = winreg.getValueString(subkey, valname);
}
winreg.setRootKey(winreg.HKEY_CURRENT_USER);
subkey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
valname = "SendTo";
szFolderSendTo = winreg.getValueString(subkey, valname);
subkey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\GrpConv\\MapGroups";
valname = "Quick Launch";
szFolderQuickLaunch = winreg.getValueString(subkey, valname);
fTemp = szStartMenuPrograms + "\\" + scFolderName;
fFolderPath = getFolder("file:///", fTemp);
logComment("Folder StartMenuPrograms: " + szStartMenuPrograms);
logComment("Folder StartMenu: " + szStartMenu);
logComment("Folder FolderDesktop: " + szFolderDesktop);
logComment("Folder FolderSendTo: " + szFolderSendTo);
logComment("Folder FolderQuickLaunch: " + szFolderQuickLaunch);
}
else
{
/* convert the path string to a path folder object */
fFolderPath = getFolder("file:///", fFolderPathStr);
}
logComment("fileExe: " + fileExe);
logComment("fFolderPath: " + fFolderPath);
logComment("scExeDesc: " + scExeDesc);
logComment("fCommunicator : " + fCommunicator);
/* explicitly create the fFolderPath even though the windowsShortcut function creates the folder.
* This is so that the folder creation gets logged for uninstall to remove it. */
File.dirCreate(fFolderPath);
/* create the shortcuts */
File.windowsShortcut(fileExe, fFolderPath, scExeDesc, fCommunicator, "", fileExe, 0);
File.windowsShortcut(fileExe, fFolderPath, scProfileDesc, fCommunicator, scProfileDescParam, fileExe, 0);
/* set the Program Folder Path in the Mozilla key in the Windows Registry */
winreg.setRootKey(winreg.HKEY_LOCAL_MACHINE);
subkey = "SOFTWARE\\Mozilla";
winreg.createKey(subkey,"");
valname = "CurrentVersion";
subkey = "SOFTWARE\\Mozilla\\Mozilla Seamonkey";
winreg.createKey(subkey,"");
valname = "CurrentVersion";
value = "$UserAgent$";
err = winreg.setValueString(subkey, valname, value);
subkey = "SOFTWARE\\Mozilla\\Mozilla Seamonkey\\$UserAgent$";
winreg.createKey(subkey,"");
subkey = "SOFTWARE\\Mozilla\\Mozilla Seamonkey\\$UserAgent$\\Main";
winreg.createKey(subkey,"");
valname = "Program Folder Path";
value = fFolderPath;
err = winreg.setValueString(subkey, valname, value);
}
else
{
logComment("winreg is null");
}
}
function updateWinReg()
{
//Notes:
// can't use a double backslash before subkey - Windows already puts it in.
// subkeys have to exist before values can be put in.
var winreg = getWinRegistry();
var subkey; //the name of the subkey you are poking around in
var valname; // the name of the value you want to look at
var value; //the data in the value you want to look at.
if(winreg != null)
{
winreg.setRootKey(winreg.HKEY_LOCAL_MACHINE);
subkey = "SOFTWARE\\Mozilla";
winreg.createKey(subkey,"");
subkey = "SOFTWARE\\Mozilla\\Mozilla Seamonkey";
winreg.createKey(subkey,"");
valname = "CurrentVersion";
value = "$UserAgent$";
err = winreg.setValueString(subkey, valname, value);
subkey = "SOFTWARE\\Mozilla\\Mozilla Seamonkey\\$UserAgent$";
winreg.createKey(subkey,"");
subkey = "SOFTWARE\\Mozilla\\Mozilla Seamonkey\\$UserAgent$\\Main";
winreg.createKey(subkey,"");
valname = "Install Directory";
value = fCommunicator;
err = winreg.setValueString(subkey, valname, value);
// set the App Paths key here
subkey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\mozilla.exe";
winreg.createKey(subkey,"");
valname = "";
value = fCommunicator + "\\mozilla.exe";
err = winreg.setValueString(subkey, valname, value);
valname = "Path";
value = fCommunicator;
err = winreg.setValueString(subkey, valname, value);
}
}
// main
var srDest;
var err;
var fCommunicator;
var fWindowsSystem;
var fileComponentRegStr;
var fileComponentReg;
srDest = $SpaceRequired$:bin;
err = startInstall("Mozilla Seamonkey", "Browser", "$Version$");
logComment("startInstall: " + err);
fCommunicator = getFolder("Communicator");
fWindowsSystem = getFolder("Win System");
logComment("fCommunicator: " + fCommunicator);
if(verifyDiskSpace(fCommunicator, srDest) == true)
{
setPackageFolder(fCommunicator);
err = addDirectory("",
"$Version$",
"bin", // dir name in jar to extract
fCommunicator, // Where to put this file (Returned from GetFolder)
"", // subdir name to create relative to fCommunicator
true); // Force Flag
logComment("addDirectory() of Program returned: " + err);
// check return value
if(!checkError(err))
{
fileComponentRegStr = fCommunicator + "\\component.reg";
fileComponentReg = getFolder("file:///", fileComponentRegStr);
err = fileDelete(fileComponentReg);
logComment("fileDelete() returned: " + err);
updateWinReg();
createShortcuts();
err = finalizeInstall();
logComment("finalizeInstall() returned: " + err);
}
}
// end main

View File

@@ -0,0 +1,494 @@
[General]
; Run Mode values:
; Normal - Shows all dialogs. Requires user input.
; Auto - Shows some dialogs, but none requiring user input. It will
; automatically install the product using default values.
; Silent - Show no dialogs at all. It will install product using default
; values.
Run Mode=Normal
Product Name=Mozilla Seamonkey
; Destination Path values:
; PROGRAMFILESDIR
; WINDISK
; WINDIR
; WINSYSDIR
Path=[PROGRAMFILESDIR]\Mozilla\Seamonkey
; Program Folder Path values:
; COMMON_STARTUP
; COMMON_PROGRAMS
; COMMON_STARTMENU
; COMMON_DESKTOP
;
; PERSONAL_STARTUP
; PERSONAL_PROGRAMS
; PERSONAL_STARTMENU
; PERSONAL_DESKTOP
;
; PERSONAL_APPDATA
; PERSONAL_CACHE
; PERSONAL_COOKIES
; PERSONAL_FAVORITES
; PERSONAL_FONTS
; PERSONAL_HISTORY
; PERSONAL_NETHOOD
; PERSONAL_PERSONAL
; PERSONAL_PRINTHOOD (supported only under Windows NT)
; PERSONAL_RECENT
; PERSONAL_SENDTO
; PERSONAL_TEMPLATES
;
; PROGRAMFILESDIR
; COMMONFILESDIR
; MEDIAPATH
; CONFIGPATH (supported only under Windows95 and Windows98)
; DEVICEPATH
Program Folder Name=Mozilla Seamonkey
Program Folder Path=[COMMON_PROGRAMS]
; Default Setup Type values:
; Setup Type 0 - first radio button (default)
; Setup Type 1 - second radio button
; Setup Type 2 - third radio button
; Setup Type 3 - fourth radio button (usually the Custom option)
Default Setup Type=Setup Type 0
; Default Font Size is 32
; Default Font Color is WHITE (of BLACK and GREEN)
; Default Font Shadow is TRUE
Setup Title0=Mozilla Seamonkey Pr2 Setup
Setup Title0 Font Size=
Setup Title0 Font Color=
Setup Title0 Font Shadow=TRUE
Setup Title1=Build $Version$
Setup Title1 Font Size=12
Setup Title1 Font Color=BLACK
Setup Title1 Font Shadow=FALSE
Setup Title2=
Setup Title2 Font Size=
Setup Title2 Font Color=
Setup Title2 Font Shadow=TRUE
; HKey: valid decryptable setup keys are [Mozilla Seamonkey CurrentVersion]
; and [Mozilla Seamonkey CurrentVersion].
; Decrypt HKey: there are times when '[' and ']' are valid part of windows registry key names.
; Contains Filename: tells setup that the path contains filename needed to be removed before
; using it as a path.
; Verify Existance: FILE or PATH
;
[Locate Previous Product Path0]
HRoot=HKEY_LOCAL_MACHINE
HKey=[Netscape Seamonkey CurrentVersion]\Main
Name=Install Directory
Decrypt HKey=TRUE
Contains Filename=FALSE
Verify Existance=
; This section checks for legacy files.
; If the file(s), indicated by the Filename= key, is found to have a version of less than the value
; indicated by the Version= key, then display the string in the Message= key.
[Legacy Check0]
Filename=[SETUP PATH]\mozilla.exe
Version=6.0.0.0
Message=Setup has detected an old version of Mozilla in the chosen destination directory that may pose compatibility issues. It is highly recommended that a different destination directory be used. Would you like to choose a different directory?
[Dialog Welcome]
Show Dialog=TRUE
Title=Welcome
Message0=Welcome to %s Setup.
Message1=It is strongly recommended that you exit all Windows programs before running this Setup program.
Message2=Click Cancel to quit Setup and then close any programs you have running. Click Next to continue the Setup program.
[Dialog License]
Show Dialog=FALSE
Title=Software License Agreement
License File=license.txt
Message0=Please read the following license agreement. Use the scroll bar to view the rest of this agreement.
Message1=Click Accept if you accept the terms of the preceeding license agreement. If No is clicked, setup will quit.
[Dialog Setup Type]
Show Dialog=TRUE
Title=Setup Type
Message0=Click the type of setup you prefer, then click Next.
Readme Filename=readme.txt
Readme App=notepad.exe
; at least one Setup Type needs to be set, and up to 4 can be
; set (Setup Type0, Setup Type1, Setup Type2, Setup Type3).
[Setup Type0]
Description Short=B&ase
Description Long=Program will be installed with the minimal options.
; List of components to install/enable for this Setup Type.
; All other components not listed here will be disabled if
; this Setup Type is selected.
C0=Component0
C1=Component1
[Setup Type1]
Description Short=C&omplete
Description Long=Program will be installed with the most common options.
; List of components to install/enable for this Setup Type.
; All other components not listed here will be disabled if
; this Setup Type is selected.
C0=Component0
C1=Component1
C2=Component2
[Setup Type2]
Description Short=C&ustom
Description Long=You may choose the options you want to install. Recommended for advanced users only.
;Description Short=&Pro
;Description Long=Program will be installed with all the options available.
; List of components to install/enable for this Setup Type.
; All other components not listed here will be disabled if
; this Setup Type is selected.
C0=Component0
C1=Component1
C2=Component2
;[Setup Type3]
;Description Short=C&ustom
;Description Long=You may choose the options you want to install. Recommended for advanced users.
; List of components to install/enable for this Setup Type.
; All other components not listed here will be disabled if
; this Setup Type is selected.
;C0=Component0
;C1=Component1
;C2=Component2
;C3=Component3
[Dialog Select Components]
Show Dialog=TRUE
Title=Select Components
Message0=The browser is always installed. Select or clear the additional components you want to install.
[Dialog Windows Integration]
Show Dialog=FALSE
Title=Windows Integration
Message0=Check the Mozilla Preference options you would like Setup to perform.
Message1=These settings allow you to set default Internet preferences for browsing and searching. They affect browsers installed on your machine, including Mozilla Communicator and Microsoft Internet Explorer.
; Only a maximum of 4 "Windows Integration-Item"s are allowded. Each Item
; shows up as a checkbox in the Windows Integration dialog.
[Windows Integration-Item0]
CheckBoxState=FALSE
Description=Make Mozilla Communicator my default Internet browser
Archive=
[Windows Integration-Item1]
CheckBoxState=FALSE
Description=Make Mozilla Netcenter my home page
Archive=
[Windows Integration-Item2]
CheckBoxState=FALSE
Description=Use Mozilla Netcenter to search the Web
Archive=
[Dialog Program Folder]
Show Dialog=TRUE
Title=Select Program Folder
Message0=Setup will add program icons to the Program Folder listed below. You may type a new folder name, or select one from the Existing Folder list. Click Install to begin installation.
[Dialog Site Selector]
Show Dialog=FALSE
Title=Site Selector
Message0=Select the region you wish to download from, or leave it on Default for Setup to automatically determine the best place to download from relative to where you are.
[Dialog Start Install]
Show Dialog=FALSE
Title=Start Install
Message0=Setup has enough information to start copying the program files. If you want to review or change settings, click Back. If you are satisfied with the current settings, click Install to begin copying files.
[Dialog Reboot]
; Show Dialog values are:
; TRUE - Always show
; FALSE - Don't show unless at least one component has its reboot show value set
; to TRUE. This will not show even if some files were in use and a reboot
; is necessary.
; AUTO - Don't show unless a component has its reboot show value set to
; TRUE or there was at least one file in use and a reboot is
; is required for the file to be replaced correctly.
Show Dialog=AUTO
; These SmartDownload sections contain information to configure SmartDownload.
; The info is applied to all components to be downloaded.
[SmartDownload-Netscape Install]
;core_file=base.zip
;core_dir=[SETUP PATH]
no_ads=true
silent=false
execution=false
confirm_install=false
;extract_msg=Uncompressing Seamonkey. Please wait...
[SmartDownload-Proxy]
[SmartDownload-Execution]
exe=
exe_param=
[Check Instance0]
Class Name=NetscapeWindowClass
Window Name=
Message=Setup has detected that an instance of Seamonkey is currently running. Please quit Seamonkey before continuing Setup.
[Check Instance1]
Process Name=psm.exe
Message=Setup has detected that an instance of Personal Security Manager is currently running. Personal Security Manager will quit by itself when there are no other applications running that require it. A reboot might be necessary. Setup will then be able to continue.
; These are the components to be offered to the user (shown in the Select
; Components dialog) for installation.
; There is no limit to the number of components to install.
[Component0]
Description Short=Mozilla Xpinstall Engine
Description Long=Install Engine
Archive=core.xpi
$InstallSize$:core
$InstallSizeSystem$
$InstallSizeArchive$:core.xpi
;Dependency0=
Dependee0=Mozilla Seamonkey
; Attributes can be the following values:
; SELECTED - the component is selected to be installed by default.
; INVISIBLE - the component is not shown in the Select Components dialog.
Attributes=SELECTED|INVISIBLE
; url keys can be as many as needed. url0 is attempted first. if it fails,
; the next url key is tried in sequential order.
; The url should not contain the filename. Setup will assemble the complete url
; using the url keys and the Archive key.
Domain0=$Domain$
Server Path0=$ServerPath$
[Component1]
Description Short=Mozilla Seamonkey
Description Long=Browser software for the internet
Archive=browser.xpi
$InstallSize$:browser
$InstallSizeSystem$
$InstallSizeArchive$:browser.xpi
;Dependency0=
; Attributes can be the following values:
; SELECTED - the component is selected to be installed by default.
; INVISIBLE - the component is not shown in the Select Components dialog.
Attributes=SELECTED|DISABLED
; url keys can be as many as needed. url0 is attempted first. if it fails,
; the next url key is tried in sequential order.
; The url should not contain the filename. Setup will assemble the complete url
; using the url keys and the Archive key.
Domain0=$Domain$
Server Path0=$ServerPath$
;url0=$URLPath$
[Component2]
Description Short=Mail & News
Description Long=Seamonkey Mail && News
Archive=mail.xpi
$InstallSize$:mail
$InstallSizeSystem$
$InstallSizeArchive$:mail.xpi
;Dependency0=
; Attributes can be the following values:
; SELECTED - the component is selected to be installed by default.
; INVISIBLE - the component is not shown in the Select Components dialog.
Attributes=SELECTED
Parameter=
; url keys can be as many as needed. url0 is attempted first. if it fails,
; the next url key is tried in sequential order.
; The url should not contain the filename. Setup will assemble the complete url
; using the url keys and the Archive key.
Domain0=$Domain$
Server Path0=$ServerPath$
;url0=$URLPath$
[Core]
Source=[XPI PATH]\core.xpi
Destination=[WIZTEMP]\core.ns
$InstallSize$:core
Cleanup=TRUE
Message=Preparing Install, please wait...
[Redirect]
Status=Enabled
url0=$RedirIniUrl$
Description=
Message=
; The Timing key needs to be one of the following values:
; pre download - process before any files have been downloaded.
; post download - process after all files have been downloaded.
; pre core - process before the core file has been uncompressed.
; post core - process after the core file has been uncompressed.
; pre smartupdate - process before the smartupdate engine has been launched.
; post smartupdate - process after the smartupdate engine has been launched.
; pre launchapp - process before the launching of executables.
; post launchapp - process after the launching of executables.
; depend reboot - process depending on if a reboot is necessary or not.
; if reboot is necessary, installer can set it up so
; the app runs once upon windows reboot.
;Uncompress FileX sections
;[Uncompress File0]
;Timing=post download
;Source=[XPI PATH]\core.xpi
;Destination=[SETUP PATH]
;Message=Configuring Seamonkey, please wait...
;[Uncompress File1]
;Timing=post download
;Source=[XPI PATH]\extratest.xpi
;Destination=[SETUP PATH]
;Message=Configuring Extra test files, please wait...
;Move FileX sections
;[Move File0]
;Timing=post download
;Source=[SETUP PATH]\bin\*
;Destination=[SETUP PATH]\program
;[Move File1]
;Timing=post download
;Source=[SETUP PATH]\ftmain\*
;Destination=[SETUP PATH]\program
;Copy FileX sections
[Copy File0]
Timing=post launchapp
Source=[JRE BIN PATH]\npjava*.dll
Destination=[SETUP PATH]\Plugins
Fail If Exists=FALSE
;[Copy File1]
;Timing=post launchapp
;Source=[TEMP]\xtratest\bin\*.*
;Destination=[SETUP PATH]
;Fail If Exists=FALSE
;[Copy File1]
;Timing=post download
;Source=[SETUP PATH]\bin\*.exe
;Destination=[TEMP]
;Fail If Exists=
;Create DirectoryX sections
[Create Directory0]
Timing=post download
Destination=[SETUP PATH]\Plugins
;[Create Directory1]
;Timing=post download
;Destination=[TEMP]\Test\temp
;Delete FileX sections
[Delete File0]
Timing=post download
Destination=[COMMON_PROGRAMS]\Mozilla Seamonkey\Mozilla AppRunner.lnk
;Remove DirectoryX sections
;[Remove Directory0]
;Timing=post launchapp
;Destination=[TEMP]\xtratest
;Remove subdirs=TRUE
;RunAppX sections
[RunApp0]
Timing=depend reboot
Wait=FALSE
Target=[SETUP PATH]\mozilla.exe
Parameters=-installer
WorkingDir=[SETUP PATH]
[Windows Registry0]
Root Key=HKEY_LOCAL_MACHINE
Key=Software\Mozilla\Mozilla Seamonkey\$UserAgent$\Main
Name=Program Folder Path
Name Value=[Default Folder]
Type=REG_SZ
Decrypt Key=FALSE
Decrypt Name=FALSE
Decrypt Name Value=TRUE
Overwrite Key=TRUE
Overwrite Name=TRUE
Timing=pre smartupdate
; Values for Show Folder:
; HIDE Hides the window and activates another window.
; MAXIMIZE Maximizes the specified window.
; MINIMIZE Minimizes the specified window and activates the next
; top-level window in the z-order.
; RESTORE Activates and displays the window. If the window is
; minimized or maximized, Windows restores it to its
; original size and position. An application should specify
; this flag when restoring a minimized window.
; SHOW Activates the window and displays it in its current size
; and position.
; SHOWMAXIMIZED Activates the window and displays it as a maximized
; window.
; SHOWMINIMIZED Activates the window and displays it as a minimized
; window.
; SHOWMINNOACTIVE Displays the window as a minimized window. The active
; window remains active.
; SHOWNA Displays the window in its current state. The active
; window remains active.
; SHOWNOACTIVATE Displays a window in its most recent size and position.
; The active window remains active.
; SHOWNORMAL Activates and displays a window. If the window is
; minimized or maximized, Windows restores it to its
; original size and position. An application should specify
; this flag when displaying the window for the first time.
[Program Folder0]
Timing=post smartupdate
Show Folder=SHOW
Program Folder=[Default Folder]
;[Program Folder0-Shortcut0]
;File=[SETUP PATH]\mozilla.exe
;Arguments=
;Working Dir=[SETUP PATH]
;Description=Mozilla Seamonkey
;Icon Path=[SETUP PATH]\mozilla.exe
;Icon Id=0
;[Program Folder0-Shortcut1]
;File=[SETUP PATH]\mozilla.exe
;Arguments=-ProfileManager
;Working Dir=[SETUP PATH]
;Description=Profile Manager
;Icon Path=[SETUP PATH]\mozilla.exe
;Icon Id=0
;[Program Folder0-Shortcut2]
;File=[SETUP PATH]\bin\Net2fone.exe
;Arguments=
;Working Dir=[SETUP PATH]
;Description=Net2Fone
;Icon Path=[SETUP PATH]\bin\Net2fone.exe
;Icon Id=0
;[Program Folder1]
;Timing=post download
;Show Folder=SHOW
;Program Folder=[Default Folder]\lala land
;[Program Folder1-Shortcut0]
;File=c:\bin\getver.exe
;Arguments=
;Working Dir=[TEMP]
;Description=Getver Test
;Icon Path=[WINDISK]\4nt\4nt.exe
;Icon Id=0
;[Program Folder1-Shortcut1]
;File=c:\perl\bin\perl.exe
;Arguments=
;Working Dir=[WINSYS]
;Description=Perl
;Icon Path=c:\perl\bin\perl.exe
;Icon Id=0

View File

@@ -0,0 +1,41 @@
// main
var srDest;
var err;
var communicatorFolder;
var fWindowsSystem;
var fileComponentRegStr;
var fileComponentReg;
srDest = $SpaceRequired$:bin;
err = startInstall("Mozilla XPCom", "XPCom", "$Version$");
logComment("startInstall: " + err);
communicatorFolder = getFolder("Communicator");
fWindowsSystem = getFolder("Win System");
logComment("communicatorFolder: " + communicatorFolder);
if(verifyDiskSpace(communicatorFolder, srDest) == true)
{
setPackageFolder(communicatorFolder);
err = addDirectory("",
"$Version$",
"bin", // dir name in jar to extract
communicatorFolder, // Where to put this file (Returned from GetFolder)
"", // subdir name to create relative to communicatorFolder
true); // Force Flag
logComment("addDirectory() of Program returned: " + err);
// check return value
if(!checkError(err))
{
fileComponentRegStr = communicatorFolder + "\\component.reg";
fileComponentReg = getFolder("file:///", fileComponentRegStr);
err = fileDelete(fileComponentReg);
logComment("fileDelete() returned: " + err);
err = finalizeInstall();
logComment("finalizeInstall() returned: " + err);
}
}
// end main

View File

@@ -0,0 +1,18 @@
var err = StartInstall("Mozilla Editor", "Seamonkey", "$Version$");
LogComment("StartInstall: " + err);
var communicatorFolder = Install.GetFolder("Communicator");
LogComment("communicatorFolder: " + communicatorFolder);
err = AddDirectory("Program",
"$Version$",
"bin", // fileName in jar,
communicatorFolder, // Where to put this file (Returned from GetFolder)
"", // fileName in jar,
true); // Force Flag
LogComment("AddDirectory() returned: " + err);
err = FinalizeInstall();
LogComment("FinalizeInstall() returned: " + err);

View File

@@ -0,0 +1,34 @@
// main
var srDest;
var err;
var communicatorFolder;
srDest = $SpaceRequired$:bin;
err = startInstall("Mozilla Mail", "Mail", "$Version$");
logComment("startInstall: " + err);
// check return value
checkError(err);
communicatorFolder = getFolder("Communicator");
logComment("communicatorFolder: " + communicatorFolder);
if(verifyDiskSpace(communicatorFolder, srDest) == true)
{
setPackageFolder(communicatorFolder);
err = addDirectory("",
"$Version$",
"bin", // dir name in jar to extract
communicatorFolder, // Where to put this file (Returned from GetFolder)
"", // subdir name to create relative to communicatorFolder
true); // Force Flag
logComment("addDirectory() returned: " + err);
// check return value
if(!checkError(err))
{
err = finalizeInstall();
logComment("finalizeInstall() returned: " + err);
}
}
// end main

View File

@@ -0,0 +1,134 @@
#!c:\perl\bin\perl
#
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 Communicator client code, released
# March 31, 1998.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998-1999 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Sean Su <ssu@netscape.com>
#
#
# This perl script builds the xpi, config.ini, and js files.
#
# Make sure there are at least four arguments
if($#ARGV < 2)
{
die "usage: $0 <default version> <staging path> <dist install path>
default version : y2k compliant based date version.
ie: 5.0.0.2000040413
staging path : full path to where the components are staged at
dist install path : full path to where the dist install dir is at.
ie: d:\\builds\\mozilla\\dist\\win32_o.obj\\install
\n";
}
$inDefaultVersion = $ARGV[0];
$inStagePath = $ARGV[1];
$inDistPath = $ARGV[2];
$inRedirIniUrl = "ftp://not.needed.com/because/the/xpi/files/will/be/located/in/the/same/dir/as/the/installer";
$inXpiUrl = "ftp://not.needed.com/because/the/xpi/files/will/be/located/in/the/same/dir/as/the/installer";
$seiFileNameGeneric = "nsinstall.exe";
$seiFileNameSpecific = "mozilla-win32-installer.exe";
$userAgent = "5.0b2 (en)";
# Check for existance of staging path
if(!(-e "$inStagePath"))
{
die "invalid path: $inStagePath\n";
}
# Make sure inDestPath exists
if(!(-e "$inDistPath"))
{
mkdir ("$inDestPath",0775);
}
# Make .js files
MakeJsFile("core");
MakeJsFile("browser");
MakeJsFile("mail");
# Make .xpi files
MakeXpiFile("core");
MakeXpiFile("browser");
MakeXpiFile("mail");
MakeConfigFile();
if(-e "$inDistPath\\setup")
{
unlink <$inDistPath\\setup\\*>;
}
else
{
mkdir ("$inDistPath\\setup",0775);
}
# Copy the setup files to the dist setup directory.
system("xcopy /f config.ini $inDistPath\\");
system("xcopy /f config.ini $inDistPath\\setup\\");
system("xcopy /f $inDistPath\\setup.exe $inDistPath\\setup\\");
system("xcopy /f $inDistPath\\setuprsc.dll $inDistPath\\setup\\");
# build the self-extracting .exe file.
print "\nbuilding self-extracting installer ($seiFileNameSpecific)...\n";
system("copy $inDistPath\\$seiFileNameGeneric $inDistPath\\$seiFileNameSpecific");
system("$inDistPath\\nszip.exe $inDistPath\\$seiFileNameSpecific $inDistPath\\setup\\*.* $inDistPath\\xpi\\*.*");
print " done!\n";
# end of script
exit(0);
sub MakeConfigFile
{
# Make config.ini file
if(system("perl makecfgini.pl config.it $inDefaultVersion \"$userAgent\" $inStagePath $inDistPath\\xpi $inRedirIniUrl $inXpiUrl") != 0)
{
exit(1);
}
}
sub MakeJsFile
{
my($componentName) = @_;
# Make .js file
if(system("perl makejs.pl $componentName.jst $inDefaultVersion \"$userAgent\" $inStagePath\\$componentName") != 0)
{
exit(1);
}
}
sub MakeXpiFile
{
my($componentName) = @_;
# Make .xpi file
if(system("perl makexpi.pl $componentName $inStagePath $inDistPath\\xpi") != 0)
{
exit(1);
}
}

View File

@@ -0,0 +1,277 @@
#!c:\perl\bin\perl
#
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 Communicator client code, released
# March 31, 1998.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998-1999 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Sean Su <ssu@netscape.com>
#
#
# This perl script parses the input file for special variables
# in the format of $Variable$ and replace it with the appropriate
# value(s).
#
# Input: .it file
# - which is a .ini template
#
# version
# - version to display on the blue background
#
# UserAgent
# - user agent to use in the windows registry. should be the same as the one
# built into the browser (ie "6.0b2 (en)")
#
# Path to staging area
# - path on where the seamonkey built bits are staged to
#
# xpi path
# - path on where xpi files will be located at
#
# redirect file url
# - url to where the redirect.ini file will be staged at.
# Either ftp:// or http:// can be used
# ie: ftp://ftp.netscape.com/pub/seamonkey
#
# xpi url
# - url to where the .xpi files will be staged at.
# Either ftp:// or http:// can be used
# ie: ftp://ftp.netscape.com/pub/seamonkey/xpi
#
# ie: perl makecfgini.pl config.it 5.0.0.1999120608 "5.0b1 (en)" k:\windows\32bit\5.0 d:\builds\mozilla\dist\win32_o.obj\install\xpi ftp://ftp.netscape.com/pub/seamonkey/windows/32bit/x86/1999-09-13-10-M10 ftp://ftp.netscape.com/pub/seamonkey/windows/32bit/x86/1999-09-13-10-M10/xpi
#
#
# Make sure there are at least two arguments
if($#ARGV < 6)
{
die "usage: $0 <.it file> <version> <UserAgent> <staging path> <.xpi path> <redirect file url> <xpi url>
.it file : input ini template file
version : version to be shown in setup. Typically the same version
as show in mozilla.exe.
UserAgent : user agent to use in the windows registry. should be the same as the one
built into the browser (ie \"6.0b2 (en)\")
staging path : path to where the components are staged at
.xpi path : path to where the .xpi files have been built to
ie: d:\\builds\\mozilla\\dist\\win32_o.obj\\install\\xpi
redirect file : url to where the redirect.ini file will be staged at.
url Either ftp:// or http:// can be used
ie: ftp://ftp.netscape.com/pub/seamonkey
xpi url : url to where the .xpi files will be staged at.
Either ftp:// or http:// can be used
ie: ftp://ftp.netscape.com/pub/seamonkey/xpi
\n";
}
$inItFile = $ARGV[0];
$inVersion = $ARGV[1];
$inUserAgent = $ARGV[2];
$inStagePath = $ARGV[3];
$inXpiPath = $ARGV[4];
$inRedirIniUrl = $ARGV[5];
$inUrl = $ARGV[6];
$inDomain;
$inServerPath;
($inDomain, $inServerPath) = ParseDomainAndPath($inUrl);
# Get the name of the file replacing the .it extension with a .ini extension
@inItFileSplit = split(/\./,$inItFile);
$outIniFile = $inItFileSplit[0];
$outIniFile .= ".ini";
# Open the input file
open(fpInIt, $inItFile) || die "\ncould not open $ARGV[0]: $!\n";
# Open the output file
open(fpOutIni, ">$outIniFile") || die "\nCould not open $outIniFile: $!\n";
print "\n Making $outIniFile...\n";
# While loop to read each line from input file
while($line = <fpInIt>)
{
# For each line read, search and replace $InstallSize$ with the calculated size
if($line =~ /\$InstallSize\$/i)
{
$installSize = 0;
$installSizeSystem = 0;
# split read line by ":" deliminator
@colonSplit = split(/:/, $line);
if($#colonSplit >= 0)
{
$componentName = $colonSplit[1];
chop($componentName);
$installSize = OutputInstallSize("$inStagePath\\$componentName");
# special oji consideration here. Since it's an installer that
# seamonkey installer will be calling, the disk space allocation
# needs to be adjusted by an expansion factor of 3.62.
if($componentName =~ /oji/i)
{
$installSize = int($installSize * 3.62);
}
}
# Read the next line to calculate for the "Install Size System="
if($line = <fpInIt>)
{
if($line =~ /\$InstallSizeSystem\$/i)
{
$installSizeSystem = OutputInstallSizeSystem($line, "$inStagePath\\$componentName");
}
}
$installSize -= $installSizeSystem;
print fpOutIni "Install Size=$installSize\n";
print fpOutIni "Install Size System=$installSizeSystem\n";
}
elsif($line =~ /\$InstallSizeArchive\$/i)
{
$installSizeArchive = 0;
# split read line by ":" deliminator
@colonSplit = split(/:/, $line);
if($#colonSplit >= 0)
{
$componentName = $colonSplit[1];
chop($componentName);
$installSizeArchive = OutputInstallSizeArchive("$inXpiPath\\$componentName");
}
print fpOutIni "Install Size Archive=$installSizeArchive\n";
}
else
{
# For each line read, search and replace $Version$ with the version passed in
$line =~ s/\$Version\$/$inVersion/i;
$line =~ s/\$Domain\$/$inDomain/i;
$line =~ s/\$ServerPath\$/$inServerPath/i;
$line =~ s/\$RedirIniUrl\$/$inRedirIniUrl/i;
$line =~ s/\$UserAgent\$/$inUserAgent/i;
print fpOutIni $line;
}
}
print " done!\n";
# end of script
exit(0);
sub ParseDomainAndPath()
{
my($aUrl) = @_;
my($aDomain, $aServerPath);
@slashSplit = split(/\//, $aUrl);
if($#slashSplit >= 0)
{
for($i = 0; $i <= $#slashSplit; $i++)
{
if($i <= 2)
{
if($aDomain eq "")
{
$aDomain = "$slashSplit[$i]";
}
else
{
$aDomain = "$aDomain/$slashSplit[$i]";
}
}
else
{
if($aServerPath eq "")
{
$aServerPath = "/$slashSplit[$i]";
}
else
{
$aServerPath = "$aServerPath/$slashSplit[$i]";
}
}
}
}
return($aDomain, $aServerPath);
}
sub OutputInstallSize()
{
my($inPath) = @_;
my($installSize);
print " calculating size for $inPath\n";
$installSize = `ds32.exe /D /L0 /A /S /C 32768 $inPath`;
$installSize += 32768; # take into account install.js
$installSize = int($installSize / 1024);
$installSize += 1;
return($installSize);
}
sub OutputInstallSizeArchive()
{
my($inPath) = @_;
my($installSizeArchive);
my($dev, $ino, $mode, $nlink, $uid, $gui, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks);
print " calculating size for $inPath\n";
($dev, $ino, $mode, $nlink, $uid, $gui, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks) = stat $inPath;
$installSizeArchive += 32768; # take into account install.js
$installSizeArchive = int($size / 1024);
$installSizeArchive += 1;
return($installSizeArchive);
}
sub OutputInstallSizeSystem()
{
my($inLine, $inPath) = @_;
my($installSizeSystem) = 0;
# split read line by ":" deliminator
@colonSplit = split(/:/, $inLine);
if($#colonSplit >= 0)
{
# split line by "," deliminator
@commaSplit = split(/\,/, $colonSplit[1]);
if($#commaSplit >= 0)
{
foreach(@commaSplit)
{
# calculate the size of component installed using ds32.exe in Kbytes
print " calculating size for $inPath\\$_";
$installSizeSystem += `ds32.exe /D /L0 /A /S /C 32768 $inPath\\$_`;
}
}
}
$installSizeSystem = int($installSizeSystem / 1024);
$installSizeSystem += 1;
return($installSizeSystem);
}

View File

@@ -0,0 +1,122 @@
#!c:\perl\bin\perl
#
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 Communicator client code, released
# March 31, 1998.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998-1999 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Sean Su <ssu@netscape.com>
#
#
# This perl script parses the input file for special variables
# in the format of $Variable$ and replace it with the appropriate
# value(s).
#
# Input: .jst file - which is a .js template
# default version - a julian date in the form of:
# major.minor.release.yydoy
# ie: 5.0.0.99256
# user agent - user agent of product
# component staging path - path to where the components are staged at
#
# ie: perl makejs.pl core.jst 5.0.0.99256
#
# Make sure there are at least two arguments
if($#ARGV < 3)
{
die "usage: $0 <.jst file> <default version> <UserAgent> <staging path>
.jst file : .js template input file
default version : default julian base version number to use in the
form of: major.minor.release.yydoy
ie: 5.0.0.99256
user agent : user agent of product (5.0b1 [en])
component staging path : path to where this component is staged at
ie: z:\\stage\\windows\\32bit\\en\\5.0\\core
\n";
}
$inJstFile = $ARGV[0];
$inVersion = $ARGV[1];
$inUserAgent = $ARGV[2];
$inStagePath = $ARGV[3];
# Get the name of the file replacing the .jst extension with a .js extension
@inJstFileSplit = split(/\./,$inJstFile);
$outJsFile = $inJstFileSplit[0];
$outJsFile .= ".js";
$outTempFile = $inJstFileSplit[0];
$outTempFile .= ".template";
system("copy ..\\common\\share.t $outTempFile");
system("cat $inJstFile >> $outTempFile");
# Open the input .template file
open(fpInTemplate, $outTempFile) || die "\ncould not open $outTempFile: $!\n";
# Open the output .js file
open(fpOutJs, ">$outJsFile") || die "\nCould not open $outJsFile: $!\n";
# While loop to read each line from input file
while($line = <fpInTemplate>)
{
# For each line read, search and replace $Version$ with the version passed in
if($line =~ /\$Version\$/i)
{
$line =~ s/\$Version\$/$inVersion/i;
}
elsif($line =~ /\$UserAgent\$/i)
{
$line =~ s/\$UserAgent\$/$inUserAgent/i;
}
elsif($line =~ /\$SpaceRequired\$/i) # For each line read, search and replace $InstallSize$ with the calculated size
{
$spaceRequired = 0;
# split read line by ":" deliminator
@colonSplit = split(/:/, $line);
if($#colonSplit > 0)
{
@semiColonSplit = split(/;/, $colonSplit[1]);
$subDir = $semiColonSplit[0];
$spaceRequired = GetSpaceRequired("$inStagePath\\$subDir");
$line =~ s/\$SpaceRequired\$:$subDir/$spaceRequired/i;
}
else
{
$spaceRequired = GetSpaceRequired("$inStagePath");
$line =~ s/\$SpaceRequired\$/$spaceRequired/i;
}
}
print fpOutJs $line;
}
sub GetSpaceRequired()
{
my($inPath) = @_;
my($spaceRequired);
print " calulating size for $inPath\n";
$spaceRequired = `ds32.exe /D /L0 /A /S /C 32768 $inPath`;
$spaceRequired = int($spaceRequired / 1024);
$spaceRequired += 1;
return($spaceRequired);
}

View File

@@ -0,0 +1,114 @@
#!c:\perl\bin\perl
#
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 Communicator client code, released
# March 31, 1998.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998-1999 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Sean Su <ssu@netscape.com>
#
#
# This perl script creates .xpi files given component input name
#
# Input: component name
# - name of the component directory located in the staging path
# staging path
# - path to where the built files are staged at
# dest path
# - path to where the .xpi files are are to be created at.
# ** MUST BE AN ABSOLUTE PATH, NOT A RELATIVE PATH **
#
# ie: perl makexpi.pl core z:\exposed\windows\32bit\en\5.0 d:\build\mozilla\dist\win32_o.obj\install\working
#
use File::Copy;
use Cwd;
# Make sure there are at least three arguments
if($#ARGV < 2)
{
die "usage: $0 <component name> <staging path> <dest path>
component name : name of component directory within staging path
staging path : path to where the components are staged at
dest path : path to where the .xpi files are to be created at
\n";
}
$inComponentName = $ARGV[0];
$inStagePath = $ARGV[1];
$inDestPath = $ARGV[2];
# check for existance of staging component path
if(!(-e "$inStagePath\\$inComponentName"))
{
die "invalid path: $inStagePath\\$inComponentName\n";
}
# check for existance of .js script
if(!(-e "$inComponentName.js"))
{
die "missing .js script: $inComponentName.js\n";
}
# delete component .xpi file
if(-e "$inDestPath\\$inComponentName.xpi")
{
unlink("$inDestPath\\$inComponentName.xpi");
}
if(-e "$inStagePath\\$incomponentName\\$inComponentName.xpi")
{
unlink("$inDestPath\\$inComponentName.xpi");
}
# delete install.js
if(-e "install.js")
{
unlink("install.js");
}
# make sure inDestPath exists
if(!(-e "$inDestPath"))
{
system("mkdir $inDestPath");
}
print "\n Making $inComponentName.xpi...\n";
$saveCwdir = cwd();
# change directory to where the files are, else zip will store
# unwanted path information.
chdir("$inStagePath\\$inComponentName");
system("zip -r $inDestPath\\$inComponentName.xpi *");
chdir("$saveCwdir");
copy("$inComponentName.js", "install.js");
system("zip -g $inDestPath\\$inComponentName.xpi install.js");
# delete install.js
if(-e "install.js")
{
unlink("install.js");
}
print " done!\n";
# end of script
exit(0);

View File

@@ -0,0 +1,111 @@
#!c:\perl\bin\perl
#
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 Communicator client code, released
# March 31, 1998.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998-1999 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Sean Su <ssu@netscape.com>
#
use Cwd;
if($#ARGV < 0)
{
print_usage();
exit(1);
}
print "removing directory:\n";
for($i = 0; $i <= $#ARGV; $i++)
{
print " $ARGV[$i]";
remove_dir_structure($ARGV[$i]);
print "\n";
}
exit(0);
# end
sub remove_dir_structure
{
my($curr_dir) = @_;
$save_cwd = cwd();
$save_cwd =~ s/\//\\/g;
if((-e "$curr_dir") && (-d "$curr_dir"))
{
remove_all_dir($curr_dir);
chdir($save_cwd);
remove_directory($curr_dir);
print " done!";
}
else
{
if(!(-e "$curr_dir"))
{
print "\n";
print "$curr_dir does not exist!";
}
elsif(!(-d "$curr_dir"))
{
print "\n";
print "$curr_dir is not a valid directory!";
}
}
}
sub remove_all_dir
{
my($curr_dir) = @_;
my(@dirlist);
my($dir);
chdir("$curr_dir");
@dirlist = <*>;
foreach $dir (@dirlist)
{
if(-d "$dir")
{
print ".";
remove_all_dir($dir);
}
}
chdir("..");
remove_directory($curr_dir);
}
sub remove_directory
{
my($directory) = @_;
my($save_cwd);
$save_cwd = cwd();
$save_cwd =~ s/\//\\/g;
if(-e "$directory")
{
chdir($directory);
unlink <*>; # remove files
chdir($save_cwd);
rmdir $directory; # remove directory
}
}
sub print_usage
{
print "usage: $0 <dir1> [dir2 dir3...]\n";
}

View File

@@ -0,0 +1,83 @@
#
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 Communicator client code,
# released March 31, 1998.
#
# 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):
# Daniel Veditz <dveditz@netscape.com>
# Douglas Turner <dougt@netscape.com>
#
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = xpinstall
LIBRARY_NAME = xpinstall
SHORT_LIBNAME = xpinstal
IS_COMPONENT = 1
EXTRA_DSO_LIBS = jsdom
REQUIRES = dom js netlib raptor xpcom
# XXX shouldn't need to export this
EXPORTS = nsXPITriggerInfo.h
CPPSRCS = \
nsInstall.cpp \
nsInstallTrigger.cpp \
nsInstallVersion.cpp \
nsInstallFolder.cpp \
nsJSInstall.cpp \
nsJSFile.cpp \
nsJSInstallTriggerGlobal.cpp \
nsJSInstallVersion.cpp \
nsSoftwareUpdate.cpp \
nsSoftwareUpdateRun.cpp \
nsInstallFile.cpp \
nsInstallDelete.cpp \
nsInstallExecute.cpp \
nsInstallPatch.cpp \
nsInstallUninstall.cpp \
nsInstallResources.cpp \
nsTopProgressNotifier.cpp \
nsLoggingProgressNotifier.cpp \
ScheduledTasks.cpp \
nsInstallProgressDialog.cpp \
nsXPITriggerInfo.cpp \
nsXPInstallManager.cpp \
nsInstallFileOpItem.cpp \
nsJSFileSpecObj.cpp \
$(NULL)
LOCAL_INCLUDES = -I$(srcdir)/../public
EXTRA_DSO_LDOPTS = \
$(MOZ_REGISTRY_LIBS) \
-L$(DIST)/bin \
$(EXTRA_DSO_LIBS) \
$(MOZ_JS_LIBS) \
$(MOZ_COMPONENT_LIBS) \
$(ZLIB_LIBS) \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,924 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code,
* released March 31, 1998.
*
* 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):
* Douglas Turner <dougt@netscape.com>
*/
#include "PatchableAppleSingle.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
OSErr PAS_EncodeFile(FSSpec *inSpec, FSSpec *outSpec);
OSErr PAS_DecodeFile(FSSpec *inSpec, FSSpec *outSpec);
OSErr PAS_encodeResource(FSSpec *inFile, short outRefNum);
OSErr PAS_decodeResource(PASEntry *entry, FSSpec *outFile, short inRefNum);
OSErr PAS_encodeMisc(FSSpec *inFile, short outRefNum);
OSErr PAS_decodeMisc(PASEntry *entry, FSSpec *outFile, short inRefNum);
OSErr PAS_encodeData(FSSpec *inFile, short outRefNum);
OSErr PAS_decodeData(PASEntry *entry, FSSpec *outFile, short inRefNum);
OSErr PAS_encodeHeader(short refnum);
OSErr PAS_decodeHeader(short refNum, PASHeader *header);
unsigned long PAS_getDataSize(FSSpec *spec);
short PAS_getResourceID(Handle resource);
OSErr PAS_flattenResource(ResType type, short *ids, long count, short source, short dest);
OSErr PAS_unflattenResource(PASResource *pasRes, Ptr buffer);
void PAS_sortTypes(short sourceRefNum, ResType **resTypePtr, long *count);
void PAS_sortIDs(short sourceRefNum, OSType theType, short **IdPtr, long *count);
void PAS_bubbleSortResType(ResType *types, long count);
void PAS_bubbleSortIDS(short *ids, long count);
OSErr PAS_EncodeFile(FSSpec *inSpec, FSSpec *outSpec)
{
OSErr err;
short outRefNum;
PASEntry dataEntry, miscEntry, resourceEntry;
long sizeOfEntry;
if (inSpec == NULL || outSpec == NULL)
return paramErr;
memset(&dataEntry, 0, sizeof(PASEntry));
memset(&miscEntry, 0, sizeof(PASEntry));
memset(&resourceEntry, 0, sizeof(PASEntry));
FSpDelete( outSpec ) ;
err = FSpCreate( outSpec, kCreator, kType ,smSystemScript );
if (err != noErr) return err;
err = FSpOpenDF(outSpec, fsRdWrPerm, &outRefNum);
if (err != noErr) goto error;
// Write Out Header
err = PAS_encodeHeader(outRefNum);
if (err != noErr) goto error;
/* Why am I using three (3)?
E stand for entry.
The data for the entry is after the THREE headers
|---------|----|----|----|---------------------->
header E E E
*/
// Write Out Data Entry
dataEntry.entryID = ePas_Data;
dataEntry.entryLength = PAS_getDataSize(inSpec);
dataEntry.entryOffset = sizeof(PASHeader) + (3 * sizeof(PASEntry));
sizeOfEntry = sizeof(PASEntry);
if(dataEntry.entryLength < 0)
{
err = dataEntry.entryLength;
goto error;
}
err = FSWrite(outRefNum, &sizeOfEntry, &dataEntry);
if (err != noErr) goto error;
// Write Out Misc Entry
miscEntry.entryID = ePas_Misc;
miscEntry.entryLength = sizeof(PASMiscInfo);
miscEntry.entryOffset = sizeof(PASHeader) + (3 * sizeof(PASEntry)) + dataEntry.entryLength;
sizeOfEntry = sizeof(PASEntry);
err = FSWrite(outRefNum, &sizeOfEntry, &miscEntry);
if (err != noErr) goto error;
// Write Out Resource Entry
resourceEntry.entryID = ePas_Resource;
resourceEntry.entryLength = -1;
resourceEntry.entryOffset = sizeof(PASHeader) + (3 * sizeof(PASEntry)) + dataEntry.entryLength + miscEntry.entryLength;
sizeOfEntry = sizeof(PASEntry);
err = FSWrite(outRefNum, &sizeOfEntry, &resourceEntry);
if (err != noErr) goto error;
err = PAS_encodeData(inSpec, outRefNum);
if (err != noErr) goto error;
err = PAS_encodeMisc(inSpec, outRefNum);
if (err != noErr) goto error;
err = PAS_encodeResource(inSpec, outRefNum);
if (err == kResFileNotOpened)
{
// there was no resource fork
err = noErr;
}
else if (err != noErr)
{
goto error;
}
FSClose(outRefNum);
return noErr;
error:
if (outRefNum != kResFileNotOpened)
{
FSClose(outRefNum);
}
FSpDelete( outSpec ) ;
return err;
}
OSErr PAS_DecodeFile(FSSpec *inSpec, FSSpec *outSpec)
{
OSErr err;
short inRefNum;
PASHeader header;
PASEntry dataEntry, miscEntry, resourceEntry;
long sizeOfEntry;
if (inSpec == NULL || outSpec == NULL)
return paramErr;
FSpDelete( outSpec ) ;
err = FSpCreate( outSpec, kCreator, kType ,smSystemScript );
if (err != noErr) return err;
err = FSpOpenDF(inSpec, fsRdPerm, &inRefNum);
if (err != noErr) goto error;
// Read Header
err = PAS_decodeHeader(inRefNum, &header);
if (err != noErr) goto error;
if( header.magicNum != PAS_MAGIC_NUM ||
header.versionNum != PAS_VERSION)
{
err = -1;
goto error;
}
// Read Data Entry
err = SetFPos(inRefNum, fsFromStart, sizeof(PASHeader));
if (err != noErr) goto error;
sizeOfEntry = sizeof(PASEntry);
err = FSRead(inRefNum, &sizeOfEntry, &dataEntry);
if (err != noErr) goto error;
// Read Misc Entry
err = SetFPos(inRefNum, fsFromStart, (sizeof(PASHeader) + sizeof(PASEntry)));
if (err != noErr) goto error;
sizeOfEntry = sizeof(PASEntry);
err = FSRead(inRefNum, &sizeOfEntry, &miscEntry);
if (err != noErr) goto error;
// Read Resource Entry
err = SetFPos(inRefNum, fsFromStart, (sizeof(PASHeader) + (2 * sizeof(PASEntry)))) ;
if (err != noErr) goto error;
sizeOfEntry = sizeof(PASEntry);
err = FSRead(inRefNum, &sizeOfEntry, &resourceEntry);
if (err != noErr) goto error;
err = PAS_decodeData(&dataEntry, outSpec, inRefNum);
if (err != noErr) goto error;
err = PAS_decodeMisc(&miscEntry, outSpec, inRefNum);
if (err != noErr) goto error;
err = PAS_decodeResource(&resourceEntry, outSpec, inRefNum);
if (err == kResFileNotOpened)
{
// there was no resource fork
err = noErr;
}
else if (err != noErr)
{
goto error;
}
FSClose(inRefNum);
return noErr;
error:
if (inRefNum != kResFileNotOpened)
{
FSClose(inRefNum);
}
FSpDelete( outSpec ) ;
return err;
}
#pragma mark -
OSErr PAS_encodeResource(FSSpec *inFile, short outRefNum)
{
OSErr err;
short inRefNum;
PASResFork resInfo;
SInt32 currentWrite;
ResType *resTypes;
long typeCount;
short *ids;
long idCount;
short oldResFile;
oldResFile=CurResFile();
inRefNum = FSpOpenResFile(inFile, fsRdPerm);
if (inRefNum < noErr) return inRefNum;
UseResFile(inRefNum);
memset(&resInfo, 0, sizeof(PASResFork));
PAS_sortTypes(inRefNum, &resTypes, &typeCount);
resInfo.NumberOfTypes = typeCount;
currentWrite = sizeof(PASResFork);
err = FSWrite(outRefNum, &currentWrite, &resInfo);
if (err != noErr) return err;
for (typeCount = 0; ((typeCount < resInfo.NumberOfTypes) && (err == noErr)); typeCount++)
{
PAS_sortIDs(inRefNum, resTypes[typeCount], &ids, &idCount);
err = PAS_flattenResource(resTypes[typeCount], ids, idCount, inRefNum, outRefNum);
DisposePtr((Ptr)ids);
}
DisposePtr((Ptr)resTypes);
UseResFile(oldResFile);
CloseResFile(inRefNum);
return err;
}
OSErr PAS_decodeResource(PASEntry *entry, FSSpec *outFile, short inRefNum)
{
OSErr err = noErr;
short outRefNum;
PASResFork info;
SInt32 infoSize;
short oldResFile;
PASResource pasRes;
SInt32 pasResSize;
long bufSize;
Handle buffer;
long counter=0;
infoSize = sizeof(PASResFork);
err = SetFPos(inRefNum, fsFromStart, (*entry).entryOffset );
if (err != noErr) return err;
err = FSRead( inRefNum, &infoSize, &info);
if (err != noErr) return err;
if(infoSize != sizeof(PASResFork))
{
err = -1;
goto error;
}
oldResFile=CurResFile();
outRefNum = FSpOpenResFile(outFile, fsRdWrPerm);
if (outRefNum < noErr) return outRefNum;
UseResFile(outRefNum);
while (1)
{
pasResSize = sizeof(PASResource);
err = FSRead( inRefNum, &pasResSize, &pasRes);
if (err != noErr)
{
if(err == eofErr)
err = noErr;
break;
}
bufSize = pasRes.length;
buffer = NewHandle(bufSize);
HLock(buffer);
if(buffer == NULL)
{
// if we did not get our memory, try updateresfile
HUnlock(buffer);
UpdateResFile(outRefNum);
counter=0;
buffer = NewHandle(bufSize);
HLock(buffer);
if(buffer == NULL)
{
err = memFullErr;
break;
}
}
err = FSRead( inRefNum, &bufSize, &(**buffer));
if (err != noErr && err != eofErr) break;
AddResource(buffer, pasRes.attrType, pasRes.attrID, pasRes.attrName);
WriteResource(buffer);
SetResAttrs(buffer, pasRes.attr);
ChangedResource(buffer);
WriteResource(buffer);
ReleaseResource(buffer);
if (counter++ > 100)
{
UpdateResFile(outRefNum);
counter=0;
}
}
error:
UseResFile(oldResFile);
CloseResFile(outRefNum);
return err;
}
#pragma mark -
OSErr PAS_encodeMisc(FSSpec *inFile, short outRefNum)
{
OSErr err;
short inRefNum;
PASMiscInfo infoBlock;
FInfo fInfo;
SInt32 currentRead;
err = FSpOpenDF(inFile, fsRdPerm, &inRefNum);
if (err != noErr) return err;
memset(&infoBlock, 0, sizeof(PASMiscInfo));
err = FSpGetFInfo(inFile, &fInfo);
if (err != noErr) return err;
infoBlock.fileType = fInfo.fdType;
infoBlock.fileCreator = fInfo.fdCreator;
infoBlock.fileFlags = fInfo.fdFlags;
FSClose(inRefNum);
inRefNum = FSpOpenResFile(inFile, fsRdPerm);
if (inRefNum > noErr)
{
infoBlock.fileHasResFork = 1;
infoBlock.fileResAttrs = GetResFileAttrs(inRefNum);
FSClose(inRefNum);
}
else
{
infoBlock.fileHasResFork = 0;
infoBlock.fileResAttrs = 0;
}
currentRead = sizeof(PASMiscInfo);
err = FSWrite(outRefNum, &currentRead, &infoBlock);
if (err != noErr) return err;
CloseResFile(inRefNum);
return noErr;
}
OSErr PAS_decodeMisc(PASEntry *entry, FSSpec *outFile, short inRefNum)
{
OSErr err = noErr;
short outRefNum;
PASMiscInfo info;
SInt32 infoSize;
FInfo theFInfo;
infoSize = sizeof(PASMiscInfo);
err = SetFPos(inRefNum, fsFromStart, (*entry).entryOffset );
if (err != noErr) return err;
err = FSRead( inRefNum, &infoSize, &info);
if (err != noErr) return err;
if(infoSize != sizeof(PASMiscInfo))
{
return -1;
}
err = FSpOpenDF(outFile, fsRdWrPerm, &outRefNum);
if (err != noErr) return err;
memset(&theFInfo, 0, sizeof(FInfo));
theFInfo.fdType = info.fileType;
theFInfo.fdCreator = info.fileCreator;
theFInfo.fdFlags = info.fileFlags;
err = FSpSetFInfo(outFile, &theFInfo);
if (err != noErr) return err;
FSClose(outRefNum);
if (info.fileHasResFork)
{
outRefNum = FSpOpenResFile(outFile, fsRdWrPerm);
if (outRefNum < noErr)
{
// maybe it does not have one!
FSpCreateResFile(outFile, info.fileCreator, info.fileType, smSystemScript);
outRefNum = FSpOpenResFile(outFile, fsRdWrPerm);
if (outRefNum < noErr)
{
return outRefNum;
}
}
SetResFileAttrs(outRefNum, info.fileResAttrs);
CloseResFile(outRefNum);
}
if(info.fileType == 'APPL')
{
// we need to add applications to the desktop database.
/* FIX :: need to find DTSetAPPL() function
err = DTSetAPPL( NULL,
outFile->vRefNum,
info.fileCreator,
outFile->parID,
outFile->name);
*/ }
return err;
}
#pragma mark -
OSErr PAS_encodeData(FSSpec *inFile, short outRefNum)
{
OSErr err;
short inRefNum;
Ptr buffer;
SInt32 currentRead = PAS_BUFFER_SIZE;
buffer = NewPtr(currentRead);
err = FSpOpenDF(inFile, fsRdPerm, &inRefNum);
if (err != noErr) return err;
while ( currentRead > 0 )
{
err = FSRead( inRefNum, &currentRead, buffer);
if (err != noErr && err != eofErr) return err;
err = FSWrite(outRefNum, &currentRead, buffer);
if (err != noErr) return err;
}
FSClose(inRefNum);
DisposePtr(buffer);
return noErr;
}
OSErr PAS_decodeData(PASEntry *entry, FSSpec *outFile, short inRefNum)
{
OSErr err;
short outRefNum;
Ptr buffer;
SInt32 currentWrite = PAS_BUFFER_SIZE;
SInt32 totalSize;
buffer = NewPtr(currentWrite);
err = FSpOpenDF(outFile, fsRdWrPerm, &outRefNum);
if (err != noErr) return err;
err = SetFPos(inRefNum, fsFromStart, (*entry).entryOffset );
if (err != noErr) return err;
err = SetFPos(outRefNum, fsFromStart, 0 );
if (err != noErr) return err;
totalSize = (*entry).entryLength;
while(totalSize > 0)
{
currentWrite = PAS_BUFFER_SIZE;
if (totalSize < currentWrite)
{
currentWrite = totalSize;
}
err = FSRead( inRefNum, &currentWrite, buffer);
if (err != noErr && err != eofErr) return err;
err = FSWrite(outRefNum, &currentWrite, buffer);
if (err != noErr) return err;
totalSize = totalSize - currentWrite;
}
FSClose(outRefNum);
DisposePtr(buffer);
return noErr;
}
#pragma mark -
OSErr PAS_encodeHeader(short refnum)
{
PASHeader header;
long sizeOfHeader;
OSErr err;
sizeOfHeader = sizeof(PASHeader);
memset(&header, 0, sizeOfHeader);
header.magicNum = PAS_MAGIC_NUM;
header.versionNum = PAS_VERSION;
header.numEntries = 3;
// Write Out Header
err = FSWrite(refnum, &sizeOfHeader, &header);
return err;
}
OSErr PAS_decodeHeader(short refNum, PASHeader *header)
{
OSErr err;
long sizeOfHeader = sizeof(PASHeader);
memset(header, 0, sizeOfHeader);
err = FSRead(refNum, &sizeOfHeader, header);
return err;
}
#pragma mark -
unsigned long PAS_getDataSize(FSSpec *spec)
{
short refNum;
OSErr err;
Str255 temp;
CInfoPBRec cbrec;
err = FSpOpenDF(spec, fsRdPerm, &refNum);
memcpy( temp, spec->name, spec->name[0] + 1);
cbrec.hFileInfo.ioNamePtr = temp;
cbrec.hFileInfo.ioDirID = spec->parID;
cbrec.hFileInfo.ioVRefNum = spec->vRefNum;
cbrec.hFileInfo.ioFDirIndex = 0;
err = PBGetCatInfoSync(&cbrec);
FSClose(refNum);
if(err != noErr)
{
cbrec.hFileInfo.ioFlLgLen = err;
}
return (cbrec.hFileInfo.ioFlLgLen);
}
short PAS_getResourceID(Handle resource)
{
ResType theType;
Str255 name;
short theID;
memset(&name, 0, sizeof(Str255));
GetResInfo(resource, &theID, &theType, name);
return theID;
}
#pragma mark -
OSErr PAS_flattenResource(ResType type, short *ids, long count, short source, short dest)
{
long idIndex;
Handle resToCopy;
long handleLength;
PASResource pasResource;
long pasResLen;
OSErr err;
for (idIndex=0; idIndex < count; idIndex++)
{
if( (type == 'SIZE') && ( ids[idIndex] == 1 || ids[idIndex] == 0 ) )
{
/*
We do not want to encode/flatten SIZE 0 or 1 because this
is the resource that the user can modify. Most applications
will not be affected if we remove these resources
*/
}
else
{
resToCopy=Get1Resource(type,ids[idIndex]);
if(!resToCopy)
{
return resNotFound;
}
memset(&pasResource, 0, sizeof(PASResource));
GetResInfo( resToCopy,
&pasResource.attrID,
&pasResource.attrType,
pasResource.attrName);
pasResource.attr = GetResAttrs(resToCopy);
DetachResource(resToCopy);
HLock(resToCopy);
pasResource.length = GetHandleSize(resToCopy);
handleLength = pasResource.length;
pasResLen = sizeof(PASResource);
err = FSWrite(dest, &pasResLen, &pasResource);
if(err != noErr)
{
return err;
}
err = FSWrite(dest, &handleLength, &(**resToCopy));
if(err != noErr)
{
return err;
}
HUnlock(resToCopy);
DisposeHandle(resToCopy);
}
}
return noErr;
}
#pragma mark -
void PAS_sortTypes(short sourceRefNum, ResType **resTypePtr, long *count)
{
short oldRef;
short typeIndex;
short numberOfTypes;
*count = -1;
oldRef = CurResFile();
UseResFile(sourceRefNum);
numberOfTypes = Count1Types();
*resTypePtr = (ResType*) NewPtrClear( numberOfTypes * sizeof(OSType) );
for (typeIndex=1; typeIndex <= numberOfTypes; typeIndex++)
{
Get1IndType(&(*resTypePtr)[typeIndex-1], typeIndex);
}
UseResFile(oldRef);
PAS_bubbleSortResType(*resTypePtr, numberOfTypes);
*count = numberOfTypes;
}
void PAS_sortIDs(short sourceRefNum, OSType theType, short **IdPtr, long *count)
{
short oldRef;
Handle theHandle;
short resCount;
short resIndex;
*count = -1;
oldRef = CurResFile();
UseResFile(sourceRefNum);
resCount = Count1Resources(theType);
*IdPtr = (short*) NewPtrClear( resCount * sizeof(short) );
for (resIndex=1; resIndex <= resCount; resIndex++)
{
theHandle = Get1IndResource(theType, resIndex);
if(theHandle == NULL) return;
(*IdPtr)[resIndex-1] = PAS_getResourceID(theHandle);
ReleaseResource(theHandle);
}
UseResFile(oldRef);
PAS_bubbleSortIDS(*IdPtr, resCount);
*count = resCount;
}
#pragma mark -
void
PAS_bubbleSortResType(ResType *types, long count)
{
long x, y;
OSType temp;
for (x=0; x < count-1; x++)
{
for (y=0; y < count-x-1; y++)
{
if (types[y] > types[y+1])
{
temp=types[y];
types[y]=types[y+1];
types[y+1]=temp;
}
}
}
}
void
PAS_bubbleSortIDS(short *ids, long count)
{
long x, y;
short temp;
for (x=0; x < count-1; x++)
{
for (y=0; y < count-x-1; y++)
{
if (ids[y] > ids[y+1])
{
temp=ids[y];
ids[y]=ids[y+1];
ids[y+1]=temp;
}
}
}
}

View File

@@ -0,0 +1,117 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code,
* released March 31, 1998.
*
* 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):
* Douglas Turner <dougt@netscape.com>
*/
#ifndef SU_PAS_H
#define SU_PAS_H
#include <Errors.h>
#include <Types.h>
#include <Files.h>
#include <Script.h>
#include <Resources.h>
typedef struct PASHeader /* header portion of Patchable AppleSingle */
{
UInt32 magicNum; /* internal file type tag = 0x00244200*/
UInt32 versionNum; /* format version: 1 = 0x00010000 */
UInt8 filler[16]; /* filler */
UInt16 numEntries; /* number of entries which follow */
} PASHeader ;
typedef struct PASEntry /* one Patchable AppleSingle entry descriptor */
{
UInt32 entryID; /* entry type: see list, 0 invalid */
UInt32 entryOffset; /* offset, in bytes, from beginning */
/* of file to this entry's data */
UInt32 entryLength; /* length of data in octets */
} PASEntry;
typedef struct PASMiscInfo
{
short fileHasResFork;
short fileResAttrs;
OSType fileType;
OSType fileCreator;
UInt32 fileFlags;
} PASMiscInfo;
typedef struct PASResFork
{
short NumberOfTypes;
} PASResFork;
typedef struct PASResource
{
short attr;
short attrID;
OSType attrType;
Str255 attrName;
unsigned long length;
} PASResource;
#if PRAGMA_ALIGN_SUPPORTED
#pragma options align=reset
#endif
#define kCreator 'MOSS'
#define kType 'PASf'
#define PAS_BUFFER_SIZE (1024*512)
#define PAS_MAGIC_NUM (0x00244200)
#define PAS_VERSION (0x00010000)
enum
{
ePas_Data = 1,
ePas_Misc,
ePas_Resource
};
#ifdef __cplusplus
extern "C" {
#endif
/* Prototypes */
OSErr PAS_EncodeFile(FSSpec *inSpec, FSSpec *outSpec);
OSErr PAS_DecodeFile(FSSpec *inSpec, FSSpec *outSpec);
#ifdef __cplusplus
}
#endif
#endif /* SU_PAS_H */

View File

@@ -0,0 +1,481 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code,
* released March 31, 1998.
*
* 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):
* Daniel Veditz <dveditz@netscape.com>
* Douglas Turner <dougt@netscape.com>
*/
#include "nscore.h"
#include "nsFileSpec.h"
#include "nsFileStream.h"
#include "nsInstall.h" // for error codes
#include "prmem.h"
#include "ScheduledTasks.h"
static nsresult
GetPersistentStringFromSpec(const nsFileSpec& inSpec, char **string)
{
if (!string) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIFileSpec> spec;
#ifdef XP_MAC
nsFileSpec interim = inSpec.GetFSSpec(); /* XXX get rid of mError in nsFileSpec */
nsresult rv = NS_NewFileSpecWithSpec(interim, getter_AddRefs(spec));
#else
nsresult rv = NS_NewFileSpecWithSpec(inSpec, getter_AddRefs(spec));
#endif
if (NS_SUCCEEDED(rv)) {
rv = spec->GetPersistentDescriptorString(string);
}
else {
*string = nsnull;
}
return rv;
}
#ifdef _WINDOWS
#include <sys/stat.h>
#include <windows.h>
PRInt32 ReplaceExistingWindowsFile(const nsFileSpec& currentSpec, const nsFileSpec& finalSpec)
{
// this routine is now for DOS-based windows only. WinNT should
// be taken care of by the XP code
//
// NOTE for WINNT:
//
// the MOVEFILE_DELAY_UNTIL_REBOOT option doesn't work on
// NT 3.51 SP4 or on NT 4.0 until SP2. On the broken versions
// of NT 4.0 Microsoft warns using it can lead to an irreparably
// corrupt windows' registry "after an unknown number of calls".
// Time to reinstall windows when that happens.
//
// I don't want to risk it, I also don't want two separate code
// paths to test, so we do it the lame way on all NT systems
// until such time as there are few enough old revs around to
// make it worth switching back to MoveFileEx().
PRInt32 err = -1;
/* Get OS version info */
DWORD dwVersion = GetVersion();
/* Get build numbers for Windows NT or Win32s */
if (dwVersion > 0x80000000)
{
// Windows 95 or Win16
// Place an entry in the WININIT.INI file in the Windows directory
// to delete finalName and rename currentName to be finalName at reboot
int strlen;
char Src[_MAX_PATH]; // 8.3 name
char Dest[_MAX_PATH]; // 8.3 name
char* final = strdup(finalSpec.GetNativePathCString());
char* current = strdup(currentSpec.GetNativePathCString());
strlen = GetShortPathName( (LPCTSTR)current, (LPTSTR)Src, (DWORD)sizeof(Src) );
if ( strlen > 0 )
{
free(current);
current = strdup(Src);
}
strlen = GetShortPathName( (LPCTSTR) final, (LPTSTR) Dest, (DWORD) sizeof(Dest));
if ( strlen > 0 )
{
free(final);
final = strdup(Dest);
}
/* NOTE: use OEM filenames! Even though it looks like a Windows
* .INI file, WININIT.INI is processed under DOS
*/
AnsiToOem( final, final );
AnsiToOem( current, current );
if ( WritePrivateProfileString( "Rename", final, current, "WININIT.INI" ) )
err = 0;
free(final);
free(current);
}
return err;
}
#endif
PRInt32 DeleteFileNowOrSchedule(const nsFileSpec& filename)
{
PRInt32 result = nsInstall::SUCCESS;
filename.Delete(PR_FALSE);
if (filename.Exists())
{
// could not delete, schedule it for later
RKEY newkey;
HREG reg;
REGERR err;
result = nsInstall::UNEXPECTED_ERROR;
err = NR_RegOpen("", &reg) ;
if ( err == REGERR_OK )
{
err = NR_RegAddKey(reg,ROOTKEY_PRIVATE,REG_DELETE_LIST_KEY,&newkey);
if ( err == REGERR_OK )
{
char valname[20];
char* fnamestr = nsnull;
err = NR_RegGetUniqueName( reg, valname, sizeof(valname) );
if ( err == REGERR_OK )
{
nsresult rv;
rv = GetPersistentStringFromSpec( filename, &fnamestr );
if ( NS_SUCCEEDED(rv) && fnamestr )
{
err = NR_RegSetEntry( reg, newkey, valname,
REGTYPE_ENTRY_BYTES,
(void*)fnamestr,
strlen(fnamestr)+1);
if ( err == REGERR_OK )
result = nsInstall::REBOOT_NEEDED;
}
}
}
NR_RegClose(reg);
}
}
return result;
}
PRInt32 ReplaceFileNow(nsFileSpec& replacementFile, nsFileSpec& doomedFile )
{
// replacement file must exist, doomed file doesn't have to
if ( !replacementFile.Exists() )
return nsInstall::DOES_NOT_EXIST;
// don't have to do anything if the files are the same
if ( replacementFile == doomedFile )
return nsInstall::SUCCESS;
PRInt32 result = nsInstall::ACCESS_DENIED;
// first try to rename the doomed file out of the way (if it exists)
char* leafname;
nsFileSpec tmpFile( doomedFile );
if ( tmpFile.Exists() )
{
tmpFile.MakeUnique();
leafname = tmpFile.GetLeafName();
tmpFile = doomedFile;
tmpFile.Rename( leafname );
nsCRT::free( leafname );
}
// if doomedFile is gone move new file into place
nsresult rv;
if ( !doomedFile.Exists() )
{
nsFileSpec parentofFinalFile;
nsFileSpec parentofReplacementFile;
doomedFile.GetParent(parentofFinalFile);
replacementFile.GetParent(parentofReplacementFile);
// XXX looks dangerous, the replacement file name may NOT be unique in the
// target directory if we have to move it! Either we should never move the
// files like this (i.e. error if not in the same dir) or we need to take
// a little more care in the move.
if(parentofReplacementFile != parentofFinalFile)
{
NS_WARN_IF_FALSE( 0, "File unpacked into a non-dest dir" );
rv = replacementFile.MoveToDir(parentofFinalFile);
}
else
rv = NS_OK;
leafname = doomedFile.GetLeafName();
if ( NS_SUCCEEDED(rv) )
rv = replacementFile.Rename( leafname );
if ( NS_SUCCEEDED(rv) )
{
// we replaced the old file OK, now we have to
// get rid of it permanently
result = DeleteFileNowOrSchedule( tmpFile );
}
else
{
// couldn't rename file, try to put old file back
tmpFile.Rename( leafname );
}
nsCRT::free( leafname );
}
return result;
}
PRInt32 ReplaceFileNowOrSchedule(nsFileSpec& replacementFile, nsFileSpec& doomedFile )
{
PRInt32 result = ReplaceFileNow( replacementFile, doomedFile );
if ( result == nsInstall::ACCESS_DENIED )
{
// if we couldn't replace the file schedule it for later
#ifdef _WINDOWS
if ( ReplaceExistingWindowsFile(replacementFile, doomedFile) == 0 )
return nsInstall::REBOOT_NEEDED;
#endif
RKEY listkey;
RKEY filekey;
HREG reg;
REGERR err;
if ( REGERR_OK == NR_RegOpen("", &reg) )
{
err = NR_RegAddKey( reg, ROOTKEY_PRIVATE, REG_REPLACE_LIST_KEY, &listkey );
if ( err == REGERR_OK )
{
char valname[20];
char* fsrc = nsnull;
char* fdest = nsnull;
REGERR err2;
nsresult rv, rv2;
err = NR_RegGetUniqueName( reg, valname, sizeof(valname) );
if ( err == REGERR_OK )
{
err = NR_RegAddKey( reg, listkey, valname, &filekey );
if ( REGERR_OK == err )
{
rv = GetPersistentStringFromSpec(replacementFile, &fsrc);
rv2 = GetPersistentStringFromSpec(doomedFile, &fdest);
if ( NS_SUCCEEDED(rv) && NS_SUCCEEDED(rv2) )
{
err = NR_RegSetEntry( reg, filekey,
REG_REPLACE_SRCFILE,
REGTYPE_ENTRY_BYTES,
(void*)fsrc,
strlen(fsrc));
err2 = NR_RegSetEntry(reg, filekey,
REG_REPLACE_DESTFILE,
REGTYPE_ENTRY_BYTES,
(void*)fdest,
strlen(fdest));
if ( err == REGERR_OK && err2 == REGERR_OK )
result = nsInstall::REBOOT_NEEDED;
else
NR_RegDeleteKey( reg, listkey, valname );
}
if (NS_SUCCEEDED(rv))
nsCRT::free(fsrc);
if (NS_SUCCEEDED(rv2))
nsCRT::free(fdest);
}
}
}
NR_RegClose(reg);
}
}
return result;
}
//-----------------------------------------------------------------------------
//
// STARTUP: DO SCHEDULED ACTIONS
//
//-----------------------------------------------------------------------------
void DeleteScheduledFiles(HREG);
void ReplaceScheduledFiles(HREG);
void PerformScheduledTasks(HREG reg)
{
DeleteScheduledFiles( reg );
ReplaceScheduledFiles( reg );
}
void DeleteScheduledFiles( HREG reg )
{
REGERR err;
RKEY key;
REGENUM state = 0;
/* perform scheduled file deletions */
if (REGERR_OK == NR_RegGetKey(reg,ROOTKEY_PRIVATE,REG_DELETE_LIST_KEY,&key))
{
// the delete key exists, so we loop through its children
// and try to delete all the listed files
char namebuf[MAXREGNAMELEN];
char valbuf[MAXREGPATHLEN];
nsFileSpec doomedFile;
nsCOMPtr<nsIFileSpec> spec;
nsresult rv = NS_NewFileSpec(getter_AddRefs(spec));
if (NS_SUCCEEDED(rv))
{
while (REGERR_OK == NR_RegEnumEntries( reg, key, &state, namebuf,
sizeof(namebuf), 0 ) )
{
uint32 bufsize = sizeof(valbuf); // gets changed, must reset
err = NR_RegGetEntry( reg, key, namebuf, valbuf, &bufsize );
if ( err == REGERR_OK )
{
// no need to check return value of
// SetPersistentDescriptorString, it's always NS_OK
spec->SetPersistentDescriptorString(valbuf);
rv = spec->GetFileSpec(&doomedFile);
if (NS_SUCCEEDED(rv))
{
doomedFile.Delete(PR_FALSE);
if ( !doomedFile.Exists() )
{
// deletion successful, don't have to retry
NR_RegDeleteEntry( reg, key, namebuf );
}
}
}
}
/* delete list node if empty */
state = 0;
err = NR_RegEnumEntries(reg, key, &state, namebuf, sizeof(namebuf), 0);
if ( err == REGERR_NOMORE )
{
NR_RegDeleteKey(reg, ROOTKEY_PRIVATE, REG_DELETE_LIST_KEY);
}
}
}
}
void ReplaceScheduledFiles( HREG reg )
{
RKEY key;
/* replace files if any listed */
if (REGERR_OK == NR_RegGetKey(reg,ROOTKEY_PRIVATE,REG_REPLACE_LIST_KEY,&key))
{
char keyname[MAXREGNAMELEN];
char doomedFile[MAXREGPATHLEN];
char srcFile[MAXREGPATHLEN];
nsFileSpec doomedSpec;
nsFileSpec srcSpec;
nsCOMPtr<nsIFileSpec> src;
nsCOMPtr<nsIFileSpec> dest;
nsresult rv1, rv2;
rv1 = NS_NewFileSpec(getter_AddRefs(src));
rv2 = NS_NewFileSpec(getter_AddRefs(dest));
if (NS_SUCCEEDED(rv1) && NS_SUCCEEDED(rv2))
{
uint32 bufsize;
REGENUM state = 0;
while (REGERR_OK == NR_RegEnumSubkeys( reg, key, &state,
keyname, sizeof(keyname), REGENUM_CHILDREN))
{
bufsize = sizeof(srcFile);
REGERR err1 = NR_RegGetEntry( reg, (RKEY)state,
REG_REPLACE_SRCFILE, srcFile, &bufsize);
bufsize = sizeof(doomedFile);
REGERR err2 = NR_RegGetEntry( reg, (RKEY)state,
REG_REPLACE_DESTFILE, doomedFile, &bufsize);
if ( err1 == REGERR_OK && err2 == REGERR_OK )
{
src->SetPersistentDescriptorString(srcFile);
rv1 = src->GetFileSpec(&srcSpec);
dest->SetPersistentDescriptorString(doomedFile);
rv2 = dest->GetFileSpec(&doomedSpec);
if (NS_SUCCEEDED(rv1) && NS_SUCCEEDED(rv2))
{
// finally now try to do the replace
PRInt32 result = ReplaceFileNow( srcSpec, doomedSpec );
if ( result == nsInstall::DOES_NOT_EXIST ||
result == nsInstall::SUCCESS )
{
// This one is done
NR_RegDeleteKey( reg, key, keyname );
}
}
}
}
/* delete list node if empty */
state = 0;
if (REGERR_NOMORE == NR_RegEnumSubkeys( reg, key, &state, keyname,
sizeof(keyname), REGENUM_CHILDREN ))
{
NR_RegDeleteKey(reg, ROOTKEY_PRIVATE, REG_REPLACE_LIST_KEY);
}
}
}
}

View File

@@ -0,0 +1,44 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code,
* released March 31, 1998.
*
* 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):
* Daniel Veditz <dveditz@netscape.com>
* Douglas Turner <dougt@netscape.com>
*/
#ifndef __SCHEDULEDTASKS_H__
#define __SCHEDULEDTASKS_H__
#include "NSReg.h"
//#include "mozreg.h"
#include "nsFileSpec.h"
PR_BEGIN_EXTERN_C
PRInt32 DeleteFileNowOrSchedule(const nsFileSpec& filename);
PRInt32 ReplaceFileNowOrSchedule(nsFileSpec& tmpfile, nsFileSpec& target );
void PerformScheduledTasks(HREG reg);
PR_END_EXTERN_C
#endif

View File

@@ -0,0 +1,139 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/*--------------------------------------------------------------
* GDIFF.H
*
* Constants used in processing the GDIFF format
*--------------------------------------------------------------*/
#include "prio.h"
#include "nsFileSpec.h"
#define GDIFF_MAGIC "\xD1\xFF\xD1\xFF"
#define GDIFF_MAGIC_LEN 4
#define GDIFF_VER 5
#define GDIFF_EOF "\0"
#define GDIFF_VER_POS 4
#define GDIFF_CS_POS 5
#define GDIFF_CSLEN_POS 6
#define GDIFF_HEADERSIZE 7
#define GDIFF_APPDATALEN 4
#define GDIFF_CS_NONE 0
#define GDIFF_CS_MD5 1
#define GDIFF_CS_SHA 2
#define GDIFF_CS_CRC32 32
#define CRC32_LEN 4
/*--------------------------------------
* GDIFF opcodes
*------------------------------------*/
#define ENDDIFF 0
#define ADD8MAX 246
#define ADD16 247
#define ADD32 248
#define COPY16BYTE 249
#define COPY16SHORT 250
#define COPY16LONG 251
#define COPY32BYTE 252
#define COPY32SHORT 253
#define COPY32LONG 254
#define COPY64 255
/* instruction sizes */
#define ADD16SIZE 2
#define ADD32SIZE 4
#define COPY16BYTESIZE 3
#define COPY16SHORTSIZE 4
#define COPY16LONGSIZE 6
#define COPY32BYTESIZE 5
#define COPY32SHORTSIZE 6
#define COPY32LONGSIZE 8
#define COPY64SIZE 12
/*--------------------------------------
* error codes
*------------------------------------*/
#define GDIFF_OK 0
#define GDIFF_ERR_UNKNOWN -1
#define GDIFF_ERR_ARGS -2
#define GDIFF_ERR_ACCESS -3
#define GDIFF_ERR_MEM -4
#define GDIFF_ERR_HEADER -5
#define GDIFF_ERR_BADDIFF -6
#define GDIFF_ERR_OPCODE -7
#define GDIFF_ERR_OLDFILE -8
#define GDIFF_ERR_CHKSUMTYPE -9
#define GDIFF_ERR_CHECKSUM -10
#define GDIFF_ERR_CHECKSUM_TARGET -11
#define GDIFF_ERR_CHECKSUM_RESULT -12
/*--------------------------------------
* types
*------------------------------------*/
#ifndef AIX
#ifdef OSF1
#include <sys/types.h>
#else
typedef unsigned char uchar;
#endif
#endif
typedef struct _diffdata {
PRFileDesc* fSrc;
PRFileDesc* fOut;
PRFileDesc* fDiff;
uint8 checksumType;
uint8 checksumLength;
uchar* oldChecksum;
uchar* newChecksum;
PRBool bMacAppleSingle;
PRBool bWin32BoundImage;
uchar* databuf;
uint32 bufsize;
} DIFFDATA;
typedef DIFFDATA* pDIFFDATA;
/*--------------------------------------
* miscellaneous
*------------------------------------*/
#define APPFLAG_W32BOUND "autoinstall:Win32PE"
#define APPFLAG_APPLESINGLE "autoinstall:AppleSingle"
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif

View File

@@ -0,0 +1,106 @@
#!nmake
#
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 Communicator client code,
# released March 31, 1998.
#
# 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):
# Daniel Veditz <dveditz@netscape.com>
# Douglas Turner <dougt@netscape.com>
DEPTH=..\..
include <$(DEPTH)/config/config.mak>
MAKE_OBJ_TYPE = DLL
MODULE=xpinstal
XPIDL_MODULE=xpinstall
DLL=.\$(OBJDIR)\$(MODULE).dll
DEFINES=-D_IMPL_NS_DOM -DWIN32_LEAN_AND_MEAN
LCFLAGS = \
$(LCFLAGS) \
$(DEFINES) \
$(NULL)
LLIBS = \
$(DIST)\lib\xpcom.lib \
$(DIST)\lib\js3250.lib \
$(DIST)\lib\jsdombase_s.lib \
$(DIST)\lib\jsdomevents_s.lib \
$(DIST)\lib\zlib.lib \
$(DIST)\lib\strres.lib \
$(LIBNSPR) \
$(DIST)\lib\mozreg.lib \
$(NULL)
OBJS = \
.\$(OBJDIR)\nsInstall.obj \
.\$(OBJDIR)\nsInstallTrigger.obj \
.\$(OBJDIR)\nsInstallVersion.obj \
.\$(OBJDIR)\nsInstallFolder.obj \
.\$(OBJDIR)\nsJSInstall.obj \
.\$(OBJDIR)\nsJSFile.obj \
.\$(OBJDIR)\nsJSInstallTriggerGlobal.obj \
.\$(OBJDIR)\nsJSInstallVersion.obj \
.\$(OBJDIR)\nsSoftwareUpdate.obj \
.\$(OBJDIR)\nsSoftwareUpdateRun.obj \
.\$(OBJDIR)\nsInstallFile.obj \
.\$(OBJDIR)\nsInstallDelete.obj \
.\$(OBJDIR)\nsInstallExecute.obj \
.\$(OBJDIR)\nsInstallPatch.obj \
.\$(OBJDIR)\nsInstallUninstall.obj \
.\$(OBJDIR)\nsInstallResources.obj \
.\$(OBJDIR)\nsTopProgressNotifier.obj \
.\$(OBJDIR)\nsLoggingProgressNotifier.obj\
.\$(OBJDIR)\ScheduledTasks.obj \
.\$(OBJDIR)\nsWinReg.obj \
.\$(OBJDIR)\nsJSWinReg.obj \
.\$(OBJDIR)\nsWinRegItem.obj \
.\$(OBJDIR)\nsWinRegValue.obj \
.\$(OBJDIR)\nsWinProfile.obj \
.\$(OBJDIR)\nsJSWinProfile.obj \
.\$(OBJDIR)\nsWinProfileItem.obj \
.\$(OBJDIR)\nsInstallProgressDialog.obj \
.\$(OBJDIR)\nsXPITriggerInfo.obj \
.\$(OBJDIR)\nsXPInstallManager.obj \
.\$(OBJDIR)\nsInstallFileOpItem.obj \
.\$(OBJDIR)\nsWinShortcut.obj \
.\$(OBJDIR)\nsJSFileSpecObj.obj \
# .\$(OBJDIR)\nsUpdateNotification.obj \
$(NULL)
WIN_LIBS= \
ole32.lib \
$(NULL)
include <$(DEPTH)\config\rules.mak>
install:: $(DLL)
$(MAKE_INSTALL) .\$(OBJDIR)\$(MODULE).lib $(DIST)\lib
$(MAKE_INSTALL) .\$(OBJDIR)\$(MODULE).dll $(DIST)\bin\components
clobber::
$(RM) $(DIST)\lib\$(MODULE).lib
$(RM) $(DIST)\bin\components\$(MODULE).dll

View File

@@ -0,0 +1,744 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code, released March
* 31, 1998.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1999
* Netscape Communications Corporation. All Rights Reserved.
*
* Contributors:
* Samir Gehani <sgehani@netscape.com>
*/
#ifndef _NS_APPLESINGLEDECODER_H_
#include "nsAppleSingleDecoder.h"
#endif
#include "MoreFilesExtras.h"
#include "MoreDesktopMgr.h"
#include "IterateDirectory.h"
#include "nsISupportsUtils.h"
/*----------------------------------------------------------------------*
* Constructors/Destructor
*----------------------------------------------------------------------*/
MOZ_DECL_CTOR_COUNTER(nsAppleSingleDecoder);
nsAppleSingleDecoder::nsAppleSingleDecoder(FSSpec *inSpec, FSSpec *outSpec)
: mInSpec(NULL),
mOutSpec(NULL),
mInRefNum(0),
mRenameReqd(false)
{
MOZ_COUNT_CTOR(nsAppleSingleDecoder);
if (inSpec && outSpec)
{
/* merely point to FSSpecs, not own 'em */
mInSpec = inSpec;
mOutSpec = outSpec;
}
}
nsAppleSingleDecoder::nsAppleSingleDecoder()
: mInSpec(NULL),
mOutSpec(NULL),
mInRefNum(0),
mRenameReqd(false)
{
MOZ_COUNT_CTOR(nsAppleSingleDecoder);
}
nsAppleSingleDecoder::~nsAppleSingleDecoder()
{
/* not freeing FSSpecs since we don't own 'em */
MOZ_COUNT_DTOR(nsAppleSingleDecoder);
}
/*----------------------------------------------------------------------*
* Public methods
*----------------------------------------------------------------------*/
OSErr
nsAppleSingleDecoder::Decode()
{
OSErr err = noErr;
ASHeader header;
long bytesRead = sizeof(header);
// param check
if (!mInSpec || !mOutSpec)
return paramErr;
// check for existence
FSSpec tmp;
err = FSMakeFSSpec(mInSpec->vRefNum, mInSpec->parID, mInSpec->name, &tmp);
if (err == fnfErr)
return err;
MAC_ERR_CHECK(FSpOpenDF( mInSpec, fsRdPerm, &mInRefNum ));
MAC_ERR_CHECK(FSRead( mInRefNum, &bytesRead, &header ));
if ( (bytesRead != sizeof(header)) ||
(header.magicNum != 0x00051600) ||
(header.versionNum != 0x00020000) ||
(header.numEntries == 0) ) // empty file?
return -1;
// create the outSpec which we'll rename correctly later
err = FSMakeFSSpec( mInSpec->vRefNum, mInSpec->parID, "\pdecode", mOutSpec );
if (err!=noErr && err!=fnfErr)
return err;
MAC_ERR_CHECK(FSMakeUnique( mOutSpec ));
MAC_ERR_CHECK(FSpCreate( mOutSpec, 'MOZZ', '????', 0 ));
/* Loop through the entries, processing each.
** Set the time/date stamps last, because otherwise they'll
** be destroyed when we write.
*/
{
Boolean hasDateEntry = false;
ASEntry dateEntry;
long offset;
ASEntry entry;
for ( int i=0; i < header.numEntries; i++ )
{
offset = sizeof( ASHeader ) + sizeof( ASEntry ) * i;
MAC_ERR_CHECK(SetFPos( mInRefNum, fsFromStart, offset ));
bytesRead = sizeof(entry);
MAC_ERR_CHECK(FSRead( mInRefNum, &bytesRead, &entry ));
if (bytesRead != sizeof(entry))
return -1;
if ( entry.entryID == AS_FILEDATES )
{
hasDateEntry = true;
dateEntry = entry;
}
else
MAC_ERR_CHECK(ProcessASEntry( entry ));
}
if ( hasDateEntry )
MAC_ERR_CHECK(ProcessASEntry( dateEntry ));
}
// close the inSpec
FSClose( mInRefNum );
// rename if need be
if (mRenameReqd)
{
FSSpec old; // delete old version of target file
FSMakeFSSpec(mInSpec->vRefNum, mInSpec->parID, mInSpec->name, &old);
MAC_ERR_CHECK(FSpDelete(&old));
MAC_ERR_CHECK(FSpRename(mOutSpec, mInSpec->name));
// reflect change in outSpec
nsAppleSingleDecoder::PLstrncpy( mOutSpec->name, mInSpec->name, mInSpec->name[0] );
mOutSpec->name[0] = mInSpec->name[0];
mRenameReqd = false; // XXX redundant reinit?
}
return err;
}
OSErr
nsAppleSingleDecoder::Decode(FSSpec *inSpec, FSSpec *outSpec)
{
OSErr err = noErr;
// param check
if (inSpec && outSpec)
{
mInSpec = inSpec; // reinit
mOutSpec = outSpec;
mRenameReqd = false;
}
else
return paramErr;
err = Decode();
return err;
}
pascal void
DecodeDirIterateFilter(const CInfoPBRec * const cpbPtr, Boolean *quitFlag, void *yourDataPtr)
{
OSErr err = noErr;
FSSpec currFSp, outFSp;
nsAppleSingleDecoder* thisObj = NULL;
Boolean isDir = false;
long dummy;
// param check
if (!yourDataPtr || !cpbPtr || !quitFlag)
return;
*quitFlag = false;
// extract 'this' -- an nsAppleSingleDecoder instance
thisObj = (nsAppleSingleDecoder*) yourDataPtr;
// make an FSSpec from the CInfoPBRec*
err = FSMakeFSSpec(cpbPtr->hFileInfo.ioVRefNum, cpbPtr->hFileInfo.ioFlParID,
cpbPtr->hFileInfo.ioNamePtr, &currFSp);
if (err == noErr)
{
FSpGetDirectoryID(&currFSp, &dummy, &isDir);
// if current FSSpec is file
if (!isDir)
{
// if file is in AppleSingle format
if (nsAppleSingleDecoder::IsAppleSingleFile(&currFSp))
{
// decode file
thisObj->Decode(&currFSp, &outFSp);
}
}
else
{
// else if current FSSpec is folder ignore
// XXX never reached?
return;
}
}
}
OSErr
nsAppleSingleDecoder::DecodeFolder(FSSpec *aFolder)
{
OSErr err = noErr;
long dummy;
Boolean isDir = false;
// check that FSSpec is folder
if (aFolder)
{
FSpGetDirectoryID(aFolder, &dummy, &isDir);
if (!isDir)
return dirNFErr;
}
// recursively enumerate contents of folder (maxLevels=0 means recurse all)
FSpIterateDirectory(aFolder, 0, DecodeDirIterateFilter, (void*)this);
return err;
}
Boolean
nsAppleSingleDecoder::IsAppleSingleFile(FSSpec *inSpec)
{
OSErr err;
Boolean bAppleSingle = false;
short inRefNum;
UInt32 magic;
long bytesRead = sizeof(magic);
// param checks
if (!inSpec)
return false;
// check for existence
FSSpec tmp;
err = FSMakeFSSpec(inSpec->vRefNum, inSpec->parID, inSpec->name, &tmp);
if (err!=noErr)
return false;
// open and read the magic number len bytes
err = FSpOpenDF( inSpec, fsRdPerm, &inRefNum );
if (err!=noErr)
return false;
err = FSRead( inRefNum, &bytesRead, &magic );
if (err!=noErr)
return false;
FSClose(inRefNum);
if (bytesRead != sizeof(magic))
return false;
// check if bytes read match magic number
bAppleSingle = (magic == 0x00051600);
return bAppleSingle;
}
/*----------------------------------------------------------------------*
* Private methods
*----------------------------------------------------------------------*/
OSErr
nsAppleSingleDecoder::ProcessASEntry(ASEntry inEntry)
{
switch (inEntry.entryID)
{
case AS_DATA:
return ProcessDataFork( inEntry );
break;
case AS_RESOURCE:
return ProcessResourceFork( inEntry );
break;
case AS_REALNAME:
ProcessRealName( inEntry );
break;
// return 0; // Ignore these errors in ASD <--- XXX remove
case AS_COMMENT:
// return ProcessComment( inEntry );
break;
case AS_ICONBW:
// return ProcessIconBW( inEntry );
break;
case AS_ICONCOLOR:
// return ProcessIconColor( inEntry );
break;
case AS_FILEDATES:
return ProcessFileDates( inEntry );
break;
case AS_FINDERINFO:
return ProcessFinderInfo( inEntry );
break;
case AS_MACINFO:
return ProcessMacInfo( inEntry );
break;
case AS_PRODOSINFO:
case AS_MSDOSINFO:
case AS_AFPNAME:
case AS_AFPINFO:
case AS_AFPDIRID:
default:
return 0;
}
return 0;
}
OSErr
nsAppleSingleDecoder::ProcessDataFork(ASEntry inEntry)
{
OSErr err = noErr;
SInt16 refNum;
/* Setup the files */
err = FSpOpenDF (mOutSpec, fsWrPerm, &refNum);
if ( err == noErr )
err = EntryToMacFile( inEntry, refNum );
FSClose( refNum );
return err;
}
OSErr
nsAppleSingleDecoder::ProcessResourceFork(ASEntry inEntry)
{
OSErr err = noErr;
SInt16 refNum;
err = FSpOpenRF(mOutSpec, fsWrPerm, &refNum);
if ( err == noErr )
err = EntryToMacFile( inEntry, refNum );
FSClose( refNum );
return err;
}
OSErr
nsAppleSingleDecoder::ProcessRealName(ASEntry inEntry)
{
OSErr err = noErr;
Str255 newName;
long bytesRead;
if ( inEntry.entryLength > 32 ) /* Max file name length for the Mac */
return -1;
MAC_ERR_CHECK(SetFPos(mInRefNum, fsFromStart, inEntry.entryOffset));
bytesRead = inEntry.entryLength;
MAC_ERR_CHECK(FSRead(mInRefNum, &bytesRead, &newName[1]));
if (bytesRead != inEntry.entryLength)
return -1;
newName[0] = inEntry.entryLength;
err = FSpRename(mOutSpec, newName);
if (err == dupFNErr)
{
// if we are trying to rename temp decode file to src name, rename later
if (nsAppleSingleDecoder::PLstrcmp(newName, mInSpec->name))
{
mRenameReqd = true;
return noErr;
}
FSSpec old; // delete old version of target file
FSMakeFSSpec(mOutSpec->vRefNum, mOutSpec->parID, newName, &old);
MAC_ERR_CHECK(FSpDelete(&old));
MAC_ERR_CHECK(FSpRename(mOutSpec, newName));
}
nsAppleSingleDecoder::PLstrncpy( mOutSpec->name, newName, inEntry.entryLength );
mOutSpec->name[0] = inEntry.entryLength;
return err;
}
OSErr
nsAppleSingleDecoder::ProcessFileDates(ASEntry inEntry)
{
OSErr err = noErr;
ASFileDates dates;
long bytesRead;
if ( inEntry.entryLength != sizeof(dates) ) /* Max file name length for the Mac */
return -1;
MAC_ERR_CHECK(SetFPos(mInRefNum, fsFromStart, inEntry.entryOffset));
bytesRead = inEntry.entryLength;
MAC_ERR_CHECK(FSRead(mInRefNum, &bytesRead, &dates));
if (bytesRead != inEntry.entryLength)
return -1;
Str31 name;
nsAppleSingleDecoder::PLstrncpy(name, mOutSpec->name, mOutSpec->name[0]);
name[0] = mOutSpec->name[0];
CInfoPBRec pb;
pb.hFileInfo.ioNamePtr = &name[0];
pb.hFileInfo.ioVRefNum = mOutSpec->vRefNum;
pb.hFileInfo.ioDirID = mOutSpec->parID;
pb.hFileInfo.ioFDirIndex = 0; /* use ioNamePtr and ioDirID */
err = PBGetCatInfoSync(&pb);
if ( err != noErr )
return -1;
#define YR_2000_SECONDS 3029529600
pb.hFileInfo.ioFlCrDat = dates.create + YR_2000_SECONDS;
pb.hFileInfo.ioFlMdDat = dates.modify + YR_2000_SECONDS;
pb.hFileInfo.ioFlBkDat = dates.backup + YR_2000_SECONDS;
/* Not sure if mac has the last access time */
nsAppleSingleDecoder::PLstrncpy(name, mOutSpec->name, mOutSpec->name[0]);
name[0] = mOutSpec->name[0];
pb.hFileInfo.ioNamePtr = name;
pb.hFileInfo.ioVRefNum = mOutSpec->vRefNum;
pb.hFileInfo.ioDirID = mOutSpec->parID;
pb.hFileInfo.ioFDirIndex = 0; /* use ioNamePtr and ioDirID */
err = PBSetCatInfo(&pb, false);
return err;
}
OSErr
nsAppleSingleDecoder::ProcessFinderInfo(ASEntry inEntry)
{
OSErr err = noErr;
ASFinderInfo info;
long bytesRead;
if (inEntry.entryLength != sizeof( ASFinderInfo ))
return -1;
MAC_ERR_CHECK(SetFPos(mInRefNum, fsFromStart, inEntry.entryOffset));
bytesRead = sizeof(info);
MAC_ERR_CHECK(FSRead(mInRefNum, &bytesRead, &info));
if (bytesRead != inEntry.entryLength)
return -1;
err = FSpSetFInfo(mOutSpec, &info.ioFlFndrInfo);
if (err!=noErr && err!=fnfErr)
return err;
Str31 name;
nsAppleSingleDecoder::PLstrncpy(name, mOutSpec->name, mOutSpec->name[0]);
name[0] = mOutSpec->name[0];
CInfoPBRec pb;
pb.hFileInfo.ioNamePtr = name;
pb.hFileInfo.ioVRefNum = mOutSpec->vRefNum;
pb.hFileInfo.ioDirID = mOutSpec->parID;
pb.hFileInfo.ioFDirIndex = 0; /* use ioNamePtr and ioDirID */
MAC_ERR_CHECK(PBGetCatInfoSync(&pb));
pb.hFileInfo.ioNamePtr = name;
pb.hFileInfo.ioVRefNum = mOutSpec->vRefNum;
pb.hFileInfo.ioDirID = mOutSpec->parID;
pb.hFileInfo.ioFDirIndex = 0; /* use ioNamePtr and ioDirID */
pb.hFileInfo.ioFlXFndrInfo = info.ioFlXFndrInfo;
err = PBSetCatInfo(&pb, false);
if (info.ioFlFndrInfo.fdType == 'APPL')
{
// need to register in desktop database or bad things will happen
DTSetAPPL( NULL,
mOutSpec->vRefNum,
info.ioFlFndrInfo.fdCreator,
mOutSpec->parID,
mOutSpec->name );
}
return err;
}
OSErr
nsAppleSingleDecoder::ProcessMacInfo(ASEntry inEntry)
{
OSErr err = noErr;
ASMacInfo info;
long bytesRead;
if (inEntry.entryLength != sizeof( ASMacInfo ))
return -1;
MAC_ERR_CHECK(SetFPos(mInRefNum, fsFromStart, inEntry.entryOffset));
bytesRead = sizeof(info);
MAC_ERR_CHECK(FSRead(mInRefNum, &bytesRead, &info));
if (bytesRead != inEntry.entryLength)
return -1;
Str31 name;
nsAppleSingleDecoder::PLstrncpy(name, mOutSpec->name, mOutSpec->name[0]);
name[0] = mOutSpec->name[0];
CInfoPBRec pb;
pb.hFileInfo.ioNamePtr = name;
pb.hFileInfo.ioVRefNum = mOutSpec->vRefNum;
pb.hFileInfo.ioDirID = mOutSpec->parID;
pb.hFileInfo.ioFDirIndex = 0; /* use ioNamePtr and ioDirID */
MAC_ERR_CHECK(PBGetCatInfoSync(&pb));
pb.hFileInfo.ioNamePtr = name;
pb.hFileInfo.ioVRefNum = mOutSpec->vRefNum;
pb.hFileInfo.ioDirID = mOutSpec->parID;
pb.hFileInfo.ioFlAttrib = info.ioFlAttrib;
err = PBSetCatInfo(&pb, false);
return err;
}
OSErr
nsAppleSingleDecoder::EntryToMacFile(ASEntry inEntry, UInt16 inTargetSpecRefNum)
{
#define BUFFER_SIZE 8192
OSErr err = noErr;
char buffer[BUFFER_SIZE];
long totalRead = 0, bytesRead, bytesToWrite;
MAC_ERR_CHECK(SetFPos( mInRefNum, fsFromStart, inEntry.entryOffset ));
while ( totalRead < inEntry.entryLength )
{
// Should we yield in here?
bytesRead = BUFFER_SIZE;
err = FSRead( mInRefNum, &bytesRead, buffer );
if (err!=noErr && err!=eofErr)
return err;
if ( bytesRead <= 0 )
return -1;
bytesToWrite = totalRead + bytesRead > inEntry.entryLength ?
inEntry.entryLength - totalRead :
bytesRead;
totalRead += bytesRead;
MAC_ERR_CHECK(FSWrite(inTargetSpecRefNum, &bytesToWrite, buffer));
}
return err;
}
OSErr DTSetAPPL(Str255 volName,
short vRefNum,
OSType creator,
long applParID,
Str255 applName)
{
OSErr err;
DTPBRec *pb = NULL;
short dtRefNum;
short realVRefNum;
Boolean newDTDatabase;
/* get the real vRefnum */
err = DetermineVRefNum(volName, vRefNum, &realVRefNum);
if (err == noErr)
{
err = DTOpen(volName, vRefNum, &dtRefNum, &newDTDatabase);
if (err == noErr && !newDTDatabase)
{
pb = (DTPBRec*) NewPtrClear( sizeof(DTPBRec) );
if (pb==NULL) return -1;
pb->ioNamePtr = applName;
pb->ioDTRefNum = dtRefNum;
pb->ioDirID = applParID;
pb->ioFileCreator = creator;
err = PBDTAddAPPLSync(pb);
if (pb) DisposePtr((Ptr)pb);
}
}
return err;
}
OSErr
nsAppleSingleDecoder::FSMakeUnique(FSSpec *ioSpec)
{
OSErr err = noErr;
Boolean bUnique = false;
FSSpec tmp;
long uniqueID = 0;
Str255 name;
short i, j;
unsigned char puniqueID[16];
char *cuniqueIDPtr;
// grab suggested name from in-out FSSpec
nsAppleSingleDecoder::PLstrncpy(name, ioSpec->name, ioSpec->name[0]);
name[0] = ioSpec->name[0];
for (i=0; i<65536; i++) // prevent infinite loop
{
if (!bUnique)
{
err = FSMakeFSSpec( ioSpec->vRefNum, ioSpec->parID, name, &tmp );
if (err == fnfErr)
{
bUnique = true;
break;
}
else if (err == noErr) // file already exists
{
// grab suggested name from in-out FSSpec
nsAppleSingleDecoder::PLstrncpy(name, ioSpec->name, ioSpec->name[0]);
name[0] = ioSpec->name[0];
// attempt to create a new unique file name
nsAppleSingleDecoder::PLstrncat( name, "\p-", 1 );
// tack on digit(s)
cuniqueIDPtr = nsAppleSingleDecoder::ltoa(uniqueID++);
puniqueID[0] = strlen(cuniqueIDPtr);
for (j=0; j<strlen(cuniqueIDPtr); j++)
{
puniqueID[j+1] = cuniqueIDPtr[j];
}
nsAppleSingleDecoder::PLstrncat( name, puniqueID, puniqueID[0] );
DisposePtr((Ptr)cuniqueIDPtr);
}
else
return err;
}
}
// put back unique name into in-out FSSpec
nsAppleSingleDecoder::PLstrncpy(ioSpec->name, name, name[0]);
ioSpec->name[0] = name[0];
return noErr;
}
/*----------------------------------------------------------------------*
* Utilities
*----------------------------------------------------------------------*/
char *
nsAppleSingleDecoder::ltoa(long n)
{
char *s;
int i, j, sign, tmp;
/* check sign and convert to positive to stringify numbers */
if ( (sign = n) < 0)
n = -n;
i = 0;
s = (char*) malloc(sizeof(char));
/* grow string as needed to add numbers from powers of 10 down till none left */
do
{
s = (char*) realloc(s, (i+1)*sizeof(char));
s[i++] = n % 10 + '0'; /* '0' or 30 is where ASCII numbers start from */
s[i] = '\0';
}
while( (n /= 10) > 0);
/* tack on minus sign if we found earlier that this was negative */
if (sign < 0)
{
s = (char*) realloc(s, (i+1)*sizeof(char));
s[i++] = '-';
}
s[i] = '\0';
/* pop numbers (and sign) off of string to push back into right direction */
for (i = 0, j = strlen(s) - 1; i < j; i++, j--)
{
tmp = s[i];
s[i] = s[j];
s[j] = tmp;
}
return s;
}
StringPtr
nsAppleSingleDecoder::PLstrncpy(StringPtr dst, ConstStr255Param src, short max)
{
int srcLen = src[0];
if (srcLen > max)
srcLen = max;
dst[0] = srcLen;
memcpy(&dst[1], &src[1], srcLen);
return dst;
}
StringPtr
nsAppleSingleDecoder::PLstrncat(StringPtr dst, ConstStr255Param src, short max)
{
int srcLen = src[0], dstLen = dst[0];
if (srcLen > max)
srcLen = max;
dst[0] += srcLen;
memcpy(&dst[dstLen+1], &src[1], srcLen);
return dst;
}
Boolean
nsAppleSingleDecoder::PLstrcmp(StringPtr str1, StringPtr str2)
{
Boolean bEqual = true;
// check for same length
if (str1[0] == str2[0])
{
// verify mem blocks match
if (0 != memcmp(&str1[1], &str2[1], str1[0]))
bEqual = false;
}
else
bEqual = false;
return bEqual;
}

View File

@@ -0,0 +1,222 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code, released March
* 31, 1998.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1999
* Netscape Communications Corporation. All Rights Reserved.
*
* Contributors:
* Samir Gehani <sgehani@netscape.com>
*/
/*----------------------------------------------------------------------*
* Implements a simple AppleSingle decoder, as described in RFC1740
* http://andrew2.andrew.cmu.edu/rfc/rfc1740.html
*----------------------------------------------------------------------*/
#ifndef macintosh
#error Sorry! This is Mac only functionality!
#endif
#pragma options align=mac68k
#ifndef _NS_APPLESINGLEDECODER_H_
#define _NS_APPLESINGLEDECODER_H_
#include <stdlib.h>
#include <string.h>
#include <Files.h>
#include <Errors.h>
/*----------------------------------------------------------------------*
* Struct definitions from RFC1740
*----------------------------------------------------------------------*/
typedef struct ASHeader /* header portion of AppleSingle */
{
/* AppleSingle = 0x00051600; AppleDouble = 0x00051607 */
UInt32 magicNum; /* internal file type tag */
UInt32 versionNum; /* format version: 2 = 0x00020000 */
UInt8 filler[16]; /* filler, currently all bits 0 */
UInt16 numEntries; /* number of entries which follow */
} ASHeader ; /* ASHeader */
typedef struct ASEntry /* one AppleSingle entry descriptor */
{
UInt32 entryID; /* entry type: see list, 0 invalid */
UInt32 entryOffset; /* offset, in octets, from beginning */
/* of file to this entry's data */
UInt32 entryLength; /* length of data in octets */
} ASEntry; /* ASEntry */
typedef struct ASFinderInfo
{
FInfo ioFlFndrInfo; /* PBGetFileInfo() or PBGetCatInfo() */
FXInfo ioFlXFndrInfo; /* PBGetCatInfo() (HFS only) */
} ASFinderInfo; /* ASFinderInfo */
typedef struct ASMacInfo /* entry ID 10, Macintosh file information */
{
UInt8 filler[3]; /* filler, currently all bits 0 */
UInt8 ioFlAttrib; /* PBGetFileInfo() or PBGetCatInfo() */
} ASMacInfo;
typedef struct ASFileDates /* entry ID 8, file dates info */
{
SInt32 create; /* file creation date/time */
SInt32 modify; /* last modification date/time */
SInt32 backup; /* last backup date/time */
SInt32 access; /* last access date/time */
} ASFileDates; /* ASFileDates */
/* entryID list */
#define AS_DATA 1 /* data fork */
#define AS_RESOURCE 2 /* resource fork */
#define AS_REALNAME 3 /* File's name on home file system */
#define AS_COMMENT 4 /* standard Mac comment */
#define AS_ICONBW 5 /* Mac black & white icon */
#define AS_ICONCOLOR 6 /* Mac color icon */
/* 7 /* not used */
#define AS_FILEDATES 8 /* file dates; create, modify, etc */
#define AS_FINDERINFO 9 /* Mac Finder info & extended info */
#define AS_MACINFO 10 /* Mac file info, attributes, etc */
#define AS_PRODOSINFO 11 /* Pro-DOS file info, attrib., etc */
#define AS_MSDOSINFO 12 /* MS-DOS file info, attributes, etc */
#define AS_AFPNAME 13 /* Short name on AFP server */
#define AS_AFPINFO 14 /* AFP file info, attrib., etc */
#define AS_AFPDIRID 15 /* AFP directory ID */
/*----------------------------------------------------------------------*
* Macros
*----------------------------------------------------------------------*/
#define MAC_ERR_CHECK(_funcCall) \
err = _funcCall; \
if (err!=noErr) \
return err;
class nsAppleSingleDecoder
{
public:
nsAppleSingleDecoder(FSSpec *inSpec, FSSpec *outSpec);
nsAppleSingleDecoder();
~nsAppleSingleDecoder();
/**
* Decode
*
* Takes an "in" FSSpec for the source file in AppleSingle
* format to decode and write out to an "out" FSSpec.
* This form is used when the Decode(void) method has already
* been invoked once and this object is reused to decode
* another AppleSingled file: useful in iteration to avoid
* nsAppleSingleDecoder object instantiation per file.
*
* @param inSpec the AppleSingled file to decode
* @param outSpec the destination file in which the decoded
* data was written out (empty when passed in
* and filled on return)
* @return err a standard MacOS OSErr where noErr means OK
*/
OSErr Decode(FSSpec *inSpec, FSSpec *outSpec);
/**
* Decode
*
* Decodes the AppleSingled file passed in to the constructor
* and writes out the decoded data to the outSpec passed to the
* constructor.
*
* @return err a standard MacOS OSErr where noErr = OK
*/
OSErr Decode();
/**
* DecodeFolder
*
* Traverses arbitrarily nested subdirs decoding any files
* in AppleSingle format and leaving other files alone.
*
* @param aFolder the folder whose contents to decode
* @return err a standard MacOS err (dirNFErr if invalid dir, noErr = OK)
*/
OSErr DecodeFolder(FSSpec *aFolder);
/**
* IsAppleSingleFile
*
* Checks the file header to see whether this is an AppleSingle
* version 2 file by matching the magicNum field in the header.
*
* @param inSpec the file to check
* @return bAppleSingle a Boolean where true indicates this is
* in fact an AppleSingle file
*/
static Boolean IsAppleSingleFile(FSSpec *inSpec);
/**
* String utilities to ensure building standalone
* since Mozilla doesn't use PLStringFuncs.
*/
static StringPtr PLstrncpy(StringPtr dst, ConstStr255Param src, short max);
static StringPtr PLstrncat(StringPtr dst, ConstStr255Param src, short max);
static Boolean PLstrcmp(StringPtr str1, StringPtr str2);
/**
* ltoa -- long to ascii
*
* Converts a long to a C string. We allocate
* a string of the appropriate size and the caller
* should assume ownership of the returned pointer.
*/
static char *ltoa(long n);
private:
FSSpec *mInSpec;
FSSpec *mOutSpec;
short mInRefNum; // cache since it's used through the life of one Decode cycle
Boolean mRenameReqd;
OSErr ProcessASEntry(ASEntry inEntry);
OSErr ProcessDataFork(ASEntry inEntry);
OSErr ProcessResourceFork(ASEntry inEntry);
OSErr ProcessRealName(ASEntry inEntry);
OSErr ProcessFileDates(ASEntry inEntry);
OSErr ProcessFinderInfo(ASEntry inEntry);
OSErr ProcessMacInfo(ASEntry inEntry);
OSErr EntryToMacFile(ASEntry inEntry, UInt16 inTargetSpecRefNum);
OSErr FSMakeUnique(FSSpec *ioSpec);
};
#ifdef __cplusplus
extern "C" {
#endif
OSErr DTSetAPPL(Str255 volName,short vRefNum,OSType creator,long applParID,Str255 applName);
pascal void
DecodeDirIterateFilter(const CInfoPBRec * const cpbPtr, Boolean *quitFlag, void *yourDataPtr);
#ifdef __cplusplus
}
#endif
#pragma options align=reset
#endif /* _NS_APPLESINGLEDECODER_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,323 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code,
* released March 31, 1998.
*
* 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):
* Daniel Veditz <dveditz@netscape.com>
* Douglas Turner <dougt@netscape.com>
*/
#ifndef __NS_INSTALL_H__
#define __NS_INSTALL_H__
#include "nscore.h"
#include "nsISupports.h"
#include "jsapi.h"
#include "plevent.h"
#include "nsString.h"
#include "nsFileSpec.h"
#include "nsVoidArray.h"
#include "nsHashtable.h"
#include "nsCOMPtr.h"
#include "nsSoftwareUpdate.h"
#include "nsInstallObject.h"
#include "nsInstallVersion.h"
#include "nsInstallFolder.h"
#include "nsIXPINotifier.h"
#include "nsIStringBundle.h"
#include "nsILocale.h"
#include "nsIEventQueueService.h"
#include "nsIServiceManager.h"
#include "nsIComponentManager.h"
#include "nsIPersistentProperties.h"
#include "nsIEnumerator.h"
#include "nsIZipReader.h"
class nsInstallInfo
{
public:
nsInstallInfo( nsIFileSpec* aFile,
const PRUnichar* aURL,
const PRUnichar* aArgs,
long aFlags,
nsIXPINotifier* aNotifier);
virtual ~nsInstallInfo();
nsresult GetLocalFile(nsFileSpec& aSpec);
void GetURL(nsString& aURL) { aURL = mURL; }
void GetArguments(nsString& aArgs) { aArgs = mArgs; }
long GetFlags() { return mFlags; }
nsIXPINotifier* GetNotifier() { return mNotifier; };
private:
nsresult mError;
long mFlags;
nsString mURL;
nsString mArgs;
nsCOMPtr<nsIFileSpec> mFile;
nsCOMPtr<nsIXPINotifier> mNotifier;
};
#ifdef XP_PC
#define FILESEP '\\'
#elif defined XP_MAC
#define FILESEP ':'
#elif defined XP_BEOS
#define FILESEP '/'
#else
#define FILESEP '/'
#endif
class nsInstall
{
friend class nsWinReg;
friend class nsWinProfile;
public:
enum
{
BAD_PACKAGE_NAME = -200,
UNEXPECTED_ERROR = -201,
ACCESS_DENIED = -202,
TOO_MANY_CERTIFICATES = -203,
NO_INSTALL_SCRIPT = -204,
NO_CERTIFICATE = -205,
NO_MATCHING_CERTIFICATE = -206,
CANT_READ_ARCHIVE = -207,
INVALID_ARGUMENTS = -208,
ILLEGAL_RELATIVE_PATH = -209,
USER_CANCELLED = -210,
INSTALL_NOT_STARTED = -211,
SILENT_MODE_DENIED = -212,
NO_SUCH_COMPONENT = -213,
DOES_NOT_EXIST = -214,
READ_ONLY = -215,
IS_DIRECTORY = -216,
NETWORK_FILE_IS_IN_USE = -217,
APPLE_SINGLE_ERR = -218,
INVALID_PATH_ERR = -219,
PATCH_BAD_DIFF = -220,
PATCH_BAD_CHECKSUM_TARGET = -221,
PATCH_BAD_CHECKSUM_RESULT = -222,
UNINSTALL_FAILED = -223,
PACKAGE_FOLDER_NOT_SET = -224,
EXTRACTION_FAILED = -225,
FILENAME_ALREADY_USED = -226,
ABORT_INSTALL = -227,
DOWNLOAD_ERROR = -228,
SCRIPT_ERROR = -229,
ALREADY_EXISTS = -230,
IS_FILE = -231,
SOURCE_DOES_NOT_EXIST = -232,
SOURCE_IS_DIRECTORY = -233,
SOURCE_IS_FILE = -234,
INSUFFICIENT_DISK_SPACE = -235,
FILENAME_TOO_LONG = -236,
OUT_OF_MEMORY = -299,
GESTALT_UNKNOWN_ERR = -5550,
GESTALT_INVALID_ARGUMENT = -5551,
SUCCESS = 0,
REBOOT_NEEDED = 999,
LIMITED_INSTALL = 0,
FULL_INSTALL = 1,
NO_STATUS_DLG = 2,
NO_FINALIZE_DLG = 4,
INSTALL_FILE_UNEXPECTED_MSG_ID = 0,
DETAILS_REPLACE_FILE_MSG_ID = 1,
DETAILS_INSTALL_FILE_MSG_ID = 2
};
nsInstall(nsIZipReader * theJARFile);
virtual ~nsInstall();
PRInt32 SetScriptObject(void* aScriptObject);
PRInt32 SaveWinRegPrototype(void* aScriptObject);
PRInt32 SaveWinProfilePrototype(void* aScriptObject);
JSObject* RetrieveWinRegPrototype(void);
JSObject* RetrieveWinProfilePrototype(void);
PRInt32 GetUserPackageName(nsString& aUserPackageName);
PRInt32 GetRegPackageName(nsString& aRegPackageName);
PRInt32 AbortInstall(PRInt32 aErrorNumber);
PRInt32 AddDirectory(const nsString& aRegName, const nsString& aVersion, const nsString& aJarSource, nsInstallFolder* aFolder, const nsString& aSubdir, PRInt32 aMode, PRInt32* aReturn);
PRInt32 AddDirectory(const nsString& aRegName, const nsString& aVersion, const nsString& aJarSource, nsInstallFolder* aFolder, const nsString& aSubdir, PRInt32* aReturn);
PRInt32 AddDirectory(const nsString& aRegName, const nsString& aJarSource, nsInstallFolder* aFolder, const nsString& aSubdir, PRInt32* aReturn);
PRInt32 AddDirectory(const nsString& aJarSource, PRInt32* aReturn);
PRInt32 AddSubcomponent(const nsString& aRegName, const nsString& aVersion, const nsString& aJarSource, nsInstallFolder *aFolder, const nsString& aTargetName, PRInt32 aMode, PRInt32* aReturn);
PRInt32 AddSubcomponent(const nsString& aRegName, const nsString& aVersion, const nsString& aJarSource, nsInstallFolder *aFolder, const nsString& aTargetName, PRInt32* aReturn);
PRInt32 AddSubcomponent(const nsString& aRegName, const nsString& aJarSource, nsInstallFolder *aFolder, const nsString& aTargetName, PRInt32* aReturn);
PRInt32 AddSubcomponent(const nsString& aJarSource, PRInt32* aReturn);
PRInt32 DeleteComponent(const nsString& aRegistryName, PRInt32* aReturn);
PRInt32 DeleteFile(nsInstallFolder* aFolder, const nsString& aRelativeFileName, PRInt32* aReturn);
PRInt32 DiskSpaceAvailable(const nsString& aFolder, PRInt64* aReturn);
PRInt32 Execute(const nsString& aJarSource, const nsString& aArgs, PRInt32* aReturn);
PRInt32 Execute(const nsString& aJarSource, PRInt32* aReturn);
PRInt32 FinalizeInstall(PRInt32* aReturn);
PRInt32 Gestalt(const nsString& aSelector, PRInt32* aReturn);
PRInt32 GetComponentFolder(const nsString& aComponentName, const nsString& aSubdirectory, nsInstallFolder** aFolder);
PRInt32 GetComponentFolder(const nsString& aComponentName, nsInstallFolder** aFolder);
PRInt32 GetFolder(nsInstallFolder& aTargetFolder, const nsString& aSubdirectory, nsInstallFolder** aFolder);
PRInt32 GetFolder(const nsString& aTargetFolder, const nsString& aSubdirectory, nsInstallFolder** aFolder);
PRInt32 GetFolder(const nsString& aTargetFolder, nsInstallFolder** aFolder);
PRInt32 GetLastError(PRInt32* aReturn);
PRInt32 GetWinProfile(const nsString& aFolder, const nsString& aFile, JSContext* jscontext, JSClass* WinProfileClass, jsval* aReturn);
PRInt32 GetWinRegistry(JSContext* jscontext, JSClass* WinRegClass, jsval* aReturn);
PRInt32 LoadResources(JSContext* cx, const nsString& aBaseName, jsval* aReturn);
PRInt32 Patch(const nsString& aRegName, const nsString& aVersion, const nsString& aJarSource, nsInstallFolder* aFolder, const nsString& aTargetName, PRInt32* aReturn);
PRInt32 Patch(const nsString& aRegName, const nsString& aJarSource, nsInstallFolder* aFolder, const nsString& aTargetName, PRInt32* aReturn);
PRInt32 ResetError();
PRInt32 SetPackageFolder(nsInstallFolder& aFolder);
PRInt32 StartInstall(const nsString& aUserPackageName, const nsString& aPackageName, const nsString& aVersion, PRInt32* aReturn);
PRInt32 Uninstall(const nsString& aPackageName, PRInt32* aReturn);
PRInt32 FileOpDirCreate(nsInstallFolder& aTarget, PRInt32* aReturn);
PRInt32 FileOpDirGetParent(nsInstallFolder& aTarget, nsFileSpec* aReturn);
PRInt32 FileOpDirRemove(nsInstallFolder& aTarget, PRInt32 aFlags, PRInt32* aReturn);
PRInt32 FileOpDirRename(nsInstallFolder& aSrc, nsString& aTarget, PRInt32* aReturn);
PRInt32 FileOpFileCopy(nsInstallFolder& aSrc, nsInstallFolder& aTarget, PRInt32* aReturn);
PRInt32 FileOpFileDelete(nsInstallFolder& aTarget, PRInt32 aFlags, PRInt32* aReturn);
PRInt32 FileOpFileExists(nsInstallFolder& aTarget, PRBool* aReturn);
PRInt32 FileOpFileExecute(nsInstallFolder& aTarget, nsString& aParams, PRInt32* aReturn);
PRInt32 FileOpFileGetNativeVersion(nsInstallFolder& aTarget, nsString* aReturn);
PRInt32 FileOpFileGetDiskSpaceAvailable(nsInstallFolder& aTarget, PRInt64* aReturn);
PRInt32 FileOpFileGetModDate(nsInstallFolder& aTarget, nsFileSpec::TimeStamp* aReturn);
PRInt32 FileOpFileGetSize(nsInstallFolder& aTarget, PRUint32* aReturn);
PRInt32 FileOpFileIsDirectory(nsInstallFolder& aTarget, PRBool* aReturn);
PRInt32 FileOpFileIsFile(nsInstallFolder& aTarget, PRBool* aReturn);
PRInt32 FileOpFileModDateChanged(nsInstallFolder& aTarget, nsFileSpec::TimeStamp& aOldStamp, PRBool* aReturn);
PRInt32 FileOpFileMove(nsInstallFolder& aSrc, nsInstallFolder& aTarget, PRInt32* aReturn);
PRInt32 FileOpFileRename(nsInstallFolder& aSrc, nsString& aTarget, PRInt32* aReturn);
PRInt32 FileOpFileWindowsShortcut(nsFileSpec& aTarget, nsFileSpec& aShortcutPath, nsString& aDescription, nsFileSpec& aWorkingPath, nsString& aParams, nsFileSpec& aIcon, PRInt32 aIconId, PRInt32* aReturn);
PRInt32 FileOpFileMacAlias(nsString& aSourcePath, nsString& aAliasPath, PRInt32* aReturn);
PRInt32 FileOpFileUnixLink(nsInstallFolder& aTarget, PRInt32 aFlags, PRInt32* aReturn);
void LogComment(nsString& aComment);
PRInt32 ExtractFileFromJar(const nsString& aJarfile, nsFileSpec* aSuggestedName, nsFileSpec** aRealName);
char* GetResourcedString(const nsString& aResName);
void AddPatch(nsHashKey *aKey, nsFileSpec* fileName);
void GetPatch(nsHashKey *aKey, nsFileSpec** fileName);
void GetJarFileLocation(nsString& aFile);
void SetJarFileLocation(const nsFileSpec& aFile);
void GetInstallArguments(nsString& args);
void SetInstallArguments(const nsString& args);
void GetInstallURL(nsString& url);
void SetInstallURL(const nsString& url);
PRBool GetStatusSent() { return mStatusSent; }
PRBool InInstallTransaction(void) { return mInstalledFiles != nsnull; }
PRInt32 Alert(nsString& string);
PRInt32 Confirm(nsString& string, PRBool* aReturn);
void InternalAbort(PRInt32 errcode);
PRInt32 SaveError(PRInt32 errcode);
private:
JSObject* mScriptObject;
JSObject* mWinRegObject;
JSObject* mWinProfileObject;
nsFileSpec mJarFileLocation;
nsIZipReader* mJarFileData;
nsString mInstallArguments;
nsString mInstallURL;
nsInstallFolder* mPackageFolder;
PRBool mUserCancelled;
PRBool mStatusSent;
PRBool mUninstallPackage;
PRBool mRegisterPackage;
PRBool mStartInstallCompleted;
nsString mRegistryPackageName; /* Name of the package we are installing */
nsString mUIName; /* User-readable package name */
nsInstallVersion* mVersionInfo; /* Component version info */
nsVoidArray* mInstalledFiles;
nsHashtable* mPatchList;
nsIXPINotifier *mNotifier;
nsCOMPtr<nsIStringBundle> mStringBundle;
PRInt32 mLastError;
void ParseFlags(int flags);
PRInt32 SanityCheck(void);
void GetTime(nsString &aString);
PRInt32 GetQualifiedRegName(const nsString& name, nsString& qualifiedRegName );
PRInt32 GetQualifiedPackageName( const nsString& name, nsString& qualifiedName );
void CurrentUserNode(nsString& userRegNode);
PRBool BadRegName(const nsString& regName);
void CleanUp();
PRInt32 ExtractDirEntries(const nsString& directory, nsVoidArray *paths);
PRInt32 ScheduleForInstall(nsInstallObject* ob);
static void DeleteVector(nsVoidArray* vector);
};
#endif

View File

@@ -0,0 +1,291 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code,
* released March 31, 1998.
*
* 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):
* Daniel Veditz <dveditz@netscape.com>
* Douglas Turner <dougt@netscape.com>
*/
#include "prmem.h"
#include "nsFileSpec.h"
#include "VerReg.h"
#include "ScheduledTasks.h"
#include "nsInstallDelete.h"
#include "nsInstallResources.h"
#include "nsInstall.h"
#include "nsIDOMInstallVersion.h"
MOZ_DECL_CTOR_COUNTER(nsInstallDelete);
nsInstallDelete::nsInstallDelete( nsInstall* inInstall,
nsInstallFolder* folderSpec,
const nsString& inPartialPath,
PRInt32 *error)
: nsInstallObject(inInstall)
{
MOZ_COUNT_CTOR(nsInstallDelete);
if ((folderSpec == nsnull) || (inInstall == nsnull))
{
*error = nsInstall::INVALID_ARGUMENTS;
return;
}
mDeleteStatus = DELETE_FILE;
mFinalFile = nsnull;
mRegistryName = "";
nsFileSpec* tmp = folderSpec->GetFileSpec();
if (!tmp)
{
*error = nsInstall::INVALID_ARGUMENTS;
return;
}
mFinalFile = new nsFileSpec(*tmp);
if (mFinalFile == nsnull)
{
*error = nsInstall::OUT_OF_MEMORY;
return;
}
*mFinalFile += inPartialPath;
*error = ProcessInstallDelete();
}
nsInstallDelete::nsInstallDelete( nsInstall* inInstall,
const nsString& inComponentName,
PRInt32 *error)
: nsInstallObject(inInstall)
{
MOZ_COUNT_CTOR(nsInstallDelete);
if (inInstall == NULL)
{
*error = nsInstall::INVALID_ARGUMENTS;
return;
}
mDeleteStatus = DELETE_COMPONENT;
mFinalFile = nsnull;
mRegistryName = inComponentName;
*error = ProcessInstallDelete();
}
nsInstallDelete::~nsInstallDelete()
{
if (mFinalFile == nsnull)
delete mFinalFile;
MOZ_COUNT_DTOR(nsInstallDelete);
}
PRInt32 nsInstallDelete::Prepare()
{
// no set-up necessary
return nsInstall::SUCCESS;
}
PRInt32 nsInstallDelete::Complete()
{
PRInt32 err = nsInstall::SUCCESS;
if (mInstall == NULL)
return nsInstall::INVALID_ARGUMENTS;
if (mDeleteStatus == DELETE_COMPONENT)
{
char* temp = mRegistryName.ToNewCString();
if (temp)
{
err = VR_Remove(temp);
Recycle(temp);
}
}
if ((mDeleteStatus == DELETE_FILE) || (err == REGERR_OK))
{
err = NativeComplete();
}
else
{
err = nsInstall::UNEXPECTED_ERROR;
}
return err;
}
void nsInstallDelete::Abort()
{
}
char* nsInstallDelete::toString()
{
char* buffer = new char[1024];
char* rsrcVal = nsnull;
if (buffer == nsnull || !mInstall)
return nsnull;
if (mDeleteStatus == DELETE_COMPONENT)
{
char* temp = mRegistryName.ToNewCString();
rsrcVal = mInstall->GetResourcedString("DeleteComponent");
if (rsrcVal)
{
sprintf( buffer, rsrcVal, temp);
nsCRT::free(rsrcVal);
}
if (temp)
Recycle(temp);
}
else
{
if (mFinalFile)
{
rsrcVal = mInstall->GetResourcedString("DeleteComponent");
if (rsrcVal)
{
sprintf( buffer, rsrcVal, mFinalFile->GetCString());
nsCRT::free(rsrcVal);
}
}
}
return buffer;
}
PRBool
nsInstallDelete::CanUninstall()
{
return PR_FALSE;
}
PRBool
nsInstallDelete::RegisterPackageNode()
{
return PR_FALSE;
}
PRInt32 nsInstallDelete::ProcessInstallDelete()
{
PRInt32 err;
char* tempCString = nsnull;
if (mDeleteStatus == DELETE_COMPONENT)
{
/* Check if the component is in the registry */
tempCString = mRegistryName.ToNewCString();
if (tempCString == nsnull)
return nsInstall::OUT_OF_MEMORY;
err = VR_InRegistry( tempCString );
if (err != REGERR_OK)
{
return err;
}
else
{
char* tempRegistryString;
tempRegistryString = (char*)PR_Calloc(MAXREGPATHLEN, sizeof(char));
if (tempRegistryString == nsnull)
return nsInstall::OUT_OF_MEMORY;
err = VR_GetPath( tempCString , MAXREGPATHLEN, tempRegistryString);
if (err == REGERR_OK)
{
if (mFinalFile)
delete mFinalFile;
mFinalFile = new nsFileSpec(tempRegistryString);
if (mFinalFile == nsnull)
return nsInstall::OUT_OF_MEMORY;
}
PR_FREEIF(tempRegistryString);
}
}
if(tempCString)
Recycle(tempCString);
if (mFinalFile->Exists())
{
if (mFinalFile->IsFile())
{
err = nsInstall::SUCCESS;
}
else
{
err = nsInstall::IS_DIRECTORY;
}
}
else
{
err = nsInstall::DOES_NOT_EXIST;
}
return err;
}
PRInt32 nsInstallDelete::NativeComplete()
{
NS_WARN_IF_FALSE(mFinalFile->Exists(),"nsInstallDelete::Complete -- file should exist!");
if (mFinalFile->Exists())
{
if (mFinalFile->IsFile())
{
return DeleteFileNowOrSchedule(*mFinalFile);
}
else
{
NS_ASSERTION(0,"nsInstallDelete::Complete -- expected file was a directory!");
return nsInstall::IS_DIRECTORY;
}
}
return nsInstall::DOES_NOT_EXIST;
}

View File

@@ -0,0 +1,78 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code,
* released March 31, 1998.
*
* 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):
* Daniel Veditz <dveditz@netscape.com>
* Douglas Turner <dougt@netscape.com>
*/
#ifndef nsInstallDelete_h__
#define nsInstallDelete_h__
#include "prtypes.h"
#include "nsString.h"
#include "nsInstallObject.h"
#include "nsInstall.h"
#define DELETE_COMPONENT 1
#define DELETE_FILE 2
class nsInstallDelete : public nsInstallObject
{
public:
nsInstallDelete( nsInstall* inInstall,
nsInstallFolder* folderSpec,
const nsString& inPartialPath,
PRInt32 *error);
nsInstallDelete( nsInstall* inInstall,
const nsString& ,
PRInt32 *error);
virtual ~nsInstallDelete();
PRInt32 Prepare();
PRInt32 Complete();
void Abort();
char* toString();
PRBool CanUninstall();
PRBool RegisterPackageNode();
private:
/* Private Fields */
nsFileSpec* mFinalFile;
nsString mRegistryName;
PRInt32 mDeleteStatus;
PRInt32 ProcessInstallDelete();
PRInt32 NativeComplete();
};
#endif /* nsInstallDelete_h__ */

View File

@@ -0,0 +1,159 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code,
* released March 31, 1998.
*
* 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):
* Daniel Veditz <dveditz@netscape.com>
* Douglas Turner <dougt@netscape.com>
*/
#include "prmem.h"
#include "nsFileSpec.h"
#include "VerReg.h"
#include "nsInstallExecute.h"
#include "nsInstallResources.h"
#include "ScheduledTasks.h"
#include "nsInstall.h"
#include "nsIDOMInstallVersion.h"
MOZ_DECL_CTOR_COUNTER(nsInstallExecute);
nsInstallExecute:: nsInstallExecute( nsInstall* inInstall,
const nsString& inJarLocation,
const nsString& inArgs,
PRInt32 *error)
: nsInstallObject(inInstall)
{
MOZ_COUNT_CTOR(nsInstallExecute);
if ((inInstall == nsnull) || (inJarLocation.Equals("")) )
{
*error = nsInstall::INVALID_ARGUMENTS;
return;
}
mJarLocation = inJarLocation;
mArgs = inArgs;
mExecutableFile = nsnull;
}
nsInstallExecute::~nsInstallExecute()
{
if (mExecutableFile)
delete mExecutableFile;
MOZ_COUNT_DTOR(nsInstallExecute);
}
PRInt32 nsInstallExecute::Prepare()
{
if (mInstall == NULL || mJarLocation.Equals(""))
return nsInstall::INVALID_ARGUMENTS;
return mInstall->ExtractFileFromJar(mJarLocation, nsnull, &mExecutableFile);
}
PRInt32 nsInstallExecute::Complete()
{
if (mExecutableFile == nsnull)
return nsInstall::INVALID_ARGUMENTS;
nsFileSpec app( *mExecutableFile);
if (!app.Exists())
{
return nsInstall::INVALID_ARGUMENTS;
}
PRInt32 result = app.Execute( mArgs );
DeleteFileNowOrSchedule( app );
return result;
}
void nsInstallExecute::Abort()
{
/* Get the names */
if (mExecutableFile == nsnull)
return;
DeleteFileNowOrSchedule(*mExecutableFile);
}
char* nsInstallExecute::toString()
{
char* buffer = new char[1024];
char* rsrcVal = nsnull;
if (buffer == nsnull || !mInstall)
return nsnull;
// if the FileSpec is NULL, just us the in jar file name.
if (mExecutableFile == nsnull)
{
char *tempString = mJarLocation.ToNewCString();
rsrcVal = mInstall->GetResourcedString("Execute");
if (rsrcVal)
{
sprintf( buffer, rsrcVal, tempString);
nsCRT::free(rsrcVal);
}
if (tempString)
Recycle(tempString);
}
else
{
rsrcVal = mInstall->GetResourcedString("Execute");
if (rsrcVal)
{
sprintf( buffer, rsrcVal, mExecutableFile->GetCString());
nsCRT::free(rsrcVal);
}
}
return buffer;
}
PRBool
nsInstallExecute::CanUninstall()
{
return PR_FALSE;
}
PRBool
nsInstallExecute::RegisterPackageNode()
{
return PR_FALSE;
}

View File

@@ -0,0 +1,73 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code,
* released March 31, 1998.
*
* 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):
* Daniel Veditz <dveditz@netscape.com>
* Douglas Turner <dougt@netscape.com>
*/
#ifndef nsInstallExecute_h__
#define nsInstallExecute_h__
#include "prtypes.h"
#include "nsString.h"
#include "nsInstallObject.h"
#include "nsInstall.h"
#include "nsIDOMInstallVersion.h"
class nsInstallExecute : public nsInstallObject
{
public:
nsInstallExecute( nsInstall* inInstall,
const nsString& inJarLocation,
const nsString& inArgs,
PRInt32 *error);
virtual ~nsInstallExecute();
PRInt32 Prepare();
PRInt32 Complete();
void Abort();
char* toString();
PRBool CanUninstall();
PRBool RegisterPackageNode();
private:
nsString mJarLocation; // Location in the JAR
nsString mArgs; // command line arguments
nsFileSpec *mExecutableFile; // temporary file location
PRInt32 NativeComplete(void);
void NativeAbort(void);
};
#endif /* nsInstallExecute_h__ */

View File

@@ -0,0 +1,452 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code,
* released March 31, 1998.
*
* 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):
* Daniel Veditz <dveditz@netscape.com>
* Douglas Turner <dougt@netscape.com>
*/
#include "prprf.h"
#include "nsInstallFile.h"
#include "nsFileSpec.h"
#include "VerReg.h"
#include "ScheduledTasks.h"
#include "nsInstall.h"
#include "nsIDOMInstallVersion.h"
#include "nsInstallResources.h"
/* Public Methods */
/* Constructor
inInstall - softUpdate object we belong to
inComponentName - full path of the registry component
inVInfo - full version info
inJarLocation - location inside the JAR file
inFinalFileSpec - final location on disk
*/
MOZ_DECL_CTOR_COUNTER(nsInstallFile);
nsInstallFile::nsInstallFile(nsInstall* inInstall,
const nsString& inComponentName,
const nsString& inVInfo,
const nsString& inJarLocation,
nsInstallFolder *folderSpec,
const nsString& inPartialPath,
PRInt32 mode,
PRInt32 *error)
: nsInstallObject(inInstall),
mVersionInfo(nsnull),
mJarLocation(nsnull),
mExtractedFile(nsnull),
mFinalFile(nsnull),
mVersionRegistryName(nsnull),
mReplaceFile(PR_FALSE),
mChildFile(PR_TRUE),
mUpgradeFile(PR_FALSE),
mSkipInstall(PR_FALSE),
mMode(mode)
{
MOZ_COUNT_CTOR(nsInstallFile);
if ((folderSpec == nsnull) || (inInstall == NULL))
{
*error = nsInstall::INVALID_ARGUMENTS;
return;
}
*error = nsInstall::SUCCESS;
/* Check for existence of the newer version */
#if 0 // XXX need to re-implement force mode in the opposite sense
char* qualifiedRegNameString = inComponentName.ToNewCString();
// --------------------------------------------------------------------
// we always install if forceInstall is true, or the new file's
// version is null, or the file doesn't previously exist.
//
// IFF it's not force, AND the new file has a version, AND it's been
// previously installed, THEN we have to do the version comparing foo.
// --------------------------------------------------------------------
if ( !(mode & INSTALL_NO_COMPARE ) && (inVInfo != "") &&
( VR_ValidateComponent( qualifiedRegNameString ) == 0 ) )
{
nsInstallVersion *newVersion = new nsInstallVersion();
if (newVersion == nsnull)
{
Recycle(qualifiedRegNameString);
*error = nsInstall::OUT_OF_MEMORY;
return;
}
newVersion->Init(inVInfo);
VERSION versionStruct;
VR_GetVersion( qualifiedRegNameString, &versionStruct );
nsInstallVersion* oldVersion = new nsInstallVersion();
if (oldVersion == nsnull)
{
Recycle(qualifiedRegNameString);
delete oldVersion;
*error = nsInstall::OUT_OF_MEMORY;
return;
}
oldVersion->Init(versionStruct.major,
versionStruct.minor,
versionStruct.release,
versionStruct.build);
PRInt32 areTheyEqual;
newVersion->CompareTo(oldVersion, &areTheyEqual);
delete oldVersion;
delete newVersion;
if ( areTheyEqual < 0 )
{
// the file to be installed is OLDER than what is on disk.
// Don't install it.
mSkipInstall = PR_TRUE;
}
}
Recycle(qualifiedRegNameString);
#endif
nsFileSpec* tmp = folderSpec->GetFileSpec();
if (!tmp)
{
*error = nsInstall::INVALID_ARGUMENTS;
return;
}
mFinalFile = new nsFileSpec(*tmp);
if (mFinalFile == nsnull)
{
*error = nsInstall::OUT_OF_MEMORY;
return;
}
if ( mFinalFile->Exists() )
{
// is there a file with the same name as the proposed folder?
if ( mFinalFile->IsFile() )
{
*error = nsInstall::FILENAME_ALREADY_USED;
return;
}
// else this directory already exists, so do nothing
}
else
{
/* the nsFileSpecMac.cpp operator += requires "this" (the nsFileSpec)
* to be an existing dir
*/
int dirPermissions = 0755; // std default for UNIX, ignored otherwise
mFinalFile->CreateDir(dirPermissions);
}
*mFinalFile += inPartialPath;
mReplaceFile = mFinalFile->Exists();
if (mReplaceFile == PR_FALSE)
{
/* although it appears that we are creating the dir _again_ it is necessary
* when inPartialPath has arbitrary levels of nested dirs before the leaf
*/
nsFileSpec parent;
mFinalFile->GetParent(parent);
nsFileSpec makeDirs(parent.GetCString(), PR_TRUE);
}
mVersionRegistryName = new nsString(inComponentName);
mJarLocation = new nsString(inJarLocation);
mVersionInfo = new nsString(inVInfo);
if (mVersionRegistryName == nsnull ||
mJarLocation == nsnull ||
mVersionInfo == nsnull )
{
*error = nsInstall::OUT_OF_MEMORY;
return;
}
nsString regPackageName;
mInstall->GetRegPackageName(regPackageName);
// determine Child status
if ( regPackageName.IsEmpty() )
{
// in the "current communicator package" absolute pathnames (start
// with slash) indicate shared files -- all others are children
mChildFile = ( mVersionRegistryName->CharAt(0) != '/' );
}
else
{
mChildFile = mVersionRegistryName->Equals( regPackageName,
PR_FALSE,
regPackageName.Length() );
}
}
nsInstallFile::~nsInstallFile()
{
if (mVersionRegistryName)
delete mVersionRegistryName;
if (mJarLocation)
delete mJarLocation;
if (mExtractedFile)
delete mExtractedFile;
if (mFinalFile)
delete mFinalFile;
if (mVersionInfo)
delete mVersionInfo;
MOZ_COUNT_DTOR(nsInstallFile);
}
/* Prepare
* Extracts file out of the JAR archive
*/
PRInt32 nsInstallFile::Prepare()
{
if (mSkipInstall)
return nsInstall::SUCCESS;
if (mInstall == nsnull || mFinalFile == nsnull || mJarLocation == nsnull )
return nsInstall::INVALID_ARGUMENTS;
return mInstall->ExtractFileFromJar(*mJarLocation, mFinalFile, &mExtractedFile);
}
/* Complete
* Completes the install:
* - move the downloaded file to the final location
* - updates the registry
*/
PRInt32 nsInstallFile::Complete()
{
PRInt32 err;
if (mInstall == nsnull || mVersionRegistryName == nsnull || mFinalFile == nsnull )
{
return nsInstall::INVALID_ARGUMENTS;
}
if (mSkipInstall)
return nsInstall::SUCCESS;
err = CompleteFileMove();
if ( 0 == err || nsInstall::REBOOT_NEEDED == err )
{
// XXX Don't register individual files for now -- crucial performance
// speed up on the Mac, and we'll switch uninstall schemes after beta
// RegisterInVersionRegistry();
}
return err;
}
void nsInstallFile::Abort()
{
if (mExtractedFile != nsnull)
mExtractedFile->Delete(PR_FALSE);
}
#define RESBUFSIZE 1024
char* nsInstallFile::toString()
{
char* buffer = new char[RESBUFSIZE];
char* rsrcVal = nsnull;
const char* fname = nsnull;
if (buffer == nsnull || !mInstall)
return nsnull;
else
buffer[0] = '\0';
if (mReplaceFile)
{
rsrcVal = mInstall->GetResourcedString("ReplaceFile");
}
else if (mSkipInstall)
{
rsrcVal = mInstall->GetResourcedString("SkipFile");
}
else
{
rsrcVal = mInstall->GetResourcedString("InstallFile");
}
if (rsrcVal)
{
if (mFinalFile)
fname = mFinalFile->GetCString();
PR_snprintf( buffer, RESBUFSIZE, rsrcVal, fname );
Recycle(rsrcVal);
}
return buffer;
}
PRInt32 nsInstallFile::CompleteFileMove()
{
int result = 0;
if (mExtractedFile == nsnull)
{
return nsInstall::UNEXPECTED_ERROR;
}
if ( *mExtractedFile == *mFinalFile )
{
/* No need to rename, they are the same */
result = nsInstall::SUCCESS;
}
else
{
result = ReplaceFileNowOrSchedule(*mExtractedFile, *mFinalFile );
}
return result;
}
PRInt32
nsInstallFile::RegisterInVersionRegistry()
{
int refCount;
nsString regPackageName;
mInstall->GetRegPackageName(regPackageName);
// Register file and log for Uninstall
if (!mChildFile)
{
int found;
if (!regPackageName.IsEmpty())
{
found = VR_UninstallFileExistsInList( (char*)(const char*)nsAutoCString(regPackageName) ,
(char*)(const char*)nsAutoCString(*mVersionRegistryName));
}
else
{
found = VR_UninstallFileExistsInList( "", (char*)(const char*)nsAutoCString(*mVersionRegistryName) );
}
if (found != REGERR_OK)
mUpgradeFile = PR_FALSE;
else
mUpgradeFile = PR_TRUE;
}
else if (REGERR_OK == VR_InRegistry( (char*)(const char*)nsAutoCString(*mVersionRegistryName)))
{
mUpgradeFile = PR_TRUE;
}
else
{
mUpgradeFile = PR_FALSE;
}
if ( REGERR_OK != VR_GetRefCount( (char*)(const char*)nsAutoCString(*mVersionRegistryName), &refCount ))
{
refCount = 0;
}
VR_Install( (char*)(const char*)nsAutoCString(*mVersionRegistryName),
(char*)(const char*)mFinalFile->GetNativePathCString(), // DO NOT CHANGE THIS.
(char*)(const char*)nsAutoCString(*mVersionInfo),
PR_FALSE );
if (mUpgradeFile)
{
if (refCount == 0)
VR_SetRefCount( (char*)(const char*)nsAutoCString(*mVersionRegistryName), 1 );
else
VR_SetRefCount( (char*)(const char*)nsAutoCString(*mVersionRegistryName), refCount ); //FIX?? what should the ref count be/
}
else
{
if (refCount != 0)
{
VR_SetRefCount( (char*)(const char*)nsAutoCString(*mVersionRegistryName), refCount + 1 );
}
else
{
if (mReplaceFile)
VR_SetRefCount( (char*)(const char*)nsAutoCString(*mVersionRegistryName), 2 );
else
VR_SetRefCount( (char*)(const char*)nsAutoCString(*mVersionRegistryName), 1 );
}
}
if ( !mChildFile && !mUpgradeFile )
{
if (!regPackageName.IsEmpty())
{
VR_UninstallAddFileToList( (char*)(const char*)nsAutoCString(regPackageName),
(char*)(const char*)nsAutoCString(*mVersionRegistryName));
}
else
{
VR_UninstallAddFileToList( "", (char*)(const char*)nsAutoCString(*mVersionRegistryName) );
}
}
return nsInstall::SUCCESS;
}
/* CanUninstall
* InstallFile() installs files which can be uninstalled,
* hence this function returns true.
*/
PRBool
nsInstallFile::CanUninstall()
{
return PR_TRUE;
}
/* RegisterPackageNode
* InstallFile() installs files which need to be registered,
* hence this function returns true.
*/
PRBool
nsInstallFile::RegisterPackageNode()
{
return PR_TRUE;
}

View File

@@ -0,0 +1,105 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code,
* released March 31, 1998.
*
* 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):
* Daniel Veditz <dveditz@netscape.com>
* Douglas Turner <dougt@netscape.com>
*/
#ifndef nsInstallFile_h__
#define nsInstallFile_h__
#include "prtypes.h"
#include "nsString.h"
#include "nsInstallObject.h"
#include "nsInstall.h"
#include "nsInstallVersion.h"
/* Global defines for file handling mode bitfield values */
#define INSTALL_NO_COMPARE 0x1
#define INSTALL_IF_NEWER 0x2
#define INSTALL_IF_EQUAL_OR_NEWER 0x4
class nsInstallFile : public nsInstallObject
{
public:
/*************************************************************
* Public Methods
*
* Constructor
* inSoftUpdate - softUpdate object we belong to
* inComponentName - full path of the registry component
* inVInfo - full version info
* inJarLocation - location inside the JAR file
* inFinalFileSpec - final location on disk
*************************************************************/
nsInstallFile( nsInstall* inInstall,
const nsString& inVRName,
const nsString& inVInfo,
const nsString& inJarLocation,
nsInstallFolder *folderSpec,
const nsString& inPartialPath,
PRInt32 mode,
PRInt32 *error);
virtual ~nsInstallFile();
PRInt32 Prepare();
PRInt32 Complete();
void Abort();
char* toString();
PRBool CanUninstall();
PRBool RegisterPackageNode();
private:
/* Private Fields */
nsString* mVersionInfo; /* Version info for this file*/
nsString* mJarLocation; /* Location in the JAR */
nsFileSpec* mExtractedFile; /* temporary file location */
nsFileSpec* mFinalFile; /* final file destination */
nsString* mVersionRegistryName; /* full version path */
PRBool mForceInstall; /* whether install is forced */
PRBool mReplaceFile; /* whether file exists */
PRBool mChildFile; /* whether file is a child */
PRBool mUpgradeFile; /* whether file is an upgrade */
PRBool mSkipInstall; /* if true don't install this file */
PRInt32 mMode; /* an integer used like a bitfield to control *
* how a file is installed or registered */
PRInt32 CompleteFileMove();
PRInt32 RegisterInVersionRegistry();
};
#endif /* nsInstallFile_h__ */

View File

@@ -0,0 +1,42 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsInstallFileOpEnums_h__
#define nsInstallFileOpEnums_h__
typedef enum nsInstallFileOpEnums {
NS_FOP_DIR_CREATE = 0,
NS_FOP_DIR_REMOVE = 1,
NS_FOP_DIR_RENAME = 2,
NS_FOP_FILE_COPY = 3,
NS_FOP_FILE_DELETE = 4,
NS_FOP_FILE_EXECUTE = 5,
NS_FOP_FILE_MOVE = 6,
NS_FOP_FILE_RENAME = 7,
NS_FOP_WIN_SHORTCUT = 8,
NS_FOP_MAC_ALIAS = 9,
NS_FOP_UNIX_LINK = 10,
NS_FOP_FILE_SET_STAT = 11
} nsInstallFileOpEnums;
#endif /* nsInstallFileOpEnums_h__ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,156 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsInstallFileOpItem_h__
#define nsInstallFileOpItem_h__
#include "prtypes.h"
#include "nsFileSpec.h"
#include "nsSoftwareUpdate.h"
#include "nsInstallObject.h"
#include "nsInstall.h"
class nsInstallFileOpItem : public nsInstallObject
{
public:
/* Public Fields */
enum
{
ACTION_NONE = -401,
ACTION_SUCCESS = -402,
ACTION_FAILED = -403
};
/* Public Methods */
// used by:
// FileOpFileDelete()
nsInstallFileOpItem(nsInstall* installObj,
PRInt32 aCommand,
nsFileSpec& aTarget,
PRInt32 aFlags,
PRInt32* aReturn);
// used by:
// FileOpDirRemove()
// FileOpFileCopy()
// FileOpFileMove()
// FileMacAlias()
nsInstallFileOpItem(nsInstall* installObj,
PRInt32 aCommand,
nsFileSpec& aSrc,
nsFileSpec& aTarget,
PRInt32* aReturn);
// used by:
// FileOpDirCreate()
nsInstallFileOpItem(nsInstall* aInstallObj,
PRInt32 aCommand,
nsFileSpec& aTarget,
PRInt32* aReturn);
// used by:
// FileOpDirRename()
// FileOpFileExecute()
// FileOpFileRename()
nsInstallFileOpItem(nsInstall* aInstallObj,
PRInt32 aCommand,
nsFileSpec& a1,
nsString& a2,
PRInt32* aReturn);
// used by:
// WindowsShortcut()
nsInstallFileOpItem(nsInstall* aInstallObj,
PRInt32 aCommand,
nsFileSpec& aTarget,
nsFileSpec& aShortcutPath,
nsString& aDescription,
nsFileSpec& aWorkingPath,
nsString& aParams,
nsFileSpec& aIcon,
PRInt32 aIconId,
PRInt32* aReturn);
virtual ~nsInstallFileOpItem();
PRInt32 Prepare(void);
PRInt32 Complete();
char* toString();
void Abort();
/* should these be protected? */
PRBool CanUninstall();
PRBool RegisterPackageNode();
private:
/* Private Fields */
nsInstall* mIObj; // initiating Install object
nsFileSpec* mSrc;
nsFileSpec* mTarget;
nsFileSpec* mShortcutPath;
nsFileSpec* mWorkingPath;
nsFileSpec* mIcon;
nsString* mDescription;
nsString* mStrTarget;
nsString* mParams;
long mFStat;
PRInt32 mFlags;
PRInt32 mIconId;
PRInt32 mCommand;
PRInt32 mAction;
/* Private Methods */
PRInt32 NativeFileOpDirCreatePrepare();
PRInt32 NativeFileOpDirCreateAbort();
PRInt32 NativeFileOpDirRemovePrepare();
PRInt32 NativeFileOpDirRemoveComplete();
PRInt32 NativeFileOpDirRenamePrepare();
PRInt32 NativeFileOpDirRenameComplete();
PRInt32 NativeFileOpDirRenameAbort();
PRInt32 NativeFileOpFileCopyPrepare();
PRInt32 NativeFileOpFileCopyComplete();
PRInt32 NativeFileOpFileCopyAbort();
PRInt32 NativeFileOpFileDeletePrepare();
PRInt32 NativeFileOpFileDeleteComplete(nsFileSpec *aTarget);
PRInt32 NativeFileOpFileExecutePrepare();
PRInt32 NativeFileOpFileExecuteComplete();
PRInt32 NativeFileOpFileMovePrepare();
PRInt32 NativeFileOpFileMoveComplete();
PRInt32 NativeFileOpFileMoveAbort();
PRInt32 NativeFileOpFileRenamePrepare();
PRInt32 NativeFileOpFileRenameComplete();
PRInt32 NativeFileOpFileRenameAbort();
PRInt32 NativeFileOpWindowsShortcutComplete();
PRInt32 NativeFileOpWindowsShortcutAbort();
PRInt32 NativeFileOpMacAliasComplete();
PRInt32 NativeFileOpMacAliasAbort();
PRInt32 NativeFileOpUnixLink();
};
#endif /* nsInstallFileOpItem_h__ */

View File

@@ -0,0 +1,467 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code,
* released March 31, 1998.
*
* 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):
* Daniel Veditz <dveditz@netscape.com>
* Douglas Turner <dougt@netscape.com>
*/
#include "nsInstall.h"
#include "nsInstallFolder.h"
#include "nscore.h"
#include "prtypes.h"
#include "nsRepository.h"
#include "nsString.h"
#include "nsFileSpec.h"
#include "nsIFileSpec.h"
#include "nsSpecialSystemDirectory.h"
#include "nsFileLocations.h"
#include "nsIFileLocator.h"
struct DirectoryTable
{
char * directoryName; /* The formal directory name */
PRInt32 folderEnum; /* Directory ID */
};
struct DirectoryTable DirectoryTable[] =
{
{"Plugins", 100 },
{"Program", 101 },
{"Communicator", 102 },
{"User Pick", 103 },
{"Temporary", 104 },
{"Installed", 105 },
{"Current User", 106 },
{"Preferences", 107 },
{"OS Drive", 108 },
{"file:///", 109 },
{"Components", 110 },
{"Chrome", 111 },
{"Win System", 200 },
{"Windows", 201 },
{"Mac System", 300 },
{"Mac Desktop", 301 },
{"Mac Trash", 302 },
{"Mac Startup", 303 },
{"Mac Shutdown", 304 },
{"Mac Apple Menu", 305 },
{"Mac Control Panel", 306 },
{"Mac Extension", 307 },
{"Mac Fonts", 308 },
{"Mac Preferences", 309 },
{"Mac Documents", 310 },
{"Unix Local", 400 },
{"Unix Lib", 401 },
{"", -1 }
};
MOZ_DECL_CTOR_COUNTER(nsInstallFolder);
nsInstallFolder::nsInstallFolder(const nsString& aFolderID)
{
nsInstallFolder( aFolderID, "" );
}
nsInstallFolder::nsInstallFolder(const nsString& aFolderID, const nsString& aRelativePath)
{
MOZ_COUNT_CTOR(nsInstallFolder);
mFileSpec = nsnull;
/*
aFolderID can be either a Folder enum in which case we merely pass it
to SetDirectoryPath, or it can be a Directory. If it is the later, it
must already exist and of course be a directory not a file.
*/
SetDirectoryPath( aFolderID, aRelativePath );
// check to see if that worked
if ( !mFileSpec )
{
// it didn't, so aFolderID is not one of the magic strings.
// maybe it's already a pathname? If so it had better be a directory
// if it already exists...
nsFileSpec dirCheck(aFolderID);
if ( (dirCheck.Error() == NS_OK) &&
( dirCheck.IsDirectory() || !dirCheck.Exists() ) )
{
mFileSpec = new nsFileSpec( dirCheck );
if (mFileSpec && aRelativePath.Length() > 0 )
{
// we've got a subdirectory to tack on
nsString morePath(aRelativePath);
if ( morePath.Last() != '/' || morePath.Last() != '\\' )
morePath += '/';
*mFileSpec += morePath;
}
// make sure that the directory is created.
// XXX: **why** are we creating these? they might not be used!
nsFileSpec(mFileSpec->GetCString(), PR_TRUE);
}
}
}
nsInstallFolder::nsInstallFolder(nsInstallFolder& inFolder, const nsString& subString)
{
MOZ_COUNT_CTOR(nsInstallFolder);
mFileSpec = new nsFileSpec();
if (mFileSpec != nsnull)
{
*mFileSpec = *inFolder.mFileSpec;
if (!subString.IsEmpty())
*mFileSpec += subString;
}
}
nsInstallFolder::~nsInstallFolder()
{
if (mFileSpec != nsnull)
delete mFileSpec;
MOZ_COUNT_DTOR(nsInstallFolder);
}
void
nsInstallFolder::GetDirectoryPath(nsString& aDirectoryPath)
{
aDirectoryPath = "";
if (mFileSpec != nsnull)
{
// We want the a NATIVE path.
aDirectoryPath.Assign(mFileSpec->GetCString());
if (mFileSpec->IsDirectory())
{
if (aDirectoryPath.Last() != FILESEP)
aDirectoryPath.Append(FILESEP);
}
}
}
void
nsInstallFolder::SetDirectoryPath(const nsString& aFolderID, const nsString& aRelativePath)
{
if ( aFolderID.EqualsIgnoreCase("User Pick") )
{
PickDefaultDirectory();
return;
}
else if ( aFolderID.EqualsIgnoreCase("Installed") )
{
// XXX block from users or remove "Installed"
// XXX the filespec creation will fail due to unix slashes on Mac
mFileSpec = new nsFileSpec(aRelativePath, PR_TRUE); // creates the directories to the relative path.
return;
}
else
{
nsresult rv = NS_OK;
PRInt32 folderDirSpecID = MapNameToEnum(aFolderID);
switch (folderDirSpecID)
{
case 100: /////////////////////////////////////////////////////////// Plugins
if (!nsSoftwareUpdate::GetProgramDirectory())
{
SetAppShellDirectory(nsSpecialFileSpec::App_PluginsDirectory );
}
else
{
mFileSpec = new nsFileSpec();
if ( !mFileSpec )
rv = NS_ERROR_OUT_OF_MEMORY;
else
rv = nsSoftwareUpdate::GetProgramDirectory()->GetFileSpec(mFileSpec);
if (NS_SUCCEEDED(rv))
{
#ifdef XP_MAC
*mFileSpec += "Plugins";
#else
*mFileSpec += "plugins";
#endif
}
else
mFileSpec = nsnull;
}
break;
case 101: /////////////////////////////////////////////////////////// Program
case 102: /////////////////////////////////////////////////////////// Communicator
if (!nsSoftwareUpdate::GetProgramDirectory())
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::OS_CurrentProcessDirectory ));
else
{
mFileSpec = new nsFileSpec();
if ( !mFileSpec )
rv = NS_ERROR_OUT_OF_MEMORY;
else
rv = nsSoftwareUpdate::GetProgramDirectory()->GetFileSpec(mFileSpec);
if (!NS_SUCCEEDED(rv))
mFileSpec = nsnull;
}
break;
case 103: /////////////////////////////////////////////////////////// User Pick
// we should never be here.
mFileSpec = nsnull;
break;
case 104: /////////////////////////////////////////////////////////// Temporary
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::OS_TemporaryDirectory ));
break;
case 105: /////////////////////////////////////////////////////////// Installed
// we should never be here.
mFileSpec = nsnull;
break;
case 106: /////////////////////////////////////////////////////////// Current User
SetAppShellDirectory(nsSpecialFileSpec::App_UserProfileDirectory50 );
break;
case 107: /////////////////////////////////////////////////////////// Preferences
SetAppShellDirectory(nsSpecialFileSpec::App_PrefsDirectory50 );
break;
case 108: /////////////////////////////////////////////////////////// OS Drive
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::OS_DriveDirectory ));
break;
case 109: /////////////////////////////////////////////////////////// File URL
{
if (aRelativePath.IsEmpty())
{
mFileSpec = nsnull;
return;
}
nsString tempFileURLString = aFolderID;
tempFileURLString += aRelativePath;
mFileSpec = new nsFileSpec( nsFileURL(tempFileURLString) );
// file:// is a special case where it returns and does not
// go to the standard relative path code below. This is
// so that nsFile(Spec|Path) will work properly. (ie. Passing
// just "file://" to the nsFileSpec && nsFileURL is wrong).
return;
}
break;
case 110: /////////////////////////////////////////////////////////// Components
if (!nsSoftwareUpdate::GetProgramDirectory())
SetAppShellDirectory(nsSpecialFileSpec::App_ComponentsDirectory );
else
{
mFileSpec = new nsFileSpec();
if ( !mFileSpec )
rv = NS_ERROR_OUT_OF_MEMORY;
else
rv = nsSoftwareUpdate::GetProgramDirectory()->GetFileSpec(mFileSpec);
if (NS_SUCCEEDED(rv))
{
#ifdef XP_MAC
*mFileSpec += "Components";
#else
*mFileSpec += "components";
#endif
}
}
break;
case 111: /////////////////////////////////////////////////////////// Chrome
if (!nsSoftwareUpdate::GetProgramDirectory())
SetAppShellDirectory(nsSpecialFileSpec::App_ChromeDirectory );
else
{
mFileSpec = new nsFileSpec();
if ( !mFileSpec )
rv = NS_ERROR_OUT_OF_MEMORY;
else
rv = nsSoftwareUpdate::GetProgramDirectory()->GetFileSpec(mFileSpec);
if (NS_SUCCEEDED(rv))
{
#ifdef XP_MAC
*mFileSpec += "Chrome";
#else
*mFileSpec += "chrome";
#endif
}
}
break;
case 200: /////////////////////////////////////////////////////////// Win System
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Win_SystemDirectory ));
break;
case 201: /////////////////////////////////////////////////////////// Windows
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Win_WindowsDirectory ));
break;
case 300: /////////////////////////////////////////////////////////// Mac System
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Mac_SystemDirectory ));
break;
case 301: /////////////////////////////////////////////////////////// Mac Desktop
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Mac_DesktopDirectory ));
break;
case 302: /////////////////////////////////////////////////////////// Mac Trash
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Mac_TrashDirectory ));
break;
case 303: /////////////////////////////////////////////////////////// Mac Startup
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Mac_StartupDirectory ));
break;
case 304: /////////////////////////////////////////////////////////// Mac Shutdown
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Mac_ShutdownDirectory ));
break;
case 305: /////////////////////////////////////////////////////////// Mac Apple Menu
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Mac_AppleMenuDirectory ));
break;
case 306: /////////////////////////////////////////////////////////// Mac Control Panel
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Mac_ControlPanelDirectory ));
break;
case 307: /////////////////////////////////////////////////////////// Mac Extension
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Mac_ExtensionDirectory ));
break;
case 308: /////////////////////////////////////////////////////////// Mac Fonts
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Mac_FontsDirectory ));
break;
case 309: /////////////////////////////////////////////////////////// Mac Preferences
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Mac_PreferencesDirectory ));
break;
case 310: /////////////////////////////////////////////////////////// Mac Documents
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Mac_DocumentsDirectory ));
break;
case 400: /////////////////////////////////////////////////////////// Unix Local
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Unix_LocalDirectory ));
break;
case 401: /////////////////////////////////////////////////////////// Unix Lib
mFileSpec = new nsFileSpec( nsSpecialSystemDirectory( nsSpecialSystemDirectory::Unix_LibDirectory ));
break;
case -1:
default:
mFileSpec = nsnull;
return;
}
if (aRelativePath.Length() > 0 && mFileSpec)
{
nsString tempPath(aRelativePath);
if (aRelativePath.Last() != '/' || aRelativePath.Last() != '\\')
tempPath += '/';
*mFileSpec += tempPath;
}
}
}
void nsInstallFolder::PickDefaultDirectory()
{
//FIX: Need to put up a dialog here and set mFileSpec
return;
}
/* MapNameToEnum
* maps name from the directory table to its enum */
PRInt32
nsInstallFolder::MapNameToEnum(const nsString& name)
{
int i = 0;
if ( name.Equals(""))
return -1;
while ( DirectoryTable[i].directoryName[0] != 0 )
{
if ( name.EqualsIgnoreCase(DirectoryTable[i].directoryName) )
return DirectoryTable[i].folderEnum;
i++;
}
return -1;
}
void
nsInstallFolder::SetAppShellDirectory(PRUint32 value)
{
nsIFileSpec* fs = NS_LocateFileOrDirectory(value);
if ( fs )
{
mFileSpec = new nsFileSpec();
fs->GetFileSpec(mFileSpec);
NS_RELEASE(fs);
}
}
nsFileSpec*
nsInstallFolder::GetFileSpec()
{
if (mFileSpec == nsnull)
return nsnull;
return mFileSpec;
}
PRInt32
nsInstallFolder::ToString(nsAutoString* outString)
{
//XXX: May need to fix. Native charset paths will be converted into Unicode when the get to JS
// This will appear to work on Latin-1 charsets but won't work on Mac or other charsets.
*outString = mFileSpec->GetCString();
return NS_OK;
}

View File

@@ -0,0 +1,61 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code,
* released March 31, 1998.
*
* 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):
* Daniel Veditz <dveditz@netscape.com>
* Douglas Turner <dougt@netscape.com>
*/
#ifndef __NS_INSTALLFOLDER_H__
#define __NS_INSTALLFOLDER_H__
#include "nscore.h"
#include "prtypes.h"
#include "nsString.h"
#include "nsFileSpec.h"
#include "nsSpecialSystemDirectory.h"
class nsInstallFolder
{
public:
nsInstallFolder(const nsString& aFolderID);
nsInstallFolder(nsInstallFolder& inFolder, const nsString& subString);
nsInstallFolder(const nsString& aFolderID, const nsString& aRelativePath);
virtual ~nsInstallFolder();
void GetDirectoryPath(nsString& aDirectoryPath);
nsFileSpec* GetFileSpec();
PRInt32 ToString(nsAutoString* outString);
private:
nsFileSpec* mFileSpec;
void SetDirectoryPath(const nsString& aFolderID, const nsString& aRelativePath);
void PickDefaultDirectory();
PRInt32 MapNameToEnum(const nsString& name);
void SetAppShellDirectory(PRUint32 value);
};
#endif

View File

@@ -0,0 +1,57 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsInstallObject_h__
#define nsInstallObject_h__
#include "prtypes.h"
class nsInstall;
class nsInstallObject
{
public:
/* Public Methods */
nsInstallObject(nsInstall* inInstall) {mInstall = inInstall; }
virtual ~nsInstallObject() {}
/* Override with your set-up action */
virtual PRInt32 Prepare() = 0;
/* Override with your Completion action */
virtual PRInt32 Complete() = 0;
/* Override with an explanatory string for the progress dialog */
virtual char* toString() = 0;
/* Override with your clean-up function */
virtual void Abort() = 0;
/* should these be protected? */
virtual PRBool CanUninstall() = 0;
virtual PRBool RegisterPackageNode() = 0;
protected:
nsInstall* mInstall;
};
#endif /* nsInstallObject_h__ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,83 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsInstallPatch_h__
#define nsInstallPatch_h__
#include "prtypes.h"
#include "nsString.h"
#include "nsInstallObject.h"
#include "nsInstall.h"
#include "nsInstallFolder.h"
#include "nsInstallVersion.h"
class nsInstallPatch : public nsInstallObject
{
public:
nsInstallPatch( nsInstall* inInstall,
const nsString& inVRName,
const nsString& inVInfo,
const nsString& inJarLocation,
nsInstallFolder* folderSpec,
const nsString& inPartialPath,
PRInt32 *error);
nsInstallPatch( nsInstall* inInstall,
const nsString& inVRName,
const nsString& inVInfo,
const nsString& inJarLocation,
PRInt32 *error);
virtual ~nsInstallPatch();
PRInt32 Prepare();
PRInt32 Complete();
void Abort();
char* toString();
PRBool CanUninstall();
PRBool RegisterPackageNode();
private:
nsInstallVersion *mVersionInfo;
nsFileSpec *mTargetFile;
nsFileSpec *mPatchFile;
nsFileSpec *mPatchedFile;
nsString *mJarLocation;
nsString *mRegistryName;
PRInt32 NativePatch(const nsFileSpec &sourceFile, const nsFileSpec &patchfile, nsFileSpec **newFile);
void* HashFilePath(const nsFilePath& aPath);
};
#endif /* nsInstallPatch_h__ */

View File

@@ -0,0 +1,364 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code,
* released March 31, 1998.
*
* 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):
* Douglas Turner <dougt@netscape.com>
* Pierre Phaneuf <pp@ludusdesign.com>
*/
#include "nsIXPINotifier.h"
#include "nsInstallProgressDialog.h"
#include "nsIAppShellComponentImpl.h"
#include "nsIDOMWindow.h"
#include "nsIServiceManager.h"
#include "nsIDocumentViewer.h"
#include "nsIContent.h"
#include "nsINameSpaceManager.h"
#include "nsIContentViewer.h"
#include "nsIDOMElement.h"
#include "nsNetUtil.h"
#include "nsIURL.h"
#include "nsIWebShell.h"
#include "nsIWebShellWindow.h"
#include "nsPIXPIManagerCallbacks.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID( kAppShellServiceCID, NS_APPSHELL_SERVICE_CID );
static NS_DEFINE_CID(kDialogParamBlockCID, NS_DialogParamBlock_CID);
nsInstallProgressDialog::nsInstallProgressDialog(nsPIXPIManagerCallbacks *aManager)
: mManager(aManager)
{
NS_INIT_ISUPPORTS();
}
nsInstallProgressDialog::~nsInstallProgressDialog()
{
}
NS_IMPL_ADDREF( nsInstallProgressDialog );
NS_IMPL_RELEASE( nsInstallProgressDialog );
NS_IMETHODIMP
nsInstallProgressDialog::QueryInterface(REFNSIID aIID,void** aInstancePtr)
{
if (aInstancePtr == NULL) {
return NS_ERROR_NULL_POINTER;
}
// Always NULL result, in case of failure
*aInstancePtr = NULL;
if (aIID.Equals(NS_GET_IID(nsIXPINotifier))) {
*aInstancePtr = (void*) ((nsIXPINotifier*)this);
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(NS_GET_IID(nsIXPIProgressDlg))) {
*aInstancePtr = (void*) ((nsIXPIProgressDlg*)this);
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*) (nsISupports*)((nsIXPINotifier*)this);
NS_ADDREF_THIS();
return NS_OK;
}
return NS_ERROR_NO_INTERFACE;
}
NS_IMETHODIMP
nsInstallProgressDialog::BeforeJavascriptEvaluation(const PRUnichar *URL)
{
return NS_OK;
}
NS_IMETHODIMP
nsInstallProgressDialog::AfterJavascriptEvaluation(const PRUnichar *URL)
{
return NS_OK;
}
NS_IMETHODIMP
nsInstallProgressDialog::InstallStarted(const PRUnichar *URL, const PRUnichar *UIPackageName)
{
return SetHeading( UIPackageName );
}
NS_IMETHODIMP
nsInstallProgressDialog::ItemScheduled(const PRUnichar *message)
{
return SetActionText( message );
}
NS_IMETHODIMP
nsInstallProgressDialog::FinalizeProgress(const PRUnichar *message, PRInt32 itemNum, PRInt32 totNum)
{
nsresult rv = SetActionText( message );
if (NS_SUCCEEDED(rv))
rv = SetProgress( itemNum, totNum, 'n' );
return rv;
}
NS_IMETHODIMP
nsInstallProgressDialog::FinalStatus(const PRUnichar *URL, PRInt32 status)
{
return NS_OK;
}
NS_IMETHODIMP
nsInstallProgressDialog::LogComment(const PRUnichar* comment)
{
return NS_OK;
}
NS_IMETHODIMP
nsInstallProgressDialog::Open(nsIDialogParamBlock* ioParamBlock)
{
nsresult rv = NS_OK;
// Now do the stuff to create a window and pass the JS args to it.
NS_WITH_SERVICE(nsIAppShellService, appShell, kAppShellServiceCID, &rv );
if ( NS_SUCCEEDED( rv ) )
{
nsCOMPtr<nsIDOMWindow> hiddenWindow;
JSContext* jsContext;
rv = appShell->GetHiddenWindowAndJSContext( getter_AddRefs(hiddenWindow), &jsContext);
if (NS_SUCCEEDED(rv))
{
nsCOMPtr<nsPIXPIManagerCallbacks> mgr = do_QueryInterface(mManager);
void* stackPtr;
jsval *argv = JS_PushArguments( jsContext,
&stackPtr,
"sss%ip%ip",
"chrome://xpinstall/content/xpistatus.xul",
"_blank",
"chrome",
(const nsIID*)&NS_GET_IID(nsIDialogParamBlock),
(nsISupports*)ioParamBlock,
(const nsIID*)&NS_GET_IID(nsPIXPIManagerCallbacks),
(nsISupports*)mgr
);
if (argv)
{
rv = hiddenWindow->OpenDialog( jsContext,
argv,
5,
getter_AddRefs( mWindow ));
}
JS_PopArguments( jsContext, stackPtr);
}
}
return rv;
}
NS_IMETHODIMP
nsInstallProgressDialog::Close()
{
mWindow->Close();
return NS_OK;
}
NS_IMETHODIMP
nsInstallProgressDialog::SetTitle(const PRUnichar * aTitle)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsInstallProgressDialog::SetHeading(const PRUnichar * aHeading)
{
return setDlgAttribute( "dialog.uiPackageName", "value", nsString(aHeading) );
}
NS_IMETHODIMP
nsInstallProgressDialog::SetActionText(const PRUnichar * aActionText)
{
const PRInt32 maxChars = 50;
nsString theMessage(aActionText);
PRInt32 len = theMessage.Length();
if (len > maxChars)
{
PRInt32 offset = (len/2) - ((len - maxChars)/2);
PRInt32 count = (len - maxChars);
theMessage.Cut(offset, count);
theMessage.Insert(nsString("..."), offset);
}
return setDlgAttribute( "dialog.currentAction", "value", theMessage );
}
NS_IMETHODIMP
nsInstallProgressDialog::SetProgress(PRInt32 aValue, PRInt32 aMax, char mode)
{
char buf[16];
static char modeFlag = 'n';
nsresult rv;
static PRInt32 previousMax;
//First check to see if the max value changed so we don't
//have to send a max value across the proxy every time.
if ( aMax != previousMax)
{
previousMax = aMax;
PR_snprintf( buf, sizeof buf, "%lu", aMax );
rv = setDlgAttribute( "dialog.progress", "max", buf );
}
//I use this modeFlag business so I don't have to send
//progressmeter mode information across the proxy every time.
if ( mode != modeFlag )
{
modeFlag = mode;
if ( modeFlag == 'n' )
rv = setDlgAttribute( "dialog.progress", "mode", "normal");
else
rv = setDlgAttribute( "dialog.progress", "mode", "undetermined");
}
if ( NS_SUCCEEDED(rv))
{
if (aMax != 0)
PR_snprintf( buf, sizeof buf, "%lu", 100 * aValue/aMax );
else
PR_snprintf( buf, sizeof buf, "%lu", 0 );
rv = setDlgAttribute( "dialog.progress", "value", buf );
}
return rv;
}
NS_IMETHODIMP
nsInstallProgressDialog::StartInstallPhase()
{
nsresult rv = NS_OK;
// don't care if this fails
setDlgAttribute("dialog.cancel", "disabled", nsString("true"));
return rv;
}
NS_IMETHODIMP
nsInstallProgressDialog::GetCancelStatus(PRBool *_retval)
{
*_retval = PR_FALSE;
return NS_OK;
}
// Utility to set element attribute.
nsresult nsInstallProgressDialog::setDlgAttribute( const char *id,
const char *name,
const nsString &value )
{
nsresult rv = NS_OK;
if (!mDocument)
{
nsCOMPtr<nsIDOMDocument> doc;
rv = mWindow->GetDocument( getter_AddRefs(doc) );
if (NS_SUCCEEDED(rv))
{
mDocument = do_QueryInterface(doc,&rv);
}
NS_WARN_IF_FALSE(rv == NS_OK,"couldn't get nsIDOMXULDocument from nsXPIProgressDlg");
}
if ( mDocument ) {
// Find specified element.
nsCOMPtr<nsIDOMElement> elem;
rv = mDocument->GetElementById( id, getter_AddRefs( elem ) );
if ( elem ) {
// Set the text attribute.
rv = elem->SetAttribute( name, value );
if ( NS_SUCCEEDED( rv ) ) {
} else {
DEBUG_PRINTF( PR_STDOUT, "%s %d: SetAttribute failed, rv=0x%X\n",
__FILE__, (int)__LINE__, (int)rv );
}
} else {
DEBUG_PRINTF( PR_STDOUT, "%s %d: GetElementById failed, rv=0x%X\n",
__FILE__, (int)__LINE__, (int)rv );
}
} else {
rv = NS_ERROR_NULL_POINTER;
}
return rv;
}
// Utility to get element attribute.
nsresult nsInstallProgressDialog::getDlgAttribute( const char *id,
const char *name,
nsString &value )
{
nsresult rv = NS_OK;
if (!mDocument)
{
nsCOMPtr<nsIDOMDocument> doc;
rv = mWindow->GetDocument( getter_AddRefs(doc) );
if (NS_SUCCEEDED(rv))
{
mDocument = do_QueryInterface(doc,&rv);
}
NS_WARN_IF_FALSE(rv == NS_OK,"couldn't get nsIDOMXULDocument from nsXPIProgressDlg");
}
if ( mDocument ) {
// Find specified element.
nsCOMPtr<nsIDOMElement> elem;
rv = mDocument->GetElementById( id, getter_AddRefs( elem ) );
if ( elem ) {
// Set the text attribute.
rv = elem->GetAttribute( name, value );
if ( NS_SUCCEEDED( rv ) ) {
} else {
DEBUG_PRINTF( PR_STDOUT, "%s %d: GetAttribute failed, rv=0x%X\n",
__FILE__, (int)__LINE__, (int)rv );
}
} else {
DEBUG_PRINTF( PR_STDOUT, "%s %d: GetElementById failed, rv=0x%X\n",
__FILE__, (int)__LINE__, (int)rv );
}
} else {
rv = NS_ERROR_NULL_POINTER;
}
return rv;
}

View File

@@ -0,0 +1,72 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code,
* released March 31, 1998.
*
* 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):
* Douglas Turner <dougt@netscape.com>
*/
#ifndef __nsInstallProgressDialog_h__
#define __nsInstallProgressDialog_h__
#include "nscore.h"
#include "nsIXPINotifier.h"
#include "nsIXPIProgressDlg.h"
#include "nsISupports.h"
#include "nsISupportsUtils.h"
#include "nsCOMPtr.h"
#include "nsIWebShell.h"
#include "nsIWebShellWindow.h"
#include "nsPIXPIManagerCallbacks.h"
#include "nsIDocument.h"
#include "nsIDOMWindow.h"
#include "nsIDOMDocument.h"
#include "nsIDOMXULDocument.h"
class nsInstallProgressDialog : public nsIXPINotifier,
public nsIXPIProgressDlg
{
public:
nsInstallProgressDialog(nsPIXPIManagerCallbacks *aManager);
virtual ~nsInstallProgressDialog();
NS_DECL_ISUPPORTS
// implement nsIXPINotifier
NS_DECL_NSIXPINOTIFIER
// implement nsIXPIProgressDlg
NS_DECL_NSIXPIPROGRESSDLG
// void SetWindow(nsISupports* aWindow);
protected:
nsresult setDlgAttribute(const char *id, const char *name, const nsString &value);
nsresult getDlgAttribute(const char *id, const char *name, nsString &value);
private:
nsPIXPIManagerCallbacks* mManager;
nsCOMPtr<nsIDOMXULDocument> mDocument; // Should this be a weak reference?
nsCOMPtr<nsIDOMWindow> mWindow; // Should this be a weak reference?
};
#endif

View File

@@ -0,0 +1,83 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code,
* released March 31, 1998.
*
* 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):
* Daniel Veditz <dveditz@netscape.com>
* Douglas Turner <dougt@netscape.com>
* Samir Gehani <sgehani@netscape.com>
*/
#include <string.h>
#include "nscore.h"
#include "nsInstallResources.h"
static nsXPIResourceTableItem XPIResTable[] =
{
/*---------------------------------------------------------------------*
* Install Actions
*---------------------------------------------------------------------*/
{ "InstallFile", "Installing: %s" },
{ "ReplaceFile", "Replacing: %s" },
{ "SkipFile", "Skipping: %s" },
{ "DeleteFile", "Deleting file: %s" },
{ "DeleteComponent", "Deleting component: %s" },
{ "Execute", "Executing: %s" },
{ "ExecuteWithArgs", "Executing: %s with argument: %s" },
{ "Patch", "Patching: %s" },
{ "Uninstall", "Uninstalling: %s" },
// XXX FileOp*() action strings
// XXX WinReg and WinProfile action strings
/*---------------------------------------------------------------------*
* Dialog Messages
*---------------------------------------------------------------------*/
{ "FinishingInstallMsg", "Finishing install... please wait." },
/*---------------------------------------------------------------------*
* Miscellaneous
*---------------------------------------------------------------------*/
{ "ERROR", "ERROR" },
{ NS_XPI_EOT, "" }
};
char*
nsInstallResources::GetDefaultVal(const char* aResName)
{
char *currResName = XPIResTable[0].resName;
char *currResVal = nsnull;
PRInt32 idx, len = 0;
for (idx = 0; 0 != strcmp(currResName, NS_XPI_EOT); idx++)
{
currResName = XPIResTable[idx].resName;
len = strlen(currResName);
if (0 == strncmp(currResName, aResName, len))
{
currResVal = XPIResTable[idx].defaultString;
break;
}
}
return currResVal;
}

View File

@@ -0,0 +1,48 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code,
* released March 31, 1998.
*
* 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):
* Daniel Veditz <dveditz@netscape.com>
* Douglas Turner <dougt@netscape.com>
* Samir Gehani <sgehani@netscape.com>
*/
#ifndef __NS_INSTALLRESOURCES_H__
#define __NS_INSTALLRESOURCES_H__
#define NS_XPI_EOT "___END_OF_TABLE___"
typedef struct _nsXPIResourceTableItem
{
char *resName;
char *defaultString;
} nsXPIResourceTableItem;
class nsInstallResources
{
public:
static char* GetDefaultVal(const char* aResName);
};
#endif

View File

@@ -0,0 +1,489 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code.
*
* 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):
*/
#include "nsSoftwareUpdate.h"
#include "nsXPInstallManager.h"
#include "nsInstallTrigger.h"
#include "nsInstallVersion.h"
#include "nsIDOMInstallTriggerGlobal.h"
#include "nscore.h"
#include "nsIFactory.h"
#include "nsISupports.h"
#include "nsIScriptGlobalObject.h"
#include "nsIPref.h"
#include "nsRepository.h"
#include "nsIServiceManager.h"
#include "nsSpecialSystemDirectory.h"
#include "VerReg.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
static NS_DEFINE_IID(kIInstallTrigger_IID, NS_IDOMINSTALLTRIGGERGLOBAL_IID);
static NS_DEFINE_IID(kIInstallTrigger_CID, NS_SoftwareUpdateInstallTrigger_CID);
nsInstallTrigger::nsInstallTrigger()
{
mScriptObject = nsnull;
NS_INIT_REFCNT();
}
nsInstallTrigger::~nsInstallTrigger()
{
}
NS_IMETHODIMP
nsInstallTrigger::QueryInterface(REFNSIID aIID,void** aInstancePtr)
{
if (aInstancePtr == NULL)
{
return NS_ERROR_NULL_POINTER;
}
// Always NULL result, in case of failure
*aInstancePtr = NULL;
if ( aIID.Equals(kIScriptObjectOwnerIID))
{
*aInstancePtr = (void*) ((nsIScriptObjectOwner*)this);
AddRef();
return NS_OK;
}
else if ( aIID.Equals(kIInstallTrigger_IID) )
{
*aInstancePtr = (void*) ((nsIDOMInstallTriggerGlobal*)this);
AddRef();
return NS_OK;
}
else if ( aIID.Equals(kISupportsIID) )
{
*aInstancePtr = (void*)(nsISupports*)(nsIScriptObjectOwner*)this;
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMPL_ADDREF(nsInstallTrigger)
NS_IMPL_RELEASE(nsInstallTrigger)
NS_IMETHODIMP
nsInstallTrigger::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
{
NS_PRECONDITION(nsnull != aScriptObject, "null arg");
nsresult res = NS_OK;
if (nsnull == mScriptObject)
{
nsIScriptGlobalObject *global = aContext->GetGlobalObject();
res = NS_NewScriptInstallTriggerGlobal( aContext,
(nsISupports *)(nsIDOMInstallTriggerGlobal*)this,
(nsISupports *)global,
&mScriptObject);
NS_IF_RELEASE(global);
}
*aScriptObject = mScriptObject;
return res;
}
NS_IMETHODIMP
nsInstallTrigger::SetScriptObject(void *aScriptObject)
{
mScriptObject = aScriptObject;
return NS_OK;
}
static NS_DEFINE_IID(kPrefsIID, NS_IPREF_IID);
static NS_DEFINE_IID(kPrefsCID, NS_PREF_CID);
NS_IMETHODIMP
nsInstallTrigger::UpdateEnabled(PRBool* aReturn)
{
nsIPref * prefs;
nsresult rv = nsServiceManager::GetService(kPrefsCID,
kPrefsIID,
(nsISupports**) &prefs);
if ( NS_SUCCEEDED(rv) )
{
rv = prefs->GetBoolPref( (const char*) XPINSTALL_ENABLE_PREF, aReturn);
if (NS_FAILED(rv))
{
*aReturn = PR_FALSE;
}
NS_RELEASE(prefs);
}
else
{
*aReturn = PR_FALSE; /* no prefs manager. set to false */
}
return NS_OK;
}
NS_IMETHODIMP
nsInstallTrigger::Install(nsXPITriggerInfo* aTrigger, PRBool* aReturn)
{
nsresult rv;
*aReturn = PR_FALSE;
PRBool enabled;
UpdateEnabled(&enabled);
if (!enabled)
{
delete aTrigger;
return NS_OK;
}
nsXPInstallManager *mgr = new nsXPInstallManager();
if (mgr)
{
// The Install manager will delete itself when done
rv = mgr->InitManager( aTrigger );
if (NS_SUCCEEDED(rv))
*aReturn = PR_TRUE;
}
else
{
delete aTrigger;
rv = NS_ERROR_OUT_OF_MEMORY;
}
return rv;
}
NS_IMETHODIMP
nsInstallTrigger::StartSoftwareUpdate(const nsString& aURL, PRInt32 aFlags, PRBool* aReturn)
{
PRBool enabled;
nsresult rv = NS_ERROR_OUT_OF_MEMORY;
*aReturn = PR_FALSE;
UpdateEnabled(&enabled);
if (!enabled)
return NS_OK;
// The Install manager will delete itself when done, once we've called
// InitManager. Before then **WE** must delete it
nsXPInstallManager *mgr = new nsXPInstallManager();
if (mgr)
{
nsXPITriggerInfo* trigger = new nsXPITriggerInfo();
if ( trigger )
{
nsXPITriggerItem* item = new nsXPITriggerItem(0,aURL.GetUnicode());
if (item)
{
trigger->Add( item );
// The Install manager will delete itself when done
rv = mgr->InitManager( trigger );
*aReturn = PR_TRUE;
}
else
{
rv = NS_ERROR_OUT_OF_MEMORY;
delete trigger;
delete mgr;
}
}
else
{
rv = NS_ERROR_OUT_OF_MEMORY;
delete mgr;
}
}
return rv;
}
NS_IMETHODIMP
nsInstallTrigger::ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, PRInt32 aDiffLevel, const nsString& aVersion, PRInt32 aMode, PRInt32* aReturn)
{
nsInstallVersion inVersion;
inVersion.Init(aVersion);
return ConditionalSoftwareUpdate(aURL, aRegName, aDiffLevel, &inVersion, aMode, aReturn);
}
NS_IMETHODIMP
nsInstallTrigger::ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, PRInt32 aDiffLevel, nsIDOMInstallVersion* aVersion, PRInt32 aMode, PRInt32* aReturn)
{
PRBool needJar = PR_FALSE;
PRBool enabled;
UpdateEnabled(&enabled);
if (!enabled)
return NS_OK;
if (aURL.IsEmpty() || aVersion == nsnull)
{
needJar = PR_TRUE;
}
else
{
char * regNameCString = aRegName.ToNewCString();
REGERR status = VR_ValidateComponent( regNameCString );
if ( status == REGERR_NOFIND || status == REGERR_NOFILE )
{
// either component is not in the registry or it's a file
// node and the physical file is missing
needJar = PR_TRUE;
}
else
{
VERSION oldVersion;
PRInt32 diffValue;
status = VR_GetVersion( regNameCString, &oldVersion );
nsInstallVersion oldInstallVersion;
oldInstallVersion.Init(oldVersion.major,
oldVersion.minor,
oldVersion.release,
oldVersion.build);
if ( status != REGERR_OK )
needJar = PR_TRUE;
else if ( aDiffLevel < 0 )
{
aVersion->CompareTo(&oldInstallVersion, &diffValue);
needJar = (diffValue <= aDiffLevel);
}
else
{
aVersion->CompareTo(&oldInstallVersion, &diffValue);
needJar = (diffValue >= aDiffLevel);
}
}
}
if (needJar)
return StartSoftwareUpdate(aURL, aMode, aReturn);
else
*aReturn = 0;
return NS_OK;
}
NS_IMETHODIMP
nsInstallTrigger::ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, nsIDOMInstallVersion* aVersion, PRInt32 aMode, PRInt32* aReturn)
{
return ConditionalSoftwareUpdate(aURL, aRegName, BLD_DIFF, aVersion, aMode, aReturn);
}
NS_IMETHODIMP
nsInstallTrigger::ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, const nsString& aVersion, PRInt32 aMode, PRInt32* aReturn)
{
nsInstallVersion inVersion;
inVersion.Init(aVersion);
return ConditionalSoftwareUpdate(aURL, aRegName, BLD_DIFF, &inVersion, aMode, aReturn);
}
NS_IMETHODIMP
nsInstallTrigger::ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, const nsString& aVersion, PRInt32* aReturn)
{
nsInstallVersion inVersion;
inVersion.Init(aVersion);;
return ConditionalSoftwareUpdate(aURL, aRegName, BLD_DIFF, &inVersion, 0, aReturn);
}
NS_IMETHODIMP
nsInstallTrigger::ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, nsIDOMInstallVersion* aVersion, PRInt32* aReturn)
{
return ConditionalSoftwareUpdate(aURL, aRegName, BLD_DIFF, aVersion, 0, aReturn);
}
NS_IMETHODIMP
nsInstallTrigger::CompareVersion(const nsString& aRegName, PRInt32 aMajor, PRInt32 aMinor, PRInt32 aRelease, PRInt32 aBuild, PRInt32* aReturn)
{
nsInstallVersion inVersion;
inVersion.Init(aMajor, aMinor, aRelease, aBuild);
return CompareVersion(aRegName, &inVersion, aReturn);
}
NS_IMETHODIMP
nsInstallTrigger::CompareVersion(const nsString& aRegName, const nsString& aVersion, PRInt32* aReturn)
{
nsInstallVersion inVersion;
inVersion.Init(aVersion);
return CompareVersion(aRegName, &inVersion, aReturn);
}
NS_IMETHODIMP
nsInstallTrigger::CompareVersion(const nsString& aRegName, nsIDOMInstallVersion* aVersion, PRInt32* aReturn)
{
*aReturn = EQUAL; // assume failure.
PRBool enabled;
UpdateEnabled(&enabled);
if (!enabled)
return NS_OK;
VERSION cVersion;
char* tempCString;
REGERR status;
nsInstallVersion regNameVersion;
tempCString = aRegName.ToNewCString();
status = VR_GetVersion( tempCString, &cVersion );
/* if we got the version */
if ( status == REGERR_OK )
{
if ( VR_ValidateComponent( tempCString ) == REGERR_NOFILE )
{
regNameVersion.Init(0,0,0,0);
}
else
{
regNameVersion.Init(cVersion.major,
cVersion.minor,
cVersion.release,
cVersion.build);
}
}
else
regNameVersion.Init(0,0,0,0);
regNameVersion.CompareTo( aVersion, aReturn );
if (tempCString)
Recycle(tempCString);
return NS_OK;
}
NS_IMETHODIMP
nsInstallTrigger::GetVersion(const nsString& component, nsString& version)
{
PRBool enabled;
UpdateEnabled(&enabled);
if (!enabled)
return NS_OK;
VERSION cVersion;
char* tempCString;
REGERR status;
tempCString = component.ToNewCString();
status = VR_GetVersion( tempCString, &cVersion );
version.Truncate();
/* if we got the version */
if ( status == REGERR_OK && VR_ValidateComponent( tempCString ) == REGERR_OK)
{
nsInstallVersion regNameVersion;
regNameVersion.Init(cVersion.major,
cVersion.minor,
cVersion.release,
cVersion.build);
regNameVersion.ToString(version);
}
if (tempCString)
Recycle(tempCString);
return NS_OK;
}
// this will take a nsIURI, and create a temporary file. If it is local, we just us it.
void
nsInstallTrigger::CreateTempFileFromURL(const nsString& aURL, nsString& tempFileString)
{
// Checking to see if the url is local
if ( aURL.EqualsIgnoreCase("file:/", 6) )
{
tempFileString.Assign( nsNSPRPath(nsFileURL(aURL)) );
}
else
{
nsSpecialSystemDirectory tempFile(nsSpecialSystemDirectory::OS_TemporaryDirectory);
PRInt32 result = aURL.RFindChar('/');
if (result != -1)
{
nsString jarName;
aURL.Right(jarName, (aURL.Length() - result) );
PRInt32 argOffset = jarName.RFindChar('?');
if (argOffset != -1)
{
// we need to remove ? and everything after it
jarName.Truncate(argOffset);
}
tempFile += jarName;
}
else
{
tempFile += "xpinstall.jar";
}
tempFile.MakeUnique();
tempFileString.Assign( nsNSPRPath( nsFilePath(tempFile) ) );
}
}

View File

@@ -0,0 +1,55 @@
#ifndef __NS_INSTALLTRIGGER_H__
#define __NS_INSTALLTRIGGER_H__
#include "nscore.h"
#include "nsString.h"
#include "nsIFactory.h"
#include "nsISupports.h"
#include "nsIScriptObjectOwner.h"
#include "prtypes.h"
#include "nsHashtable.h"
#include "nsIDOMInstallTriggerGlobal.h"
#include "nsSoftwareUpdate.h"
#include "nsXPITriggerInfo.h"
class nsInstallTrigger: public nsIScriptObjectOwner, public nsIDOMInstallTriggerGlobal
{
public:
static const nsIID& IID() { static nsIID iid = NS_SoftwareUpdateInstallTrigger_CID; return iid; }
nsInstallTrigger();
virtual ~nsInstallTrigger();
NS_DECL_ISUPPORTS
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void* aScriptObject);
NS_IMETHOD UpdateEnabled(PRBool* aReturn);
NS_IMETHOD Install(nsXPITriggerInfo *aInfo, PRBool* aReturn);
NS_IMETHOD StartSoftwareUpdate(const nsString& aURL, PRInt32 aFlags, PRInt32* aReturn);
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, PRInt32 aDiffLevel, const nsString& aVersion, PRInt32 aMode, PRInt32* aReturn);
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, PRInt32 aDiffLevel, nsIDOMInstallVersion* aVersion, PRInt32 aMode, PRInt32* aReturn);
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, nsIDOMInstallVersion* aVersion, PRInt32 aMode, PRInt32* aReturn);
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, const nsString& aVersion, PRInt32 aMode, PRInt32* aReturn);
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, const nsString& aVersion, PRInt32* aReturn);
NS_IMETHOD ConditionalSoftwareUpdate(const nsString& aURL, const nsString& aRegName, nsIDOMInstallVersion* aVersion, PRInt32* aReturn);
NS_IMETHOD CompareVersion(const nsString& aRegName, PRInt32 aMajor, PRInt32 aMinor, PRInt32 aRelease, PRInt32 aBuild, PRInt32* aReturn);
NS_IMETHOD CompareVersion(const nsString& aRegName, const nsString& aVersion, PRInt32* aReturn);
NS_IMETHOD CompareVersion(const nsString& aRegName, nsIDOMInstallVersion* aVersion, PRInt32* aReturn);
NS_IMETHOD GetVersion(const nsString& component, nsString& version);
private:
void *mScriptObject;
void CreateTempFileFromURL(const nsString& aURL, nsString& tempFileString);
};
#define NS_INSTALLTRIGGERCOMPONENT_PROGID NS_IXPINSTALLCOMPONENT_PROGID "/installtrigger"
#endif

View File

@@ -0,0 +1,216 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code,
* released March 31, 1998.
*
* 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):
* Daniel Veditz <dveditz@netscape.com>
* Douglas Turner <dougt@netscape.com>
*/
#include "nsInstall.h"
#include "nsInstallUninstall.h"
#include "nsInstallResources.h"
#include "VerReg.h"
#include "prmem.h"
#include "nsFileSpec.h"
#include "ScheduledTasks.h"
extern "C" NS_EXPORT PRInt32 SU_Uninstall(char *regPackageName);
REGERR su_UninstallProcessItem(char *component_path);
MOZ_DECL_CTOR_COUNTER(nsInstallUninstall);
nsInstallUninstall::nsInstallUninstall( nsInstall* inInstall,
const nsString& regName,
PRInt32 *error)
: nsInstallObject(inInstall)
{
MOZ_COUNT_CTOR(nsInstallUninstall);
if (regName.Equals(""))
{
*error = nsInstall::INVALID_ARGUMENTS;
return;
}
mRegName.Assign(regName);
char* userName = (char*)PR_Malloc(MAXREGPATHLEN);
PRInt32 err = VR_GetUninstallUserName( (char*) (const char*) nsAutoCString(regName),
userName,
MAXREGPATHLEN );
mUIName.Assign(userName);
if (err != REGERR_OK)
{
*error = nsInstall::NO_SUCH_COMPONENT;
}
PR_FREEIF(userName);
}
nsInstallUninstall::~nsInstallUninstall()
{
MOZ_COUNT_CTOR(nsInstallUninstall);
}
PRInt32 nsInstallUninstall::Prepare()
{
// no set-up necessary
return nsInstall::SUCCESS;
}
PRInt32 nsInstallUninstall::Complete()
{
PRInt32 err = nsInstall::SUCCESS;
if (mInstall == NULL)
return nsInstall::INVALID_ARGUMENTS;
err = SU_Uninstall( (char*)(const char*) nsAutoCString(mRegName) );
return err;
}
void nsInstallUninstall::Abort()
{
}
char* nsInstallUninstall::toString()
{
char* buffer = new char[1024];
char* rsrcVal = nsnull;
if (buffer == nsnull || !mInstall)
return buffer;
char* temp = mUIName.ToNewCString();
if (temp)
{
rsrcVal = mInstall->GetResourcedString("Uninstall");
if (rsrcVal)
{
sprintf( buffer, rsrcVal, temp);
nsCRT::free(rsrcVal);
}
}
if (temp)
Recycle(temp);
return buffer;
}
PRBool
nsInstallUninstall::CanUninstall()
{
return PR_FALSE;
}
PRBool
nsInstallUninstall::RegisterPackageNode()
{
return PR_FALSE;
}
extern "C" NS_EXPORT PRInt32 SU_Uninstall(char *regPackageName)
{
REGERR status = REGERR_FAIL;
char pathbuf[MAXREGPATHLEN+1] = {0};
char sharedfilebuf[MAXREGPATHLEN+1] = {0};
REGENUM state = 0;
int32 length;
int32 err;
if (regPackageName == NULL)
return REGERR_PARAM;
if (pathbuf == NULL)
return REGERR_PARAM;
/* Get next path from Registry */
status = VR_Enum( regPackageName, &state, pathbuf, MAXREGPATHLEN );
/* if we got a good path */
while (status == REGERR_OK)
{
char component_path[2*MAXREGPATHLEN+1] = {0};
strcat(component_path, regPackageName);
length = strlen(regPackageName);
if (component_path[length - 1] != '/')
strcat(component_path, "/");
strcat(component_path, pathbuf);
err = su_UninstallProcessItem(component_path);
status = VR_Enum( regPackageName, &state, pathbuf, MAXREGPATHLEN );
}
err = VR_Remove(regPackageName);
// there is a problem here. It looks like if the file is refcounted, we still blow away the reg key
// FIX!
state = 0;
status = VR_UninstallEnumSharedFiles( regPackageName, &state, sharedfilebuf, MAXREGPATHLEN );
while (status == REGERR_OK)
{
err = su_UninstallProcessItem(sharedfilebuf);
err = VR_UninstallDeleteFileFromList(regPackageName, sharedfilebuf);
status = VR_UninstallEnumSharedFiles( regPackageName, &state, sharedfilebuf, MAXREGPATHLEN );
}
err = VR_UninstallDeleteSharedFilesKey(regPackageName);
err = VR_UninstallDestroy(regPackageName);
return err;
}
REGERR su_UninstallProcessItem(char *component_path)
{
int refcount;
int err;
char filepath[MAXREGPATHLEN];
err = VR_GetPath(component_path, sizeof(filepath), filepath);
if ( err == REGERR_OK )
{
err = VR_GetRefCount(component_path, &refcount);
if ( err == REGERR_OK )
{
--refcount;
if (refcount > 0)
err = VR_SetRefCount(component_path, refcount);
else
{
err = VR_Remove(component_path);
DeleteFileNowOrSchedule(nsFileSpec(filepath));
}
}
else
{
/* delete node and file */
err = VR_Remove(component_path);
DeleteFileNowOrSchedule(nsFileSpec(filepath));
}
}
return err;
}

View File

@@ -0,0 +1,63 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code,
* released March 31, 1998.
*
* 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):
* Daniel Veditz <dveditz@netscape.com>
* Douglas Turner <dougt@netscape.com>
*/
#ifndef nsInstallUninstall_h__
#define nsInstallUninstall_h__
#include "prtypes.h"
#include "nsString.h"
#include "nsInstallObject.h"
#include "nsInstall.h"
class nsInstallUninstall : public nsInstallObject
{
public:
nsInstallUninstall( nsInstall* inInstall,
const nsString& regName,
PRInt32 *error);
virtual ~nsInstallUninstall();
PRInt32 Prepare();
PRInt32 Complete();
void Abort();
char* toString();
PRBool CanUninstall();
PRBool RegisterPackageNode();
private:
nsString mRegName; // Registry name of package
nsString mUIName; // User name of package
};
#endif /* nsInstallUninstall_h__ */

View File

@@ -0,0 +1,341 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code.
*
* 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):
*/
#include "nsSoftwareUpdate.h"
#include "nsInstallVersion.h"
#include "nsIDOMInstallVersion.h"
#include "nscore.h"
#include "nsIFactory.h"
#include "nsISupports.h"
#include "nsIScriptGlobalObject.h"
#include "prprf.h"
#include "prmem.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
static NS_DEFINE_IID(kIInstallVersion_IID, NS_IDOMINSTALLVERSION_IID);
nsInstallVersion::nsInstallVersion()
{
mScriptObject = nsnull;
NS_INIT_REFCNT();
}
nsInstallVersion::~nsInstallVersion()
{
}
NS_IMETHODIMP
nsInstallVersion::QueryInterface(REFNSIID aIID,void** aInstancePtr)
{
if (aInstancePtr == NULL)
{
return NS_ERROR_NULL_POINTER;
}
// Always NULL result, in case of failure
*aInstancePtr = NULL;
if ( aIID.Equals(kIScriptObjectOwnerIID))
{
*aInstancePtr = (void*) ((nsIScriptObjectOwner*)this);
AddRef();
return NS_OK;
}
else if ( aIID.Equals(kIInstallVersion_IID) )
{
*aInstancePtr = (void*) ((nsIDOMInstallVersion*)this);
AddRef();
return NS_OK;
}
else if ( aIID.Equals(kISupportsIID) )
{
*aInstancePtr = (void*)(nsISupports*)(nsIScriptObjectOwner*)this;
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMPL_ADDREF(nsInstallVersion)
NS_IMPL_RELEASE(nsInstallVersion)
NS_IMETHODIMP
nsInstallVersion::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
{
NS_PRECONDITION(nsnull != aScriptObject, "null arg");
nsresult res = NS_OK;
if (nsnull == mScriptObject)
{
res = NS_NewScriptInstallVersion(aContext,
(nsISupports *)(nsIDOMInstallVersion*)this,
nsnull,
&mScriptObject);
}
*aScriptObject = mScriptObject;
return res;
}
NS_IMETHODIMP
nsInstallVersion::SetScriptObject(void *aScriptObject)
{
mScriptObject = aScriptObject;
return NS_OK;
}
// this will go away when our constructors can have parameters.
NS_IMETHODIMP
nsInstallVersion::Init(PRInt32 aMajor, PRInt32 aMinor, PRInt32 aRelease, PRInt32 aBuild)
{
major = aMajor;
minor = aMinor;
release = aRelease;
build = aBuild;
return NS_OK;
}
NS_IMETHODIMP
nsInstallVersion::Init(const nsString& version)
{
PRInt32 errorCode;
PRInt32 aMajor, aMinor, aRelease, aBuild;
major = minor = release = build = 0;
errorCode = nsInstallVersion::StringToVersionNumbers(version, &aMajor, &aMinor, &aRelease, &aBuild);
if (NS_SUCCEEDED(errorCode))
{
Init(aMajor, aMinor, aRelease, aBuild);
}
return NS_OK;
}
NS_IMETHODIMP
nsInstallVersion::GetMajor(PRInt32* aMajor)
{
*aMajor = major;
return NS_OK;
}
NS_IMETHODIMP
nsInstallVersion::SetMajor(PRInt32 aMajor)
{
major = aMajor;
return NS_OK;
}
NS_IMETHODIMP
nsInstallVersion::GetMinor(PRInt32* aMinor)
{
*aMinor = minor;
return NS_OK;
}
NS_IMETHODIMP
nsInstallVersion::SetMinor(PRInt32 aMinor)
{
minor = aMinor;
return NS_OK;
}
NS_IMETHODIMP
nsInstallVersion::GetRelease(PRInt32* aRelease)
{
*aRelease = release;
return NS_OK;
}
NS_IMETHODIMP
nsInstallVersion::SetRelease(PRInt32 aRelease)
{
release = aRelease;
return NS_OK;
}
NS_IMETHODIMP
nsInstallVersion::GetBuild(PRInt32* aBuild)
{
*aBuild = build;
return NS_OK;
}
NS_IMETHODIMP
nsInstallVersion::SetBuild(PRInt32 aBuild)
{
build = aBuild;
return NS_OK;
}
NS_IMETHODIMP
nsInstallVersion::CompareTo(nsIDOMInstallVersion* aVersion, PRInt32* aReturn)
{
PRInt32 aMajor, aMinor, aRelease, aBuild;
aVersion->GetMajor(&aMajor);
aVersion->GetMinor(&aMinor);
aVersion->GetRelease(&aRelease);
aVersion->GetBuild(&aBuild);
CompareTo(aMajor, aMinor, aRelease, aBuild, aReturn);
return NS_OK;
}
NS_IMETHODIMP
nsInstallVersion::CompareTo(const nsString& aString, PRInt32* aReturn)
{
nsInstallVersion inVersion;
inVersion.Init(aString);
return CompareTo(&inVersion, aReturn);
}
NS_IMETHODIMP
nsInstallVersion::CompareTo(PRInt32 aMajor, PRInt32 aMinor, PRInt32 aRelease, PRInt32 aBuild, PRInt32* aReturn)
{
int diff;
if ( major == aMajor )
{
if ( minor == aMinor )
{
if ( release == aRelease )
{
if ( build == aBuild )
diff = EQUAL;
else if ( build > aBuild )
diff = BLD_DIFF;
else
diff = BLD_DIFF_MINUS;
}
else if ( release > aRelease )
diff = REL_DIFF;
else
diff = REL_DIFF_MINUS;
}
else if ( minor > aMinor )
diff = MINOR_DIFF;
else
diff = MINOR_DIFF_MINUS;
}
else if ( major > aMajor )
diff = MAJOR_DIFF;
else
diff = MAJOR_DIFF_MINUS;
*aReturn = diff;
return NS_OK;
}
NS_IMETHODIMP
nsInstallVersion::ToString(nsString& aReturn)
{
char *result=NULL;
result = PR_sprintf_append(result, "%d.%d.%d.%d", major, minor, release, build);
aReturn.Assign(result);
PR_FREEIF(result);
return NS_OK;
}
nsresult
nsInstallVersion::StringToVersionNumbers(const nsString& version, PRInt32 *aMajor, PRInt32 *aMinor, PRInt32 *aRelease, PRInt32 *aBuild)
{
PRInt32 errorCode;
int dot = version.FindChar('.', PR_FALSE,0);
if ( dot == -1 )
{
*aMajor = version.ToInteger(&errorCode);
}
else
{
nsString majorStr;
version.Mid(majorStr, 0, dot);
*aMajor = majorStr.ToInteger(&errorCode);
int prev = dot+1;
dot = version.FindChar('.',PR_FALSE,prev);
if ( dot == -1 )
{
nsString minorStr;
version.Mid(minorStr, prev, version.Length() - prev);
*aMinor = minorStr.ToInteger(&errorCode);
}
else
{
nsString minorStr;
version.Mid(minorStr, prev, dot - prev);
*aMinor = minorStr.ToInteger(&errorCode);
prev = dot+1;
dot = version.FindChar('.',PR_FALSE,prev);
if ( dot == -1 )
{
nsString releaseStr;
version.Mid(releaseStr, prev, version.Length() - prev);
*aRelease = releaseStr.ToInteger(&errorCode);
}
else
{
nsString releaseStr;
version.Mid(releaseStr, prev, dot - prev);
*aRelease = releaseStr.ToInteger(&errorCode);
prev = dot+1;
if ( version.Length() > dot )
{
nsString buildStr;
version.Mid(buildStr, prev, version.Length() - prev);
*aBuild = buildStr.ToInteger(&errorCode);
}
}
}
}
return errorCode;
}

View File

@@ -0,0 +1,60 @@
#ifndef __NS_INSTALLVERSION_H__
#define __NS_INSTALLVERSION_H__
#include "nscore.h"
#include "nsString.h"
#include "nsIFactory.h"
#include "nsISupports.h"
#include "nsIScriptObjectOwner.h"
#include "nsIDOMInstallVersion.h"
#include "nsSoftwareUpdate.h"
#include "prtypes.h"
class nsInstallVersion: public nsIScriptObjectOwner, public nsIDOMInstallVersion
{
public:
static const nsIID& IID() { static nsIID iid = NS_SoftwareUpdateInstallVersion_CID; return iid; }
nsInstallVersion();
virtual ~nsInstallVersion();
NS_DECL_ISUPPORTS
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void* aScriptObject);
NS_IMETHOD Init(PRInt32 aMajor, PRInt32 aMinor, PRInt32 aRelease, PRInt32 aBuild);
NS_IMETHOD Init(const nsString& aVersionString);
NS_IMETHOD GetMajor(PRInt32* aMajor);
NS_IMETHOD SetMajor(PRInt32 aMajor);
NS_IMETHOD GetMinor(PRInt32* aMinor);
NS_IMETHOD SetMinor(PRInt32 aMinor);
NS_IMETHOD GetRelease(PRInt32* aRelease);
NS_IMETHOD SetRelease(PRInt32 aRelease);
NS_IMETHOD GetBuild(PRInt32* aBuild);
NS_IMETHOD SetBuild(PRInt32 aBuild);
NS_IMETHOD ToString(nsString& aReturn);
NS_IMETHOD CompareTo(nsIDOMInstallVersion* aVersion, PRInt32* aReturn);
NS_IMETHOD CompareTo(const nsString& aString, PRInt32* aReturn);
NS_IMETHOD CompareTo(PRInt32 aMajor, PRInt32 aMinor, PRInt32 aRelease, PRInt32 aBuild, PRInt32* aReturn);
static nsresult StringToVersionNumbers(const nsString& version, PRInt32 *aMajor, PRInt32 *aMinor, PRInt32 *aRelease, PRInt32 *aBuild);
private:
void *mScriptObject;
PRInt32 major;
PRInt32 minor;
PRInt32 release;
PRInt32 build;
};
#define NS_INSTALLVERSIONCOMPONENT_PROGID NS_IXPINSTALLCOMPONENT_PROGID "/installversion"
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,93 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef __NS_JSFILE_H__
#define __NS_JSFILE_H__
#include "jsapi.h"
#include "nsJSUtils.h"
#include "nscore.h"
JSBool PR_CALLBACK
InstallFileOpDirCreate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
JSBool PR_CALLBACK
InstallFileOpDirGetParent(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
JSBool PR_CALLBACK
InstallFileOpDirRemove(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
JSBool PR_CALLBACK
InstallFileOpDirRename(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
JSBool PR_CALLBACK
InstallFileOpFileCopy(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
JSBool PR_CALLBACK
InstallFileOpFileDelete(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
JSBool PR_CALLBACK
InstallFileOpFileExists(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
JSBool PR_CALLBACK
InstallFileOpFileExecute(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
JSBool PR_CALLBACK
InstallFileOpFileGetNativeVersion(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
JSBool PR_CALLBACK
InstallFileOpFileGetDiskSpaceAvailable(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
JSBool PR_CALLBACK
InstallFileOpFileGetModDate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
JSBool PR_CALLBACK
InstallFileOpFileGetSize(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
JSBool PR_CALLBACK
InstallFileOpFileIsDirectory(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
JSBool PR_CALLBACK
InstallFileOpFileIsFile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
JSBool PR_CALLBACK
InstallFileOpFileModDateChanged(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
JSBool PR_CALLBACK
InstallFileOpFileMove(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
JSBool PR_CALLBACK
InstallFileOpFileRename(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
JSBool PR_CALLBACK
InstallFileOpFileWindowsShortcut(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
JSBool PR_CALLBACK
InstallFileOpFileMacAlias(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
JSBool PR_CALLBACK
InstallFileOpFileUnixLink(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
PRInt32 InitXPFileOpObjectPrototype(JSContext *jscontext, JSObject *global, JSObject **fileOpObjectPrototype);
#endif

View File

@@ -0,0 +1,150 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "jsapi.h"
#include "nsJSUtils.h"
#include "nscore.h"
#include "nsIScriptContext.h"
#include "nsString.h"
#include "nsInstall.h"
#include "nsJSFileSpecObj.h"
extern void ConvertJSValToStr(nsString& aString,
JSContext* aContext,
jsval aValue);
extern void ConvertStrToJSVal(const nsString& aProp,
JSContext* aContext,
jsval* aReturn);
extern PRBool ConvertJSValToBool(PRBool* aProp,
JSContext* aContext,
jsval aValue);
extern PRBool ConvertJSValToObj(nsISupports** aSupports,
REFNSIID aIID,
const nsString& aTypeName,
JSContext* aContext,
jsval aValue);
/***********************************************************************************/
// Native methods for FileSpecObj functions
/*
* Native method fso_ToString
*/
PR_STATIC_CALLBACK(JSBool)
fso_ToString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsInstallFolder *nativeThis = (nsInstallFolder*)JS_GetPrivate(cx, obj);
nsAutoString stringReturned;
*rval = JSVAL_NULL;
// If there's no private data, this must be the prototype, so ignore
if(nsnull == nativeThis)
{
return JS_TRUE;
}
if(NS_OK != nativeThis->ToString(&stringReturned))
return JS_FALSE;
nsJSUtils::nsConvertStringToJSVal(stringReturned, cx, rval);
return JS_TRUE;
}
/*
* Native method fso_AppendString
*/
PR_STATIC_CALLBACK(JSBool)
fso_AppendPath(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
return JS_TRUE;
}
/*
* FileSpecObj destructor
*/
static void PR_CALLBACK FileSpecObjectCleanup(JSContext *cx, JSObject *obj)
{
nsInstallFolder *nativeThis = (nsInstallFolder*)JS_GetPrivate(cx, obj);
if (nativeThis != nsnull)
delete nativeThis;
}
/***********************************************************************/
//
// class for FileObj
//
JSClass FileSpecObjectClass = {
"FileSpecObject",
JSCLASS_HAS_PRIVATE,
JS_PropertyStub,
JS_PropertyStub,
JS_PropertyStub,
JS_PropertyStub,
JS_EnumerateStub,
JS_ResolveStub,
JS_ConvertStub,
FileSpecObjectCleanup
};
//
// FileObj class methods
//
static JSFunctionSpec fileSpecObjMethods[] =
{
{"appendPath", fso_AppendPath, 1},
{"toString", fso_ToString, 0},
{0}
};
PRInt32 InitFileSpecObjectPrototype(JSContext *jscontext,
JSObject *global,
JSObject **fileSpecObjectPrototype)
{
*fileSpecObjectPrototype = JS_InitClass( jscontext, // context
global, // global object
nsnull, // parent proto
&FileSpecObjectClass, // JSClass
nsnull, // JSNative ctor
0, // ctor args
nsnull, // proto props
fileSpecObjMethods,// proto funcs
nsnull, // ctor props (static)
nsnull); // ctor funcs (static)
if (nsnull == *fileSpecObjectPrototype)
{
return NS_ERROR_FAILURE;
}
return NS_OK;
}

View File

@@ -0,0 +1,25 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef __NS_JSFILEOBJ_H__
#define __NS_JSFILEOBJ_H__
PRInt32
InitFileSpecObjectPrototype(JSContext *jscontext, JSObject *global, JSObject **fileSpecObjectPrototype);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,719 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "jsapi.h"
#include "nsJSUtils.h"
#include "nscore.h"
#include "nsIScriptContext.h"
#include "nsIJSScriptObject.h"
#include "nsIScriptObjectOwner.h"
#include "nsIScriptGlobalObject.h"
#include "nsCRT.h"
#include "nsString.h"
#include "nsIDOMInstallVersion.h"
#include "nsIDOMInstallTriggerGlobal.h"
#include "nsXPITriggerInfo.h"
#include "nsRepository.h"
#include "nsSoftwareUpdateIIDs.h"
extern void ConvertJSValToStr(nsString& aString,
JSContext* aContext,
jsval aValue);
extern void ConvertStrToJSVal(const nsString& aProp,
JSContext* aContext,
jsval* aReturn);
extern PRBool ConvertJSValToBool(PRBool* aProp,
JSContext* aContext,
jsval aValue);
extern PRBool ConvertJSValToObj(nsISupports** aSupports,
REFNSIID aIID,
const nsString& aTypeName,
JSContext* aContext,
jsval aValue);
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
static NS_DEFINE_IID(kIJSScriptObjectIID, NS_IJSSCRIPTOBJECT_IID);
static NS_DEFINE_IID(kIScriptGlobalObjectIID, NS_ISCRIPTGLOBALOBJECT_IID);
static NS_DEFINE_IID(kIInstallTriggerGlobalIID, NS_IDOMINSTALLTRIGGERGLOBAL_IID);
//
// InstallTriggerGlobal finalizer
//
PR_STATIC_CALLBACK(void)
FinalizeInstallTriggerGlobal(JSContext *cx, JSObject *obj)
{
nsJSUtils::nsGenericFinalize(cx, obj);
}
static NS_DEFINE_IID(kIDOMInstallTriggerIID, NS_IDOMINSTALLTRIGGERGLOBAL_IID);
static NS_DEFINE_IID(kInstallTrigger_CID, NS_SoftwareUpdateInstallTrigger_CID);
static JSBool CreateNativeObject(JSContext *cx, JSObject *obj, nsIDOMInstallTriggerGlobal **aResult)
{
nsresult result;
nsIScriptObjectOwner *owner = nsnull;
nsIDOMInstallTriggerGlobal *nativeThis;
result = nsRepository::CreateInstance(kInstallTrigger_CID,
nsnull,
kIDOMInstallTriggerIID,
(void **)&nativeThis);
if (NS_OK != result) return JS_FALSE;
result = nativeThis->QueryInterface(kIScriptObjectOwnerIID, (void **)&owner);
if (NS_OK != result)
{
NS_RELEASE(nativeThis);
return JS_FALSE;
}
owner->SetScriptObject((void *)obj);
JS_SetPrivate(cx, obj, nativeThis);
*aResult = nativeThis;
NS_RELEASE(nativeThis); // we only want one refcnt. JSUtils cleans us up.
return JS_TRUE;
}
//
// Native method UpdateEnabled
//
PR_STATIC_CALLBACK(JSBool)
InstallTriggerGlobalUpdateEnabled(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMInstallTriggerGlobal *nativeThis = (nsIDOMInstallTriggerGlobal*)JS_GetPrivate(cx, obj);
PRBool nativeRet;
*rval = JSVAL_NULL;
if (nsnull == nativeThis && (JS_FALSE == CreateNativeObject(cx, obj, &nativeThis)) )
return JS_FALSE;
if (argc >= 0) {
if (NS_OK != nativeThis->UpdateEnabled(&nativeRet)) {
return JS_FALSE;
}
*rval = BOOLEAN_TO_JSVAL(nativeRet);
}
else {
JS_ReportError(cx, "Function UpdateEnabled requires 0 parameters");
return JS_FALSE;
}
return JS_TRUE;
}
//
// Native method Install
//
PR_STATIC_CALLBACK(JSBool)
InstallTriggerGlobalInstall(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMInstallTriggerGlobal *nativeThis = (nsIDOMInstallTriggerGlobal*)JS_GetPrivate(cx, obj);
*rval = JSVAL_FALSE;
if (nsnull == nativeThis && (JS_FALSE == CreateNativeObject(cx, obj, &nativeThis)) )
return JS_FALSE;
// make sure XPInstall is enabled, return false if not
PRBool enabled = PR_FALSE;
nativeThis->UpdateEnabled(&enabled);
if (!enabled)
return JS_TRUE;
// get window.location to construct relative URLs
nsString baseURL;
JSObject* global = JS_GetGlobalObject(cx);
if (global)
{
jsval v;
if (JS_GetProperty(cx,global,"location",&v))
{
ConvertJSValToStr( baseURL, cx, v );
PRInt32 lastslash = baseURL.RFindChar('/');
if (lastslash != kNotFound)
{
baseURL.Truncate(lastslash+1);
}
}
}
// parse associative array of installs
if ( argc >= 1 && JSVAL_IS_OBJECT(argv[0]) )
{
nsXPITriggerInfo *trigger = new nsXPITriggerInfo();
if (!trigger)
return JS_FALSE;
JSIdArray *ida = JS_Enumerate( cx, JSVAL_TO_OBJECT(argv[0]) );
if ( ida )
{
jsval v;
PRUnichar *name, *URL;
for (int i = 0; i < ida->length; i++ )
{
JS_IdToValue( cx, ida->vector[i], &v );
name = JS_GetStringChars( JS_ValueToString( cx, v ) );
JS_GetUCProperty( cx, JSVAL_TO_OBJECT(argv[0]), name, nsCRT::strlen(name), &v );
URL = JS_GetStringChars( JS_ValueToString( cx, v ) );
if ( name && URL )
{
nsXPITriggerItem *item = new nsXPITriggerItem( name, URL );
if ( item )
{
if ( item->IsRelativeURL() )
{
item->mURL.Insert( baseURL, 0 );
}
trigger->Add( item );
}
else
; // XXX signal error somehow
}
else
; // XXX need to signal error
}
JS_DestroyIdArray( cx, ida );
}
// save callback function if any (ignore bad args for now)
if ( argc >= 2 && JS_TypeOfValue(cx,argv[1]) == JSTYPE_FUNCTION )
{
trigger->SaveCallback( cx, argv[1] );
}
// pass on only if good stuff found
if (trigger->Size() > 0)
{
PRBool result;
nativeThis->Install(trigger,&result);
*rval = BOOLEAN_TO_JSVAL(result);
return JS_TRUE;
}
else
delete trigger;
}
JS_ReportError(cx, "Incorrect arguments to InstallTrigger.Install()");
return JS_FALSE;
}
//
// Native method StartSoftwareUpdate
//
PR_STATIC_CALLBACK(JSBool)
InstallTriggerGlobalStartSoftwareUpdate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMInstallTriggerGlobal *nativeThis = (nsIDOMInstallTriggerGlobal*)JS_GetPrivate(cx, obj);
PRBool nativeRet;
nsAutoString b0;
PRInt32 b1 = 0;
*rval = JSVAL_FALSE;
if (nsnull == nativeThis && (JS_FALSE == CreateNativeObject(cx, obj, &nativeThis)) )
return JS_FALSE;
if ( argc >= 1 )
{
ConvertJSValToStr(b0, cx, argv[0]);
if (argc >= 2 && !JS_ValueToInt32(cx, argv[1], (int32 *)&b1))
{
JS_ReportError(cx, "StartSoftwareUpdate() 2nd parameter must be a number");
return JS_FALSE;
}
if(NS_OK != nativeThis->StartSoftwareUpdate(b0, b1, &nativeRet))
{
return JS_FALSE;
}
*rval = BOOLEAN_TO_JSVAL(nativeRet);
}
else
{
JS_ReportError(cx, "Function StartSoftwareUpdate requires 2 parameters");
return JS_FALSE;
}
return JS_TRUE;
}
//
// Native method ConditionalSoftwareUpdate
//
PR_STATIC_CALLBACK(JSBool)
InstallTriggerGlobalConditionalSoftwareUpdate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMInstallTriggerGlobal *nativeThis = (nsIDOMInstallTriggerGlobal*)JS_GetPrivate(cx, obj);
PRInt32 nativeRet;
nsAutoString b0;
nsAutoString b1;
nsAutoString b2str;
PRInt32 b2int;
nsAutoString b3str;
PRInt32 b3int;
PRInt32 b4;
*rval = JSVAL_NULL;
if (nsnull == nativeThis && (JS_FALSE == CreateNativeObject(cx, obj, &nativeThis)) )
return JS_FALSE;
if(argc >= 5)
{
// public int ConditionalSoftwareUpdate(String url,
// String registryName,
// int diffLevel,
// String version, --OR-- VersionInfo version
// int mode);
ConvertJSValToStr(b0, cx, argv[0]);
ConvertJSValToStr(b1, cx, argv[1]);
if(!JS_ValueToInt32(cx, argv[2], (int32 *)&b2int))
{
JS_ReportError(cx, "3rd parameter must be a number");
return JS_FALSE;
}
if(!JS_ValueToInt32(cx, argv[4], (int32 *)&b4))
{
JS_ReportError(cx, "5th parameter must be a number");
return JS_FALSE;
}
if(JSVAL_IS_OBJECT(argv[3]))
{
JSObject* jsobj = JSVAL_TO_OBJECT(argv[3]);
JSClass* jsclass = JS_GetClass(cx, jsobj);
if((nsnull != jsclass) && (jsclass->flags & JSCLASS_HAS_PRIVATE))
{
nsIDOMInstallVersion* version = (nsIDOMInstallVersion*)JS_GetPrivate(cx, jsobj);
if(NS_OK != nativeThis->ConditionalSoftwareUpdate(b0, b1, b2int, version, b4, &nativeRet))
{
return JS_FALSE;
}
}
}
else
{
ConvertJSValToStr(b3str, cx, argv[3]);
if(NS_OK != nativeThis->ConditionalSoftwareUpdate(b0, b1, b2int, b3str, b4, &nativeRet))
{
return JS_FALSE;
}
}
*rval = INT_TO_JSVAL(nativeRet);
}
else if(argc >= 4)
{
// public int ConditionalSoftwareUpdate(String url,
// String registryName,
// String version, --OR-- VersionInfo version
// int mode);
ConvertJSValToStr(b0, cx, argv[0]);
ConvertJSValToStr(b1, cx, argv[1]);
if(!JS_ValueToInt32(cx, argv[3], (int32 *)&b3int))
{
JS_ReportError(cx, "4th parameter must be a number");
return JS_FALSE;
}
if(JSVAL_IS_OBJECT(argv[2]))
{
JSObject* jsobj = JSVAL_TO_OBJECT(argv[2]);
JSClass* jsclass = JS_GetClass(cx, jsobj);
if((nsnull != jsclass) && (jsclass->flags & JSCLASS_HAS_PRIVATE))
{
nsIDOMInstallVersion* version = (nsIDOMInstallVersion*)JS_GetPrivate(cx, jsobj);
if(NS_OK != nativeThis->ConditionalSoftwareUpdate(b0, b1, version, b3int, &nativeRet))
{
return JS_FALSE;
}
}
}
else
{
ConvertJSValToStr(b2str, cx, argv[2]);
if(NS_OK != nativeThis->ConditionalSoftwareUpdate(b0, b1, b2str, b3int, &nativeRet))
{
return JS_FALSE;
}
}
*rval = INT_TO_JSVAL(nativeRet);
}
else if(argc >= 3)
{
// public int ConditionalSoftwareUpdate(String url,
// String registryName,
// String version); --OR-- VersionInfo version
ConvertJSValToStr(b0, cx, argv[0]);
ConvertJSValToStr(b1, cx, argv[1]);
if(JSVAL_IS_OBJECT(argv[2]))
{
JSObject* jsobj = JSVAL_TO_OBJECT(argv[2]);
JSClass* jsclass = JS_GetClass(cx, jsobj);
if((nsnull != jsclass) && (jsclass->flags & JSCLASS_HAS_PRIVATE))
{
nsIDOMInstallVersion* version = (nsIDOMInstallVersion*)JS_GetPrivate(cx, jsobj);
if(NS_OK != nativeThis->ConditionalSoftwareUpdate(b0, b1, version, &nativeRet))
{
return JS_FALSE;
}
}
}
else
{
ConvertJSValToStr(b2str, cx, argv[2]);
if(NS_OK != nativeThis->ConditionalSoftwareUpdate(b0, b1, b2str, &nativeRet))
{
return JS_FALSE;
}
}
*rval = INT_TO_JSVAL(nativeRet);
}
else
{
JS_ReportError(cx, "Function ConditionalSoftwareUpdate requires 5 parameters");
return JS_FALSE;
}
return JS_TRUE;
}
//
// Native method CompareVersion
//
PR_STATIC_CALLBACK(JSBool)
InstallTriggerGlobalCompareVersion(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMInstallTriggerGlobal *nativeThis = (nsIDOMInstallTriggerGlobal*)JS_GetPrivate(cx, obj);
PRInt32 nativeRet;
nsAutoString regname;
nsAutoString version;
int32 major,minor,release,build;
*rval = JSVAL_NULL;
if (nsnull == nativeThis && (JS_FALSE == CreateNativeObject(cx, obj, &nativeThis)) )
return JS_FALSE;
if (argc < 2 )
{
JS_ReportError(cx, "CompareVersion requires at least 2 parameters");
return JS_FALSE;
}
else if ( !JSVAL_IS_STRING(argv[0]) )
{
JS_ReportError(cx, "Invalid parameter passed to CompareVersion");
return JS_FALSE;
}
// get the registry name argument
ConvertJSValToStr(regname, cx, argv[0]);
if (argc == 2 )
{
// public int CompareVersion(String registryName, String version)
// --OR-- CompareVersion(String registryNamve, InstallVersion version)
ConvertJSValToStr(version, cx, argv[1]);
if(NS_OK != nativeThis->CompareVersion(regname, version, &nativeRet))
{
return JS_FALSE;
}
}
else
{
// public int CompareVersion(String registryName,
// int major,
// int minor,
// int release,
// int build);
//
// minor, release, and build values are optional
major = minor = release = build = 0;
if(!JS_ValueToInt32(cx, argv[1], &major))
{
JS_ReportError(cx, "2th parameter must be a number");
return JS_FALSE;
}
if( argc > 2 && !JS_ValueToInt32(cx, argv[2], &minor) )
{
JS_ReportError(cx, "3th parameter must be a number");
return JS_FALSE;
}
if( argc > 3 && !JS_ValueToInt32(cx, argv[3], &release) )
{
JS_ReportError(cx, "4th parameter must be a number");
return JS_FALSE;
}
if( argc > 4 && !JS_ValueToInt32(cx, argv[4], &build) )
{
JS_ReportError(cx, "5th parameter must be a number");
return JS_FALSE;
}
if(NS_OK != nativeThis->CompareVersion(regname, major, minor, release, build, &nativeRet))
{
return JS_FALSE;
}
}
*rval = INT_TO_JSVAL(nativeRet);
return JS_TRUE;
}
//
// Native method GetVersion
//
PR_STATIC_CALLBACK(JSBool)
InstallTriggerGlobalGetVersion(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMInstallTriggerGlobal *nativeThis = (nsIDOMInstallTriggerGlobal*)JS_GetPrivate(cx, obj);
nsAutoString regname;
nsAutoString version;
*rval = JSVAL_NULL;
if (nsnull == nativeThis && (JS_FALSE == CreateNativeObject(cx, obj, &nativeThis)) )
return JS_FALSE;
// get the registry name argument
ConvertJSValToStr(regname, cx, argv[0]);
if(NS_OK != nativeThis->GetVersion(regname, version))
{
return JS_FALSE;
}
if(version.Equals(""))
*rval = JSVAL_NULL;
else
ConvertStrToJSVal(version, cx, rval);
return JS_TRUE;
}
/***********************************************************************/
//
// class for InstallTriggerGlobal
//
JSClass InstallTriggerGlobalClass = {
"InstallTrigger",
JSCLASS_HAS_PRIVATE,
JS_PropertyStub,
JS_PropertyStub,
JS_PropertyStub,
JS_PropertyStub,
JS_EnumerateStub,
JS_ResolveStub,
JS_ConvertStub,
FinalizeInstallTriggerGlobal
};
//
// InstallTriggerGlobal class methods
//
static JSFunctionSpec InstallTriggerGlobalMethods[] =
{
{"UpdateEnabled", InstallTriggerGlobalUpdateEnabled, 0},
{"Install", InstallTriggerGlobalInstall, 2},
{"StartSoftwareUpdate", InstallTriggerGlobalStartSoftwareUpdate, 2},
{"ConditionalSoftwareUpdate", InstallTriggerGlobalConditionalSoftwareUpdate, 5},
{"CompareVersion", InstallTriggerGlobalCompareVersion, 5},
{"GetVersion", InstallTriggerGlobalGetVersion, 2},
// -- new forms to match JS style --
{"updateEnabled", InstallTriggerGlobalUpdateEnabled, 0},
{"install", InstallTriggerGlobalInstall, 2},
{"startSoftwareUpdate", InstallTriggerGlobalStartSoftwareUpdate, 2},
{"conditionalSoftwareUpdate", InstallTriggerGlobalConditionalSoftwareUpdate, 5},
{"compareVersion", InstallTriggerGlobalCompareVersion, 5},
{"getVersion", InstallTriggerGlobalGetVersion, 2},
{0}
};
static JSConstDoubleSpec diff_constants[] =
{
{ nsIDOMInstallTriggerGlobal::MAJOR_DIFF, "MAJOR_DIFF" },
{ nsIDOMInstallTriggerGlobal::MINOR_DIFF, "MINOR_DIFF" },
{ nsIDOMInstallTriggerGlobal::REL_DIFF, "REL_DIFF" },
{ nsIDOMInstallTriggerGlobal::BLD_DIFF, "BLD_DIFF" },
{ nsIDOMInstallTriggerGlobal::EQUAL, "EQUAL" },
{0}
};
nsresult InitInstallTriggerGlobalClass(JSContext *jscontext, JSObject *global, void** prototype)
{
JSObject *proto = nsnull;
if (prototype != nsnull)
*prototype = nsnull;
proto = JS_InitClass(jscontext, // context
global, // global object
nsnull, // parent proto
&InstallTriggerGlobalClass, // JSClass
nsnull, // JSNative ctor
nsnull, // ctor args
nsnull, // proto props
nsnull, // proto funcs
nsnull, // ctor props (static)
InstallTriggerGlobalMethods); // ctor funcs (static)
if (nsnull == proto) return NS_ERROR_FAILURE;
if ( PR_FALSE == JS_DefineConstDoubles(jscontext, proto, diff_constants) )
return NS_ERROR_FAILURE;
if (prototype != nsnull)
*prototype = proto;
return NS_OK;
}
//
// InstallTriggerGlobal class initialization
//
nsresult NS_InitInstallTriggerGlobalClass(nsIScriptContext *aContext, void **aPrototype)
{
JSContext *jscontext = (JSContext *)aContext->GetNativeContext();
JSObject *proto = nsnull;
JSObject *constructor = nsnull;
JSObject *global = JS_GetGlobalObject(jscontext);
jsval vp;
if ((PR_TRUE != JS_LookupProperty(jscontext, global, "InstallTriggerGlobal", &vp)) ||
!JSVAL_IS_OBJECT(vp) ||
((constructor = JSVAL_TO_OBJECT(vp)) == nsnull) ||
(PR_TRUE != JS_LookupProperty(jscontext, JSVAL_TO_OBJECT(vp), "prototype", &vp)) ||
!JSVAL_IS_OBJECT(vp))
{
nsresult rv = InitInstallTriggerGlobalClass(jscontext, global, (void**)&proto);
if (NS_FAILED(rv)) return rv;
}
else if ((nsnull != constructor) && JSVAL_IS_OBJECT(vp))
{
proto = JSVAL_TO_OBJECT(vp);
}
else
{
return NS_ERROR_FAILURE;
}
if (aPrototype)
*aPrototype = proto;
return NS_OK;
}
//
// Method for creating a new InstallTriggerGlobal JavaScript object
//
extern "C" NS_DOM nsresult NS_NewScriptInstallTriggerGlobal(nsIScriptContext *aContext, nsISupports *aSupports, nsISupports *aParent, void **aReturn)
{
NS_PRECONDITION(nsnull != aContext && nsnull != aSupports && nsnull != aReturn, "null argument to NS_NewScriptInstallTriggerGlobal");
JSObject *proto;
JSObject *parent;
nsIScriptObjectOwner *owner;
JSContext *jscontext = (JSContext *)aContext->GetNativeContext();
nsresult result = NS_OK;
nsIDOMInstallTriggerGlobal *aInstallTriggerGlobal;
if (nsnull == aParent) {
parent = nsnull;
}
else if (NS_OK == aParent->QueryInterface(kIScriptObjectOwnerIID, (void**)&owner)) {
if (NS_OK != owner->GetScriptObject(aContext, (void **)&parent)) {
NS_RELEASE(owner);
return NS_ERROR_FAILURE;
}
NS_RELEASE(owner);
}
else {
return NS_ERROR_FAILURE;
}
if (NS_OK != NS_InitInstallTriggerGlobalClass(aContext, (void **)&proto)) {
return NS_ERROR_FAILURE;
}
result = aSupports->QueryInterface(kIInstallTriggerGlobalIID, (void **)&aInstallTriggerGlobal);
if (NS_OK != result) {
return result;
}
// create a js object for this class
*aReturn = JS_NewObject(jscontext, &InstallTriggerGlobalClass, proto, parent);
if (nsnull != *aReturn) {
// connect the native object to the js object
JS_SetPrivate(jscontext, (JSObject *)*aReturn, aInstallTriggerGlobal);
}
else {
NS_RELEASE(aInstallTriggerGlobal);
return NS_ERROR_FAILURE;
}
return NS_OK;
}

View File

@@ -0,0 +1,651 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/* AUTO-GENERATED. DO NOT EDIT!!! */
#include "jsapi.h"
#include "nsJSUtils.h"
#include "nscore.h"
#include "nsIScriptContext.h"
#include "nsIJSScriptObject.h"
#include "nsIScriptObjectOwner.h"
#include "nsIScriptGlobalObject.h"
#include "nsString.h"
#include "nsIDOMInstallVersion.h"
#include "nsIScriptNameSpaceManager.h"
#include "nsRepository.h"
#include "nsDOMCID.h"
#include "nsSoftwareUpdateIIDs.h"
extern void ConvertJSValToStr(nsString& aString,
JSContext* aContext,
jsval aValue);
extern void ConvertStrToJSVal(const nsString& aProp,
JSContext* aContext,
jsval* aReturn);
extern PRBool ConvertJSValToBool(PRBool* aProp,
JSContext* aContext,
jsval aValue);
extern PRBool ConvertJSValToObj(nsISupports** aSupports,
REFNSIID aIID,
const nsString& aTypeName,
JSContext* aContext,
jsval aValue);
void ConvertJSvalToVersionString(nsString& versionString, JSContext* cx, jsval* argument);
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
static NS_DEFINE_IID(kIJSScriptObjectIID, NS_IJSSCRIPTOBJECT_IID);
static NS_DEFINE_IID(kIScriptGlobalObjectIID, NS_ISCRIPTGLOBALOBJECT_IID);
static NS_DEFINE_IID(kIInstallVersionIID, NS_IDOMINSTALLVERSION_IID);
//
// InstallVersion property ids
//
enum InstallVersion_slots {
INSTALLVERSION_MAJOR = -1,
INSTALLVERSION_MINOR = -2,
INSTALLVERSION_RELEASE = -3,
INSTALLVERSION_BUILD = -4
};
/***********************************************************************/
//
// InstallVersion Properties Getter
//
PR_STATIC_CALLBACK(JSBool)
GetInstallVersionProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
nsIDOMInstallVersion *a = (nsIDOMInstallVersion*)JS_GetPrivate(cx, obj);
// If there's no private data, this must be the prototype, so ignore
if (nsnull == a) {
return JS_TRUE;
}
if (JSVAL_IS_INT(id)) {
switch(JSVAL_TO_INT(id)) {
case INSTALLVERSION_MAJOR:
{
PRInt32 prop;
if (NS_OK == a->GetMajor(&prop)) {
*vp = INT_TO_JSVAL(prop);
}
else {
return JS_FALSE;
}
break;
}
case INSTALLVERSION_MINOR:
{
PRInt32 prop;
if (NS_OK == a->GetMinor(&prop)) {
*vp = INT_TO_JSVAL(prop);
}
else {
return JS_FALSE;
}
break;
}
case INSTALLVERSION_RELEASE:
{
PRInt32 prop;
if (NS_OK == a->GetRelease(&prop)) {
*vp = INT_TO_JSVAL(prop);
}
else {
return JS_FALSE;
}
break;
}
case INSTALLVERSION_BUILD:
{
PRInt32 prop;
if (NS_OK == a->GetBuild(&prop)) {
*vp = INT_TO_JSVAL(prop);
}
else {
return JS_FALSE;
}
break;
}
default:
return nsJSUtils::nsCallJSScriptObjectGetProperty(a, cx, obj, id, vp);
}
}
else {
return nsJSUtils::nsCallJSScriptObjectGetProperty(a, cx, obj, id, vp);
}
return PR_TRUE;
}
/***********************************************************************/
//
// InstallVersion Properties Setter
//
PR_STATIC_CALLBACK(JSBool)
SetInstallVersionProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
nsIDOMInstallVersion *a = (nsIDOMInstallVersion*)JS_GetPrivate(cx, obj);
// If there's no private data, this must be the prototype, so ignore
if (nsnull == a) {
return JS_TRUE;
}
if (JSVAL_IS_INT(id)) {
switch(JSVAL_TO_INT(id)) {
case INSTALLVERSION_MAJOR:
{
PRInt32 prop;
int32 temp;
if (JSVAL_IS_NUMBER(*vp) && JS_ValueToInt32(cx, *vp, &temp)) {
prop = (PRInt32)temp;
}
else {
JS_ReportError(cx, "Parameter must be a number");
return JS_FALSE;
}
a->SetMajor(prop);
break;
}
case INSTALLVERSION_MINOR:
{
PRInt32 prop;
int32 temp;
if (JSVAL_IS_NUMBER(*vp) && JS_ValueToInt32(cx, *vp, &temp)) {
prop = (PRInt32)temp;
}
else {
JS_ReportError(cx, "Parameter must be a number");
return JS_FALSE;
}
a->SetMinor(prop);
break;
}
case INSTALLVERSION_RELEASE:
{
PRInt32 prop;
int32 temp;
if (JSVAL_IS_NUMBER(*vp) && JS_ValueToInt32(cx, *vp, &temp)) {
prop = (PRInt32)temp;
}
else {
JS_ReportError(cx, "Parameter must be a number");
return JS_FALSE;
}
a->SetRelease(prop);
break;
}
case INSTALLVERSION_BUILD:
{
PRInt32 prop;
int32 temp;
if (JSVAL_IS_NUMBER(*vp) && JS_ValueToInt32(cx, *vp, &temp)) {
prop = (PRInt32)temp;
}
else {
JS_ReportError(cx, "Parameter must be a number");
return JS_FALSE;
}
a->SetBuild(prop);
break;
}
default:
return nsJSUtils::nsCallJSScriptObjectSetProperty(a, cx, obj, id, vp);
}
}
else {
return nsJSUtils::nsCallJSScriptObjectSetProperty(a, cx, obj, id, vp);
}
return PR_TRUE;
}
//
// InstallVersion finalizer
//
PR_STATIC_CALLBACK(void)
FinalizeInstallVersion(JSContext *cx, JSObject *obj)
{
nsJSUtils::nsGenericFinalize(cx, obj);
}
//
// InstallVersion enumerate
//
PR_STATIC_CALLBACK(JSBool)
EnumerateInstallVersion(JSContext *cx, JSObject *obj)
{
return nsJSUtils::nsGenericEnumerate(cx, obj);
}
//
// InstallVersion resolve
//
PR_STATIC_CALLBACK(JSBool)
ResolveInstallVersion(JSContext *cx, JSObject *obj, jsval id)
{
return nsJSUtils::nsGenericResolve(cx, obj, id);
}
//
// Native method Init
//
PR_STATIC_CALLBACK(JSBool)
InstallVersionInit(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMInstallVersion *nativeThis = (nsIDOMInstallVersion*)JS_GetPrivate(cx, obj);
nsAutoString b0;
*rval = JSVAL_NULL;
// If there's no private data, this must be the prototype, so ignore
if (nsnull == nativeThis) {
return JS_TRUE;
}
if (argc == 1)
{
nsJSUtils::nsConvertJSValToString(b0, cx, argv[0]);
}
else
{
b0 = "0.0.0.0";
}
if (NS_OK != nativeThis->Init(b0))
return JS_FALSE;
*rval = JSVAL_VOID;
return JS_TRUE;
}
//
// Native method ToString
//
PR_STATIC_CALLBACK(JSBool)
InstallVersionToString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMInstallVersion *nativeThis = (nsIDOMInstallVersion*)JS_GetPrivate(cx, obj);
nsAutoString nativeRet;
*rval = JSVAL_NULL;
// If there's no private data, this must be the prototype, so ignore
if (nsnull == nativeThis) {
return JS_TRUE;
}
if (argc >= 0) {
if (NS_OK != nativeThis->ToString(nativeRet)) {
return JS_FALSE;
}
nsJSUtils::nsConvertStringToJSVal(nativeRet, cx, rval);
}
else {
JS_ReportError(cx, "Function toString requires 0 parameters");
return JS_FALSE;
}
return JS_TRUE;
}
//
// Native method CompareTo
//
PR_STATIC_CALLBACK(JSBool)
InstallVersionCompareTo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMInstallVersion *nativeThis = (nsIDOMInstallVersion*)JS_GetPrivate(cx, obj);
PRInt32 nativeRet;
nsString b0str;
PRInt32 b0int;
PRInt32 b1int;
PRInt32 b2int;
PRInt32 b3int;
*rval = JSVAL_NULL;
// If there's no private data, this must be the prototype, so ignore
if (nsnull == nativeThis) {
return JS_TRUE;
}
if(argc >= 4)
{
// public int CompareTo(int major,
// int minor,
// int release,
// int build);
if(!JSVAL_IS_INT(argv[0]))
{
JS_ReportError(cx, "1st parameter must be a number");
return JS_FALSE;
}
else if(!JSVAL_IS_INT(argv[1]))
{
JS_ReportError(cx, "2nd parameter must be a number");
return JS_FALSE;
}
else if(!JSVAL_IS_INT(argv[2]))
{
JS_ReportError(cx, "3rd parameter must be a number");
return JS_FALSE;
}
else if(!JSVAL_IS_INT(argv[3]))
{
JS_ReportError(cx, "4th parameter must be a number");
return JS_FALSE;
}
b0int = JSVAL_TO_INT(argv[0]);
b1int = JSVAL_TO_INT(argv[1]);
b2int = JSVAL_TO_INT(argv[2]);
b3int = JSVAL_TO_INT(argv[3]);
if(NS_OK != nativeThis->CompareTo(b0int, b1int, b2int, b3int, &nativeRet))
{
return JS_FALSE;
}
*rval = INT_TO_JSVAL(nativeRet);
}
else if(argc >= 1)
{
// public int AddDirectory(String version); --OR-- VersionInfo version
if(JSVAL_IS_OBJECT(argv[0]))
{
nsCOMPtr<nsIDOMInstallVersion> versionObj;
if(JS_FALSE == ConvertJSValToObj(getter_AddRefs(versionObj),
kIInstallVersionIID,
"InstallVersion",
cx,
argv[0]))
{
return JS_FALSE;
}
if(NS_OK != nativeThis->CompareTo(versionObj, &nativeRet))
{
return JS_FALSE;
}
}
else
{
ConvertJSValToStr(b0str, cx, argv[0]);
if(NS_OK != nativeThis->CompareTo(b0str, &nativeRet))
{
return JS_FALSE;
}
}
*rval = INT_TO_JSVAL(nativeRet);
}
else
{
JS_ReportError(cx, "Function compareTo requires 4 parameters");
return JS_FALSE;
}
return JS_TRUE;
}
/***********************************************************************/
//
// class for InstallVersion
//
JSClass InstallVersionClass = {
"InstallVersion",
JSCLASS_HAS_PRIVATE,
JS_PropertyStub,
JS_PropertyStub,
GetInstallVersionProperty,
SetInstallVersionProperty,
EnumerateInstallVersion,
ResolveInstallVersion,
JS_ConvertStub,
FinalizeInstallVersion
};
//
// InstallVersion class properties
//
static JSPropertySpec InstallVersionProperties[] =
{
{"major", INSTALLVERSION_MAJOR, JSPROP_ENUMERATE},
{"minor", INSTALLVERSION_MINOR, JSPROP_ENUMERATE},
{"release", INSTALLVERSION_RELEASE, JSPROP_ENUMERATE},
{"build", INSTALLVERSION_BUILD, JSPROP_ENUMERATE},
{0}
};
//
// InstallVersion class methods
//
static JSFunctionSpec InstallVersionMethods[] =
{
{"init", InstallVersionInit, 1},
{"toString", InstallVersionToString, 0},
{"compareTo", InstallVersionCompareTo, 1},
{0}
};
static JSConstDoubleSpec version_constants[] =
{
{ nsIDOMInstallVersion::EQUAL, "EQUAL" },
{ nsIDOMInstallVersion::BLD_DIFF, "BLD_DIFF" },
{ nsIDOMInstallVersion::BLD_DIFF_MINUS, "BLD_DIFF_MINUS" },
{ nsIDOMInstallVersion::REL_DIFF, "REL_DIFF" },
{ nsIDOMInstallVersion::REL_DIFF_MINUS, "REL_DIFF_MINUS" },
{ nsIDOMInstallVersion::MINOR_DIFF, "MINOR_DIFF" },
{ nsIDOMInstallVersion::MINOR_DIFF_MINUS, "MINOR_DIFF_MINUS" },
{ nsIDOMInstallVersion::MAJOR_DIFF, "MAJOR_DIFF" },
{ nsIDOMInstallVersion::MAJOR_DIFF_MINUS, "MAJOR_DIFF_MINUS" },
{0}
};
//
// InstallVersion constructor
//
PR_STATIC_CALLBACK(JSBool)
InstallVersion(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsresult result;
nsIDOMInstallVersion *nativeThis;
nsIScriptObjectOwner *owner = nsnull;
static NS_DEFINE_IID(kIDOMInstallVersionIID, NS_IDOMINSTALLVERSION_IID);
static NS_DEFINE_IID(kInstallVersion_CID, NS_SoftwareUpdateInstallVersion_CID);
result = nsRepository::CreateInstance(kInstallVersion_CID,
nsnull,
kIDOMInstallVersionIID,
(void **)&nativeThis);
if (NS_OK != result) return JS_FALSE;
result = nativeThis->QueryInterface(kIScriptObjectOwnerIID, (void **)&owner);
if (NS_OK != result) {
NS_RELEASE(nativeThis);
return JS_FALSE;
}
owner->SetScriptObject((void *)obj);
JS_SetPrivate(cx, obj, nativeThis);
NS_RELEASE(owner);
jsval ignore;
InstallVersionInit(cx, obj, argc, argv, &ignore);
return JS_TRUE;
}
nsresult InitInstallVersionClass(JSContext *jscontext, JSObject *global, void** prototype)
{
JSObject *proto = nsnull;
if (prototype != nsnull)
*prototype = nsnull;
proto = JS_InitClass(jscontext, // context
global, // global object
nsnull, // parent proto
&InstallVersionClass, // JSClass
InstallVersion, // JSNative ctor
0, // ctor args
InstallVersionProperties, // proto props
InstallVersionMethods, // proto funcs
nsnull, // ctor props (static)
nsnull); // ctor funcs (static)
if (nsnull == proto)
return NS_ERROR_FAILURE;
if ( PR_FALSE == JS_DefineConstDoubles(jscontext, proto, version_constants) )
return NS_ERROR_FAILURE;
if (prototype != nsnull)
*prototype = proto;
return NS_OK;
}
//
// InstallVersion class initialization
//
nsresult NS_InitInstallVersionClass(nsIScriptContext *aContext, void **aPrototype)
{
JSContext *jscontext = (JSContext *)aContext->GetNativeContext();
JSObject *proto = nsnull;
JSObject *constructor = nsnull;
JSObject *global = JS_GetGlobalObject(jscontext);
jsval vp;
if ((PR_TRUE != JS_LookupProperty(jscontext, global, "InstallVersion", &vp)) ||
!JSVAL_IS_OBJECT(vp) ||
((constructor = JSVAL_TO_OBJECT(vp)) == nsnull) ||
(PR_TRUE != JS_LookupProperty(jscontext, JSVAL_TO_OBJECT(vp), "prototype", &vp)) ||
!JSVAL_IS_OBJECT(vp))
{
nsresult rv = InitInstallVersionClass(jscontext, global, (void**)&proto);
if (NS_FAILED(rv)) return rv;
}
else if ((nsnull != constructor) && JSVAL_IS_OBJECT(vp))
{
proto = JSVAL_TO_OBJECT(vp);
}
else
{
return NS_ERROR_FAILURE;
}
if (aPrototype)
*aPrototype = proto;
return NS_OK;
}
//
// Method for creating a new InstallVersion JavaScript object
//
extern "C" NS_DOM nsresult NS_NewScriptInstallVersion(nsIScriptContext *aContext, nsISupports *aSupports, nsISupports *aParent, void **aReturn)
{
NS_PRECONDITION(nsnull != aContext && nsnull != aSupports && nsnull != aReturn, "null argument to NS_NewScriptInstallVersion");
JSObject *proto;
JSObject *parent;
nsIScriptObjectOwner *owner;
JSContext *jscontext = (JSContext *)aContext->GetNativeContext();
nsresult result = NS_OK;
nsIDOMInstallVersion *aInstallVersion;
if (nsnull == aParent) {
parent = nsnull;
}
else if (NS_OK == aParent->QueryInterface(kIScriptObjectOwnerIID, (void**)&owner)) {
if (NS_OK != owner->GetScriptObject(aContext, (void **)&parent)) {
NS_RELEASE(owner);
return NS_ERROR_FAILURE;
}
NS_RELEASE(owner);
}
else {
return NS_ERROR_FAILURE;
}
if (NS_OK != NS_InitInstallVersionClass(aContext, (void **)&proto)) {
return NS_ERROR_FAILURE;
}
result = aSupports->QueryInterface(kIInstallVersionIID, (void **)&aInstallVersion);
if (NS_OK != result) {
return result;
}
// create a js object for this class
*aReturn = JS_NewObject(jscontext, &InstallVersionClass, proto, parent);
if (nsnull != *aReturn) {
// connect the native object to the js object
JS_SetPrivate(jscontext, (JSObject *)*aReturn, aInstallVersion);
}
else {
NS_RELEASE(aInstallVersion);
return NS_ERROR_FAILURE;
}
return NS_OK;
}

View File

@@ -0,0 +1,211 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "jsapi.h"
#include "nscore.h"
#include "nsIScriptContext.h"
#include "nsString.h"
#include "nsInstall.h"
#include "nsWinProfile.h"
#include "nsJSWinProfile.h"
extern void ConvertJSValToStr(nsString& aString,
JSContext* aContext,
jsval aValue);
extern void ConvertStrToJSVal(const nsString& aProp,
JSContext* aContext,
jsval* aReturn);
extern PRBool ConvertJSValToBool(PRBool* aProp,
JSContext* aContext,
jsval aValue);
extern PRBool ConvertJSValToObj(nsISupports** aSupports,
REFNSIID aIID,
const nsString& aTypeName,
JSContext* aContext,
jsval aValue);
static void PR_CALLBACK WinProfileCleanup(JSContext *cx, JSObject *obj)
{
nsWinProfile *nativeThis = (nsWinProfile*)JS_GetPrivate(cx, obj);
delete nativeThis;
}
/***********************************************************************************/
// Native mothods for WinProfile functions
//
// Native method GetString
//
PR_STATIC_CALLBACK(JSBool)
WinProfileGetString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsWinProfile *nativeThis = (nsWinProfile*)JS_GetPrivate(cx, obj);
nsString nativeRet;
nsAutoString b0;
nsAutoString b1;
*rval = JSVAL_NULL;
// If there's no private data, this must be the prototype, so ignore
if(nsnull == nativeThis)
{
return JS_TRUE;
}
if(argc >= 2)
{
// public int getString ( String section,
// String key);
ConvertJSValToStr(b0, cx, argv[0]);
ConvertJSValToStr(b1, cx, argv[1]);
nativeThis->GetString(b0, b1, &nativeRet);
ConvertStrToJSVal(nativeRet, cx, rval);
}
else
{
JS_ReportError(cx, "WinProfile.getString() parameters error");
return JS_FALSE;
}
return JS_TRUE;
}
//
// Native method WriteString
//
PR_STATIC_CALLBACK(JSBool)
WinProfileWriteString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsWinProfile *nativeThis = (nsWinProfile*)JS_GetPrivate(cx, obj);
PRInt32 nativeRet;
nsAutoString b0;
nsAutoString b1;
nsAutoString b2;
*rval = JSVAL_NULL;
// If there's no private data, this must be the prototype, so ignore
if(nsnull == nativeThis)
{
return JS_TRUE;
}
if(argc >= 3)
{
// public int writeString ( String section,
// String key,
// String value);
ConvertJSValToStr(b0, cx, argv[0]);
ConvertJSValToStr(b1, cx, argv[1]);
ConvertJSValToStr(b2, cx, argv[2]);
if(NS_OK != nativeThis->WriteString(b0, b1, b2, &nativeRet))
{
return JS_FALSE;
}
*rval = INT_TO_JSVAL(nativeRet);
}
else
{
JS_ReportError(cx, "WinProfile.writeString() parameters error");
return JS_FALSE;
}
return JS_TRUE;
}
//
// WinProfile constructor
//
PR_STATIC_CALLBACK(JSBool)
WinProfile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
return JS_FALSE;
}
/***********************************************************************/
//
// class for WinProfile
//
JSClass WinProfileClass = {
"WinProfile",
JSCLASS_HAS_PRIVATE,
JS_PropertyStub,
JS_PropertyStub,
JS_PropertyStub,
JS_PropertyStub,
JS_EnumerateStub,
JS_ResolveStub,
JS_ConvertStub,
WinProfileCleanup
};
static JSConstDoubleSpec winprofile_constants[] =
{
{0}
};
//
// WinProfile class methods
//
static JSFunctionSpec WinProfileMethods[] =
{
{"getString", WinProfileGetString, 2},
{"writeString", WinProfileWriteString, 3},
{0}
};
PRInt32
InitWinProfilePrototype(JSContext *jscontext, JSObject *global, JSObject **winProfilePrototype)
{
*winProfilePrototype = JS_InitClass( jscontext, // context
global, // global object
nsnull, // parent proto
&WinProfileClass, // JSClass
nsnull, // JSNative ctor
0, // ctor args
nsnull, // proto props
nsnull, // proto funcs
nsnull, // ctor props (static)
WinProfileMethods); // ctor funcs (static)
if(nsnull == *winProfilePrototype)
{
return NS_ERROR_FAILURE;
}
if(PR_FALSE == JS_DefineConstDoubles(jscontext, *winProfilePrototype, winprofile_constants))
return NS_ERROR_FAILURE;
return NS_OK;
}

View File

@@ -0,0 +1,29 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef __NS_JSWINPROTOTYPE_H__
#define __NS_JSWINPROTOTYPE_H__
PRInt32
InitWinProfilePrototype(JSContext *jscontext, JSObject *global, JSObject **winRegPrototype);
#endif

View File

@@ -0,0 +1,593 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "jsapi.h"
#include "nscore.h"
#include "nsIScriptContext.h"
#include "nsString.h"
#include "nsInstall.h"
#include "nsWinReg.h"
#include "nsJSWinReg.h"
static void PR_CALLBACK WinRegCleanup(JSContext *cx, JSObject *obj);
extern void ConvertJSValToStr(nsString& aString,
JSContext* aContext,
jsval aValue);
extern void ConvertStrToJSVal(const nsString& aProp,
JSContext* aContext,
jsval* aReturn);
extern PRBool ConvertJSValToBool(PRBool* aProp,
JSContext* aContext,
jsval aValue);
extern PRBool ConvertJSValToObj(nsISupports** aSupports,
REFNSIID aIID,
const nsString& aTypeName,
JSContext* aContext,
jsval aValue);
static void PR_CALLBACK WinRegCleanup(JSContext *cx, JSObject *obj)
{
nsWinReg *nativeThis = (nsWinReg*)JS_GetPrivate(cx, obj);
delete nativeThis;
}
/***********************************************************************************/
// Native mothods for WinReg functions
//
// Native method SetRootKey
//
PR_STATIC_CALLBACK(JSBool)
WinRegSetRootKey(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsWinReg *nativeThis = (nsWinReg*)JS_GetPrivate(cx, obj);
JSBool rBool = JS_FALSE;
PRInt32 b0;
*rval = JSVAL_NULL;
// If there's no private data, this must be the prototype, so ignore
if(nsnull == nativeThis)
{
return JS_TRUE;
}
if(argc >= 1)
{
// public int setRootKey(PRInt32 key);
if(!JS_ValueToInt32(cx, argv[0], (int32 *)&b0))
{
JS_ReportError(cx, "Parameter must be a number");
return JS_FALSE;
}
if(NS_OK != nativeThis->SetRootKey(b0))
{
return JS_FALSE;
}
*rval = JSVAL_VOID;
}
else
{
JS_ReportError(cx, "Function SetRootKey requires 1 parameters");
return JS_FALSE;
}
return JS_TRUE;
}
//
// Native method CreateKey
//
PR_STATIC_CALLBACK(JSBool)
WinRegCreateKey(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsWinReg *nativeThis = (nsWinReg*)JS_GetPrivate(cx, obj);
PRInt32 nativeRet;
nsAutoString b0;
nsAutoString b1;
*rval = JSVAL_NULL;
// If there's no private data, this must be the prototype, so ignore
if(nsnull == nativeThis)
{
return JS_TRUE;
}
if(argc >= 2)
{
// public int createKey ( String subKey,
// String className);
ConvertJSValToStr(b0, cx, argv[0]);
ConvertJSValToStr(b1, cx, argv[1]);
if(NS_OK != nativeThis->CreateKey(b0, b1, &nativeRet))
{
return JS_FALSE;
}
*rval = INT_TO_JSVAL(nativeRet);
}
else
{
JS_ReportError(cx, "WinReg.CreateKey() parameters error");
return JS_FALSE;
}
return JS_TRUE;
}
//
// Native method DeleteKey
//
PR_STATIC_CALLBACK(JSBool)
WinRegDeleteKey(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsWinReg *nativeThis = (nsWinReg*)JS_GetPrivate(cx, obj);
PRInt32 nativeRet;
nsAutoString b0;
*rval = JSVAL_NULL;
// If there's no private data, this must be the prototype, so ignore
if(nsnull == nativeThis)
{
return JS_TRUE;
}
if(argc >= 1)
{
// public int deleteKey ( String subKey);
ConvertJSValToStr(b0, cx, argv[0]);
if(NS_OK != nativeThis->DeleteKey(b0, &nativeRet))
{
return JS_FALSE;
}
*rval = INT_TO_JSVAL(nativeRet);
}
else
{
JS_ReportError(cx, "WinReg.DeleteKey() parameters error");
return JS_FALSE;
}
return JS_TRUE;
}
//
// Native method DeleteValue
//
PR_STATIC_CALLBACK(JSBool)
WinRegDeleteValue(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsWinReg *nativeThis = (nsWinReg*)JS_GetPrivate(cx, obj);
PRInt32 nativeRet;
nsString b0;
nsString b1;
*rval = JSVAL_NULL;
// If there's no private data, this must be the prototype, so ignore
if(nsnull == nativeThis)
{
return JS_TRUE;
}
if(argc >= 2)
{
// public int deleteValue ( String subKey,
// String valueName);
ConvertJSValToStr(b0, cx, argv[0]);
ConvertJSValToStr(b1, cx, argv[1]);
if(NS_OK != nativeThis->DeleteValue(b0, b1, &nativeRet))
{
return JS_FALSE;
}
*rval = INT_TO_JSVAL(nativeRet);
}
else
{
JS_ReportError(cx, "WinReg.DeleteValue() parameters error");
return JS_FALSE;
}
return JS_TRUE;
}
//
// Native method SetValueString
//
PR_STATIC_CALLBACK(JSBool)
WinRegSetValueString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsWinReg *nativeThis = (nsWinReg*)JS_GetPrivate(cx, obj);
PRInt32 nativeRet;
nsAutoString b0;
nsAutoString b1;
nsAutoString b2;
*rval = JSVAL_NULL;
// If there's no private data, this must be the prototype, so ignore
if(nsnull == nativeThis)
{
return JS_TRUE;
}
if(argc >= 3)
{
// public int setValueString ( String subKey,
// String valueName,
// String value);
ConvertJSValToStr(b0, cx, argv[0]);
ConvertJSValToStr(b1, cx, argv[1]);
ConvertJSValToStr(b2, cx, argv[2]);
if(NS_OK != nativeThis->SetValueString(b0, b1, b2, &nativeRet))
{
return JS_FALSE;
}
*rval = INT_TO_JSVAL(nativeRet);
}
else
{
JS_ReportError(cx, "WinReg.SetValueString() parameters error");
return JS_FALSE;
}
return JS_TRUE;
}
//
// Native method GetValueString
//
PR_STATIC_CALLBACK(JSBool)
WinRegGetValueString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsWinReg* nativeThis = (nsWinReg*)JS_GetPrivate(cx, obj);
nsString nativeRet;
nsAutoString b0;
nsAutoString b1;
*rval = JSVAL_NULL;
// If there's no private data, this must be the prototype, so ignore
if(nsnull == nativeThis)
{
return JS_TRUE;
}
if(argc >= 2)
{
// public int getValueString ( String subKey,
// String valueName);
ConvertJSValToStr(b0, cx, argv[0]);
ConvertJSValToStr(b1, cx, argv[1]);
if(NS_OK != nativeThis->GetValueString(b0, b1, &nativeRet))
{
return JS_FALSE;
}
ConvertStrToJSVal(nativeRet, cx, rval);
}
else
{
JS_ReportError(cx, "WinReg.GetValueString() parameters error");
return JS_FALSE;
}
return JS_TRUE;
}
//
// Native method SetValueNumber
//
PR_STATIC_CALLBACK(JSBool)
WinRegSetValueNumber(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsWinReg *nativeThis = (nsWinReg*)JS_GetPrivate(cx, obj);
PRInt32 nativeRet;
nsAutoString b0;
nsAutoString b1;
// nsAutoString b2;
PRInt32 ib2;
*rval = JSVAL_NULL;
// If there's no private data, this must be the prototype, so ignore
if(nsnull == nativeThis)
{
return JS_TRUE;
}
if(argc >= 3)
{
// public int setValueNumber ( String subKey,
// String valueName,
// Number value);
ConvertJSValToStr(b0, cx, argv[0]);
ConvertJSValToStr(b1, cx, argv[1]);
if(JSVAL_IS_INT(argv[2]))
{
ib2 = JSVAL_TO_INT(argv[2]);
// ConvertJSValToStr(b2, cx, argv[2]);
}
else
{
JS_ReportError(cx, "Parameter 3 must be a number");
return JS_FALSE;
}
if(NS_OK != nativeThis->SetValueNumber(b0, b1, ib2, &nativeRet))
{
return JS_FALSE;
}
*rval = INT_TO_JSVAL(nativeRet);
}
else
{
JS_ReportError(cx, "WinReg.SetValueNumber() parameters error");
return JS_FALSE;
}
return JS_TRUE;
}
//
// Native method GetValueNumber
//
PR_STATIC_CALLBACK(JSBool)
WinRegGetValueNumber(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsWinReg* nativeThis = (nsWinReg*)JS_GetPrivate(cx, obj);
PRInt32 nativeRet;
nsAutoString b0;
nsAutoString b1;
*rval = JSVAL_NULL;
// If there's no private data, this must be the prototype, so ignore
if(nsnull == nativeThis)
{
return JS_TRUE;
}
if(argc >= 2)
{
// public int getValueNumber ( String subKey,
// Number valueName);
ConvertJSValToStr(b0, cx, argv[0]);
ConvertJSValToStr(b1, cx, argv[1]);
if(NS_OK != nativeThis->GetValueNumber(b0, b1, &nativeRet))
{
return JS_FALSE;
}
*rval = INT_TO_JSVAL(nativeRet);
}
else
{
JS_ReportError(cx, "WinReg.GetValueNumber() parameters error");
return JS_FALSE;
}
return JS_TRUE;
}
//
// Native method SetValue
//
PR_STATIC_CALLBACK(JSBool)
WinRegSetValue(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsWinReg *nativeThis = (nsWinReg*)JS_GetPrivate(cx, obj);
// PRInt32 nativeRet;
nsAutoString b0;
nsAutoString b1;
// nsWinRegItem *b2;
*rval = JSVAL_NULL;
// If there's no private data, this must be the prototype, so ignore
if(nsnull == nativeThis)
{
return JS_TRUE;
}
if(argc >= 3)
{
// public int setValue ( String subKey,
// String valueName,
// nsWinRegItem *value);
ConvertJSValToStr(b0, cx, argv[0]);
ConvertJSValToStr(b1, cx, argv[1]);
// fix: this parameter is an object, not a string.
// A way needs to be figured out to convert the JSVAL to this object type
// ConvertJSValToStr(b2, cx, argv[2]);
// if(NS_OK != nativeThis->SetValue(b0, b1, b2, &nativeRet))
// {
// return JS_FALSE;
// }
// *rval = INT_TO_JSVAL(nativeRet);
}
else
{
JS_ReportError(cx, "WinReg.SetValue() parameters error");
return JS_FALSE;
}
return JS_TRUE;
}
//
// Native method GetValue
//
PR_STATIC_CALLBACK(JSBool)
WinRegGetValue(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsWinReg *nativeThis = (nsWinReg*)JS_GetPrivate(cx, obj);
nsWinRegValue *nativeRet;
nsAutoString b0;
nsAutoString b1;
*rval = JSVAL_NULL;
// If there's no private data, this must be the prototype, so ignore
if(nsnull == nativeThis)
{
return JS_TRUE;
}
if(argc >= 2)
{
// public int getValue ( String subKey,
// String valueName);
ConvertJSValToStr(b0, cx, argv[0]);
ConvertJSValToStr(b1, cx, argv[1]);
if(NS_OK != nativeThis->GetValue(b0, b1, &nativeRet))
{
return JS_FALSE;
}
*rval = INT_TO_JSVAL(nativeRet);
}
else
{
JS_ReportError(cx, "WinReg.GetValue() parameters error");
return JS_FALSE;
}
return JS_TRUE;
}
//
// WinReg constructor
//
PR_STATIC_CALLBACK(JSBool)
WinReg(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
return JS_FALSE;
}
/***********************************************************************/
//
// class for WinReg
//
JSClass WinRegClass = {
"WinReg",
JSCLASS_HAS_PRIVATE,
JS_PropertyStub,
JS_PropertyStub,
JS_PropertyStub,
JS_PropertyStub,
JS_EnumerateStub,
JS_ResolveStub,
JS_ConvertStub,
WinRegCleanup
};
static JSConstDoubleSpec winreg_constants[] =
{
{ nsWinReg::HKEY_CLASSES_ROOT, "HKEY_CLASSES_ROOT" },
{ nsWinReg::HKEY_CURRENT_USER, "HKEY_CURRENT_USER" },
{ nsWinReg::HKEY_LOCAL_MACHINE, "HKEY_LOCAL_MACHINE" },
{ nsWinReg::HKEY_USERS, "HKEY_USERS" },
{0}
};
//
// WinReg class methods
//
static JSFunctionSpec WinRegMethods[] =
{
{"setRootKey", WinRegSetRootKey, 1},
{"createKey", WinRegCreateKey, 2},
{"deleteKey", WinRegDeleteKey, 1},
{"deleteValue", WinRegDeleteValue, 2},
{"setValueString", WinRegSetValueString, 3},
{"getValueString", WinRegGetValueString, 2},
{"setValueNumber", WinRegSetValueNumber, 3},
{"getValueNumber", WinRegGetValueNumber, 2},
{"setValue", WinRegSetValue, 3},
{"getValue", WinRegGetValue, 2},
{0}
};
PRInt32
InitWinRegPrototype(JSContext *jscontext, JSObject *global, JSObject **winRegPrototype)
{
*winRegPrototype = JS_InitClass( jscontext, // context
global, // global object
nsnull, // parent proto
&WinRegClass, // JSClass
nsnull, // JSNative ctor
0, // ctor args
nsnull, // proto props
nsnull, // proto funcs
nsnull, // ctor props (static)
WinRegMethods); // ctor funcs (static)
if(nsnull == *winRegPrototype)
{
return NS_ERROR_FAILURE;
}
if(PR_FALSE == JS_DefineConstDoubles(jscontext, *winRegPrototype, winreg_constants))
return NS_ERROR_FAILURE;
return NS_OK;
}

View File

@@ -0,0 +1,29 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef __NS_JSWINREG_H__
#define __NS_JSWINREG_H__
PRInt32
InitWinRegPrototype(JSContext *jscontext, JSObject *global, JSObject **winRegPrototype);
#endif

View File

@@ -0,0 +1,198 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code,
* released March 31, 1998.
*
* 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):
* Douglas Turner <dougt@netscape.com>
* Pierre Phaneuf <pp@ludusdesign.com>
*/
#include "nsIXPINotifier.h"
#include "nsLoggingProgressNotifier.h"
#include "nsInstall.h"
#include "nsFileSpec.h"
#include "nsFileStream.h"
#include "nsSpecialSystemDirectory.h"
#include "nspr.h"
nsLoggingProgressNotifier::nsLoggingProgressNotifier()
: mLogStream(0)
{
NS_INIT_ISUPPORTS();
}
nsLoggingProgressNotifier::~nsLoggingProgressNotifier()
{
if (mLogStream)
{
NS_WARN_IF_FALSE(PR_FALSE, "We're being destroyed before script finishes!");
mLogStream->close();
delete mLogStream;
mLogStream = 0;
}
}
NS_IMPL_ISUPPORTS(nsLoggingProgressNotifier, NS_GET_IID(nsIXPINotifier));
NS_IMETHODIMP
nsLoggingProgressNotifier::BeforeJavascriptEvaluation(const PRUnichar *URL)
{
nsSpecialSystemDirectory logFile(nsSpecialSystemDirectory::OS_CurrentProcessDirectory);
#ifdef XP_MAC
logFile += "Install Log";
#else
logFile += "install.log";
#endif
mLogStream = new nsOutputFileStream(logFile, PR_WRONLY | PR_CREATE_FILE | PR_APPEND, 0744 );
if (!mLogStream)
return NS_ERROR_NULL_POINTER;
char* time;
GetTime(&time);
mLogStream->seek(logFile.GetFileSize());
*mLogStream << "-------------------------------------------------------------------------------" << nsEndl;
*mLogStream << nsAutoCString(URL) << " -- " << time << nsEndl;
*mLogStream << "-------------------------------------------------------------------------------" << nsEndl;
*mLogStream << nsEndl;
PL_strfree(time);
return NS_OK;
}
NS_IMETHODIMP
nsLoggingProgressNotifier::AfterJavascriptEvaluation(const PRUnichar *URL)
{
if (mLogStream == nsnull) return NS_ERROR_NULL_POINTER;
char* time;
GetTime(&time);
// *mLogStream << nsEndl;
*mLogStream << " Finished Installation " << time << nsEndl << nsEndl;
PL_strfree(time);
mLogStream->close();
delete mLogStream;
mLogStream = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsLoggingProgressNotifier::InstallStarted(const PRUnichar *URL, const PRUnichar* UIPackageName)
{
if (mLogStream == nsnull) return NS_ERROR_NULL_POINTER;
// char* time;
// GetTime(&time);
nsCString name(UIPackageName);
nsCString uline;
uline.SetCapacity(name.Length());
for ( unsigned int i=0; i < name.Length(); ++i)
uline.Append('-');
*mLogStream << " " << name.GetBuffer() << nsEndl;
*mLogStream << " " << uline.GetBuffer() << nsEndl;
*mLogStream << nsEndl;
// *mLogStream << " Starting Installation at " << time << nsEndl;
// *mLogStream << nsEndl;
// PL_strfree(time);
return NS_OK;
}
NS_IMETHODIMP
nsLoggingProgressNotifier::ItemScheduled(const PRUnichar* message )
{
return NS_OK;
}
NS_IMETHODIMP
nsLoggingProgressNotifier::FinalizeProgress(const PRUnichar* message, PRInt32 itemNum, PRInt32 totNum )
{
if (mLogStream == nsnull) return NS_ERROR_NULL_POINTER;
*mLogStream << " [" << (itemNum) << "/" << totNum << "]\t" << nsAutoCString(message) << nsEndl;
return NS_OK;
}
NS_IMETHODIMP
nsLoggingProgressNotifier::FinalStatus(const PRUnichar *URL, PRInt32 status)
{
if (mLogStream == nsnull) return NS_ERROR_NULL_POINTER;
*mLogStream << nsEndl;
switch (status)
{
case nsInstall::SUCCESS:
*mLogStream << " Install completed successfully" << nsEndl;
break;
case nsInstall::REBOOT_NEEDED:
*mLogStream << " Install completed successfully, restart required" << nsEndl;
break;
case nsInstall::ABORT_INSTALL:
*mLogStream << " Install script aborted" << nsEndl;
break;
case nsInstall::USER_CANCELLED:
*mLogStream << " Install cancelled by user" << nsEndl;
break;
default:
*mLogStream << " Install **FAILED** with error " << status << nsEndl;
break;
}
return NS_OK;
}
void
nsLoggingProgressNotifier::GetTime(char** aString)
{
PRExplodedTime et;
char line[256];
PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &et);
PR_FormatTimeUSEnglish(line, sizeof(line), "%m/%d/%Y %H:%M:%S", &et);
*aString = PL_strdup(line);
}
NS_IMETHODIMP
nsLoggingProgressNotifier::LogComment(const PRUnichar* comment)
{
if (mLogStream == nsnull) return NS_ERROR_NULL_POINTER;
*mLogStream << " ** " << nsAutoCString(comment) << nsEndl;
return NS_OK;
}

View File

@@ -0,0 +1,51 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code,
* released March 31, 1998.
*
* 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):
* Daniel Veditz <dveditz@netscape.com>
* Douglas Turner <dougt@netscape.com>
*/
#ifndef nsLoggingProgressNotifier_H__
#define nsLoggingProgressNotifier_H__
#include "nsIXPINotifier.h"
#include "nsFileStream.h"
class nsLoggingProgressNotifier : public nsIXPINotifier
{
public:
nsLoggingProgressNotifier();
virtual ~nsLoggingProgressNotifier();
NS_DECL_ISUPPORTS
// nsIXPINotifier interfaces
NS_DECL_NSIXPINOTIFIER
private:
void GetTime(char** aString);
nsOutputFileStream *mLogStream;
};
#endif

View File

@@ -0,0 +1,655 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code.
*
* 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):
* Pierre Phaneuf <pp@ludusdesign.com>
*/
#include "nscore.h"
#include "nsIGenericFactory.h"
#include "nsIFactory.h"
#include "nsISupports.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsCOMPtr.h"
#include "nsCRT.h"
#include "nspr.h"
#include "prlock.h"
#include "NSReg.h"
#include "VerReg.h"
#include "nsSpecialSystemDirectory.h"
#include "nsInstall.h"
#include "nsSoftwareUpdateIIDs.h"
#include "nsSoftwareUpdate.h"
#include "nsSoftwareUpdateRun.h"
#include "nsInstallTrigger.h"
#include "nsInstallVersion.h"
#include "ScheduledTasks.h"
#include "nsTopProgressNotifier.h"
#include "nsLoggingProgressNotifier.h"
#include "nsIAppShellComponent.h"
#include "nsIRegistry.h"
#include "nsBuildID.h"
/* For Javascript Namespace Access */
#include "nsDOMCID.h"
#include "nsIServiceManager.h"
#include "nsINameSpaceManager.h"
#include "nsIScriptObjectOwner.h"
#include "nsIScriptGlobalObject.h"
#include "nsIScriptNameSetRegistry.h"
#include "nsIScriptNameSpaceManager.h"
#include "nsIScriptExternalNameSet.h"
#include "nsIEventQueueService.h"
#include "nsProxyObjectManager.h"
////////////////////////////////////////////////////////////////////////////////
// Globals
////////////////////////////////////////////////////////////////////////////////
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
static NS_DEFINE_IID(kIScriptNameSetRegistryIID, NS_ISCRIPTNAMESETREGISTRY_IID);
static NS_DEFINE_CID(kCScriptNameSetRegistryCID, NS_SCRIPT_NAMESET_REGISTRY_CID);
static NS_DEFINE_IID(kIScriptExternalNameSetIID, NS_ISCRIPTEXTERNALNAMESET_IID);
static NS_DEFINE_IID(kISoftwareUpdate_IID, NS_ISOFTWAREUPDATE_IID);
static NS_DEFINE_IID(kIInstallTrigger_IID, NS_IDOMINSTALLTRIGGERGLOBAL_IID);
static NS_DEFINE_CID(kInstallTrigger_CID, NS_SoftwareUpdateInstallTrigger_CID);
static NS_DEFINE_IID(kIInstallVersion_IID, NS_IDOMINSTALLVERSION_IID);
static NS_DEFINE_CID(kInstallVersion_CID, NS_SoftwareUpdateInstallVersion_CID);
static NS_DEFINE_CID(knsRegistryCID, NS_REGISTRY_CID);
nsSoftwareUpdate* nsSoftwareUpdate::mInstance = nsnull;
nsIFileSpec* nsSoftwareUpdate::mProgramDir = nsnull;
#if NOTIFICATION_ENABLE
#include "nsUpdateNotification.h"
static NS_DEFINE_CID(kUpdateNotificationCID, NS_XPI_UPDATE_NOTIFIER_CID);
nsIUpdateNotification* nsSoftwareUpdate::mUpdateNotifier= nsnull;
#endif
nsSoftwareUpdate *
nsSoftwareUpdate::GetInstance()
{
if (mInstance == nsnull)
mInstance = new nsSoftwareUpdate();
NS_IF_ADDREF(mInstance);
return mInstance;
}
nsSoftwareUpdate::nsSoftwareUpdate()
: mInstalling(PR_FALSE),
mStubLockout(PR_FALSE),
mReg(0)
{
NS_INIT_ISUPPORTS();
mLock = PR_NewLock();
/***************************************/
/* Startup the Version Registry */
/***************************************/
NR_StartupRegistry(); /* startup the registry; if already started, this will essentially be a noop */
nsSpecialSystemDirectory appDir(nsSpecialSystemDirectory::OS_CurrentProcessDirectory);
VR_SetRegDirectory( appDir.GetNativePathCString() );
}
nsSoftwareUpdate::~nsSoftwareUpdate()
{
PR_Lock(mLock);
nsInstallInfo* element;
for (PRInt32 i=0; i < mJarInstallQueue.Count(); i++)
{
element = (nsInstallInfo*)mJarInstallQueue.ElementAt(i);
//FIX: need to add to registry....
delete element;
}
mJarInstallQueue.Clear();
PR_Unlock(mLock);
PR_DestroyLock(mLock);
NR_ShutdownRegistry();
NS_IF_RELEASE( mProgramDir );
mInstance = nsnull;
}
//------------------------------------------------------------------------
// nsISupports implementation
//------------------------------------------------------------------------
NS_IMPL_THREADSAFE_ADDREF( nsSoftwareUpdate );
NS_IMPL_THREADSAFE_RELEASE( nsSoftwareUpdate );
NS_IMETHODIMP
nsSoftwareUpdate::QueryInterface( REFNSIID anIID, void **anInstancePtr )
{
nsresult rv = NS_OK;
/* Check for place to return result. */
if ( !anInstancePtr )
{
rv = NS_ERROR_NULL_POINTER;
}
else
{
/* Check for IIDs we support and cast this appropriately. */
if ( anIID.Equals( NS_GET_IID(nsISoftwareUpdate) ) )
*anInstancePtr = (void*) ( (nsISoftwareUpdate*)this );
else if ( anIID.Equals( NS_GET_IID(nsIAppShellComponent) ) )
*anInstancePtr = (void*) ( (nsIAppShellComponent*)this );
else if (anIID.Equals( NS_GET_IID(nsPIXPIStubHook) ) )
*anInstancePtr = (void*) ( (nsPIXPIStubHook*)this );
else if ( anIID.Equals( kISupportsIID ) )
*anInstancePtr = (void*) ( (nsISupports*) (nsISoftwareUpdate*) this );
else
{
/* Not an interface we support. */
*anInstancePtr = 0;
rv = NS_NOINTERFACE;
}
}
if (NS_SUCCEEDED(rv))
NS_ADDREF_THIS();
return rv;
}
NS_IMETHODIMP
nsSoftwareUpdate::Initialize( nsIAppShellService *anAppShell, nsICmdLineService *aCmdLineService )
{
// Close the registry if open. We left it open through most of startup
// so it wouldn't get opened and closed a lot by different services
if (mReg)
NR_RegClose(mReg);
// prevent use of nsPIXPIStubHook by browser
mStubLockout = PR_TRUE;
/***************************************/
/* Add us to the Javascript Name Space */
/***************************************/
RegisterNameset();
/***************************************/
/* Register us with NetLib */
/***************************************/
// FIX
/***************************************/
/* Create a top level observer */
/***************************************/
nsLoggingProgressNotifier *logger = new nsLoggingProgressNotifier();
RegisterNotifier(logger);
#if NOTIFICATION_ENABLE
/***************************************/
/* Create a Update notification object */
/***************************************/
NS_IF_RELEASE(mUpdateNotifier);
nsComponentManager::CreateInstance(kUpdateNotificationCID,
nsnull,
NS_GET_IID(nsIUpdateNotification),
(void**)&mUpdateNotifier);
#endif
return NS_OK;
}
NS_IMETHODIMP
nsSoftwareUpdate::Shutdown()
{
#if NOTIFICATION_ENABLED
if (mUpdateNotifier)
{
mUpdateNotifier->DisplayUpdateDialog();
NS_RELEASE(mUpdateNotifier);
}
#endif
// nothing to do here. Should we UnregisterService?
return NS_OK;
}
NS_IMETHODIMP
nsSoftwareUpdate::RegisterNotifier(nsIXPINotifier *notifier)
{
// we are going to ignore the returned ID and enforce that once you
// register a notifier, you can not remove it. This should at some
// point be fixed.
(void) mMasterNotifier.RegisterNotifier(notifier);
return NS_OK;
}
NS_IMETHODIMP
nsSoftwareUpdate::GetMasterNotifier(nsIXPINotifier **notifier)
{
NS_ASSERTION(notifier, "getter has invalid return pointer");
if (!notifier)
return NS_ERROR_NULL_POINTER;
*notifier = &mMasterNotifier;
return NS_OK;
}
NS_IMETHODIMP
nsSoftwareUpdate::SetActiveNotifier(nsIXPINotifier *notifier)
{
mMasterNotifier.SetActiveNotifier(notifier);
return NS_OK;
}
NS_IMETHODIMP
nsSoftwareUpdate::InstallJar( nsIFileSpec* aLocalFile,
const PRUnichar* aURL,
const PRUnichar* aArguments,
long flags,
nsIXPINotifier* aNotifier)
{
if ( !aLocalFile )
return NS_ERROR_NULL_POINTER;
nsInstallInfo *info =
new nsInstallInfo( aLocalFile, aURL, aArguments, flags, aNotifier );
if (!info)
return NS_ERROR_OUT_OF_MEMORY;
PR_Lock(mLock);
mJarInstallQueue.AppendElement( info );
PR_Unlock(mLock);
RunNextInstall();
return NS_OK;
}
NS_IMETHODIMP
nsSoftwareUpdate::InstallJarCallBack()
{
PR_Lock(mLock);
nsInstallInfo *nextInstall = (nsInstallInfo*)mJarInstallQueue.ElementAt(0);
if (nextInstall != nsnull)
delete nextInstall;
mJarInstallQueue.RemoveElementAt(0);
mInstalling = PR_FALSE;
PR_Unlock(mLock);
return RunNextInstall();
}
NS_IMETHODIMP
nsSoftwareUpdate::StartupTasks( PRBool *needAutoreg )
{
PRBool autoReg = PR_FALSE;
RKEY xpiRoot;
REGERR err;
*needAutoreg = PR_TRUE;
// First do any left-over file replacements and deletes
// NOTE: we leave the registry open until later to prevent
// having to load and unload it many times at startup
if ( REGERR_OK == NR_RegOpen("", &mReg) )
{
// XXX get a return val and if not all replaced autoreg again later
PerformScheduledTasks(mReg);
// now look for an autoreg flag left behind by XPInstall
err = NR_RegGetKey( mReg, ROOTKEY_COMMON, XPI_ROOT_KEY, &xpiRoot);
if ( err == REGERR_OK )
{
char buf[8];
err = NR_RegGetEntryString( mReg, xpiRoot, XPI_AUTOREG_VAL,
buf, sizeof(buf) );
if ( err == REGERR_OK && !strcmp( buf, "yes" ) )
autoReg = PR_TRUE;
}
}
// Also check for build number changes
nsresult rv;
PRInt32 buildID = 0;
nsRegistryKey idKey = 0;
nsCOMPtr<nsIRegistry> reg = do_GetService(knsRegistryCID,&rv);
if (NS_SUCCEEDED(rv))
{
rv = reg->OpenWellKnownRegistry(nsIRegistry::ApplicationComponentRegistry);
if (NS_SUCCEEDED(rv))
{
rv = reg->GetSubtree(nsIRegistry::Common,XPCOM_KEY,&idKey);
if (NS_SUCCEEDED(rv))
{
rv = reg->GetInt( idKey, XPI_AUTOREG_VAL, &buildID );
}
}
}
// Autoregister if we found the XPInstall flag, the stored BuildID
// is not the actual BuildID, or if we couldn't get the BuildID
if ( autoReg || NS_FAILED(rv) || buildID != NS_BUILD_ID )
{
rv = nsComponentManager::AutoRegister(nsIComponentManager::NS_Startup,0);
if (NS_SUCCEEDED(rv))
{
*needAutoreg = PR_FALSE;
// Now store back into the registries so we don't do this again
if ( autoReg )
NR_RegSetEntryString( mReg, xpiRoot, XPI_AUTOREG_VAL, "no" );
if ( buildID != NS_BUILD_ID && idKey != 0 )
reg->SetInt( idKey, XPI_AUTOREG_VAL, NS_BUILD_ID );
}
}
else
{
//We don't need to autoreg, we're up to date
*needAutoreg = PR_FALSE;
#ifdef DEBUG
// debug (developer) builds should always autoreg
*needAutoreg = PR_TRUE;
#endif
}
return rv;
}
nsresult
nsSoftwareUpdate::RunNextInstall()
{
nsresult rv = NS_OK;
nsInstallInfo* info = nsnull;
PR_Lock(mLock);
if (!mInstalling)
{
if ( mJarInstallQueue.Count() > 0 )
{
info = (nsInstallInfo*)mJarInstallQueue.ElementAt(0);
if ( info )
mInstalling = PR_TRUE;
else
{
// bogus elements got into the queue
NS_ERROR("leaks remaining nsInstallInfos, please file bug!");
rv = NS_ERROR_NULL_POINTER;
VR_Close();
}
}
else
{
// nothing more to do
VR_Close();
}
}
PR_Unlock(mLock);
// make sure to RunInstall() outside of locked section due to callbacks
if (info)
RunInstall( info );
return rv;
}
nsresult
nsSoftwareUpdate::RegisterNameset()
{
nsresult rv;
nsCOMPtr<nsIScriptNameSetRegistry> namesetService =
do_GetService( kCScriptNameSetRegistryCID, &rv );
if (NS_SUCCEEDED(rv))
{
nsSoftwareUpdateNameSet* nameset = new nsSoftwareUpdateNameSet();
// the NameSet service will AddRef this one
namesetService->AddExternalNameSet( nameset );
}
return rv;
}
NS_IMETHODIMP
nsSoftwareUpdate::StubInitialize(nsIFileSpec *aDir)
{
if (mStubLockout)
return NS_ERROR_ABORT;
else if ( !aDir )
return NS_ERROR_NULL_POINTER;
// only allow once, it could be a mess if we've already started installing
mStubLockout = PR_TRUE;
// fix GetFolder return path
mProgramDir = aDir;
NS_ADDREF(mProgramDir);
// make sure registry updates go to the right place
nsFileSpec instDir;
if (NS_SUCCEEDED( aDir->GetFileSpec( &instDir ) ) )
VR_SetRegDirectory( instDir.GetNativePathCString() );
// Create the logfile observer
nsLoggingProgressNotifier *logger = new nsLoggingProgressNotifier();
RegisterNotifier(logger);
// setup version registry path
char* path;
nsresult rv = aDir->GetNativePath( &path );
if (NS_SUCCEEDED(rv))
{
VR_SetRegDirectory( path );
nsCRT::free( path );
}
return rv;
}
////////////////////////////////////////////////////////////////////////////////
// nsSoftwareUpdateNameSet
////////////////////////////////////////////////////////////////////////////////
nsSoftwareUpdateNameSet::nsSoftwareUpdateNameSet()
{
NS_INIT_ISUPPORTS();
}
nsSoftwareUpdateNameSet::~nsSoftwareUpdateNameSet()
{
}
NS_IMPL_ISUPPORTS(nsSoftwareUpdateNameSet, kIScriptExternalNameSetIID);
NS_IMETHODIMP
nsSoftwareUpdateNameSet::InitializeClasses(nsIScriptContext* aScriptContext)
{
nsresult result = NS_OK;
result = NS_InitInstallVersionClass(aScriptContext, nsnull);
if (NS_FAILED(result)) return result;
result = NS_InitInstallTriggerGlobalClass(aScriptContext, nsnull);
return result;
}
NS_IMETHODIMP
nsSoftwareUpdateNameSet::AddNameSet(nsIScriptContext* aScriptContext)
{
nsresult result = NS_OK;
nsIScriptNameSpaceManager* manager;
result = aScriptContext->GetNameSpaceManager(&manager);
if (NS_SUCCEEDED(result))
{
result = manager->RegisterGlobalName("InstallVersion",
kInstallVersion_CID,
PR_TRUE);
if (NS_FAILED(result)) return result;
result = manager->RegisterGlobalName("InstallTrigger",
kInstallTrigger_CID,
PR_FALSE);
}
if (manager != nsnull)
NS_RELEASE(manager);
return result;
}
//----------------------------------------------------------------------
// Functions used to create new instances of a given object by the
// generic factory.
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsSoftwareUpdate,nsSoftwareUpdate::GetInstance);
NS_GENERIC_FACTORY_CONSTRUCTOR(nsInstallTrigger);
NS_GENERIC_FACTORY_CONSTRUCTOR(nsInstallVersion);
//----------------------------------------------------------------------
static NS_METHOD
RegisterSoftwareUpdate( nsIComponentManager *aCompMgr,
nsIFile *aPath,
const char *registryLocation,
const char *componentType)
{
// get the registry
nsIRegistry* registry;
nsresult rv = nsServiceManager::GetService(NS_REGISTRY_PROGID,
NS_GET_IID(nsIRegistry),
(nsISupports**)&registry);
if ( NS_SUCCEEDED( rv ) )
{
registry->OpenWellKnownRegistry(nsIRegistry::ApplicationComponentRegistry);
char buffer[256];
char *cid = nsSoftwareUpdate::GetCID().ToString();
PR_snprintf( buffer,
sizeof buffer,
"%s/%s",
NS_IAPPSHELLCOMPONENT_KEY,
cid ? cid : "unknown" );
nsCRT::free(cid);
nsRegistryKey key;
rv = registry->AddSubtree( nsIRegistry::Common,
buffer,
&key );
nsServiceManager::ReleaseService(NS_REGISTRY_PROGID, registry);
}
return rv;
}
// The list of components we register
static nsModuleComponentInfo components[] =
{
{ "SoftwareUpdate Component",
NS_SoftwareUpdate_CID,
NS_IXPINSTALLCOMPONENT_PROGID,
nsSoftwareUpdateConstructor,
RegisterSoftwareUpdate
},
{ "InstallTrigger Component",
NS_SoftwareUpdateInstallTrigger_CID,
NS_INSTALLTRIGGERCOMPONENT_PROGID,
nsInstallTriggerConstructor
},
{ "InstallVersion Component",
NS_SoftwareUpdateInstallVersion_CID,
NS_INSTALLVERSIONCOMPONENT_PROGID,
nsInstallVersionConstructor
},
#if NOTIFICATION_ENABLED
{ "XPInstall Update Notifier",
NS_XPI_UPDATE_NOTIFIER_CID,
NS_XPI_UPDATE_NOTIFIER_PROGID,
nsXPINotifierImpl::New
},
#endif
};
NS_IMPL_NSGETMODULE("nsSoftwareUpdate", components)

View File

@@ -0,0 +1,114 @@
#ifndef nsSoftwareUpdate_h___
#define nsSoftwareUpdate_h___
#include "nsSoftwareUpdateIIDs.h"
#include "nsISoftwareUpdate.h"
#include "nscore.h"
#include "nsIFactory.h"
#include "nsISupports.h"
#include "nsString.h"
#include "nsVoidArray.h"
#include "prlock.h"
//#include "mozreg.h"
#include "NSReg.h"
class nsInstallInfo;
#include "nsIScriptExternalNameSet.h"
#include "nsIAppShellComponent.h"
#include "nsIXPINotifier.h"
#include "nsPIXPIStubHook.h"
#include "nsTopProgressNotifier.h"
#if NOTIFICATION_ENABLE
#include "nsIUpdateNotification.h"
#endif
#define XPI_ROOT_KEY "software/mozilla/xpinstall"
#define XPI_AUTOREG_VAL "Autoreg"
#define XPCOM_KEY "software/mozilla/XPCOM"
class nsSoftwareUpdate: public nsIAppShellComponent,
public nsISoftwareUpdate,
public nsPIXPIStubHook
{
public:
NS_DEFINE_STATIC_CID_ACCESSOR( NS_SoftwareUpdate_CID );
static nsSoftwareUpdate *GetInstance();
/** GetProgramDirectory
* information used within the XPI module -- not
* available through any interface
*/
static nsIFileSpec* GetProgramDirectory() { return mProgramDir; }
NS_DECL_ISUPPORTS
NS_DECL_NSIAPPSHELLCOMPONENT
NS_IMETHOD InstallJar( nsIFileSpec* localFile,
const PRUnichar* URL,
const PRUnichar* arguments,
long flags = 0,
nsIXPINotifier* notifier = 0);
NS_IMETHOD RegisterNotifier(nsIXPINotifier *notifier);
NS_IMETHOD InstallJarCallBack();
NS_IMETHOD GetMasterNotifier(nsIXPINotifier **notifier);
NS_IMETHOD SetActiveNotifier(nsIXPINotifier *notifier);
NS_IMETHOD StartupTasks( PRBool* needAutoreg );
/** StubInitialize() is private for the Install Wizard.
* The mStubLockout property makes sure this is only called
* once, and is also set by the AppShellComponent initialize
* so it can't be called during a normal Mozilla run
*/
NS_IMETHOD StubInitialize(nsIFileSpec *dir);
nsSoftwareUpdate();
virtual ~nsSoftwareUpdate();
private:
static nsSoftwareUpdate* mInstance;
static nsIFileSpec* mProgramDir;
#if NOTIFICATION_ENABLE
static nsIUpdateNotification *mUpdateNotifier;
#endif
nsresult RunNextInstall();
nsresult RegisterNameset();
PRLock* mLock;
PRBool mInstalling;
PRBool mStubLockout;
nsVoidArray mJarInstallQueue;
nsTopProgressNotifier mMasterNotifier;
HREG mReg;
};
class nsSoftwareUpdateNameSet : public nsIScriptExternalNameSet
{
public:
nsSoftwareUpdateNameSet();
virtual ~nsSoftwareUpdateNameSet();
// nsISupports
NS_DECL_ISUPPORTS
// nsIScriptExternalNameSet
NS_IMETHOD InitializeClasses(nsIScriptContext* aScriptContext);
NS_IMETHOD AddNameSet(nsIScriptContext* aScriptContext);
};
#endif

View File

@@ -0,0 +1,448 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code,
* released March 31, 1998.
*
* 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):
* Daniel Veditz <dveditz@netscape.com>
* Douglas Turner <dougt@netscape.com>
*/
#include "nsSoftwareUpdate.h"
#include "nsSoftwareUpdateRun.h"
#include "nsSoftwareUpdateIIDs.h"
#include "nsInstall.h"
#include "nsRepository.h"
#include "nsIServiceManager.h"
#include "nsSpecialSystemDirectory.h"
#include "nsFileStream.h"
#include "nspr.h"
#include "jsapi.h"
#include "nsIEventQueueService.h"
#include "nsIEnumerator.h"
#include "nsIZipReader.h"
#include "nsIJSRuntimeService.h"
#include "nsCOMPtr.h"
#include "nsIEventQueueService.h"
#include "nsILocalFile.h"
static NS_DEFINE_CID(kSoftwareUpdateCID, NS_SoftwareUpdate_CID);
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
extern JSObject *InitXPInstallObjects(JSContext *jscontext, JSObject *global, const nsFileSpec& jarfile, const PRUnichar* url, const PRUnichar* args, nsIZipReader* hZip);
extern nsresult InitInstallVersionClass(JSContext *jscontext, JSObject *global, void** prototype);
extern nsresult InitInstallTriggerGlobalClass(JSContext *jscontext, JSObject *global, void** prototype);
// Defined in this file:
static void XPInstallErrorReporter(JSContext *cx, const char *message, JSErrorReport *report);
static PRInt32 GetInstallScriptFromJarfile(nsIZipReader* hZip, nsFileSpec& jarFile, char** scriptBuffer, PRUint32 *scriptLength);
static nsresult SetupInstallContext(nsIZipReader* hZip, const nsFileSpec& jarFile, const PRUnichar* url, const PRUnichar* args, JSRuntime *jsRT, JSContext **jsCX, JSObject **jsGlob);
extern "C" void RunInstallOnThread(void *data);
///////////////////////////////////////////////////////////////////////////////////////////////
// Function name : XPInstallErrorReporter
// Description : Prints error message to stdout
// Return type : void
// Argument : JSContext *cx
// Argument : const char *message
// Argument : JSErrorReport *report
///////////////////////////////////////////////////////////////////////////////////////////////
static void
XPInstallErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
{
int i, j, k, n;
fputs("xpinstall: ", stderr);
if (!report)
{
fprintf(stderr, "%s\n", message);
return;
}
if (report->filename)
fprintf(stderr, "%s, ", report->filename);
if (report->lineno)
fprintf(stderr, "line %u: ", report->lineno);
fputs(message, stderr);
if (!report->linebuf)
{
putc('\n', stderr);
return;
}
fprintf(stderr, ":\n%s\n", report->linebuf);
n = report->tokenptr - report->linebuf;
for (i = j = 0; i < n; i++) {
if (report->linebuf[i] == '\t') {
for (k = (j + 8) & ~7; j < k; j++)
putc('.', stderr);
continue;
}
putc('.', stderr);
j++;
}
fputs("^\n", stderr);
}
///////////////////////////////////////////////////////////////////////////////////////////////
// Function name : GetInstallScriptFromJarfile
// Description : Extracts and reads in a install.js file from a passed jar file.
// Return type : static PRInt32
// Argument : const char* jarFile - **NSPR** filepath
// Argument : char** scriptBuffer - must be deleted via delete []
// Argument : PRUint32 *scriptLength
///////////////////////////////////////////////////////////////////////////////////////////////
static PRInt32
GetInstallScriptFromJarfile(nsIZipReader* hZip, nsFileSpec& jarFile, char** scriptBuffer, PRUint32 *scriptLength)
{
PRInt32 result = NS_OK;
*scriptBuffer = nsnull;
*scriptLength = 0;
nsCOMPtr<nsILocalFile> jFile;
nsresult rv = NS_NewLocalFile(jarFile, getter_AddRefs(jFile));
if (NS_SUCCEEDED(rv))
rv = hZip->Init(jFile);
if (NS_FAILED(rv))
return nsInstall::CANT_READ_ARCHIVE;
rv = hZip->Open();
if (NS_FAILED(rv))
return nsInstall::CANT_READ_ARCHIVE;
// Extract the install.js file to the temporary directory
nsSpecialSystemDirectory installJSFileSpec(nsSpecialSystemDirectory::OS_TemporaryDirectory);
installJSFileSpec += "install.js";
installJSFileSpec.MakeUnique();
// Extract the install.js file.
nsCOMPtr<nsILocalFile> iFile;
rv = NS_NewLocalFile(installJSFileSpec, getter_AddRefs(iFile));
if (NS_SUCCEEDED(rv))
rv = hZip->Extract("install.js", iFile);
if ( NS_SUCCEEDED(rv) )
{
// Read it into a buffer
char* buffer;
PRUint32 bufferLength;
PRUint32 readLength;
result = nsInstall::CANT_READ_ARCHIVE;
nsInputFileStream fileStream(installJSFileSpec);
nsCOMPtr<nsIInputStream> instream = fileStream.GetIStream();
if ( instream )
{
instream->Available(&bufferLength);
buffer = new char[bufferLength + 1];
if (buffer != nsnull)
{
rv = instream->Read(buffer, bufferLength, &readLength);
if (NS_SUCCEEDED(rv) && readLength > 0)
{
*scriptBuffer = buffer;
*scriptLength = readLength;
result = NS_OK;
}
else
{
delete [] buffer;
}
}
fileStream.close();
}
installJSFileSpec.Delete(PR_FALSE);
}
else
{
result = nsInstall::NO_INSTALL_SCRIPT;
}
return result;
}
///////////////////////////////////////////////////////////////////////////////////////////////
// Function name : SetupInstallContext
// Description : Creates a Javascript context and adds our xpinstall objects to it.
// Return type : static nsresult
// Argument : nsIZipReader hZip - the handle to the open archive file
// Argument : const char* jarFile - native filepath to where jar exists on disk
// Argument : const PRUnichar* url - URL of where this package came from
// Argument : const PRUnichar* args - any arguments passed into the javascript context
// Argument : JSRuntime *jsRT - A valid JS Runtime
// Argument : JSContext **jsCX - Created context, destroy via JS_DestroyContext
// Argument : JSObject **jsGlob - created global object
///////////////////////////////////////////////////////////////////////////////////////////////
static nsresult SetupInstallContext(nsIZipReader* hZip,
const nsFileSpec& jarFile,
const PRUnichar* url,
const PRUnichar* args,
JSRuntime *rt,
JSContext **jsCX,
JSObject **jsGlob)
{
JSContext *cx;
JSObject *glob;
*jsCX = nsnull;
*jsGlob = nsnull;
if (!rt)
return NS_ERROR_OUT_OF_MEMORY;
cx = JS_NewContext(rt, 8192);
if (!cx)
{
return NS_ERROR_OUT_OF_MEMORY;
}
JS_SetErrorReporter(cx, XPInstallErrorReporter);
glob = InitXPInstallObjects(cx, nsnull, jarFile, url, args, hZip);
// Init standard classes
JS_InitStandardClasses(cx, glob);
// Add our Install class to this context
InitInstallVersionClass(cx, glob, nsnull);
InitInstallTriggerGlobalClass(cx, glob, nsnull);
*jsCX = cx;
*jsGlob = glob;
return NS_OK;
}
///////////////////////////////////////////////////////////////////////////////////////////////
// Function name : RunInstall
// Description : Creates our Install Thread.
// Return type : PRInt32
// Argument : nsInstallInfo *installInfo
///////////////////////////////////////////////////////////////////////////////////////////////
PRInt32 RunInstall(nsInstallInfo *installInfo)
{
if (installInfo->GetFlags() & XPI_NO_NEW_THREAD)
{
RunInstallOnThread((void *)installInfo);
}
else
{
PR_CreateThread(PR_USER_THREAD,
RunInstallOnThread,
(void*)installInfo,
PR_PRIORITY_NORMAL,
PR_GLOBAL_THREAD,
PR_UNJOINABLE_THREAD,
0);
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////
// Function name : RunInstallOnThread
// Description : called by starting thread. It directly calls the C api for xpinstall,
// : and once that returns, it calls the completion routine to notify installation
// : completion.
// Return type : extern "C"
// Argument : void *data
///////////////////////////////////////////////////////////////////////////////////////////////
extern "C" void RunInstallOnThread(void *data)
{
nsInstallInfo *installInfo = (nsInstallInfo*)data;
char *scriptBuffer = nsnull;
PRUint32 scriptLength;
JSRuntime *rt;
JSContext *cx;
JSObject *glob;
nsCOMPtr<nsIZipReader> hZip;
static NS_DEFINE_IID(kIZipReaderIID, NS_IZIPREADER_IID);
static NS_DEFINE_IID(kZipReaderCID, NS_ZIPREADER_CID);
nsresult rv = nsComponentManager::CreateInstance(kZipReaderCID, nsnull, kIZipReaderIID,
getter_AddRefs(hZip));
if (NS_FAILED(rv))
return;
// we will plan on sending a failure status back from here unless we
// find positive acknowledgement that the script sent the status
PRInt32 finalStatus;
PRBool sendStatus = PR_TRUE;
nsIXPINotifier *notifier;
// lets set up an eventQ so that our xpcom/proxies will not have to:
nsCOMPtr<nsIEventQueue> eventQ;
NS_WITH_SERVICE(nsIEventQueueService, eventQService, kEventQueueServiceCID, &rv);
if (NS_SUCCEEDED(rv))
{
eventQService->CreateThreadEventQueue();
eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(eventQ));
}
NS_WITH_SERVICE(nsISoftwareUpdate, softwareUpdate, kSoftwareUpdateCID, &rv );
if (!NS_SUCCEEDED(rv))
{
NS_WARNING("shouldn't have RunInstall() if we can't get SoftwareUpdate");
return;
}
softwareUpdate->SetActiveNotifier( installInfo->GetNotifier() );
softwareUpdate->GetMasterNotifier(&notifier);
nsString url;
installInfo->GetURL(url);
if(notifier)
notifier->BeforeJavascriptEvaluation( url.GetUnicode() );
nsString args;
installInfo->GetArguments(args);
nsFileSpec jarpath;
rv = installInfo->GetLocalFile(jarpath);
if (NS_SUCCEEDED(rv))
{
finalStatus = GetInstallScriptFromJarfile( hZip,
jarpath,
&scriptBuffer,
&scriptLength);
if ( finalStatus == NS_OK && scriptBuffer )
{
PRBool ownRuntime = PR_FALSE;
NS_WITH_SERVICE(nsIJSRuntimeService, rtsvc, "nsJSRuntimeService", &rv);
if(NS_FAILED(rv) || NS_FAILED(rtsvc->GetRuntime(&rt)))
{
// service not available (wizard context?)
// create our own runtime
ownRuntime = PR_TRUE;
rt = JS_Init(4L * 1024L * 1024L);
}
rv = SetupInstallContext( hZip, jarpath,
url.GetUnicode(),
args.GetUnicode(),
rt, &cx, &glob);
if (NS_SUCCEEDED(rv))
{
// Go ahead and run!!
jsval rval;
jsval installedFiles;
PRBool ok = JS_EvaluateScript( cx,
glob,
scriptBuffer,
scriptLength,
nsnull,
0,
&rval);
if(!ok)
{
// problem compiling or running script
if(JS_GetProperty(cx, glob, "_installedFiles", &installedFiles) &&
JSVAL_TO_BOOLEAN(installedFiles))
{
nsInstall *a = (nsInstall*)JS_GetPrivate(cx, glob);
a->InternalAbort(nsInstall::SCRIPT_ERROR);
}
finalStatus = nsInstall::SCRIPT_ERROR;
}
else
{
// check to make sure the script sent back a status
jsval sent;
if(JS_GetProperty(cx, glob, "_installedFiles", &installedFiles) &&
JSVAL_TO_BOOLEAN(installedFiles))
{
nsInstall *a = (nsInstall*)JS_GetPrivate(cx, glob);
a->InternalAbort(nsInstall::SCRIPT_ERROR);
}
if ( JS_GetProperty( cx, glob, "_statusSent", &sent ) &&
JSVAL_TO_BOOLEAN(sent) )
sendStatus = PR_FALSE;
else
finalStatus = nsInstall::SCRIPT_ERROR;
}
JS_DestroyContext(cx);
}
else
{
// couldn't initialize install context
finalStatus = nsInstall::UNEXPECTED_ERROR;
}
// clean up Runtime if we created it ourselves
if ( ownRuntime )
JS_DestroyRuntime(rt);
}
}
else
{
// no path to local jar archive
finalStatus = nsInstall::DOWNLOAD_ERROR;
}
if(notifier)
{
if ( sendStatus )
notifier->FinalStatus( url.GetUnicode(), finalStatus );
notifier->AfterJavascriptEvaluation( url.GetUnicode() );
}
if (scriptBuffer) delete [] scriptBuffer;
softwareUpdate->SetActiveNotifier(0);
softwareUpdate->InstallJarCallBack();
}

View File

@@ -0,0 +1,6 @@
#ifndef __NS_SoftwareUpdateRun_H__
#define __NS_SoftwareUpdateRun_H__
PRInt32 RunInstall(nsInstallInfo *installInfo);
#endif

View File

@@ -0,0 +1,211 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code,
* released March 31, 1998.
*
* 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):
* Douglas Turner <dougt@netscape.com>
* Daniel Veditz <dveditz@netscape.com>
* Pierre Phaneuf <pp@ludusdesign.com>
*/
#include "nsIXPINotifier.h"
#include "nsTopProgressNotifier.h"
nsTopProgressNotifier::nsTopProgressNotifier()
{
NS_INIT_ISUPPORTS();
mNotifiers = new nsVoidArray();
mActive = 0;
}
nsTopProgressNotifier::~nsTopProgressNotifier()
{
if (mNotifiers)
{
PRInt32 i=0;
for (; i < mNotifiers->Count(); i++)
{
nsIXPINotifier* element = (nsIXPINotifier*)mNotifiers->ElementAt(i);
NS_IF_RELEASE(element);
}
mNotifiers->Clear();
delete (mNotifiers);
}
}
NS_IMPL_ISUPPORTS(nsTopProgressNotifier, NS_GET_IID(nsIXPINotifier));
long
nsTopProgressNotifier::RegisterNotifier(nsIXPINotifier * newNotifier)
{
NS_IF_ADDREF( newNotifier );
return mNotifiers->AppendElement( newNotifier );
}
void
nsTopProgressNotifier::UnregisterNotifier(long id)
{
nsIXPINotifier *item = (nsIXPINotifier*)mNotifiers->ElementAt(id);
NS_IF_RELEASE(item);
mNotifiers->ReplaceElementAt(nsnull, id);
}
NS_IMETHODIMP
nsTopProgressNotifier::BeforeJavascriptEvaluation(const PRUnichar *URL)
{
if (mActive)
mActive->BeforeJavascriptEvaluation(URL);
if (mNotifiers)
{
PRInt32 i=0;
for (; i < mNotifiers->Count(); i++)
{
nsIXPINotifier* element = (nsIXPINotifier*)mNotifiers->ElementAt(i);
if (element != NULL)
element->BeforeJavascriptEvaluation(URL);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsTopProgressNotifier::AfterJavascriptEvaluation(const PRUnichar *URL)
{
if (mActive)
mActive->AfterJavascriptEvaluation(URL);
if (mNotifiers)
{
PRInt32 i=0;
for (; i < mNotifiers->Count(); i++)
{
nsIXPINotifier* element = (nsIXPINotifier*)mNotifiers->ElementAt(i);
if (element != NULL)
element->AfterJavascriptEvaluation(URL);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsTopProgressNotifier::InstallStarted(const PRUnichar *URL, const PRUnichar* UIPackageName)
{
if (mActive)
mActive->InstallStarted(URL, UIPackageName);
if (mNotifiers)
{
PRInt32 i=0;
for (; i < mNotifiers->Count(); i++)
{
nsIXPINotifier* element = (nsIXPINotifier*)mNotifiers->ElementAt(i);
if (element != NULL)
element->InstallStarted(URL, UIPackageName);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsTopProgressNotifier::ItemScheduled( const PRUnichar* message )
{
long rv = 0;
if (mActive)
mActive->ItemScheduled( message );
if (mNotifiers)
{
PRInt32 i=0;
for (; i < mNotifiers->Count(); i++)
{
nsIXPINotifier* element = (nsIXPINotifier*)mNotifiers->ElementAt(i);
if (element != NULL)
element->ItemScheduled( message );
}
}
return rv;
}
NS_IMETHODIMP
nsTopProgressNotifier::FinalizeProgress( const PRUnichar* message, PRInt32 itemNum, PRInt32 totNum )
{
if (mActive)
mActive->FinalizeProgress( message, itemNum, totNum );
if (mNotifiers)
{
PRInt32 i=0;
for (; i < mNotifiers->Count(); i++)
{
nsIXPINotifier* element = (nsIXPINotifier*)mNotifiers->ElementAt(i);
if (element != NULL)
element->FinalizeProgress( message, itemNum, totNum );
}
}
return NS_OK;
}
NS_IMETHODIMP
nsTopProgressNotifier::FinalStatus(const PRUnichar *URL, PRInt32 status)
{
if (mActive)
mActive->FinalStatus(URL, status);
if (mNotifiers)
{
PRInt32 i=0;
for (; i < mNotifiers->Count(); i++)
{
nsIXPINotifier* element = (nsIXPINotifier*)mNotifiers->ElementAt(i);
if (element != NULL)
element->FinalStatus(URL,status);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsTopProgressNotifier::LogComment(const PRUnichar* comment)
{
if (mActive)
mActive->LogComment(comment);
if (mNotifiers)
{
PRInt32 i=0;
for (; i < mNotifiers->Count(); i++)
{
nsIXPINotifier* element = (nsIXPINotifier*)mNotifiers->ElementAt(i);
if (element != NULL)
element->LogComment(comment);
}
}
return NS_OK;
}

View File

@@ -0,0 +1,57 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code,
* released March 31, 1998.
*
* 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):
* Douglas Turner <dougt@netscape.com>
* Daniel Veditz <dveditz@netscape.com>
*/
#ifndef nsTopProgressNotifier_h__
#define nsTopProgressNotifier_h__
#include "nsCOMPtr.h"
#include "nsIXPINotifier.h"
#include "nsVoidArray.h"
class nsTopProgressNotifier : public nsIXPINotifier
{
public:
nsTopProgressNotifier();
virtual ~nsTopProgressNotifier();
long RegisterNotifier(nsIXPINotifier * newNotifier);
void UnregisterNotifier(long id);
void SetActiveNotifier(nsIXPINotifier *aNotifier)
{ mActive = aNotifier; }
NS_DECL_ISUPPORTS
// implements nsIXPINotifier
NS_DECL_NSIXPINOTIFIER
private:
nsVoidArray *mNotifiers;
nsCOMPtr<nsIXPINotifier> mActive;
};
#endif

View File

@@ -0,0 +1,645 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code,
* released March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998-1999 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Doug Turner <dougt@netscape.com>
* Pierre Phaneuf <pp@ludusdesign.com>
*/
#include "nsUpdateNotification.h"
#include "nsISupports.h"
#include "nsIServiceManager.h"
#include "nsCOMPtr.h"
#include "nsIComponentManager.h"
#include "nsIGenericFactory.h"
#include "nsIRDFContainer.h"
#include "nsIRDFDataSource.h"
#include "nsIRDFService.h"
#include "nsIRDFRemoteDataSource.h"
#include "nsRDFCID.h"
#include "nsIRDFXMLSink.h"
#include "nsIPref.h"
#include "nsISoftwareUpdate.h"
#define NC_RDF_NAME "http://home.netscape.com/NC-rdf#name"
#define NC_RDF_SOURCE "http://home.netscape.com/NC-rdf#source"
#define NC_RDF_URL "http://home.netscape.com/NC-rdf#url"
#define NC_RDF_CHILD "http://home.netscape.com/NC-rdf#child"
#define NC_RDF_NOTIFICATION_ROOT "http://home.netscape.com/NC-rdf#SoftwareNotificationRoot"
#define NC_XPI_SOURCES "http://home.netscape.com/NC-rdf#SoftwareUpdateDataSources"
#define NC_XPI_PACKAGES "http://home.netscape.com/NC-rdf#SoftwarePackages"
#define NC_XPI_TITLE "http://home.netscape.com/NC-rdf#title"
#define NC_XPI_REGKEY "http://home.netscape.com/NC-rdf#registryKey"
#define NC_XPI_VERSION "http://home.netscape.com/NC-rdf#version"
#define NC_XPI_DESCRIPTION "http://home.netscape.com/NC-rdf#description"
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
static NS_DEFINE_CID(kRDFContainerCID, NS_RDFCONTAINER_CID);
static NS_DEFINE_IID(kPrefsIID, NS_IPREF_IID);
static NS_DEFINE_IID(kPrefsCID, NS_PREF_CID);
nsIRDFResource* nsXPINotifierImpl::kXPI_NotifierSources = nsnull;
nsIRDFResource* nsXPINotifierImpl::kXPI_NotifierPackages = nsnull;
nsIRDFResource* nsXPINotifierImpl::kXPI_NotifierPackage_Title = nsnull;
nsIRDFResource* nsXPINotifierImpl::kXPI_NotifierPackage_Version = nsnull;
nsIRDFResource* nsXPINotifierImpl::kXPI_NotifierPackage_Description = nsnull;
nsIRDFResource* nsXPINotifierImpl::kXPI_NotifierPackage_RegKey = nsnull;
nsIRDFResource* nsXPINotifierImpl::kNC_NotificationRoot = nsnull;
nsIRDFResource* nsXPINotifierImpl::kNC_Source = nsnull;
nsIRDFResource* nsXPINotifierImpl::kNC_Name = nsnull;
nsIRDFResource* nsXPINotifierImpl::kNC_URL = nsnull;
nsIRDFResource* nsXPINotifierImpl::kNC_Child = nsnull;
nsXPINotifierImpl::nsXPINotifierImpl()
: mRDF(nsnull)
{
NS_INIT_REFCNT();
mPendingRefreshes = 0;
static NS_DEFINE_CID(kRDFInMemoryDataSourceCID, NS_RDFINMEMORYDATASOURCE_CID);
nsComponentManager::CreateInstance(kRDFInMemoryDataSourceCID,
nsnull,
NS_GET_IID(nsISupports),
getter_AddRefs(mNotifications));
}
nsXPINotifierImpl::~nsXPINotifierImpl()
{
if (mRDF)
{
nsServiceManager::ReleaseService(kRDFServiceCID, mRDF);
mRDF = nsnull;
}
NS_IF_RELEASE(kXPI_NotifierSources);
NS_IF_RELEASE(kXPI_NotifierPackages);
NS_IF_RELEASE(kXPI_NotifierPackage_Title);
NS_IF_RELEASE(kXPI_NotifierPackage_Version);
NS_IF_RELEASE(kXPI_NotifierPackage_Description);
NS_IF_RELEASE(kXPI_NotifierPackage_RegKey);
NS_IF_RELEASE(kNC_NotificationRoot);
NS_IF_RELEASE(kNC_Source);
NS_IF_RELEASE(kNC_Name);
NS_IF_RELEASE(kNC_URL);
NS_IF_RELEASE(kNC_Child);
}
NS_IMPL_ISUPPORTS2(nsXPINotifierImpl, nsIRDFXMLSinkObserver, nsIUpdateNotification);
nsresult
nsXPINotifierImpl::NotificationEnabled(PRBool* aReturn)
{
*aReturn = PR_FALSE;
nsIPref * prefs;
nsresult rv = nsServiceManager::GetService(kPrefsCID,
kPrefsIID,
(nsISupports**) &prefs);
if ( NS_SUCCEEDED(rv) )
{
PRBool value;
// check to see if we are on.
rv = prefs->GetBoolPref( (const char*) XPINSTALL_NOTIFICATIONS_ENABLE, &value);
if (NS_SUCCEEDED(rv) && value)
{
// check to see the last time we did anything. Since flash does not have a persistant
// way to do poll invervals longer than a session, we will implemented that here by using the
// preferences.
PRInt32 intervalHours = 0;
PRTime now = 0;
PRInt32 nowSec = 0;
PRInt32 lastTime = 0;
rv = prefs->GetIntPref(XPINSTALL_NOTIFICATIONS_INTERVAL, &intervalHours);
if (NS_FAILED(rv))
{
intervalHours = 7*24; // default at once a week
rv = prefs->SetIntPref(XPINSTALL_NOTIFICATIONS_INTERVAL, intervalHours);
}
rv = prefs->GetIntPref(XPINSTALL_NOTIFICATIONS_LASTDATE, &lastTime);
now = PR_Now();
// nowSec = now / 1000000
LL_DIV(nowSec, now, 1000000);
if (NS_FAILED(rv) || lastTime == 0)
{
rv = prefs->SetIntPref(XPINSTALL_NOTIFICATIONS_LASTDATE, nowSec);
return NS_OK;
}
if ((lastTime + (intervalHours*60*24)) <= nowSec)
{
*aReturn = PR_TRUE;
}
NS_RELEASE(prefs);
}
}
return NS_OK;
}
nsresult
nsXPINotifierImpl::Init()
{
PRBool enabled;
NotificationEnabled(&enabled);
if (!enabled)
return NS_ERROR_FAILURE;
if (mNotifications == nsnull)
return NS_ERROR_FAILURE;
nsresult rv;
nsCOMPtr<nsIRDFDataSource> distributors;
nsCOMPtr<nsIRDFContainer> distributorsContainer;
nsCOMPtr <nsISimpleEnumerator> distributorEnumerator;
PRBool moreElements;
// Read the distributor registry
rv = nsServiceManager::GetService(kRDFServiceCID, NS_GET_IID(nsIRDFService), (nsISupports**) &mRDF);
if (NS_FAILED(rv)) return rv;
if (! kXPI_NotifierSources)
{
mRDF->GetResource(NC_XPI_SOURCES, &kXPI_NotifierSources);
mRDF->GetResource(NC_XPI_PACKAGES, &kXPI_NotifierPackages);
mRDF->GetResource(NC_XPI_TITLE, &kXPI_NotifierPackage_Title);
mRDF->GetResource(NC_XPI_VERSION, &kXPI_NotifierPackage_Version);
mRDF->GetResource(NC_XPI_DESCRIPTION, &kXPI_NotifierPackage_Description);
mRDF->GetResource(NC_XPI_REGKEY, &kXPI_NotifierPackage_RegKey);
mRDF->GetResource(NC_RDF_NOTIFICATION_ROOT, &kNC_NotificationRoot);
mRDF->GetResource(NC_RDF_SOURCE, &kNC_Source);
mRDF->GetResource(NC_RDF_NAME, &kNC_Name);
mRDF->GetResource(NC_RDF_URL, &kNC_URL);
mRDF->GetResource(NC_RDF_CHILD, &kNC_Child);
}
rv = OpenRemoteDataSource(BASE_DATASOURCE_URL, PR_TRUE, getter_AddRefs(distributors));
if (NS_FAILED(rv)) return rv;
rv = nsComponentManager::CreateInstance(kRDFContainerCID,
nsnull,
NS_GET_IID(nsIRDFContainer),
getter_AddRefs(distributorsContainer));
if (NS_SUCCEEDED(rv))
{
rv = distributorsContainer->Init(distributors, kXPI_NotifierSources);
if (NS_SUCCEEDED(rv))
{
rv = distributorsContainer->GetElements(getter_AddRefs(distributorEnumerator));
if (NS_SUCCEEDED(rv))
{
distributorEnumerator->HasMoreElements(&moreElements);
while (moreElements)
{
nsCOMPtr<nsISupports> i;
rv = distributorEnumerator->GetNext(getter_AddRefs(i));
if (NS_FAILED(rv)) break;
nsCOMPtr<nsIRDFResource> aDistributor(do_QueryInterface(i, &rv));
if (NS_FAILED(rv)) break;
char* uri;
nsCOMPtr<nsIRDFDataSource> remoteDatasource;
aDistributor->GetValue(&uri);
rv = OpenRemoteDataSource(uri, PR_FALSE, getter_AddRefs(remoteDatasource));
nsAllocator::Free(uri);
if (NS_FAILED(rv)) break;
distributorEnumerator->HasMoreElements(&moreElements);
}
}
}
}
return NS_OK;
}
PRBool
nsXPINotifierImpl::IsNewerOrUninstalled(const char* regKey, const char* versionString)
{
PRBool needJar = PR_FALSE;
REGERR status = VR_ValidateComponent( (char*) regKey );
if ( status == REGERR_NOFIND || status == REGERR_NOFILE )
{
// either component is not in the registry or it's a file
// node and the physical file is missing
needJar = PR_TRUE;
}
else
{
VERSION oldVersion;
status = VR_GetVersion( (char*)regKey, &oldVersion );
if ( status != REGERR_OK )
{
needJar = PR_TRUE;
}
else
{
VERSION newVersion;
StringToVersionNumbers(versionString, &(newVersion).major, &(newVersion).minor, &(newVersion).release, &(newVersion).build);
if ( CompareVersions(&oldVersion, &newVersion) < 0 )
needJar = PR_TRUE;
}
}
return needJar;
}
PRInt32
nsXPINotifierImpl::CompareVersions(VERSION *oldversion, VERSION *newVersion)
{
PRInt32 diff;
if ( oldversion->major == newVersion->major )
{
if ( oldversion->minor == newVersion->minor )
{
if ( oldversion->release == newVersion->release )
{
if ( oldversion->build == newVersion->build )
diff = 0;
else if ( oldversion->build > newVersion->build )
diff = 1;
else
diff = -1;
}
else if ( oldversion->release > newVersion->release )
diff = 1;
else
diff = -1;
}
else if ( oldversion->minor > newVersion->minor )
diff = 1;
else
diff = -1;
}
else if ( oldversion->major > newVersion->major )
diff = 1;
else
diff = -1;
return diff;
}
void
nsXPINotifierImpl::StringToVersionNumbers(const nsString& version, int32 *aMajor, int32 *aMinor, int32 *aRelease, int32 *aBuild)
{
PRInt32 errorCode;
int dot = version.FindChar('.', PR_FALSE,0);
if ( dot == -1 )
{
*aMajor = version.ToInteger(&errorCode);
}
else
{
nsString majorStr;
version.Mid(majorStr, 0, dot);
*aMajor = majorStr.ToInteger(&errorCode);
int prev = dot+1;
dot = version.FindChar('.',PR_FALSE,prev);
if ( dot == -1 )
{
nsString minorStr;
version.Mid(minorStr, prev, version.Length() - prev);
*aMinor = minorStr.ToInteger(&errorCode);
}
else
{
nsString minorStr;
version.Mid(minorStr, prev, dot - prev);
*aMinor = minorStr.ToInteger(&errorCode);
prev = dot+1;
dot = version.FindChar('.',PR_FALSE,prev);
if ( dot == -1 )
{
nsString releaseStr;
version.Mid(releaseStr, prev, version.Length() - prev);
*aRelease = releaseStr.ToInteger(&errorCode);
}
else
{
nsString releaseStr;
version.Mid(releaseStr, prev, dot - prev);
*aRelease = releaseStr.ToInteger(&errorCode);
prev = dot+1;
if ( version.Length() > dot )
{
nsString buildStr;
version.Mid(buildStr, prev, version.Length() - prev);
*aBuild = buildStr.ToInteger(&errorCode);
}
}
}
}
}
nsresult
nsXPINotifierImpl::OpenRemoteDataSource(const char* aURL, PRBool blocking, nsIRDFDataSource** aResult)
{
static NS_DEFINE_CID(kRDFXMLDataSourceCID, NS_RDFXMLDATASOURCE_CID);
nsresult rv;
nsCOMPtr<nsIRDFRemoteDataSource> remote;
rv = nsComponentManager::CreateInstance(kRDFXMLDataSourceCID,
nsnull,
NS_GET_IID(nsIRDFRemoteDataSource),
getter_AddRefs(remote));
if (NS_FAILED(rv)) return rv;
rv = remote->Init(aURL);
if (NS_SUCCEEDED(rv))
{
if (! blocking)
{
nsCOMPtr<nsIRDFXMLSink> sink = do_QueryInterface(remote, &rv);
if (NS_FAILED(rv)) return rv;
rv = sink->AddXMLSinkObserver(this);
if (NS_FAILED(rv)) return rv;
}
rv = remote->Refresh(blocking);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIRDFDataSource> result = do_QueryInterface(remote, &rv);
*aResult = result;
NS_IF_ADDREF(*aResult);
return rv;
}
else
{
// we've already loaded this datasource. use cached copy
return mRDF->GetDataSource(aURL, aResult);
}
}
NS_IMETHODIMP
nsXPINotifierImpl::New(nsISupports* aOuter, REFNSIID aIID, void** aResult)
{
NS_PRECONDITION(aOuter == nsnull, "no aggregation");
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsXPINotifierImpl* result = new nsXPINotifierImpl();
if (! result)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(result); // stabilize
nsresult rv;
rv = result->Init();
if (NS_SUCCEEDED(rv)) {
rv = result->QueryInterface(aIID, aResult);
}
NS_RELEASE(result);
return rv;
}
NS_IMETHODIMP
nsXPINotifierImpl::OnBeginLoad(nsIRDFXMLSink *aSink)
{
return NS_OK;
}
NS_IMETHODIMP
nsXPINotifierImpl::OnInterrupt(nsIRDFXMLSink *aSink)
{
return NS_OK;
}
NS_IMETHODIMP
nsXPINotifierImpl::OnResume(nsIRDFXMLSink *aSink)
{
return NS_OK;
}
NS_IMETHODIMP
nsXPINotifierImpl::OnEndLoad(nsIRDFXMLSink *aSink)
{
nsresult rv;
(void) aSink->RemoveXMLSinkObserver(this);
nsCOMPtr<nsIRDFDataSource> distributorDataSource = do_QueryInterface(aSink, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIRDFContainer> distributorContainer;
nsCOMPtr <nsISimpleEnumerator> packageEnumerator;
PRBool moreElements;
rv = nsComponentManager::CreateInstance(kRDFContainerCID,
nsnull,
NS_GET_IID(nsIRDFContainer),
getter_AddRefs(distributorContainer));
if (NS_SUCCEEDED(rv))
{
rv = distributorContainer->Init(distributorDataSource, kXPI_NotifierPackages);
if (NS_SUCCEEDED(rv))
{
rv = distributorContainer->GetElements(getter_AddRefs(packageEnumerator));
if (NS_SUCCEEDED(rv))
{
packageEnumerator->HasMoreElements(&moreElements);
while (moreElements)
{
nsCOMPtr<nsISupports> i;
rv = packageEnumerator->GetNext(getter_AddRefs(i));
if (NS_FAILED(rv)) break;
nsCOMPtr<nsIRDFResource> aPackage(do_QueryInterface(i, &rv));
if (NS_FAILED(rv)) break;
// Get the version information
nsCOMPtr<nsIRDFNode> versionNode;
distributorDataSource->GetTarget(aPackage,
kXPI_NotifierPackage_Version,
PR_TRUE,
getter_AddRefs(versionNode));
nsCOMPtr<nsIRDFLiteral> version(do_QueryInterface(versionNode, &rv));
if (NS_FAILED(rv)) break;
// Get the regkey information
nsCOMPtr<nsIRDFNode> regkeyNode;
distributorDataSource->GetTarget(aPackage,
kXPI_NotifierPackage_RegKey,
PR_TRUE,
getter_AddRefs(regkeyNode));
nsCOMPtr<nsIRDFLiteral> regkey(do_QueryInterface(regkeyNode, &rv));
if (NS_FAILED(rv)) break;
// convert them into workable nsAutoStrings
PRUnichar* regkeyCString;
regkey->GetValue(&regkeyCString);
nsString regKeyString(regkeyCString);
PRUnichar* versionCString;
version->GetValue(&versionCString);
nsString versionString(versionCString);
nsAllocator::Free(versionCString);
nsAllocator::Free(regkeyCString);
// check to see if this software title should be "flashed"
if (IsNewerOrUninstalled(nsAutoCString(regKeyString), nsAutoCString(versionString)))
{
//assert into flash
nsCOMPtr<nsIRDFNode> urlNode;
distributorDataSource->GetTarget(kXPI_NotifierPackages,
kNC_URL,
PR_TRUE,
getter_AddRefs(urlNode));
nsCOMPtr<nsIRDFLiteral> url(do_QueryInterface(urlNode, &rv));
if (NS_FAILED(rv)) break;
nsCOMPtr<nsIRDFNode> titleNode;
distributorDataSource->GetTarget(kXPI_NotifierPackages,
kXPI_NotifierPackage_Title,
PR_TRUE,
getter_AddRefs(titleNode));
nsCOMPtr<nsIRDFLiteral> title(do_QueryInterface(titleNode, &rv));
if (NS_FAILED(rv)) break;
nsCOMPtr<nsIRDFDataSource> ds = do_QueryInterface(mNotifications);
ds->Assert(aPackage, kNC_Name, title, PR_TRUE);
ds->Assert(aPackage, kNC_URL, url, PR_TRUE);
ds->Assert(kNC_NotificationRoot, kNC_Child, aPackage, PR_TRUE);
break;
}
}
}
}
}
VR_Close();
return NS_OK;
}
NS_IMETHODIMP
nsXPINotifierImpl::OnError(nsIRDFXMLSink *aSink, nsresult aResult, const PRUnichar* aErrorMsg)
{
(void) aSink->RemoveXMLSinkObserver(this);
return NS_OK;
}
NS_IMETHODIMP
nsXPINotifierImpl::DisplayUpdateDialog(void)
{
nsresult rv;
nsCOMPtr <nsISimpleEnumerator> packages;
PRBool moreElements;
nsCOMPtr<nsIRDFDataSource> ds = do_QueryInterface(mNotifications, &rv);
if (NS_SUCCEEDED(rv))
{
rv = ds->GetAllResources(getter_AddRefs(packages));
if (NS_SUCCEEDED(rv))
{
packages->HasMoreElements(&moreElements);
while (moreElements)
{
nsCOMPtr<nsISupports> i;
rv = packages->GetNext(getter_AddRefs(i));
if (NS_FAILED(rv)) break;
nsCOMPtr<nsIRDFResource> aPackage(do_QueryInterface(i, &rv));
if (NS_FAILED(rv)) break;
// Get the version information
nsCOMPtr<nsIRDFNode> name;
ds->GetTarget(aPackage,
nsXPINotifierImpl::kNC_Name,
PR_TRUE,
getter_AddRefs(name));
nsCOMPtr<nsIRDFLiteral> nameLiteral = do_QueryInterface(name, &rv);
if (NS_FAILED(rv)) break;
}
}
}
return rv;
}

View File

@@ -0,0 +1,92 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code,
* released March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998-1999 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Doug Turner <dougt@netscape.com>
* Pierre Phaneuf <pp@ludusdesign.com>
*/
#include "nsCOMPtr.h"
#include "nsIRDFDataSource.h"
#include "nsRDFCID.h"
#include "nsIRDFXMLSink.h"
#include "nsIRDFResource.h"
#include "nsIRDFService.h"
#include "VerReg.h"
#include "nsIUpdateNotification.h"
#define NS_XPI_UPDATE_NOTIFIER_DATASOURCE_CID \
{ 0x69fdc800, 0x4050, 0x11d3, { 0xbe, 0x2f, 0x0, 0x10, 0x4b, 0xde, 0x60, 0x48 } }
#define NS_XPI_UPDATE_NOTIFIER_CID \
{ 0x68a24e36, 0x042d, 0x11d4, { 0xac, 0x85, 0x0, 0xc0, 0x4f, 0xa0, 0xd2, 0x6b } }
#define NS_XPI_UPDATE_NOTIFIER_PROGID "component://mozilla/xpinstall/notifier"
#define BASE_DATASOURCE_URL "chrome://xpinstall/content/SoftwareUpdates.rdf"
class nsXPINotifierImpl : public nsIUpdateNotification, public nsIRDFXMLSinkObserver
{
public:
static NS_IMETHODIMP New(nsISupports* aOuter, REFNSIID aIID, void** aResult);
NS_DECL_ISUPPORTS
NS_DECL_NSIRDFXMLSINKOBSERVER
NS_DECL_NSIUPDATENOTIFICATION
protected:
nsXPINotifierImpl();
virtual ~nsXPINotifierImpl();
nsresult NotificationEnabled(PRBool* aReturn);
nsresult Init();
nsresult OpenRemoteDataSource(const char* aURL, PRBool blocking, nsIRDFDataSource** aResult);
PRBool IsNewerOrUninstalled(const char* regKey, const char* versionString);
PRInt32 CompareVersions(VERSION *oldversion, VERSION *newVersion);
void StringToVersionNumbers(const nsString& version, int32 *aMajor, int32 *aMinor, int32 *aRelease, int32 *aBuild);
nsCOMPtr<nsISupports> mNotifications;
nsIRDFService* mRDF;
PRUint32 mPendingRefreshes;
static nsIRDFResource* kXPI_NotifierSources;
static nsIRDFResource* kXPI_NotifierPackages;
static nsIRDFResource* kXPI_NotifierPackage_Title;
static nsIRDFResource* kXPI_NotifierPackage_Version;
static nsIRDFResource* kXPI_NotifierPackage_Description;
static nsIRDFResource* kXPI_NotifierPackage_RegKey;
static nsIRDFResource* kNC_NotificationRoot;
static nsIRDFResource* kNC_Source;
static nsIRDFResource* kNC_Name;
static nsIRDFResource* kNC_URL;
static nsIRDFResource* kNC_Child;
};

View File

@@ -0,0 +1,169 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsWinProfile.h"
#include "nsWinProfileItem.h"
#include "nspr.h"
#include <windows.h>
/* Public Methods */
MOZ_DECL_CTOR_COUNTER(nsWinProfile);
nsWinProfile::nsWinProfile( nsInstall* suObj, const nsString& folder, const nsString& file )
{
MOZ_COUNT_CTOR(nsWinProfile);
mFilename = new nsString(folder);
if (mFilename)
{
if(mFilename->Last() != '\\')
{
mFilename->Append("\\");
}
mFilename->Append(file);
mInstallObject = suObj;
}
}
nsWinProfile::~nsWinProfile()
{
if (mFilename)
delete mFilename;
MOZ_COUNT_DTOR(nsWinProfile);
}
PRInt32
nsWinProfile::GetString(nsString section, nsString key, nsString* aReturn)
{
return NativeGetString(section, key, aReturn);
}
PRInt32
nsWinProfile::WriteString(nsString section, nsString key, nsString value, PRInt32* aReturn)
{
*aReturn = NS_OK;
nsWinProfileItem* wi = new nsWinProfileItem(this, section, key, value, aReturn);
if(wi == nsnull)
{
*aReturn = nsInstall::OUT_OF_MEMORY;
return NS_OK;
}
if(*aReturn != nsInstall::SUCCESS)
{
if(wi)
{
delete wi;
return NS_OK;
}
}
if (mInstallObject)
mInstallObject->ScheduleForInstall(wi);
return NS_OK;
}
nsString* nsWinProfile::GetFilename()
{
return mFilename;
}
nsInstall* nsWinProfile::InstallObject()
{
return mInstallObject;
}
PRInt32
nsWinProfile::FinalWriteString( nsString section, nsString key, nsString value )
{
/* do we need another security check here? */
return NativeWriteString(section, key, value);
}
/* Private Methods */
#define STRBUFLEN 255
PRInt32
nsWinProfile::NativeGetString(nsString section, nsString key, nsString* aReturn )
{
int numChars;
char valbuf[STRBUFLEN];
char* sectionCString;
char* keyCString;
char* filenameCString;
/* make sure conversions worked */
if(section.First() != '\0' && key.First() != '\0' && mFilename->First() != '\0')
{
sectionCString = section.ToNewCString();
keyCString = key.ToNewCString();
filenameCString = mFilename->ToNewCString();
numChars = GetPrivateProfileString(sectionCString, keyCString, "", valbuf, STRBUFLEN, filenameCString);
*aReturn = valbuf;
if (sectionCString) Recycle(sectionCString);
if (keyCString) Recycle(keyCString);
if (filenameCString) Recycle(filenameCString);
}
return numChars;
}
PRInt32
nsWinProfile::NativeWriteString( nsString section, nsString key, nsString value )
{
char* sectionCString;
char* keyCString;
char* valueCString;
char* filenameCString;
int success = 0;
/* make sure conversions worked */
if(section.First() != '\0' && key.First() != '\0' && mFilename->First() != '\0')
{
sectionCString = section.ToNewCString();
keyCString = key.ToNewCString();
valueCString = value.ToNewCString();
filenameCString = mFilename->ToNewCString();
success = WritePrivateProfileString( sectionCString, keyCString, valueCString, filenameCString );
if (sectionCString) Recycle(sectionCString);
if (keyCString) Recycle(keyCString);
if (valueCString) Recycle(valueCString);
if (filenameCString) Recycle(filenameCString);
}
return success;
}

View File

@@ -0,0 +1,76 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsWinProfile_h__
#define nsWinProfile_h__
#include "prtypes.h"
#include "nsInstall.h"
class nsWinProfile
{
public:
/* Public Fields */
/* Public Methods */
nsWinProfile( nsInstall* suObj, const nsString& folder, const nsString& file );
~nsWinProfile();
/**
* Schedules a write into a windows "ini" file. "Value" can be
* null to delete the value, but we don't support deleting an entire
* section via a null "key". The actual write takes place during
* SoftwareUpdate.FinalizeInstall();
*
* @return false for failure, true for success
*/
PRInt32 WriteString( nsString section, nsString key, nsString value, PRInt32* aReturn );
/**
* Reads a value from a windows "ini" file. We don't support using
* a null "key" to return a list of keys--you have to know what you want
*
* @return String value from INI, "" if not found, null if error
*/
PRInt32 GetString( nsString section, nsString key, nsString* aReturn );
nsString* GetFilename();
nsInstall* InstallObject();
PRInt32 FinalWriteString( nsString section, nsString key, nsString value );
private:
/* Private Fields */
nsString* mFilename;
nsInstall* mInstallObject;
/* Private Methods */
PRInt32 NativeWriteString( nsString section, nsString key, nsString value );
PRInt32 NativeGetString( nsString section, nsString key, nsString* aReturn );
};
#endif /* nsWinProfile_h__ */

View File

@@ -0,0 +1,127 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsWinProfileItem.h"
#include "nspr.h"
#include <windows.h>
/* Public Methods */
MOZ_DECL_CTOR_COUNTER(nsWinProfileItem);
nsWinProfileItem::nsWinProfileItem(nsWinProfile* profileObj,
nsString sectionName,
nsString keyName,
nsString val,
PRInt32 *aReturn) : nsInstallObject(profileObj->InstallObject())
{
MOZ_COUNT_CTOR(nsWinProfileItem);
mProfile = profileObj;
mSection = new nsString(sectionName);
mKey = new nsString(keyName);
mValue = new nsString(val);
*aReturn = nsInstall::SUCCESS;
if((mSection == nsnull) ||
(mKey == nsnull) ||
(mValue == nsnull))
{
*aReturn = nsInstall::OUT_OF_MEMORY;
}
}
nsWinProfileItem::~nsWinProfileItem()
{
if (mSection) delete mSection;
if (mKey) delete mKey;
if (mValue) delete mValue;
MOZ_COUNT_DTOR(nsWinProfileItem);
}
PRInt32 nsWinProfileItem::Complete()
{
if (mProfile)
mProfile->FinalWriteString(*mSection, *mKey, *mValue);
return NS_OK;
}
char* nsWinProfileItem::toString()
{
char* resultCString;
nsString* filename = new nsString(*mProfile->GetFilename());
nsString* result = new nsString("Write ");
if (filename == nsnull || result == nsnull)
return nsnull;
result->Append(*filename);
result->Append(": [");
result->Append(*mSection);
result->Append("] ");
result->Append(*mKey);
result->Append("=");
result->Append(*mValue);
resultCString = result->ToNewCString();
if (result) delete result;
if (filename) delete filename;
return resultCString;
}
void nsWinProfileItem::Abort()
{
}
PRInt32 nsWinProfileItem::Prepare()
{
return nsnull;
}
/* CanUninstall
* WinProfileItem() does not install any files which can be uninstalled,
* hence this function returns false.
*/
PRBool
nsWinProfileItem::CanUninstall()
{
return PR_FALSE;
}
/* RegisterPackageNode
* WinProfileItem() installs files which need to be registered,
* hence this function returns true.
*/
PRBool
nsWinProfileItem::RegisterPackageNode()
{
return PR_TRUE;
}

View File

@@ -0,0 +1,81 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsWinProfileItem_h__
#define nsWinProfileItem_h__
#include "prtypes.h"
#include "nsSoftwareUpdate.h"
#include "nsInstallObject.h"
#include "nsWinProfile.h"
PR_BEGIN_EXTERN_C
class nsWinProfileItem : public nsInstallObject {
public:
/* Public Fields */
/* Public Methods */
nsWinProfileItem(nsWinProfile* profileObj,
nsString sectionName,
nsString keyName,
nsString val,
PRInt32 *aReturn);
virtual ~nsWinProfileItem();
/**
* Completes the install:
* - writes the data into the .INI file
*/
PRInt32 Complete();
char* toString();
// no need for special clean-up
void Abort();
// no need for set-up
PRInt32 Prepare();
/* should these be protected? */
PRBool CanUninstall();
PRBool RegisterPackageNode();
private:
/* Private Fields */
nsWinProfile* mProfile; // initiating profile object
nsString* mSection; // Name of section
nsString* mKey; // Name of key
nsString* mValue; // data to write
/* Private Methods */
};
PR_END_EXTERN_C
#endif /* nsWinProfileItem_h__ */

View File

@@ -0,0 +1,536 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsWinReg.h"
#include "nsWinRegItem.h"
#include <windows.h> /* is this needed? */
/* Public Methods */
MOZ_DECL_CTOR_COUNTER(nsWinReg);
nsWinReg::nsWinReg(nsInstall* suObj)
{
MOZ_COUNT_CTOR(nsWinReg);
mInstallObject = suObj;
mRootKey = (PRInt32)HKEY_CLASSES_ROOT;
}
nsWinReg::~nsWinReg()
{
MOZ_COUNT_CTOR(nsWinReg);
}
PRInt32
nsWinReg::SetRootKey(PRInt32 key)
{
mRootKey = key;
return NS_OK;
}
PRInt32
nsWinReg::CreateKey(const nsString& subkey, const nsString& classname, PRInt32* aReturn)
{
nsWinRegItem* wi = new nsWinRegItem(this, mRootKey, NS_WIN_REG_CREATE, subkey, classname, "null", aReturn);
if(wi == nsnull)
{
*aReturn = nsInstall::OUT_OF_MEMORY;
return NS_OK;
}
if(*aReturn != nsInstall::SUCCESS)
{
if(wi)
{
delete wi;
return NS_OK;
}
}
if(mInstallObject)
mInstallObject->ScheduleForInstall(wi);
return 0;
}
PRInt32
nsWinReg::DeleteKey(const nsString& subkey, PRInt32* aReturn)
{
nsWinRegItem* wi = new nsWinRegItem(this, mRootKey, NS_WIN_REG_DELETE, subkey, "null", "null", aReturn);
if(wi == nsnull)
{
*aReturn = nsInstall::OUT_OF_MEMORY;
return NS_OK;
}
if(*aReturn != nsInstall::SUCCESS)
{
if(wi)
{
delete wi;
return NS_OK;
}
}
if(mInstallObject)
mInstallObject->ScheduleForInstall(wi);
return 0;
}
PRInt32
nsWinReg::DeleteValue(const nsString& subkey, const nsString& valname, PRInt32* aReturn)
{
nsWinRegItem* wi = new nsWinRegItem(this, mRootKey, NS_WIN_REG_DELETE_VAL, subkey, valname, "null", aReturn);
if(wi == nsnull)
{
*aReturn = nsInstall::OUT_OF_MEMORY;
return NS_OK;
}
if(*aReturn != nsInstall::SUCCESS)
{
if(wi)
{
delete wi;
return NS_OK;
}
}
if(mInstallObject)
mInstallObject->ScheduleForInstall(wi);
return 0;
}
PRInt32
nsWinReg::SetValueString(const nsString& subkey, const nsString& valname, const nsString& value, PRInt32* aReturn)
{
nsWinRegItem* wi = new nsWinRegItem(this, mRootKey, NS_WIN_REG_SET_VAL_STRING, subkey, valname, value, aReturn);
if(wi == nsnull)
{
*aReturn = nsInstall::OUT_OF_MEMORY;
return NS_OK;
}
if(*aReturn != nsInstall::SUCCESS)
{
if(wi)
{
delete wi;
return NS_OK;
}
}
if(mInstallObject)
mInstallObject->ScheduleForInstall(wi);
return 0;
}
PRInt32
nsWinReg::GetValueString(const nsString& subkey, const nsString& valname, nsString* aReturn)
{
NativeGetValueString(subkey, valname, aReturn);
return NS_OK;
}
PRInt32
nsWinReg::SetValueNumber(const nsString& subkey, const nsString& valname, PRInt32 value, PRInt32* aReturn)
{
nsWinRegItem* wi = new nsWinRegItem(this, mRootKey, NS_WIN_REG_SET_VAL_NUMBER, subkey, valname, value, aReturn);
if(wi == nsnull)
{
*aReturn = nsInstall::OUT_OF_MEMORY;
return NS_OK;
}
if(*aReturn != nsInstall::SUCCESS)
{
if(wi)
{
delete wi;
return NS_OK;
}
}
if(mInstallObject)
mInstallObject->ScheduleForInstall(wi);
return 0;
}
PRInt32
nsWinReg::GetValueNumber(const nsString& subkey, const nsString& valname, PRInt32* aReturn)
{
NativeGetValueNumber(subkey, valname, aReturn);
return NS_OK;
}
PRInt32
nsWinReg::SetValue(const nsString& subkey, const nsString& valname, nsWinRegValue* value, PRInt32* aReturn)
{
// fix: need to figure out what to do with nsWinRegValue class.
//
// nsWinRegItem* wi = new nsWinRegItem(this, mRootKey, NS_WIN_REG_SET_VAL, subkey, valname, (nsWinRegValue*)value, aReturn);
//
// if(wi == nsnull)
// {
// return NS_OK;
// }
// mInstallObject->ScheduleForInstall(wi);
return 0;
}
PRInt32
nsWinReg::GetValue(const nsString& subkey, const nsString& valname, nsWinRegValue** aReturn)
{
// fix:
return NS_OK;
}
nsInstall* nsWinReg::InstallObject()
{
return mInstallObject;
}
PRInt32
nsWinReg::FinalCreateKey(PRInt32 root, const nsString& subkey, const nsString& classname, PRInt32* aReturn)
{
SetRootKey(root);
*aReturn = NativeCreateKey(subkey, classname);
return NS_OK;
}
PRInt32
nsWinReg::FinalDeleteKey(PRInt32 root, const nsString& subkey, PRInt32* aReturn)
{
SetRootKey(root);
*aReturn = NativeDeleteKey(subkey);
return NS_OK;
}
PRInt32
nsWinReg::FinalDeleteValue(PRInt32 root, const nsString& subkey, const nsString& valname, PRInt32* aReturn)
{
SetRootKey(root);
*aReturn = NativeDeleteValue(subkey, valname);
return NS_OK;
}
PRInt32
nsWinReg::FinalSetValueString(PRInt32 root, const nsString& subkey, const nsString& valname, const nsString& value, PRInt32* aReturn)
{
SetRootKey(root);
*aReturn = NativeSetValueString(subkey, valname, value);
return NS_OK;
}
PRInt32
nsWinReg::FinalSetValueNumber(PRInt32 root, const nsString& subkey, const nsString& valname, PRInt32 value, PRInt32* aReturn)
{
SetRootKey(root);
*aReturn = NativeSetValueNumber(subkey, valname, value);
return NS_OK;
}
PRInt32
nsWinReg::FinalSetValue(PRInt32 root, const nsString& subkey, const nsString& valname, nsWinRegValue* value, PRInt32* aReturn)
{
SetRootKey(root);
*aReturn = NativeSetValue(subkey, valname, value);
return NS_OK;
}
/* Private Methods */
PRInt32
nsWinReg::NativeCreateKey(const nsString& subkey, const nsString& classname)
{
HKEY root, newkey;
LONG result;
ULONG disposition;
char* subkeyCString = subkey.ToNewCString();
char* classnameCString = classname.ToNewCString();
#ifdef WIN32
root = (HKEY)mRootKey;
result = RegCreateKeyEx(root, subkeyCString, 0, classnameCString, REG_OPTION_NON_VOLATILE, KEY_WRITE, nsnull, &newkey, &disposition);
if(ERROR_SUCCESS == result)
{
RegCloseKey( newkey );
}
#endif
if (subkeyCString) Recycle(subkeyCString);
if (classnameCString) Recycle(classnameCString);
return result;
}
PRInt32
nsWinReg::NativeDeleteKey(const nsString& subkey)
{
HKEY root;
LONG result;
char* subkeyCString = subkey.ToNewCString();
#ifdef WIN32
root = (HKEY) mRootKey;
result = RegDeleteKey( root, subkeyCString );
#endif
if (subkeyCString) Recycle(subkeyCString);
return result;
}
PRInt32
nsWinReg::NativeDeleteValue(const nsString& subkey, const nsString& valname)
{
#if defined (WIN32) || defined (XP_OS2)
HKEY root, newkey;
LONG result;
char* subkeyCString = subkey.ToNewCString();
char* valnameCString = valname.ToNewCString();
root = (HKEY) mRootKey;
result = RegOpenKeyEx( root, subkeyCString, 0, KEY_WRITE, &newkey);
if ( ERROR_SUCCESS == result )
{
result = RegDeleteValue( newkey, valnameCString );
RegCloseKey( newkey );
}
if (subkeyCString) Recycle(subkeyCString);
if (valnameCString) Recycle(valnameCString);
return result;
#else
return ERROR_INVALID_PARAMETER;
#endif
}
PRInt32
nsWinReg::NativeSetValueString(const nsString& subkey, const nsString& valname, const nsString& value)
{
HKEY root;
HKEY newkey;
LONG result;
DWORD length;
char* subkeyCString = subkey.ToNewCString();
char* valnameCString = valname.ToNewCString();
char* valueCString = value.ToNewCString();
length = value.Length();
root = (HKEY) mRootKey;
result = RegOpenKeyEx( root, subkeyCString, 0, KEY_WRITE, &newkey);
if(ERROR_SUCCESS == result)
{
result = RegSetValueEx( newkey, valnameCString, 0, REG_SZ, (unsigned char*)valueCString, length );
RegCloseKey( newkey );
}
if (subkeyCString) Recycle(subkeyCString);
if (valnameCString) Recycle(valnameCString);
if (valueCString) Recycle(valueCString);
return result;
}
#define STRBUFLEN 255
void
nsWinReg::NativeGetValueString(const nsString& subkey, const nsString& valname, nsString* aReturn)
{
unsigned char valbuf[_MAXKEYVALUE_];
HKEY root;
HKEY newkey;
LONG result;
DWORD type = REG_SZ;
DWORD length = _MAXKEYVALUE_;
char* subkeyCString = subkey.ToNewCString();
char* valnameCString = valname.ToNewCString();
root = (HKEY) mRootKey;
result = RegOpenKeyEx( root, subkeyCString, 0, KEY_READ, &newkey );
if ( ERROR_SUCCESS == result ) {
result = RegQueryValueEx( newkey, valnameCString, nsnull, &type, valbuf, &length );
RegCloseKey( newkey );
}
if(ERROR_SUCCESS == result && type == REG_SZ)
{
*aReturn = (char*)valbuf;
}
if (subkeyCString) Recycle(subkeyCString);
if (valnameCString) Recycle(valnameCString);
}
PRInt32
nsWinReg::NativeSetValueNumber(const nsString& subkey, const nsString& valname, PRInt32 value)
{
HKEY root;
HKEY newkey;
LONG result;
char* subkeyCString = subkey.ToNewCString();
char* valnameCString = valname.ToNewCString();
root = (HKEY) mRootKey;
result = RegOpenKeyEx( root, subkeyCString, 0, KEY_WRITE, &newkey);
if(ERROR_SUCCESS == result)
{
result = RegSetValueEx( newkey, valnameCString, 0, REG_DWORD, (LPBYTE)&value, sizeof(PRInt32));
RegCloseKey( newkey );
}
if (subkeyCString) Recycle(subkeyCString);
if (valnameCString) Recycle(valnameCString);
return result;
}
void
nsWinReg::NativeGetValueNumber(const nsString& subkey, const nsString& valname, PRInt32* aReturn)
{
PRInt32 valbuf;
PRInt32 valbuflen;
HKEY root;
HKEY newkey;
LONG result;
DWORD type = REG_DWORD;
DWORD length = _MAXKEYVALUE_;
char* subkeyCString = subkey.ToNewCString();
char* valnameCString = valname.ToNewCString();
valbuflen = sizeof(PRInt32);
root = (HKEY) mRootKey;
result = RegOpenKeyEx( root, subkeyCString, 0, KEY_READ, &newkey );
if ( ERROR_SUCCESS == result ) {
result = RegQueryValueEx( newkey, valnameCString, nsnull, &type, (LPBYTE)&valbuf, (LPDWORD)&valbuflen);
RegCloseKey( newkey );
}
if(ERROR_SUCCESS == result && type == REG_DWORD)
{
*aReturn = valbuf;
}
if (subkeyCString) Recycle(subkeyCString);
if (valnameCString) Recycle(valnameCString);
}
PRInt32
nsWinReg::NativeSetValue(const nsString& subkey, const nsString& valname, nsWinRegValue* value)
{
#if defined (WIN32) || defined (XP_OS2)
HKEY root;
HKEY newkey;
LONG result;
DWORD length;
DWORD type;
unsigned char* data;
char* subkeyCString = subkey.ToNewCString();
char* valnameCString = valname.ToNewCString();
root = (HKEY) mRootKey;
result = RegOpenKeyEx( root, subkeyCString, 0, KEY_WRITE, &newkey );
if(ERROR_SUCCESS == result)
{
type = (DWORD)value->type;
data = (unsigned char*)value->data;
length = (DWORD)value->data_length;
result = RegSetValueEx( newkey, valnameCString, 0, type, data, length);
RegCloseKey( newkey );
}
if (subkeyCString) Recycle(subkeyCString);
if (valnameCString) Recycle(valnameCString);
return result;
#else
return ERROR_INVALID_PARAMETER;
#endif
}
nsWinRegValue*
nsWinReg::NativeGetValue(const nsString& subkey, const nsString& valname)
{
#if defined (WIN32) || defined (XP_OS2)
unsigned char valbuf[STRBUFLEN];
HKEY root;
HKEY newkey;
LONG result;
DWORD length=STRBUFLEN;
DWORD type;
nsString* data;
nsWinRegValue* value = nsnull;
char* subkeyCString = subkey.ToNewCString();
char* valnameCString = valname.ToNewCString();
root = (HKEY) mRootKey;
result = RegOpenKeyEx( root, subkeyCString, 0, KEY_READ, &newkey );
if(ERROR_SUCCESS == result)
{
result = RegQueryValueEx( newkey, valnameCString, nsnull, &type, valbuf, &length );
if ( ERROR_SUCCESS == result ) {
data = new nsString((char*)valbuf);
length = data->Length();
value = new nsWinRegValue(type, (void*)data, length);
}
RegCloseKey( newkey );
}
if (subkeyCString) Recycle(subkeyCString);
if (valnameCString) Recycle(valnameCString);
return value;
#else
return nsnull;
#endif
}

View File

@@ -0,0 +1,108 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef __NS_WINREG_H__
#define __NS_WINREG_H__
#include "nsWinRegEnums.h"
#include "nsWinRegValue.h"
#include "nscore.h"
#include "nsISupports.h"
#include "jsapi.h"
#include "plevent.h"
#include "nsString.h"
#include "nsFileSpec.h"
#include "nsHashtable.h"
#include "nsSoftwareUpdate.h"
#include "nsInstallObject.h"
#include "nsInstallVersion.h"
#include "nsInstall.h"
#define _MAXKEYVALUE_ 8196
class nsWinReg
{
public:
enum
{
HKEY_CLASSES_ROOT = 0x80000000,
HKEY_CURRENT_USER = 0x80000001,
HKEY_LOCAL_MACHINE = 0x80000002,
HKEY_USERS = 0x80000003
};
/* Public Fields */
/* Public Methods */
nsWinReg(nsInstall* suObj);
~nsWinReg();
PRInt32 SetRootKey(PRInt32 key);
PRInt32 CreateKey(const nsString& subkey, const nsString& classname, PRInt32* aReturn);
PRInt32 DeleteKey(const nsString& subkey, PRInt32* aReturn);
PRInt32 DeleteValue(const nsString& subkey, const nsString& valname, PRInt32* aReturn);
PRInt32 SetValueString(const nsString& subkey, const nsString& valname, const nsString& value, PRInt32* aReturn);
PRInt32 GetValueString(const nsString& subkey, const nsString& valname, nsString* aReturn);
PRInt32 SetValueNumber(const nsString& subkey, const nsString& valname, PRInt32 value, PRInt32* aReturn);
PRInt32 GetValueNumber(const nsString& subkey, const nsString& valname, PRInt32* aReturn);
PRInt32 SetValue(const nsString& subkey, const nsString& valname, nsWinRegValue* value, PRInt32* aReturn);
PRInt32 GetValue(const nsString& subkey, const nsString& valname, nsWinRegValue** aReturn);
nsInstall* InstallObject(void);
PRInt32 FinalCreateKey(PRInt32 root, const nsString& subkey, const nsString& classname, PRInt32* aReturn);
PRInt32 FinalDeleteKey(PRInt32 root, const nsString& subkey, PRInt32* aReturn);
PRInt32 FinalDeleteValue(PRInt32 root, const nsString& subkey, const nsString& valname, PRInt32* aReturn);
PRInt32 FinalSetValueString(PRInt32 root, const nsString& subkey, const nsString& valname, const nsString& value, PRInt32* aReturn);
PRInt32 FinalSetValueNumber(PRInt32 root, const nsString& subkey, const nsString& valname, PRInt32 value, PRInt32* aReturn);
PRInt32 FinalSetValue(PRInt32 root, const nsString& subkey, const nsString& valname, nsWinRegValue* value, PRInt32* aReturn);
private:
/* Private Fields */
PRInt32 mRootKey;
nsInstall* mInstallObject;
/* Private Methods */
PRInt32 NativeCreateKey(const nsString& subkey, const nsString& classname);
PRInt32 NativeDeleteKey(const nsString& subkey);
PRInt32 NativeDeleteValue(const nsString& subkey, const nsString& valname);
PRInt32 NativeSetValueString(const nsString& subkey, const nsString& valname, const nsString& value);
void NativeGetValueString(const nsString& subkey, const nsString& valname, nsString* aReturn);
PRInt32 NativeSetValueNumber(const nsString& subkey, const nsString& valname, PRInt32 value);
void NativeGetValueNumber(const nsString& subkey, const nsString& valname, PRInt32* aReturn);
PRInt32 NativeSetValue(const nsString& subkey, const nsString& valname, nsWinRegValue* value);
nsWinRegValue* NativeGetValue(const nsString& subkey, const nsString& valname);
};
#endif /* __NS_WINREG_H__ */

View File

@@ -0,0 +1,51 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsWinRegEnums_h__
#define nsWinRegEnums_h__
typedef enum nsWinRegEnum {
NS_WIN_REG_CREATE = 1,
NS_WIN_REG_DELETE = 2,
NS_WIN_REG_DELETE_VAL = 3,
NS_WIN_REG_SET_VAL_STRING = 4,
NS_WIN_REG_SET_VAL_NUMBER = 5,
NS_WIN_REG_SET_VAL = 6
} nsWinRegEnum;
typedef enum nsWinRegValueEnum {
NS_WIN_REG_SZ = 1,
NS_WIN_REG_EXPAND_SZ = 2,
NS_WIN_REG_BINARY = 3,
NS_WIN_REG_DWORD = 4,
NS_WIN_REG_DWORD_LITTLE_ENDIAN = 4,
NS_WIN_REG_DWORD_BIG_ENDIAN = 5,
NS_WIN_REG_LINK = 6,
NS_WIN_REG_MULTI_SZ = 7,
NS_WIN_REG_RESOURCE_LIST = 8,
NS_WIN_REG_FULL_RESOURCE_DESCRIPTOR = 9,
NS_WIN_REG_RESOURCE_REQUIREMENTS_LIST = 10
} nsWinRegValueEnum;
#endif /* nsWinRegEnums_h__ */

View File

@@ -0,0 +1,312 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsWinRegItem.h"
#include "nspr.h"
#ifdef WIN32
#include <windows.h> /* is this needed? */
#endif
/* Public Methods */
MOZ_DECL_CTOR_COUNTER(nsWinRegItem);
nsWinRegItem::nsWinRegItem(nsWinReg* regObj, PRInt32 root, PRInt32 action, const nsString& sub, const nsString& valname, const nsString& val, PRInt32 *aReturn)
: nsInstallObject(regObj->InstallObject())
{
MOZ_COUNT_CTOR(nsWinRegItem);
mReg = regObj;
mCommand = action;
mRootkey = root;
*aReturn = nsInstall::SUCCESS;
/* I'm assuming we need to copy these */
mSubkey = new nsString(sub);
mName = new nsString(valname);
mValue = new nsString(val);
if((mSubkey == nsnull) ||
(mName == nsnull) ||
(mValue == nsnull))
{
*aReturn = nsInstall::OUT_OF_MEMORY;
}
}
nsWinRegItem::nsWinRegItem(nsWinReg* regObj, PRInt32 root, PRInt32 action, const nsString& sub, const nsString& valname, PRInt32 val, PRInt32 *aReturn)
: nsInstallObject(regObj->InstallObject())
{
MOZ_COUNT_CTOR(nsWinRegItem);
mReg = regObj;
mCommand = action;
mRootkey = root;
*aReturn = nsInstall::SUCCESS;
/* I'm assuming we need to copy these */
mSubkey = new nsString(sub);
mName = new nsString(valname);
mValue = new PRInt32(val);
if((mSubkey == nsnull) ||
(mName == nsnull) ||
(mValue == nsnull))
{
*aReturn = nsInstall::OUT_OF_MEMORY;
}
}
nsWinRegItem::~nsWinRegItem()
{
if (mSubkey) delete mSubkey;
if (mName) delete mName;
if (mValue) delete mValue;
MOZ_COUNT_DTOR(nsWinRegItem);
}
PRInt32 nsWinRegItem::Complete()
{
PRInt32 aReturn = NS_OK;
if (mReg == nsnull)
return nsInstall::OUT_OF_MEMORY;
switch (mCommand)
{
case NS_WIN_REG_CREATE:
mReg->FinalCreateKey(mRootkey, *mSubkey, *mName, &aReturn);
break;
case NS_WIN_REG_DELETE:
mReg->FinalDeleteKey(mRootkey, *mSubkey, &aReturn);
break;
case NS_WIN_REG_DELETE_VAL:
mReg->FinalDeleteValue(mRootkey, *mSubkey, *mName, &aReturn);
break;
case NS_WIN_REG_SET_VAL_STRING:
mReg->FinalSetValueString(mRootkey, *mSubkey, *mName, *(nsString*)mValue, &aReturn);
break;
case NS_WIN_REG_SET_VAL_NUMBER:
mReg->FinalSetValueNumber(mRootkey, *mSubkey, *mName, *(PRInt32*)mValue, &aReturn);
break;
case NS_WIN_REG_SET_VAL:
mReg->FinalSetValue(mRootkey, *mSubkey, *mName, (nsWinRegValue*)mValue, &aReturn);
break;
}
return aReturn;
}
#define kCRK "Create Registry Key: "
#define kDRK "Delete Registry Key: "
#define kDRV "Delete Registry Value: "
#define kSRVS "Store Registry Value String: "
#define kSRVN "Store Registry Value Number: "
#define kSRV "Store Registry Value: "
#define kUNK "Unknown "
char* nsWinRegItem::toString()
{
nsString* keyString = nsnull;
nsString* result = nsnull;
char* resultCString = nsnull;
switch(mCommand)
{
case NS_WIN_REG_CREATE:
keyString = keystr(mRootkey, mSubkey, nsnull);
result = new nsString(kCRK);
break;
case NS_WIN_REG_DELETE:
keyString = keystr(mRootkey, mSubkey, nsnull);
result = new nsString(kDRK);
break;
case NS_WIN_REG_DELETE_VAL:
keyString = keystr(mRootkey, mSubkey, mName);
result = new nsString(kDRV);
break;
case NS_WIN_REG_SET_VAL_STRING:
keyString = keystr(mRootkey, mSubkey, mName);
result = new nsString(kSRVS);
break;
case NS_WIN_REG_SET_VAL_NUMBER:
keyString = keystr(mRootkey, mSubkey, mName);
result = new nsString(kSRVN);
break;
case NS_WIN_REG_SET_VAL:
keyString = keystr(mRootkey, mSubkey, mName);
result = new nsString(kSRV);
break;
default:
keyString = keystr(mRootkey, mSubkey, mName);
result = new nsString(kUNK);
break;
}
if (result)
{
result->Append(*keyString);
resultCString = result->ToNewCString();
}
if (keyString) delete keyString;
if (result) delete result;
return resultCString;
}
PRInt32 nsWinRegItem::Prepare()
{
return nsnull;
}
void nsWinRegItem::Abort()
{
}
/* Private Methods */
nsString* nsWinRegItem::keystr(PRInt32 root, nsString* mSubkey, nsString* mName)
{
nsString rootstr;
nsString* finalstr = nsnull;
char* istr = nsnull;
switch(root)
{
case (int)(HKEY_CLASSES_ROOT) :
rootstr = "HKEY_CLASSES_ROOT\\";
break;
case (int)(HKEY_CURRENT_USER) :
rootstr = "HKEY_CURRENT_USER\\";
break;
case (int)(HKEY_LOCAL_MACHINE) :
rootstr = "HKEY_LOCAL_MACHINE\\";
break;
case (int)(HKEY_USERS) :
rootstr = "HKEY_USERS\\";
break;
default:
istr = itoa(root);
if (istr)
{
rootstr = "#";
rootstr.Append(istr);
rootstr.Append("\\");
PR_DELETE(istr);
}
break;
}
finalstr = new nsString(rootstr);
if(finalstr != nsnull)
{
finalstr->Append(*mSubkey);
finalstr->Append(" [");
if(mName != nsnull)
finalstr->Append(*mName);
finalstr->Append("]");
}
return finalstr;
}
char* nsWinRegItem::itoa(PRInt32 n)
{
char* s;
int i, sign;
if((sign = n) < 0)
n = -n;
i = 0;
s = (char*)PR_CALLOC(sizeof(char));
do
{
s = (char*)PR_REALLOC(s, (i+1)*sizeof(char));
s[i++] = n%10 + '0';
s[i] = '\0';
} while ((n/=10) > 0);
if(sign < 0)
{
s = (char*)PR_REALLOC(s, (i+1)*sizeof(char));
s[i++] = '-';
}
s[i] = '\0';
reverseString(s);
return s;
}
void nsWinRegItem::reverseString(char* s)
{
int c, i, j;
for(i=0, j=strlen(s)-1; i<j; i++, j--)
{
c = s[i];
s[i] = s[j];
s[j] = c;
}
}
/* CanUninstall
* WinRegItem() does not install any files which can be uninstalled,
* hence this function returns false.
*/
PRBool
nsWinRegItem:: CanUninstall()
{
return PR_FALSE;
}
/* RegisterPackageNode
* WinRegItem() installs files which need to be registered,
* hence this function returns true.
*/
PRBool
nsWinRegItem:: RegisterPackageNode()
{
return PR_TRUE;
}

View File

@@ -0,0 +1,92 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsWinRegItem_h__
#define nsWinRegItem_h__
#include "prtypes.h"
#include "nsSoftwareUpdate.h"
#include "nsInstallObject.h"
#include "nsWinReg.h"
PR_BEGIN_EXTERN_C
class nsWinRegItem : public nsInstallObject {
public:
/* Public Fields */
/* Public Methods */
nsWinRegItem(nsWinReg* regObj,
PRInt32 root,
PRInt32 action,
const nsString& sub,
const nsString& valname,
const nsString& val,
PRInt32* aReturn);
nsWinRegItem(nsWinReg* regObj,
PRInt32 root,
PRInt32 action,
const nsString& sub,
const nsString& valname,
PRInt32 val,
PRInt32* aReturn);
virtual ~nsWinRegItem();
PRInt32 Prepare(void);
PRInt32 Complete();
char* toString();
void Abort();
/* should these be protected? */
PRBool CanUninstall();
PRBool RegisterPackageNode();
private:
/* Private Fields */
nsWinReg* mReg; // initiating WinReg object
PRInt32 mRootkey;
PRInt32 mCommand;
nsString* mSubkey; // Name of section
nsString* mName; // Name of key
void* mValue; // data to write
/* Private Methods */
nsString* keystr(PRInt32 root, nsString* subkey, nsString* name);
char* itoa(PRInt32 n);
void reverseString(char* s);
};
PR_END_EXTERN_C
#endif /* nsWinRegItem_h__ */

View File

@@ -0,0 +1,28 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsWinRegValue.h"
PR_BEGIN_EXTERN_C
PR_END_EXTERN_C

View File

@@ -0,0 +1,60 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsWinRegValue_h__
#define nsWinRegValue_h__
#include "prtypes.h"
PR_BEGIN_EXTERN_C
struct nsWinRegValue {
public:
/* Public Fields */
PRInt32 type;
void* data;
PRInt32 data_length;
/* Public Methods */
nsWinRegValue(PRInt32 datatype, void* regdata, PRInt32 len)
{
type = datatype;
data = regdata;
data_length = len;
}
/* should we copy the regdata? */
private:
/* Private Fields */
/* Private Methods */
};
PR_END_EXTERN_C
#endif /* nsWinRegValue_h__ */

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