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
170 changed files with 41540 additions and 9122 deletions

View File

@@ -1,80 +0,0 @@
#!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.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):
# Simon Fraser <sfraser@netscape.com>
#
require 5.004;
use strict;
use Cwd;
use Moz::BuildUtils;
use Moz::BuildCore;
#-------------------------------------------------------------
# Where have the build options gone?
#
# The various build flags have been centralized into one place.
# The master list of options is in MozBuildFlags.txt. However,
# you should never need to edit that file, or this one.
#
# To customize what gets built, or where to start the build,
# edit the $prefs_file_name file in
# System Folder:Preferences:Mozilla build prefs:
# Documentation is provided in that file.
#-------------------------------------------------------------
my($prefs_file_name) = "Mozilla opt build prefs";
my($config_header_file_name) = ":mozilla:config:mac:DefinesOptions.h";
#-------------------------------------------------------------
# hashes to hold build options
#-------------------------------------------------------------
my(%build);
my(%options);
my(%filepaths);
my(%optiondefines);
# Hash of input files for this build. Eventually, there will be
# input files for manifests, and projects too.
my(%inputfiles) = (
"buildflags", "MozillaBuildFlags.txt",
"checkoutdata", "MozillaCheckoutList.txt",
"buildprogress", "¥ Mozilla opt progress",
"buildmodule", "MozillaBuildList.pm",
"checkouttime", "Mozilla last checkout"
);
#-------------------------------------------------------------
# end build hashes
#-------------------------------------------------------------
# set the build root directory, which is the the dir above mozilla
SetupBuildRootDir(":mozilla:build:mac:build_scripts");
# Set up all the flags on $main::, like DEBUG, CARBON etc.
# Override the defaults using the preferences files.
SetupDefaultBuildOptions(0, ":mozilla:dist:viewer:", $config_header_file_name);
my($do_checkout) = 0;
my($do_build) = 1;
RunBuild($do_checkout, $do_build, \%inputfiles, $prefs_file_name);

View File

@@ -1,80 +0,0 @@
#!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.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):
# Simon Fraser <sfraser@netscape.com>
#
require 5.004;
use strict;
use Cwd;
use Moz::BuildUtils;
use Moz::BuildCore;
#-------------------------------------------------------------
# Where have the build options gone?
#
# The various build flags have been centralized into one place.
# The master list of options is in MozBuildFlags.txt. However,
# you should never need to edit that file, or this one.
#
# To customize what gets built, or where to start the build,
# edit the $prefs_file_name file in
# System Folder:Preferences:Mozilla build prefs:
# Documentation is provided in that file.
#-------------------------------------------------------------
my($prefs_file_name) = "Mozilla debug build prefs";
my($config_header_file_name) = ":mozilla:config:mac:DefinesOptionsDebug.h";
#-------------------------------------------------------------
# hashes to hold build options
#-------------------------------------------------------------
my(%build);
my(%options);
my(%filepaths);
my(%optiondefines);
# Hash of input files for this build. Eventually, there will be
# input files for manifests, and projects too.
my(%inputfiles) = (
"buildflags", "MozillaBuildFlags.txt",
"checkoutdata", "MozillaCheckoutList.txt",
"buildprogress", "¥ Mozilla debug progress",
"buildmodule", "MozillaBuildList.pm",
"checkouttime", "Mozilla last checkout"
);
#-------------------------------------------------------------
# end build hashes
#-------------------------------------------------------------
# set the build root directory, which is the the dir above mozilla
SetupBuildRootDir(":mozilla:build:mac:build_scripts");
# Set up all the flags on $main::, like DEBUG, CARBON etc.
# Override the defaults using the preferences files.
SetupDefaultBuildOptions(1, ":mozilla:dist:viewer_debug:", $config_header_file_name);
my($do_pull) = 0; # overridden by flags and prefs
my($do_build) = 1;
RunBuild($do_pull, $do_build, \%inputfiles, $prefs_file_name);

View File

@@ -1,595 +0,0 @@
#!perl -w
package Moz::BuildCore;
require 5.004;
require Exporter;
use strict;
use vars qw( @ISA @EXPORT );
# perl includes
use Cwd;
use POSIX;
use Time::Local;
use File::Basename;
use LWP::Simple;
# homegrown
use Moz::Moz;
use Moz::Jar;
use Moz::BuildFlags;
use Moz::BuildUtils;
use Moz::CodeWarriorLib;
# use MozillaBuildList; # eventually, this should go away, and be replaced by data input
@ISA = qw(Exporter);
@EXPORT = qw(
RunBuild
);
#//--------------------------------------------------------------------------------------------------
#// DoPrebuildCheck
#//
#// Check the build tools etc before running the build.
#//--------------------------------------------------------------------------------------------------
sub DoPrebuildCheck()
{
SanityCheckBuildOptions();
# launch codewarrior and persist its location. Have to call this before first
# call to getCodeWarriorPath().
my($ide_path_file) = $main::filepaths{"idepath"};
$ide_path_file = full_path_to($ide_path_file);
LaunchCodeWarrior($ide_path_file);
}
#//--------------------------------------------------------------------------------------------------
#// SanityCheckBuildOptions
#//--------------------------------------------------------------------------------------------------
sub SanityCheckBuildOptions()
{
my($bad_options) = 0;
# Jar options
if (!$main::options{chrome_jars} && !$main::options{chrome_files})
{
print "Warning: Both \$options{chrome_jars} and \$options{chrome_files} are off. You won't get any chrome.\n";
$bad_options = 1;
}
if (!$main::options{chrome_jars} && $main::options{use_jars})
{
print "Warning: \$options{chrome_jars} is off but \$options{use_jars} is on. Your build won't run (expects jars, got files).\n";
$bad_options = 1;
}
if (!$main::options{chrome_files} && !$main::options{use_jars})
{
print "Warning: \$options{chrome_jars} is off but \$options{chrome_files} is on. Your build won't run (expects files, got jars).\n";
$bad_options = 1;
}
if ($main::options{ldap_experimental} && !$main::options{ldap})
{
print "Warning: \$options{ldap_experimental} is on but \$options{ldap} is off. LDAP experimental features will not be built.\n";
$bad_options = 1;
}
if ($main::options{wsp} && !$main::options{xmlextras})
{
print "Warning: \$options{wsp} is on but \$options{xmlextras} is off. wsp will not be built.\n";
$bad_options = 1;
}
if ($bad_options) {
print "Build will start in 5 seconds. Press command-. to stop\n";
DelayFor(5);
}
}
#//--------------------------------------------------------------------------------------------------
#// GenBuildSystemInfo
#//--------------------------------------------------------------------------------------------------
sub GenBuildSystemInfo()
{
# always rebuild the configuration program.
BuildProjectClean(":mozilla:build:mac:tools:BuildSystemInfo:BuildSystemInfo.mcp", "BuildSystemInfo");
# delete the configuration file.
unlink(":mozilla:build:mac:BuildSystemInfo.pm");
# run the program.
system(":mozilla:build:mac:BuildSystemInfo");
# wait for the file to be created.
while (!(-e ":mozilla:build:mac:BuildSystemInfo.pm")) { WaitNextEvent(); }
# wait for BuildSystemInfo to finish, so that we see correct results.
while (IsProcessRunning("BuildSystemInfo")) { WaitNextEvent(); }
# now, evaluate the contents of the file.
open(F, ":mozilla:build:mac:BuildSystemInfo.pm");
while (<F>) { eval; }
close(F);
}
#//--------------------------------------------------------------------------------------------------
#// Make library aliases
#//--------------------------------------------------------------------------------------------------
sub MakeLibAliases()
{
my($dist_dir) = GetBinDirectory();
#// ProfilerLib
if ($main::PROFILE)
{
my($profilerlibpath) = Moz::CodeWarriorLib::getCodeWarriorPath("MacOS Support:Profiler:Profiler Common:ProfilerLib");
MakeAlias("$profilerlibpath", "$dist_dir"."Essential Files:");
}
}
#//--------------------------------------------------------------------------------------------------
#// ConfigureBuildSystem
#//
#// defines some build-system configuration variables.
#//--------------------------------------------------------------------------------------------------
sub ConfigureBuildSystem()
{
#// In the future, we may want to do configurations based on the actual build system itself.
#// GenBuildSystemInfo();
#// For now, if we discover a newer header file than existed in Universal Interfaces 3.2,
#// we'll assume that 3.3 or later is in use.
my($universal_interfaces) = Moz::CodeWarriorLib::getCodeWarriorPath("MacOS Support:Universal:Interfaces:CIncludes:");
if (-e ($universal_interfaces . "ControlDefinitions.h")) {
$main::UNIVERSAL_INTERFACES_VERSION = 0x0330;
}
#// Rename IC SDK folder in the Mac OS Support folder
my($ic_sdk_folder) = Moz::CodeWarriorLib::getCodeWarriorPath("MacOS Support:ICProgKit2.0.2");
if( -e $ic_sdk_folder)
{
my($new_ic_folder_name) = Moz::CodeWarriorLib::getCodeWarriorPath("MacOS Support:(ICProgKit2.0.2)");
rename ($ic_sdk_folder, $new_ic_folder_name);
# note that CodeWarrior doesn't descend into folders with () the name
print "Mozilla no longer needs the Internet Config SDK to build:\n Renaming the 'ICProgKit2.0.2' folder to '(ICProgKit2.0.2)'\n";
}
printf("UNIVERSAL_INTERFACES_VERSION = 0x%04X\n", $main::UNIVERSAL_INTERFACES_VERSION);
# alias required CodeWarrior libs into the Essential Files folder (only the Profiler lib now)
MakeLibAliases();
}
#//--------------------------------------------------------------------------------------------------
#// CheckOutModule. Takes variable number of args; first two are required
#//--------------------------------------------------------------------------------------------------
sub CheckOutModule($$$$)
{
my($session, $module, $revision, $date) = @_;
my($result) = $session->checkout($module, $revision, $date);
# result of 1 is success
if ($result) { return; }
my($checkout_err) = $session->getLastError();
if ($checkout_err == 708) {
die "Error: Checkout was cancelled.\n";
} elsif ($checkout_err == 911) {
die "Error: CVS session settings are incorrect. Check your password, and the CVS root settings.\n";
} elsif ($checkout_err == 703) {
die "Error: CVS checkout failed. Unknown module, unknown tag, bad username, or other CVS error.\n";
} elsif ($checkout_err == 711) {
print "Checkout of '$module' failed.\n";
}
}
#//--------------------------------------------------------------------------------------------------
#// getScriptFolder
#//--------------------------------------------------------------------------------------------------
sub getScriptFolder()
{
return dirname($0);
}
#//--------------------------------------------------------------------------------------------------
#// getScriptFolder
#//--------------------------------------------------------------------------------------------------
sub get_url_contents($)
{
my($url) = @_;
my($url_contents) = LWP::Simple::get($url);
$url_contents =~ s/\r\n/\n/g; # normalize linebreaks
$url_contents =~ s/\r/\n/g; # normalize linebreaks
return $url_contents;
}
#//--------------------------------------------------------------------------------------------------
#// get_files_from_content
#//--------------------------------------------------------------------------------------------------
sub uniq
{
my $lastval;
grep(($_ ne $lastval, $lastval = $_)[$[], @_);
}
#//--------------------------------------------------------------------------------------------------
#// get_files_from_content
#//--------------------------------------------------------------------------------------------------
sub get_files_from_content($)
{
my($content) = @_;
my(@jscalls) = grep (/return js_file_menu[^{]*/, split(/\n/, $content));
my $i;
for ($i = 0; $i < @jscalls ; $i++)
{
$jscalls[$i] =~ s/.*\(|\).*//g;
my(@callparams) = split(/,/, $jscalls[$i]);
my ($repos, $dir, $file, $rev) = grep(s/['\s]//g, @callparams);
$jscalls[$i] = "$dir/$file";
}
&uniq(sort(@jscalls));
}
#//--------------------------------------------------------------------------------------------------
#// getLastUpdateTime
#//
#// Get the last time we updated. Return 0 on failure
#//--------------------------------------------------------------------------------------------------
sub getLastUpdateTime($)
{
my($timestamp_file) = @_;
my($time_string);
local(*TIMESTAMP_FILE);
unless (open(TIMESTAMP_FILE, "< $timestamp_file")) { return 0; }
while (<TIMESTAMP_FILE>)
{
my($line) = $_;
chomp($line);
# ignore comments and empty lines
if ($line =~ /^\#/ || $line =~ /^\s*$/) {
next;
}
$time_string = $line;
}
# get the epoch seconds
my($last_update_secs) = $time_string;
$last_update_secs =~ s/\s#.+$//;
print "FAST_UPDATE found that you last updated at ".localtime($last_update_secs)."\n";
# how long ago was this, in hours?
my($gm_now) = time();
my($update_hours) = 1 + ceil(($gm_now - $last_update_secs) / (60 * 60));
return $update_hours;
}
#//--------------------------------------------------------------------------------------------------
#// saveCheckoutTimestamp
#//
#// Create a file on disk containing the current time. Param is time(), which is an Epoch seconds
#// (and therefore in GMT).
#//
#//--------------------------------------------------------------------------------------------------
sub saveCheckoutTimestamp($$)
{
my($gm_secs, $timestamp_file) = @_;
local(*TIMESTAMP_FILE);
open(TIMESTAMP_FILE, ">$timestamp_file") || die "Failed to open $timestamp_file\n";
print(TIMESTAMP_FILE "# time of last checkout or update, in GMT. Used by FAST_UPDATE\n");
print(TIMESTAMP_FILE "$gm_secs \# around ".localtime()." local time\n");
close(TIMESTAMP_FILE);
}
#//--------------------------------------------------------------------------------------------------
#// FastUpdate
#//
#// Use Bonsai url data to update only those dirs which have new files
#//
#//--------------------------------------------------------------------------------------------------
sub FastUpdate($$)
{
my($modules, $timestamp_file) = @_; # list of modules to check out
my($num_hours) = getLastUpdateTime($timestamp_file);
if ($num_hours == 0 || $num_hours > 170) {
print "Can't fast_update; last update was too long ago, or never. Doing normal checkout.\n";
return 0;
}
print "Doing fast update, pulling files changed in the last $num_hours hours\n";
my($cvsfile) = AskAndPersistFile($main::filepaths{"sessionpath"});
my($session) = Moz::MacCVS->new( $cvsfile );
unless (defined($session)) { die "Error: Checkout aborted. Cannot create session file: $session" }
# activate MacCVS
ActivateApplication('Mcvs');
my($checkout_start_time) = time();
#print "Time now is $checkout_start_time ($checkout_start_time + 0)\n";
my($this_co);
foreach $this_co (@$modules)
{
my($module, $revision, $date) = ($this_co->[0], $this_co->[1], $this_co->[2]);
# assume that things pulled by date wont change
if ($date ne "") {
print "$module is pulled by date, so ignoring in FastUpdate.\n";
next;
}
my($search_type) = "hours";
my($min_date) = "";
my($max_date) = "";
my($url) = "http://bonsai.mozilla.org/cvsquery.cgi?treeid=default&module=${module}&branch=${revision}&branchtype=match&dir=&file=&filetype=match&who=&whotype=match&sortby=Date&hours=${num_hours}&date=${search_type}&mindate=${min_date}&maxdate=${max_date}&cvsroot=%2Fcvsroot";
if ($revision eq "") {
print "Getting list of checkins to $module from Bonsai...\n";
} else {
print "Getting list of checkins to $module on branch $revision from Bonsai...\n";
}
my(@files) = &get_files_from_content(&get_url_contents($url));
if ($#files > 0)
{
my(@cvs_co_list);
my($co_file);
foreach $co_file (@files)
{
print "Updating $co_file\n";
push(@cvs_co_list, $co_file);
}
my($result) = $session->update($revision, \@cvs_co_list);
# result of 1 is success
if (!$result) { die "Error: Fast update failed\n"; }
} else {
print "No files in this module changed\n";
}
}
saveCheckoutTimestamp($checkout_start_time, $timestamp_file);
return 1;
}
#//--------------------------------------------------------------------------------------------------
#// Checkout
#//--------------------------------------------------------------------------------------------------
sub CheckoutModules($$$)
{
my($modules, $pull_date, $timestamp_file) = @_; # list of modules to check out
my($start_time) = TimeStart();
# assertRightDirectory();
my($cvsfile) = AskAndPersistFile($main::filepaths{"sessionpath"});
my($session) = Moz::MacCVS->new( $cvsfile );
unless (defined($session)) { die "Error: Checkout aborted. Cannot create session file: $session" }
my($checkout_start_time) = time();
# activate MacCVS
ActivateApplication('Mcvs');
my($this_co);
foreach $this_co (@$modules)
{
my($module, $revision, $date) = ($this_co->[0], $this_co->[1], $this_co->[2]);
if ($date eq "") {
$date = $pull_date;
}
CheckOutModule($session, $module, $revision, $date);
# print "Checking out $module with ref $revision, date $date\n";
}
saveCheckoutTimestamp($checkout_start_time, $timestamp_file);
TimeEnd($start_time, "Checkout");
}
#//--------------------------------------------------------------------------------------------------
#// ReadCheckoutModulesFile
#//--------------------------------------------------------------------------------------------------
sub ReadCheckoutModulesFile($$)
{
my($modules_file, $co_list) = @_;
my($checkout_file) = getScriptFolder().":".$modules_file;
local(*CHECKOUT_FILE);
open(CHECKOUT_FILE, "< $checkout_file") || die "Error: failed to open checkout list $checkout_file\n";
while (<CHECKOUT_FILE>)
{
my($line) = $_;
chomp($line);
# ignore comments and empty lines
if ($line =~ /^\#/ || $line =~ /^\s*$/) {
next;
}
my(@cvs_co) = ["", "", ""];
my($module, $revision, $date) = (0, 1, 2);
if ($line =~ /\s*([^#,\s]+)\s*\,\s*([^#,\s]+)\s*\,\s*([^#]+)/)
{
@cvs_co[$module] = $1;
@cvs_co[$revision] = $2;
@cvs_co[$date] = $3;
}
elsif ($line =~ /\s*([^#,\s]+)\s*\,\s*([^#,\s]+)\s*(#.+)?/)
{
@cvs_co[$module] = $1;
@cvs_co[$revision] = $2;
}
elsif ($line =~ /\s*([^#,\s]+)\s*\,\s*,\s*([^#,]+)/)
{
@cvs_co[$module] = $1;
@cvs_co[$date] = $2;
}
elsif ($line =~ /\s*([^#,\s]+)/)
{
@cvs_co[$module] = $1;
}
else
{
die "Error: unrecognized line '$line' in $modules_file\n";
}
# strip surrounding space from date
@cvs_co[$date] =~ s/^\s*|\s*$//g;
# print "Going to check out '@cvs_co[$module]', '@cvs_co[$revision]', '@cvs_co[$date]'\n";
push(@$co_list, \@cvs_co);
}
close(CHECKOUT_FILE);
}
#//--------------------------------------------------------------------------------------------------
#// PullFromCVS
#//--------------------------------------------------------------------------------------------------
sub PullFromCVS($$)
{
unless ( $main::build{pull} ) { return; }
my($modules_file, $timestamp_file) = @_;
StartBuildModule("pull");
my(@cvs_co_list);
ReadCheckoutModulesFile($modules_file, \@cvs_co_list);
if ($main::FAST_UPDATE && $main::options{pull_by_date})
{
die "Error: you can't use FAST_UPDATE if you are pulling by date.\n";
}
my($did_fast_update) = $main::FAST_UPDATE && FastUpdate(\@cvs_co_list, $timestamp_file);
if (!$did_fast_update)
{
my($pull_date) = "";
if ($main::options{pull_by_date})
{
# acceptable CVS date formats are (in local time):
# ISO8601 (e.g. "1972-09-24 20:05") and Internet (e.g. "24 Sep 1972 20:05").
# Perl's localtime() string format also seems to work.
$pull_date = localtime().""; # force string interp.
print "Pulling by date $pull_date\n";
}
CheckoutModules(\@cvs_co_list, $pull_date, $timestamp_file);
}
EndBuildModule("pull");
}
#//--------------------------------------------------------------------------------------------------
#// RunBuild
#//--------------------------------------------------------------------------------------------------
sub RunBuild($$$$)
{
my($do_pull, $do_build, $input_files, $build_prefs) = @_;
InitBuildProgress($input_files->{"buildprogress"});
# if we are pulling, we probably want to do a full build, so clear the build progress
if ($do_pull) {
ClearBuildProgress();
}
# read local prefs, and the build progress file, and set flags to say what to build
SetupBuildParams(\%main::build,
\%main::options,
\%main::optiondefines,
\%main::filepaths,
$input_files->{"buildflags"},
$build_prefs);
# If we were told to pull, make sure we do, overriding prefs etc.
if ($do_pull)
{
$main::build{"pull"} = 1;
}
# transfer this flag
$CodeWarriorLib::CLOSE_PROJECTS_FIRST = $main::CLOSE_PROJECTS_FIRST;
# setup the build log
SetupBuildLog($main::filepaths{"buildlogfilepath"}, $main::USE_TIMESTAMPED_LOGS);
StopForErrors();
if ($main::LOG_TO_FILE) {
RedirectOutputToFile($main::filepaths{"scriptlogfilepath"});
}
# run a pre-build check to see that the tools etc are in order
DoPrebuildCheck();
# do the pull
PullFromCVS($input_files->{"checkoutdata"}, $input_files->{"checkouttime"});
unless ($do_build) { return; }
my($build_start) = TimeStart();
# check the build environment
ConfigureBuildSystem();
# here we load and call methods in the build module indirectly.
# we have to use indirection because the build module can be named
# differently for different builds.
chdir(dirname($0)); # change to the script dir
my($build_module) = $input_files->{"buildmodule"};
# load the build module
require $build_module;
{ # scope for no strict 'refs'
no strict 'refs';
my($package_name) = $build_module;
$package_name =~ s/\.pm$//;
chdir($main::MOZ_SRC);
&{$package_name."::BuildDist"}();
chdir($main::MOZ_SRC);
&{$package_name."::BuildProjects"}();
}
# the build finished, so clear the build progress state
ClearBuildProgress();
TimeEnd($build_start, "Build");
print "Build complete\n";
}
1;

View File

@@ -1,425 +0,0 @@
#!perl -w
package Moz::BuildFlags;
require 5.004;
require Exporter;
# Package that attempts to read a file from the Preferences folder,
# and get build settings out of it
use strict;
use Exporter;
use Cwd;
use File::Basename;
use Moz::Moz;
use Moz::Prefs;
use vars qw(@ISA @EXPORT);
@ISA = qw(Exporter);
@EXPORT = qw(
SetupBuildParams
InitBuildProgress
WriteBuildProgress
ClearBuildProgress
ReadBuildProgress
);
my(@build_flags);
my(@options_flags);
my(@filepath_flags);
my(%arrays_list) = (
"build_flags", \@build_flags,
"options_flags", \@options_flags,
"filepath_flags", \@filepath_flags
);
my($progress_file) = "¥ÊBuild progress";
#-------------------------------------------------------------------------------
# appendArrayFlag
#
# Set a flag in the array
#-------------------------------------------------------------------------------
sub appendArrayFlag(@)
{
my($array_name) = shift;
my($setting) = shift;
my($value) = shift;
my(@optional_values);
foreach (@_) {
push(@optional_values, $_);
}
my(@this_flag) = [$setting, $value, @optional_values];
my($flags_array) = $arrays_list{$array_name};
if ($flags_array)
{
push(@{$flags_array}, @this_flag) || die "Failed to append\n";
}
else
{
die "Error: unknown build flags array $array_name\n";
}
}
#-------------------------------------------------------------------------------
# readFlagsFile
#
# Read the file of build flags from disk. File path is relative to the
# script directory.
#-------------------------------------------------------------------------------
sub readFlagsFile($)
{
my($flags_file) = @_;
my($file_path) = $0;
$file_path =~ s/[^:]+$/$flags_file/;
print "Reading build flags from '$file_path'\n";
local(*FLAGS_FILE);
open(FLAGS_FILE, "< $file_path") || die "Error: failed to open flags file $file_path\n";
my($cur_array) = "";
while(<FLAGS_FILE>)
{
my($line) = $_;
chomp($line);
# ignore comments and empty lines
if ($line =~ /^\#/ || $line =~ /^\s*$/) {
next;
}
# 1-word line, probably array name
if ($line =~ /^([^#\s]+)\s*$/)
{
$cur_array = $1;
next;
}
elsif ($line =~ /^([^#\s]+)\s+\"(.+)\"(\s+#.+)?$/) # quoted option, possible comment
{
my($flag) = $1;
my($setting) = $2;
appendArrayFlag($cur_array, $flag, $setting);
}
elsif ($line =~ /^([^#\s]+)((\s+[^#\s]+)+)(\s+#.+)?$/) # multiple word line, possible comment
{
my($flag) = $1;
appendArrayFlag($cur_array, $flag, split(' ', $2));
}
else
{
die "Error: unknown build flag at '$line'\n";
}
}
close(FLAGS_FILE);
}
#-------------------------------------------------------------------------------
# flagsArrayToHash
#
# Utility routine to migrate flag from a 2D array to a hash, where
# item[n][0] is the hash entry name, and item[n][1] is the hash entry value.
#-------------------------------------------------------------------------------
sub flagsArrayToHash($$)
{
my($src_array, $dest_hash) = @_;
my($item);
foreach $item (@$src_array)
{
$dest_hash->{$item->[0]} = $item->[1];
}
}
#-----------------------------------------------
# printHash
#
# Utility routine to print a hash
#-----------------------------------------------
sub printHash($)
{
my($hash_ref) = @_;
print "Printing hash:\n";
my($key, $value);
while (($key, $value) = each (%$hash_ref))
{
print " $key $value\n";
}
}
#-----------------------------------------------
# printBuildArray
#
# Utility routine to print a 2D array
#-----------------------------------------------
sub printBuildArray($)
{
my($build_array) = @_;
my($entry);
foreach $entry (@$build_array)
{
print "$entry->[0] = $entry->[1]\n";
}
}
#-------------------------------------------------------------------------------
# SetBuildFlags
#-------------------------------------------------------------------------------
sub SetBuildFlags($)
{
my($build) = @_;
flagsArrayToHash(\@build_flags, $build);
}
#-------------------------------------------------------------------------------
# SetBuildOptions
#-------------------------------------------------------------------------------
sub SetBuildOptions($)
{
my($options) = @_;
flagsArrayToHash(\@options_flags, $options);
}
#-------------------------------------------------------------------------------
# SetFilepathFlags
#-------------------------------------------------------------------------------
sub SetFilepathFlags($)
{
my($filepath) = @_;
flagsArrayToHash(\@filepath_flags, $filepath);
}
#-------------------------------------------------------------------------------
# SetOptionDefines
#-------------------------------------------------------------------------------
sub SetOptionDefines($)
{
my($optiondefines) = @_;
foreach my $entry (@options_flags)
{
if (defined($entry->[2])) {
$optiondefines->{$entry->[0]}{$entry->[2]} = 1;
}
}
}
#-------------------------------------------------------------------------------
# PropagateAllFlags
#-------------------------------------------------------------------------------
sub PropagateAllFlags($)
{
my($build_array) = @_;
# if "all" is set, set all the flags to 1
unless ($build_array->[0][0] eq "all") { die "Error: 'all' must come first in the flags array\n"; }
if ($build_array->[0][1] == 1)
{
my($index);
foreach $index (@$build_array)
{
$index->[1] = 1;
}
}
}
#//--------------------------------------------------------------------------------------------------
#// _getBuildProgressFile
#//--------------------------------------------------------------------------------------------------
sub _getBuildProgressFile()
{
return $progress_file;
}
#//--------------------------------------------------------------------------------------------------
#// setBuildProgressStart
#//
#// This automagically sets $build{"all"} to 0
#//--------------------------------------------------------------------------------------------------
sub setBuildProgressStart($$)
{
my($build_array, $name) = @_;
my($index);
foreach $index (@$build_array)
{
$index->[1] = 0;
if ($index->[0] eq $name) {
last;
}
}
print "Building from module after $name, as specified by build progress\n";
}
#//--------------------------------------------------------------------------------------------------
#// InitBuildProgress
#//--------------------------------------------------------------------------------------------------
sub InitBuildProgress($)
{
my($prog_file) = @_;
if ($prog_file ne "") {
$progress_file = full_path_to($prog_file);
print "Writing build progress to $progress_file\n";
}
}
#//--------------------------------------------------------------------------------------------------
#// WriteBuildProgress
#//--------------------------------------------------------------------------------------------------
sub WriteBuildProgress($)
{
my($module_built) = @_;
my($progress_file) = _getBuildProgressFile();
if ($progress_file ne "")
{
open(PROGRESS_FILE, ">>$progress_file") || die "Failed to open $progress_file\n";
print(PROGRESS_FILE "$module_built\n");
close(PROGRESS_FILE);
}
}
#//--------------------------------------------------------------------------------------------------
#// ClearBuildProgress
#//--------------------------------------------------------------------------------------------------
sub ClearBuildProgress()
{
my($progress_file) = _getBuildProgressFile();
if ($progress_file ne "") {
unlink $progress_file;
}
}
#//--------------------------------------------------------------------------------------------------
#// WipeBuildProgress
#//--------------------------------------------------------------------------------------------------
sub WipeBuildProgress()
{
print "Ignoring build progress\n";
ClearBuildProgress();
$progress_file = "";
}
#//--------------------------------------------------------------------------------------------------
#// ReadBuildProgress
#//--------------------------------------------------------------------------------------------------
sub ReadBuildProgress($)
{
my($build_array) = @_;
my($progress_file) = _getBuildProgressFile();
my($last_module);
if (open(PROGRESS_FILE, "< $progress_file"))
{
print "Getting build progress from $progress_file\n";
while (<PROGRESS_FILE>)
{
my($line) = $_;
chomp($line);
$last_module = $line;
}
close(PROGRESS_FILE);
}
if ($last_module)
{
setBuildProgressStart($build_array, $last_module);
}
}
#-------------------------------------------------------------------------------
# clearOldBuildSettings
#-------------------------------------------------------------------------------
sub clearOldBuildSettings($$$$)
{
my($build, $options, $optiondefines, $filepaths) = @_;
# empty the arrays in case we're being called twice
@build_flags = ();
@options_flags = ();
@filepath_flags = ();
# and empty the hashes
%$build = ();
%$options = ();
%$optiondefines = ();
%$filepaths = ();
}
#-------------------------------------------------------------------------------
# SetupBuildParams
#-------------------------------------------------------------------------------
sub SetupBuildParams($$$$$$)
{
my($build, $options, $optiondefines, $filepaths, $flags_file, $prefs_file) = @_;
# Empty the hashes and arrays, to wipe out any stale data.
# Needed because these structures persist across two build scripts
# called using 'do' from a parent script.
clearOldBuildSettings($build, $options, $optiondefines, $filepaths);
# Read from the flags file, which sets up the various arrays
readFlagsFile($flags_file);
# If 'all' is set in the build array, propagate that to all entries
PropagateAllFlags(\@build_flags);
# read the user pref file, that can change values in the array
ReadMozUserPrefs($prefs_file, \@build_flags, \@options_flags, \@filepath_flags);
# If build progress exists, this clears flags in the array up to a certain point
if ($main::USE_BUILD_PROGRESS) {
ReadBuildProgress(\@build_flags);
} else {
WipeBuildProgress();
}
# printBuildArray(\@build_flags);
# printBuildArray(\@options_flags);
SetBuildFlags($build);
SetBuildOptions($options);
SetOptionDefines($optiondefines);
SetFilepathFlags($filepaths);
# printHash($build);
# printHash($options);
}
1;

View File

@@ -1,786 +0,0 @@
package Moz::BuildUtils;
require 5.004;
require Exporter;
# Package that contains build util functions specific to the Mozilla build
# process.
use strict;
use Exporter;
use Cwd;
use File::Path;
use File::Basename;
use Mac::Events;
use Mac::StandardFile;
use Moz::Moz;
use Moz::BuildFlags;
use Moz::MacCVS;
#use Moz::ProjectXML; #optional; required for static build only
use vars qw(@ISA @EXPORT);
@ISA = qw(Exporter);
@EXPORT = qw(
SetupDefaultBuildOptions
SetupBuildRootDir
StartBuildModule
EndBuildModule
GetBinDirectory
BuildOneProjectWithOutput
BuildOneProject
BuildProject
BuildProjectClean
BuildIDLProject
BuildFolderResourceAliases
AskAndPersistFile
DelayFor
TimeStart
TimeEnd
EmptyTree
SetupBuildLog
SetBuildNumber
SetTimeBomb
UpdateConfigHeader
);
#//--------------------------------------------------------------------------------------------------
#// SetupDefaultBuildOptions
#//--------------------------------------------------------------------------------------------------
sub SetupDefaultBuildOptions($$$)
{
my($debug, $bin_dir, $config_header_file_name) = @_;
# Here we set up defaults for the various build flags.
# If you want to override any of these, it's best to do
# so via the relevant preferences file, which lives in
# System Folder:Preferences:Mozilla build prefs:{build prefs file}.
# For the name of the prefs file, see the .pl script that you
# run to start this build. The prefs files are created when
# you run the build, and contain some documentation.
#-------------------------------------------------------------
# configuration variables that globally affect what is built
#-------------------------------------------------------------
$main::DEBUG = $debug;
$main::PROFILE = 0;
$main::RUNTIME = 0; # turn on to just build runtime support and NSPR projects
$main::GC_LEAK_DETECTOR = 0; # turn on to use GC leak detection
$main::MOZILLA_OFFICIAL = 0; # generate build number
$main::LOG_TO_FILE = 0; # write perl output to a file
#-------------------------------------------------------------
# configuration variables that affect the manner of building,
# but possibly affecting the outcome.
#-------------------------------------------------------------
$main::ALIAS_SYM_FILES = $main::DEBUG;
$main::CLOBBER_LIBS = 1; # turn on to clobber existing libs and .xSYM files before
# building each project
# The following two options will delete all dist files (if you have $main::build{dist} turned on),
# but leave the directory structure intact.
$main::CLOBBER_DIST_ALL = 1; # turn on to clobber all aliases/files inside dist (headers/xsym/libs)
$main::CLOBBER_DIST_LIBS = 0; # turn on to clobber only aliases/files for libraries/sym files in dist
$main::CLOBBER_IDL_PROJECTS = 0; # turn on to clobber all IDL projects.
$main::CLOBBER_PROJECTS = 0; # turn on to remove object code from each project before building it
$main::UNIVERSAL_INTERFACES_VERSION = 0x0320;
#-------------------------------------------------------------
# configuration variables that are preferences for the build,
# style and do not affect what is built.
#-------------------------------------------------------------
$main::CLOSE_PROJECTS_FIRST = 0;
# 1 = close then make (for development),
# 0 = make then close (for tinderbox).
$main::USE_TIMESTAMPED_LOGS = 0;
$main::USE_BUILD_PROGRESS = 1; # track build progress for restartable builds
#-------------------------------------------------------------
# END OF CONFIG SWITCHES
#-------------------------------------------------------------
$main::BIN_DIRECTORY = $bin_dir;
$main::DEFINESOPTIONS_FILE = $config_header_file_name;
}
#//--------------------------------------------------------------------------------------------------
#// SetupBuildRootDir
#//--------------------------------------------------------------------------------------------------
sub SetupBuildRootDir($)
{
my($rel_path_to_script) = @_;
my($cur_dir) = cwd();
$cur_dir =~ s/$rel_path_to_script$//;
chdir($cur_dir) || die "Error: failed to set build root directory to '$cur_dir'.\nYou probably need to put 'mozilla' one level down (in a folder).\n";
$main::MOZ_SRC = cwd();
}
#//--------------------------------------------------------------------------------------------------
#// StartBuildModule
#//--------------------------------------------------------------------------------------------------
sub StartBuildModule($)
{
my($module) = @_;
print("---- Start of $module ----\n");
}
#//--------------------------------------------------------------------------------------------------
#// EndBuildModule
#//--------------------------------------------------------------------------------------------------
sub EndBuildModule($)
{
my($module) = @_;
WriteBuildProgress($module);
print("---- End of $module ----\n");
}
#--------------------------------------------------------------------------------------------------
# GetBinDirectory
#--------------------------------------------------------------------------------------------------
sub GetBinDirectory()
{
if ($main::BIN_DIRECTORY eq "") { die "Dist directory not set\n"; }
return $main::BIN_DIRECTORY;
}
#--------------------------------------------------------------------------------------------------
# AskAndPersistFile stores the information about the user pick inside
# the file $session_storage
#--------------------------------------------------------------------------------------------------
sub AskAndPersistFile($)
{
my ($sessionStorage) = @_;
my $cvsfile;
if (( -e $sessionStorage) &&
open( SESSIONFILE, $sessionStorage ))
{
# Read in the path if available
$cvsfile = <SESSIONFILE>;
chomp $cvsfile;
close SESSIONFILE;
if ( ! -e $cvsfile )
{
print STDERR "$cvsfile has disappeared\n";
undef $cvsfile;
}
}
unless (defined ($cvsfile))
{
# make sure that MacPerl is a front process
ActivateApplication('McPL');
MacPerl::Answer("Could not find your MacCVS session file. Please choose one", "OK");
# prompt user for the file name, and store it
my $macFile = StandardGetFile( 0, "McvD");
if ( $macFile->sfGood() )
{
$cvsfile = $macFile->sfFile();
# save the choice if we can
if ( open (SESSIONFILE, ">" . $sessionStorage))
{
printf SESSIONFILE $cvsfile, "\n";
close SESSIONFILE;
}
else
{
print STDERR "Could not open storage file $sessionStorage for saving $cvsfile\n";
}
}
}
return $cvsfile;
}
#--------------------------------------------------------------------------------------------------
# BuildIDLProject
#
#--------------------------------------------------------------------------------------------------
sub BuildIDLProject($$)
{
my ($project_path, $module_name) = @_;
if ($main::CLOBBER_IDL_PROJECTS)
{
my (@suffix_list) = (".mcp", ".xml");
my ($project_name, $project_dir, $suffix) = fileparse($project_path, @suffix_list);
if ($suffix eq "") { die "Error: Project, $project_path must end in .xml or .mcp\n"; }
my($datafolder_path);
if ($suffix eq ".xml")
{
$datafolder_path = $project_dir . "_" . $project_name . " Data:";
}
else {
$datafolder_path = $project_dir . $project_name . " Data:";
}
print STDERR "Deleting IDL data folder: $datafolder_path\n";
EmptyTree($datafolder_path);
}
BuildOneProject($project_path, "headers", 0, 0, 0);
BuildOneProject($project_path, $module_name.".xpt", 1, 0, 1);
}
#--------------------------------------------------------------------------------------------------
# CreateStaticLibTargets
#
#--------------------------------------------------------------------------------------------------
sub CreateXMLStaticLibTargets($)
{
my($xml_path) = @_;
my (@suffix_list) = (".xml");
my ($project_name, $project_dir, $suffix) = fileparse($xml_path, @suffix_list);
if ($suffix eq "") { die "XML munging: $xml_path must end in .xml\n"; }
#sniff the file to see if we need to fix up broken Pro5-exported XML
print "Parsing $xml_path\n";
my $ide_version = Moz::ProjectXML::SniffProjectXMLIDEVersion($xml_path);
if ($ide_version eq "4.0")
{
my $new_file = $project_dir.$project_name."2.xml";
print "Cleaning up Pro 5 xml to $new_file\n";
Moz::ProjectXML::CleanupPro5XML($xml_path, $new_file);
unlink $xml_path;
rename ($new_file, $xml_path);
}
my $doc = Moz::ProjectXML::ParseXMLDocument($xml_path);
my @target_list = Moz::ProjectXML::GetTargetsList($doc);
my $target;
my %target_hash; # for easy lookups below
foreach $target (@target_list) { $target_hash{$target} = 1; }
foreach $target (@target_list)
{
if ($target =~ /(.+).shlb$/) # if this is a shared lib target
{
my $target_base = $1;
my $static_target = $target_base.".o";
# ensure that this does not exist already
if ($target_hash{$static_target}) {
print "Static target $static_target already exists in project. Not making\n";
next;
}
print "Making static target '$static_target' from target '$target'\n";
Moz::ProjectXML::CloneTarget($doc, $target, $static_target);
Moz::ProjectXML::SetAsStaticLibraryTarget($doc, $static_target, $static_target);
}
}
print "Writing XML file to $xml_path\n";
my $temp_path = $project_dir."_".$project_name.".xml";
Moz::ProjectXML::WriteXMLDocument($doc, $temp_path, $ide_version);
Moz::ProjectXML::DisposeXMLDocument($doc);
if (-e $temp_path)
{
unlink $xml_path;
rename ($temp_path, $xml_path);
}
else
{
die "Error: Failed to add new targets to XML project\n";
}
}
#//--------------------------------------------------------------------------------------------------
#// ProcessProjectXML
#//
#// Helper routine to allow for XML pre-processing. This should read in the XML, process it,
#// and replace the original file with the processed version.
#//--------------------------------------------------------------------------------------------------
sub ProcessProjectXML($)
{
my($xml_path) = @_;
# we need to manually load Moz::ProjectXML, becaues not everyone will have the
# required perl modules in their distro.
my($cur_dir) = cwd();
chdir(dirname($0)); # change to the script dir
eval "require Moz::ProjectXML";
if ($@) { die "Error: could not do Project XML munging because you do not have the correct XML modules installed. Error is:\n################\n $@################"; }
chdir($cur_dir);
CreateXMLStaticLibTargets($xml_path);
}
#//--------------------------------------------------------------------------------------------------
#// Build one project, and make the alias. Parameters are project path, target name, shared library
#// name, make shlb alias (boolean), make xSYM alias (boolean), and is component (boolean).
#//--------------------------------------------------------------------------------------------------
sub BuildOneProjectWithOutput($$$$$$)
{
my ($project_path, $target_name, $output_name, $alias_lib, $alias_xSYM, $component) = @_;
unless ($project_path =~ m/^$main::BUILD_ROOT.+/) { return; }
my (@suffix_list) = (".mcp", ".xml");
my ($project_name, $project_dir, $suffix) = fileparse($project_path, @suffix_list);
if ($suffix eq "") { die "Error: Project, $project_path must end in .xml or .mcp\n"; }
my($dist_dir) = GetBinDirectory();
# Put libraries in "Essential Files" folder, Components in "Components" folder
my($output_dir) = $component ? "Components:" : "Essential Files:";
my($output_path) = $dist_dir.$output_dir;
if ($main::options{static_build})
{
if ($output_name =~ /\.o$/ || $output_name =~ /\.[Ll]ib$/)
{
$alias_xSYM = 0;
$alias_lib = 1;
$output_path = $main::DEBUG ? ":mozilla:dist:static_libs_debug:" : ":mozilla:dist:static_libs:";
}
}
# if the flag is on to export projects to XML, export and munge them
if ($main::EXPORT_PROJECTS && !($project_path =~ /IDL\.mcp$/))
{
my $xml_out_path = $project_path;
$xml_out_path =~ s/\.mcp$/\.xml/;
# only do this if project is newer?
if (! -e $xml_out_path)
{
ExportProjectToXML(full_path_to($project_path), full_path_to($xml_out_path));
ProcessProjectXML($xml_out_path);
}
}
# if the flag is set to use XML projects, default to XML if the file
# is present.
if ($main::USE_XML_PROJECTS && !($project_path =~ /IDL\.mcp$/))
{
my $xml_project_path = $project_dir.$project_name.".xml";
if (-e $xml_project_path)
{
$project_path = $xml_project_path;
$suffix = ".xml";
}
}
if ($suffix eq ".xml")
{
my($xml_path) = $project_path;
# Prepend an "_" onto the name of the generated project file so it doesn't conflict
$project_path = $project_dir . "_" . $project_name . ".mcp";
my($project_modtime) = (-e $project_path ? GetFileModDate($project_path) : 0);
my($xml_modtime) = (-e $xml_path ? GetFileModDate($xml_path) : 0);
if ($xml_modtime > $project_modtime)
{
print("Importing $project_path from $project_name.xml.\n");
unlink($project_path);
# Might want to delete the "xxx.mcp Data" dir ???
ImportXMLProject(full_path_to($xml_path), full_path_to($project_path));
}
}
if ($main::CLOBBER_LIBS)
{
unlink "$project_dir$output_name"; # it's OK if these fail
unlink "$project_dir$output_name.xSYM";
}
DoBuildProject($project_path, $target_name, $main::CLOBBER_PROJECTS);
$alias_lib ? MakeAlias("$project_dir$output_name", "$output_path") : 0;
$alias_xSYM ? MakeAlias("$project_dir$output_name.xSYM", "$output_path") : 0;
}
#//--------------------------------------------------------------------------------------------------
#// For compatiblity with existing scripts, BuildOneProject now just calls
#// BuildOneProjectWithOutput, with the output name and target name identical.
#// Note that this routine assumes that the target name and the shared libary name
#// are the same.
#//--------------------------------------------------------------------------------------------------
sub BuildOneProject($$$$$)
{
my ($project_path, $target_name, $alias_lib, $alias_xSYM, $component) = @_;
BuildOneProjectWithOutput($project_path, $target_name, $target_name,
$alias_lib, $alias_xSYM, $component);
}
#//--------------------------------------------------------------------------------------------------
#// For compatiblity with existing scripts, BuildProject now just calls
#// BuildOneProjectWithOutput, with the output name and target name identical.
#// Note that this routine assumes that the target name and the shared libary name
#// are the same. No aliases of the output are made.
#//--------------------------------------------------------------------------------------------------
sub BuildProject($$)
{
my ($project_path, $target_name) = @_;
BuildOneProjectWithOutput($project_path, $target_name, $target_name, 0, 0, 0);
}
#//--------------------------------------------------------------------------------------------------
#// Identical to BuildProject but clobbers the project before building it.
#//--------------------------------------------------------------------------------------------------
sub BuildProjectClean($$)
{
my ($project_path, $target_name) = @_;
my ($save_clobber_flag) = $main::CLOBBER_PROJECTS;
$main::CLOBBER_PROJECTS = 1;
BuildOneProjectWithOutput($project_path, $target_name, $target_name, 0, 0, 0);
$main::CLOBBER_PROJECTS = $save_clobber_flag;
}
#//--------------------------------------------------------------------------------------------------
#// Make resource aliases for one directory
#//--------------------------------------------------------------------------------------------------
sub BuildFolderResourceAliases($$)
{
my($src_dir, $dest_dir) = @_;
# get a list of all the resource files
opendir(SRCDIR, $src_dir) || die("can't open $src_dir");
my(@resource_files) = readdir(SRCDIR);
closedir(SRCDIR);
# make aliases for each one into the dest directory
print("Placing aliases to all files from $src_dir in $dest_dir\n");
for ( @resource_files )
{
next if $_ eq "CVS";
#print(" Doing $_\n");
if (-l $src_dir.$_)
{
print(" $_ is an alias\n");
next;
}
my($file_name) = $src_dir . $_;
MakeAlias($file_name, $dest_dir);
}
}
#//--------------------------------------------------------------------------------------------------
#// DelayFor
#//
#// Delay for the given number of seconds, allowing the script to be cancelled
#//--------------------------------------------------------------------------------------------------
sub DelayFor($)
{
my($delay_secs) = @_;
STDOUT->autoflush(1);
my($end_time) = time() + $delay_secs;
my($last_time) = 0;
my($cur_time) = time();
while ($cur_time < $end_time)
{
$cur_time = time();
if ($cur_time > $last_time)
{
print ".";
$last_time = $cur_time;
}
WaitNextEvent();
}
print "\n";
STDOUT->autoflush(0);
}
#//--------------------------------------------------------------------------------------------------
#// TimeStart
#//--------------------------------------------------------------------------------------------------
sub TimeStart()
{
return time();
}
#//--------------------------------------------------------------------------------------------------
#// TimeEnd
#//--------------------------------------------------------------------------------------------------
sub TimeEnd($$)
{
use integer;
my($start_time, $operation_name) = @_;
my($end_time) = time();
my($tot_sec) = $end_time - $start_time;
my($seconds) = $tot_sec;
my($hours) = $seconds / (60 * 60);
$seconds -= $hours * (60 * 60);
my($minutes) = $seconds / 60;
$seconds -= $minutes * 60;
print "$operation_name took $hours hours $minutes minutes and $seconds seconds\n";
}
#//--------------------------------------------------------------------------------------------------
#// Remove all files from a tree, leaving directories intact (except "CVS").
#//--------------------------------------------------------------------------------------------------
sub EmptyTree($)
{
my ($root) = @_;
#print "EmptyTree($root)\n";
opendir(DIR, $root);
my $sub;
foreach $sub (readdir(DIR))
{
my $fullpathname = $root.$sub; # -f, -d only work on full paths
# Don't call empty tree for the alias of a directory.
# -d returns true for the alias of a directory, false for a broken alias)
if (-d $fullpathname)
{
if (-l $fullpathname) # delete aliases
{
unlink $fullpathname;
next;
}
EmptyTree($fullpathname.":");
if ($sub eq "CVS")
{
#print "rmdir $fullpathname\n";
rmdir $fullpathname;
}
}
else
{
unless (unlink $fullpathname) { die "Failed to delete $fullpathname\n"; }
}
}
closedir(DIR);
}
#//--------------------------------------------------------------------------------------------------
#// Recurse through a directory hierarchy, looking for MANIFEST files.
#// Currently unused.
#//--------------------------------------------------------------------------------------------------
sub ScanForManifestFiles($$$$)
{
my($dir, $theme_root, $theme_name, $dist_dir) = @_;
opendir(DIR, $dir) or die "Cannot open dir $dir\n";
my @files = readdir(DIR);
closedir DIR;
my $file;
foreach $file (@files)
{
my $filepath = $dir.":".$file;
if (-d $filepath)
{
# print "Looking for MANIFEST files in $filepath\n";
ScanForManifestFiles($filepath, $theme_root, $theme_name, $dist_dir);
}
elsif ($file eq "MANIFEST")
{
# print "Doing manifest file $filepath\n";
# Get the dest path from the first line of the file
open(MANIFEST, $filepath) || die "Could not open file $file";
# Read in the path if available
my($dest_line) = <MANIFEST>;
chomp $dest_line;
close MANIFEST;
$dest_line =~ s|^#!dest[\t ]+|| || die "No destination line found in $filepath\n";
my($dest_path) = $dist_dir."chrome:skins:$theme_name:$dest_line";
# print " Destination is $dest_path\n";
InstallResources($filepath, "$dest_path", 0);
}
}
}
#-----------------------------------------------
# SetupBuildLog
#-----------------------------------------------
sub SetupBuildLog($$)
{
my($logfile_path, $timestamped_log) = @_;
my($logdir) = "";
my($logfile) = $logfile_path;
if ($logfile_path =~ /(.+?:)([^:]+)$/) # ? for non-greedy match
{
$logdir = $1;
$logfile = $2;
mkpath($logdir);
}
if ($timestamped_log)
{
#Use time-stamped names so that you don't clobber your previous log file!
my $now = localtime();
while ($now =~ s@:@.@) {} # replace all colons by periods
OpenErrorLog("${logdir}${now}");
}
else
{
OpenErrorLog("${logdir}${logfile}");
}
}
#-----------------------------------------------
# SetBuildNumber
#-----------------------------------------------
sub SetBuildNumber($$)
{
my($build_num_file, $files_to_touch) = @_;
# Make sure we add the config dir to search, to pick up mozBDate.pm
# Need to do this dynamically, because this module can be used before
# mozilla/config has been checked out.
my ($inc_path) = $0; # $0 is the path to the parent script
$inc_path =~ s/:build:mac:build_scripts:.+$/:config/;
push(@INC, $inc_path);
require mozBDate;
mozBDate::UpdateBuildNumber($build_num_file, $main::MOZILLA_OFFICIAL);
my($file);
foreach $file (@$files_to_touch)
{
print "Writing build number to $file from ${file}.in\n";
mozBDate::SubstituteBuildNumber($file, $build_num_file, "${file}.in");
}
}
#-----------------------------------------------
# SetTimeBomb
#-----------------------------------------------
sub SetTimeBomb($$)
{
my ($warn_days, $bomb_days) = @_;
system("perl :mozilla:config:mac-set-timebomb.pl $warn_days $bomb_days");
}
#//--------------------------------------------------------------------------------------------------
#// Regenerate a configuration header file if necessary
#//--------------------------------------------------------------------------------------------------
sub UpdateConfigHeader($)
{
my($config_path) = @_;
my($config, $oldconfig) = ("", "");
my($define, $definevalue, $defines);
my($k, $l,);
foreach $k (keys(%main::options))
{
if ($main::options{$k})
{
foreach $l (keys(%{$main::optiondefines{$k}}))
{
$my::defines{$l} = $main::optiondefines{$k}{$l};
print "Setting up my::defines{$l}\n";
}
}
}
my $config_headerfile = current_directory().$config_path;
if (-e $config_headerfile)
{
open(CONFIG_HEADER, "< $config_headerfile") || die "$config_headerfile: $!\n";
my($line);
while ($line = <CONFIG_HEADER>)
{
if ($line =~ m/#define\s+([^\s]*)\s+([^\s]*)\s*\n/)
{
$define = $1;
$definevalue = $2;
#canonicalize so that whitespace changes are not significant
my $canon_value = "#define " . $define . " " . $definevalue . "\n";
$oldconfig .= $canon_value;
if (exists ($my::defines{$define}) and ($my::defines{$define} == $definevalue))
{
delete $my::defines{$define};
$config .= $canon_value;
}
}
}
close(CONFIG_HEADER);
}
if (%my::defines)
{
foreach $k (keys(%my::defines))
{
$config .= "#define " . $k . " " . $my::defines{$k} . "\n";
}
}
my $file_name = basename($config_headerfile);
if (($config ne $oldconfig) || (!-e $config_headerfile))
{
printf("Writing new configuration header $file_name\n");
open(CONFIG_HEADER, "> $config_headerfile") || die "$config_headerfile: $!\n";
print(CONFIG_HEADER "/* This file is auto-generated based on build options. Do not edit. */\n");
print CONFIG_HEADER ($config);
close(CONFIG_HEADER);
MacPerl::SetFileInfo("CWIE", "TEXT", $config_headerfile);
}
else
{
printf("Configuration header $file_name is up-to-date\n");
}
}
1;

View File

@@ -1,660 +0,0 @@
#!perl
package Moz::CodeWarriorLib;
=pod
=head1 NAME
CodeWarriorLib - supply interface to CodeWarrior
=head1 SYNOPSIS
#!perl
use CodeWarriorLib;
CodeWarriorLib::activate();
$had_errors = CodeWarriorLib::build_project(
$project_path, $target_name, $recent_errors_file, $clean_build
);
=head1 DESCRIPTION
Replaces the AppleScript library I<CodeWarriorLib>.
=over 4
=cut
use strict;
use Cwd;
use File::Basename;
use Mac::Types;
use Mac::Events;
use Mac::AppleEvents;
use Mac::AppleEvents::Simple;
use Mac::Processes;
use Mac::MoreFiles;
use Mac::StandardFile;
use vars qw($VERSION);
$VERSION = '1.02';
my($app) = 'CWIE';
my($scriptDir) = cwd(); # could use $0 for this
my($ide_loc_file) = "";
# 0 == don't switch CWIE to front app in do_event(), 1 == do switch
# note: activate() still switches when called
$Mac::AppleEvents::Simple::SWITCH = 0;
# $Mac::AppleEvents::Simple::WARN = 1;
# supply your own path to the source here
#_test('PowerPudgeIV:mozilla:mozilla:');
# If you want to understand the gobbldeygook that's used to build Apple Events,
# you should start by reading the AEGizmos documentation.
=pod
=item _get_project($full_path)
A private routine returning a reference to the open project with the given name,
or else the empty string (when that project is not open)
full_path is a string identifying the project to be built and is of the form,
e.g., "HD:ProjectFolder:MyProject.mcp". It must be supplied.
=cut
sub _get_project ($) {
my(
$full_path, $candidate_projects
) = @_;
$candidate_projects = _doc_named(basename($full_path, '*'));
if ($candidate_projects) {
my($cps) = _get_dobj($candidate_projects);
my($num) = AECountItems($cps);
if ($num) { # is a list
foreach (1 .. AECountItems($cps)) {
my($cp) = AEGetNthDesc($cps, $_);
if (lc $full_path eq lc _full_path($cp)) {
return($cp);
}
}
} else { # is only one, not a list
if (lc $full_path eq lc _full_path($cps)) {
return($cps);
}
}
}
return;
}
=pod
=item build_project
Build a selected target of a project, saving any errors to a file, if supplied.
full_path is a string identifying the project to be built and is of the form,
e.g., "HD:ProjectFolder:MyProject.mcp". It must be supplied.
If target_name is the empty string, the current target of the selected project
will be built, else, target_name should be a string matching a target name in
the selected project.
If error_path is the empty string, errors will not be saved to a file,
else, error_path should be the full path of a file to save error messages into.
=cut
$CodeWarriorLib::CLOSE_PROJECTS_FIRST = 0; # If true we close then make. If false, make then close.
my $last_project_built = "";
my $last_project_was_closed = 0;
sub build_project ($;$$$) {
my(
$full_path, $target_name, $error_path,
$remove_object, $p, $project_was_closed, $had_errors
) = @_;
_close_errors_window();
if ($CodeWarriorLib::CLOSE_PROJECTS_FIRST && ($last_project_built ne $full_path))
{
# If we're in "close first" mode, we don't close if the current project
# is the same as the previous one.
if ($last_project_was_closed) {
$p = _get_project($last_project_built);
_close($p);
}
$last_project_built = $full_path;
$last_project_was_closed = 0; # now refers to the new project
}
$project_was_closed = 0;
while (1) {
$p = _get_project($full_path);
if (!$p) {
if ($project_was_closed) {
print "### Error - request for project document failed after opening\n";
die "### possibly CW Pro 4 bug: be sure to close your Find window\n";
}
$project_was_closed = 1;
$last_project_was_closed = 1;
_open_file($full_path);
} else {
last;
}
}
$had_errors = 0;
if ($target_name eq '') {
if ($remove_object) {_remove_object($p)}
_build($p);
} else {
if ($remove_object) {_remove_object($p, $target_name)}
_build($p, $target_name);
}
if ($error_path ne '') {
_save_errors_window($error_path);
}
$had_errors = _close_errors_window();
if (!$CodeWarriorLib::CLOSE_PROJECTS_FIRST)
{
if ($project_was_closed) {
$p = _get_project($full_path);
_close($p);
}
}
return($had_errors);
}
=pod
=item appIsRunning()
=cut
sub _appIsRunning($)
{
my ($appSignature) = @_;
my ($psi);
my ($found) = 0;
my ($appPSN);
foreach $psi (values(%Process))
{
if ($psi->processSignature() eq $appSignature)
{
$appPSN = $psi->processNumber();
$found = 1;
last;
}
}
return $found;
}
=pod
=item appIsFrontmost()
=cut
sub _appIsFrontmost($)
{
my ($appSignature) = @_;
my ($psi);
my ($found) = 0;
my ($appPSN);
foreach $psi (values(%Process))
{
if ($psi->processSignature() eq $appSignature)
{
$appPSN = $psi->processNumber();
$found = 1;
last;
}
}
return (GetFrontProcess() == $appPSN);
}
=pod
=item activate()
Launches CodeWarrior and brings it to the front.
Once found, path will be saved in $idepath_file for future reference.
Edit or delete this file to change the location of the IDE. If app is
moved, C<activate()> will prompt for a new location.
First looks for an open CodeWarrior app. Second, tries to open previously
saved location in ':idepath.txt'. Third, tries to find it and allow user
to choose it with Navigation Services (if present). Fourth, uses good old
GUSI routines built-in to MacPerl for a Choose Directory dialog box.
=cut
sub activate ($) {
$ide_loc_file = $_[0]; # save in global
my($filepath, $appath, $psi) = ($ide_loc_file);
foreach $psi (values(%Process)) {
if ($psi->processSignature() eq $app) {
$appath = $psi->processAppSpec();
_save_appath($filepath, $appath);
last;
}
}
if (!$appath || !-x $appath) {
$appath = _read_appath($filepath);
}
if (!$appath || ! -x $appath)
{
# make sure that MacPerl is a front process
#ActivateApplication('McPL');
MacPerl::Answer("Please locate the CodeWarrior application.", "OK");
# prompt user for the file name, and store it
my $macFile = StandardGetFile( 0, "APPL");
if ( $macFile->sfGood() )
{
$appath = $macFile->sfFile();
}
else
{
die "Operation canceled\n";
}
# if (eval {require Mac::Navigation}) {
# my($options, $nav);
# Mac::Navigation->import();
# $options = NavGetDefaultDialogOptions();
# $options->message('Where is CodeWarrior IDE?');
# $options->windowTitle('Find CodeWarrior IDE');
# $nav = NavChooseObject($Application{$app}, $options);
# die "CodeWarrior IDE not found.\n" if (!$nav || !$nav->file(1));
# $appath = $nav->file(1);
# } else {
# local(*D);
# my $cwd = `pwd`;
# $appath = _get_folder(
# 'Where is the CW IDE folder?',
# dirname($Application{$app})
# );
# die "CodeWarrior IDE not found.\n" if !$appath;
# opendir(D, $appath) or die $!;
# chdir($appath);
# foreach my $file (sort readdir (D)) {
# my(@app) = MacPerl::GetFileInfo($file);
# if ($app[0] && $app[1] &&
# $app[1] eq 'APPL' && $app[0] eq $app
# ) {
# $appath .= $file;
# last;
# }
# }
# chomp($cwd);
# chdir($cwd);
# }
_save_appath($filepath, $appath);
}
my($lp) = LaunchParam->new(
launchAppSpec => $appath,
launchControlFlags => launchContinue() + launchNoFileFlags()
);
unless (LaunchApplication($lp)) {
unlink($filepath);
die $^E;
}
# wait for CodeWarrior to show up in the list of processes
while (!_appIsRunning('CWIE'))
{
WaitNextEvent();
}
# wait for CodeWarrior to come to the front
while (!_appIsFrontmost('CWIE'))
{
WaitNextEvent();
}
}
=pod
=item getCodeWarriorPath()
Returns a file path relative to the CodeWarrior folder
=cut
sub getCodeWarriorPath($)
{
my($subfolder)=@_;
my($app_path) = _read_appath($ide_loc_file);
if ($app_path eq "") { die "Error: Failed to get CodeWarrior IDE path\n"; }
my($codewarrior_root) = $app_path;
$codewarrior_root =~ s/[^:]*$//;
return ($codewarrior_root . $subfolder);
}
=pod
=item getCodeWarriorIDEName()
Returns the name of the CodeWarrior application
=cut
sub getCodeWarriorIDEName()
{
my($subfolder)=@_;
my($app_path) = _read_appath($ide_loc_file);
if ($app_path eq "") { die "Error: Failed to get CodeWarrior IDE path\n"; }
my(@codewarrior_path) = split(/:/, $app_path);
return pop(@codewarrior_path);
}
=pod
=item quit()
Quits CodeWarrior.
=cut
sub quit() {
$last_project_built = "";
$last_project_was_closed = 0;
my($evt) = do_event(qw/aevt quit/, $app);
}
sub _build ($;$) {
my($evt);
if ($_[1]) {
my($prm) =
q"'----':obj {form:name, want:type(TRGT), seld:TEXT(@), from:" .
AEPrint($_[0]) . '}';
$evt = do_event(qw/CWIE MAKE/, $app, $prm, $_[1]);
} else {
my($prm) = q"'----':" . AEPrint($_[0]);
$evt = do_event(qw/CWIE MAKE/, $app, $prm);
}
}
sub _remove_object ($;$) {
my($evt);
if ($_[1]) {
my($prm) =
q"'----':obj {form:name, want:type(TRGT), seld:TEXT(@), from:" .
AEPrint($_[0]) . '}';
$evt = do_event(qw/CWIE RMOB/, $app, $prm, $_[1]);
} else {
my($prm) = q"'----':" . AEPrint($_[0]);
$evt = do_event(qw/CWIE RMOB/, $app, $prm);
}
}
sub _open_file ($) {
my($prm) =
q"'----':obj {form:name, want:type(alis), " .
q"seld:TEXT(@), from:'null'()}";
do_event(qw/aevt odoc/, $app, $prm, $_[0]);
}
sub import_project ($$) {
my($xml_file, $project_path) = @_;
my($prm) = "kocl:type(PRJD), rtyp:TEXT(@), data:TEXT(@), &subj:'null'()";
my($evt) = do_event(qw/core crel/, $app, $prm, $project_path, $xml_file);
my($result) = _get_event_result($evt);
if ($result eq "") {
_close(_get_project($project_path));
}
return $result;
}
sub export_project ($$) {
my($project_path, $xml_out_path) = @_;
my($p, $project_was_closed);
$project_was_closed = 0;
while (1) {
$p = _get_project($project_path);
if (!$p) {
if ($project_was_closed) {
print "### Error - request for project document failed after opening\n";
die "### possibly CW bug: be sure to close your Find window\n";
}
$project_was_closed = 1;
_open_file($project_path);
} else {
last;
}
}
# avoid problems with the Project Messages window
_close_named_window("Project Messages");
my($prm) =
q"'----':obj {form:indx, want:type(PRJD), " .
q"seld:1, from:'null'()}, kfil:TEXT(@)";
my($evt) = do_event(qw/CWIE EXPT/, $app, $prm, $xml_out_path);
if ($project_was_closed) {
$p = _get_project($project_path);
_close($p);
}
return _get_event_result($evt);
}
sub _doc_named ($) {
my($prm) =
q"'----':obj {form:test, want:type(docu), from:'null'(), " .
q"seld:cmpd{relo:'= ', 'obj1':obj {form:prop, want:type" .
q"(prop), seld:type(pnam), from:'exmn'()}, 'obj2':TEXT(@)}}";
my($evt) = do_event(qw/core getd/, $app, $prm, $_[0]);
return($evt->{REPLY} eq 'aevt\ansr{}' ? undef : $evt);
}
sub _full_path ($) {
my($obj) = $_[0];
my($prm) =
q"'----':obj {form:prop, want:type(prop), seld:type(FILE), " .
q"from:" . AEPrint($_[0]) . q"}, rtyp:type(TEXT)";
my($evt) = do_event(qw/core getd/, $app, $prm);
return MacPerl::MakePath(
MacUnpack('fss ', (
AEGetParamDesc($evt->{REP}, keyDirectObject()))->data()->get()
)
);
}
sub _save_errors_window ($) {
my($prm) =
q"'----':obj {form:name, want:type(alis), seld:TEXT(@), from:'null'()}";
do_event(qw/MMPR SvMs/, $app, $prm, $_[0]);
}
sub _close_errors_window () {
return _close_named_window('Errors & Warnings');
}
sub _close_named_window ($) {
my($window_name) = @_;
my($prm) =
q"'----':obj {form:name, want:type(cwin), " .
q"seld:TEXT(@), from:'null'()}";
my($evt) = do_event(qw/core clos/, $app, $prm, $window_name);
return($evt->{REPLY} eq 'aevt\ansr{}' ? 1 : 0);
}
sub _close () {
my($prm) = q"'----':" . AEPrint($_[0]);
do_event(qw/core clos/, $app, $prm);
}
sub _get_dobj ($) {
return(AEGetParamDesc($_[0]->{REP}, keyDirectObject()));
}
sub _get_folder ($$) {
require 'GUSI.ph';
my($prompt, $default) = @_;
MacPerl::Choose(
GUSI::AF_FILE(), 0, $prompt, '',
GUSI::CHOOSE_DIR() + ($default ? &GUSI::CHOOSE_DEFAULT : 0),
$default
);
}
sub _get_event_result ($)
{
my($evt) = @_;
my($result) = $evt->{ERROR};
if ( $result eq "" && $evt->{ERRNO} != 0 )
{
$result = "unknown error (".$evt->{ERRNO}.")";
}
return $result;
}
sub _save_appath ($$) {
my($cwd) = cwd(); # remember the current working dir
chdir($scriptDir); # change dir to the script dir
local(*F);
open(F, '>' . $_[0]) or die $!;
print F $_[1];
close(F);
chdir($cwd); # restore the cwd
}
sub _read_appath ($) {
my($filepath) = @_;
my($cwd) = cwd(); # remember the current working dir
chdir($scriptDir); # change dir to the script dir
if (! -e $filepath) {
return "";
}
local(*F);
open(F, $filepath);
my($appath) = <F>;
close(F);
chdir($cwd); # restore the cwd
return($appath);
}
sub _test ($) {
activate($ide_loc_file);
my($path) = $_[0];
build_project(
"${path}modules:xml:macbuild:XML.mcp", '',
"${path}build:mac:Mozilla.BuildLog.part"
);
}
1;
=pod
=back
=head1 HISTORY
=over 4
=item v1.02, September 23, 1998
Made fixes in finding and saving location of CodeWarrior IDE.
=item v1.01, June 1, 1998
Made fixes to C<chdir()> in C<activate()>, made C<activate()> more robust
in finding CodeWarrior IDE, added global variable to NOT switch to IDE
for each sent event, a few other fixes.
=item v1.00, May 30, 1998
First shot
=back
=head1 AUTHORS
Chris Nandor F<E<lt>pudge@pobox.comE<gt>>, and the author of the
original I<CodeWarriorLib>, Scott Collins F<E<lt>scc@netscape.comE<gt>>.
=head1 SEE ALSO
BuildProject L<Moz>.
=head1 COPYRIGHT
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):
=cut

View File

@@ -1,573 +0,0 @@
#!perl -w
package Moz::Jar;
#
# Module for creating jar files, either using a jar manifest, or
# simply jarring up folders on disk.
#
require 5.004;
require Exporter;
use strict;
use Archive::Zip;
use File::Path;
use Mac::Files;
use Moz::Moz;
use vars qw( @ISA @EXPORT );
@ISA = qw(Exporter);
@EXPORT = qw(
CreateJarFileFromDirectory
CreateJarFromManifest
WriteOutJarFiles
SanityCheckJarOptions
);
#-------------------------------------------------------------------------------
# Add the contents of a directory to the zip file
#
#-------------------------------------------------------------------------------
sub _addDirToJar($$$$)
{
my($dir, $jar_root, $zip, $compress) = @_;
opendir(DIR, $dir) or die "Error: Cannot open dir $dir\n";
my @files = readdir(DIR);
closedir DIR;
my $unix_jar_root = $jar_root;
$unix_jar_root =~ s|:|/|g; # colon to slash conversion
my $file;
foreach $file (@files)
{
my $filepath = $dir.":".$file;
if (-d $filepath)
{
print "Adding files to jar from $filepath\n";
_addDirToJar($filepath, $jar_root, $zip, $compress);
}
else
{
my $member = Archive::Zip::Member->newFromFile($filepath);
die "Error: Failed to create zip file member $filepath\n" unless $member;
my $unixName = $filepath;
$unixName =~ s|:|/|g; # colon to slash conversion
$unixName =~ s|^$unix_jar_root||; # relativise
$member->fileName($unixName);
# print "Adding $file as $unixName\n";
if ($compress) {
$member->desiredCompressionMethod(Archive::Zip::COMPRESSION_DEFLATED);
} else {
$member->desiredCompressionMethod(Archive::Zip::COMPRESSION_STORED);
}
$zip->addMember($member);
}
}
}
#-------------------------------------------------------------------------------
# Add the contents of a directory to the zip file
#
#-------------------------------------------------------------------------------
sub CreateJarFileFromDirectory($$$)
{
my($srcdir, $jarpath, $compress) = @_;
my $zip = Archive::Zip->new();
_addDirToJar($srcdir, $srcdir, $zip, $compress);
print "Saving zip file...\n";
my $status = $zip->writeToFileNamed($jarpath);
if ($status == 0) {
print "Zipping completed successfully\n";
} else {
print "Error saving zip file\n";
}
# set the file type/creator to something reasonable
MacPerl::SetFileInfo("ZIP ", "ZIP ", $jarpath);
}
#-------------------------------------------------------------------------------
# printZipContents
#
#-------------------------------------------------------------------------------
sub printZipContents($)
{
my($zip) = @_;
my(@members) = $zip->memberNames();
print "Zip contains:\n";
my($member);
foreach $member (@members)
{
print " $member\n";
}
}
#-------------------------------------------------------------------------------
# safeSaveJarFile
#
# Archive::Zip has a problem where you cannot save a zip file on top of
# an existing zip file that it has open, because it holds references
# into that zip. So we have to save to a temp file, then do a swap.
#
# Note that the zip will become invalid after this operation.
# If you want to do further operations on it, you'll have to reread it.
#-------------------------------------------------------------------------------
sub safeSaveJarFile($$)
{
my($zip, $full_dest_path) = @_;
my($temp_file_name) = $full_dest_path."_temp";
($zip->writeToFileNamed($temp_file_name) == Archive::Zip::AZ_OK) || die "Error: died writing jar to temp file $temp_file_name\n";
unlink $full_dest_path;
(rename $temp_file_name, $full_dest_path) || die "Error: Failed to rename $temp_file_name\n";
MacPerl::SetFileInfo("ZIP ", "ZIP ", $full_dest_path);
}
#-------------------------------------------------------------------------------
# addToJarFile
#
# Add a file to a jar file
#
# Parameters:
# 1. Jar ID. Unix path of jar file inside chrome.
# 2. Abs path to jar.mn file (i.e. source) (mac breaks)
# 3. File source, relative to jar.mn path (mac breaks)
# 4. Abs path to the resulting .jar file (mac breaks)
# 5. Relative file path within the jar (unix breaks)
# 6. Reference to hash of jar files
#
#-------------------------------------------------------------------------------
sub addToJarFile($$$$$$$)
{
my($jar_id, $jar_man_dir, $file_src, $jar_path, $file_jar_path, $override, $jars) = @_;
# print "addToJarFile with:\n $jar_man_dir\n $file_src\n $jar_path\n $file_jar_path\n";
unless ($jar_path =~ m/(.+:)([^:]+)$/) { die "Error: Bad jar path $jar_path\n"; }
my($target_dir) = $1;
my($jar_name) = $2;
$target_dir =~ s/[^:]+$//;
# print "¥ $target_dir $jar_name\n";
# find the source file
my($src) = $jar_man_dir.":".$file_src;
if ((!-e $src) && ($file_src =~ m/.+:([^:]+)$/)) # src does not exist. Fall back to looking for src in jar.mn dir
{
$file_src = $1;
$src = $jar_man_dir.":".$file_src;
if (!-e $src) {
die "Error: Can't find chrome file $src\n";
}
}
if ($main::options{chrome_jars})
{
my($zip) = $jars->{$jar_id};
unless ($zip) { die "Error: Can't find Zip entry for $jar_id\n"; }
# print "Adding $file_src to jar file $jar_path at $file_jar_path\n";
my($member) = Archive::Zip::Member->newFromFile($src);
unless ($member) { die "Error: Failed to create zip file member $src\n"; }
$member->fileName($file_jar_path);
my($compress) = 1;
if ($compress) {
$member->desiredCompressionMethod(Archive::Zip::COMPRESSION_DEFLATED);
$member->desiredCompressionLevel(Archive::Zip::COMPRESSION_LEVEL_DEFAULT); # defaults to 6
} else {
$member->desiredCompressionMethod(Archive::Zip::COMPRESSION_STORED);
}
my($old_member) = $zip->memberNamed($file_jar_path);
if ($override)
{
if ($old_member)
{
# print "Overriding $file_jar_path in jar file $jar_id\n";
# need to compare mod dates or use the + here
$zip->removeMember($old_member);
}
$zip->addMember($member);
}
else
{
if ($old_member)
{
#compare dates here
my($member_moddate) = $old_member->lastModTime();
my($file_moddate) = GetFileModDate($src);
if ($file_moddate > $member_moddate)
{
print "Updating older file $file_jar_path in $jar_id\n";
$zip->removeMember($old_member);
$zip->addMember($member);
}
else
{
print "File $file_jar_path in $jar_id is more recent. Not updating.\n";
}
}
else
{
$zip->addMember($member);
}
}
}
if ($main::options{chrome_files}) # we install raw files too
{
my($rel_path) = $file_jar_path;
$rel_path =~ s|/|:|g; # slash to colons
my($dir_name) = $jar_name;
$dir_name =~ s/\.jar$//;
my($dst) = $target_dir.$dir_name.":".$rel_path;
# print "Aliassing $src\n to\n$dst\n";
if ($override)
{
unlink $dst;
MakeAlias($src, $dst); # don't check errors, otherwise we fail on replacement
}
else
{
if (-e $dst)
{
#compare dates here
my($dst_moddate) = GetFileModDate($dst);
my($file_moddate) = GetFileModDate($src);
if ($file_moddate > $dst_moddate)
{
print "Updating older file $rel_path in $dir_name\n";
unlink $dst;
MakeAlias($src, $dst);
}
else
{
print "File $file_jar_path in $jar_id is more recent. Not updating.\n";
}
}
else
{
MakeAlias($src, $dst);
}
}
}
}
#-------------------------------------------------------------------------------
# setupJarFile
#
# setup a zip for writing
#-------------------------------------------------------------------------------
sub setupJarFile($$$)
{
my($jar_id, $dest_path, $jar_hash) = @_;
# print "Creating jar file $jar_id at $jar_path\n";
my($jar_file) = $jar_id;
$jar_file =~ s|/|:|g; # slash to colons
my($full_jar_path) = full_path_to($dest_path.":".$jar_file);
if ($main::options{chrome_jars})
{
my($zip) = $jar_hash->{$jar_id};
if (!$zip) # if we haven't made it already, do so
{
my($zip) = Archive::Zip->new();
$jar_hash->{$jar_id} = $zip;
# does the jar file exist already? If so, read it in
if (-e $full_jar_path)
{
print "Reading in jar file $jar_id\n";
if ($zip->read($full_jar_path) != Archive::Zip::AZ_OK) { die "Error: Failed to re-read $full_jar_path\n"; }
# printZipContents($zip);
}
}
}
else
{
# installing files.
# nothing to do. MakeAlias creates dirs as needed.
# add this jar to the list
$jar_hash->{$jar_id} = 1;
}
}
#-------------------------------------------------------------------------------
# closeJarFile
#
# We're done with this jar file _for this jar.mn_. We may add more entries
# to it later, so keep it open in the hash.
#-------------------------------------------------------------------------------
sub closeJarFile($$)
{
my($jar_path, $jar_hash) = @_;
# print "Closing jar file $jar_path\n";
if ($main::options{chrome_jars})
{
}
else
{
# installing files.
# nothing to do
}
}
#-------------------------------------------------------------------------------
# WriteOutJarFiles
#
# Now we dump out the jars
#-------------------------------------------------------------------------------
sub WriteOutJarFiles($$)
{
my($chrome_dir, $jars) = @_;
unless ($main::options{chrome_jars}) { return; }
my($full_chrome_path) = full_path_to($chrome_dir);
my($key);
foreach $key (keys %$jars)
{
my($zip) = $jars->{$key};
my($rel_path) = $key;
$rel_path =~ s/\//:/g;
my($output_path) = $full_chrome_path.":".$rel_path;
print "Writing zip file $key to $output_path\n";
# ensure the target dirs exist
my($path) = $output_path;
$path =~ s/[^:]+$//;
mkpath($path);
# unlink $output_path; # remove any existing jar
safeSaveJarFile($zip, $output_path);
# $zip is invalid after this operation, so nuke it here
$jars->{$key} = 0;
}
}
#-------------------------------------------------------------------------------
# registerChromePackage
#
# Enter a chrome package into the installed-chrome.txt file
#-------------------------------------------------------------------------------
sub registerChromePackage($$$$$$)
{
my($jar_file, $file_path, $chrome_dir, $jar_hash, $chrome_type, $pkg_name) = @_;
my($manifest_subdir) = $jar_file;
$manifest_subdir =~ s/:/\//g;
my($chrome_entry);
if ($main::options{use_jars}) {
$chrome_entry = "$chrome_type,install,url,jar:resource:/chrome/$manifest_subdir!/$chrome_type/$pkg_name";
} else {
$manifest_subdir =~ s/\.jar$//;
$chrome_entry = "$chrome_type,install,url,resource:/chrome/$manifest_subdir/$chrome_type/$pkg_name";
}
# print "Entering $chrome_entry in installed-chrome.txt\n";
# ensure chrome_dir exists
mkpath($chrome_dir);
my($inst_chrome) = ${chrome_dir}.":installed-chrome.txt";
if (open(CHROMEFILE, "<$inst_chrome")) {
while (<CHROMEFILE>) {
chomp;
if ($_ eq $chrome_entry) {
# $chrome_entry already appears in installed-chrome.txt file
# just update the mod date
my $now = time;
utime($now, $now, $inst_chrome) || die "Error: Couldn't touch $inst_chrome";
print "+++ updating chrome $inst_chrome\n+++\t\t$chrome_entry\n";
close(CHROMEFILE) || die "Error: can't close $inst_chrome: $!";
return 0;
}
}
close(CHROMEFILE) || die "Error: can't close $inst_chrome: $!";
}
open(CHROMEFILE, ">>${inst_chrome}") || die "Error: Failed to open $inst_chrome\n";
print(CHROMEFILE "${chrome_entry}\n");
close(CHROMEFILE) || die "Error: Failed to close $inst_chrome\n";
print "+++ adding chrome $inst_chrome\n+++\t\t$chrome_entry\n";
}
#-------------------------------------------------------------------------------
# Create or add to a jar file from a jar.mn file.
# Both arguments are relative to the mozilla root dir.
#
#
#-------------------------------------------------------------------------------
sub CreateJarFromManifest($$$)
{
my($jar_man_path, $dest_path, $jars) = @_;
if ($main::options{chrome_jars}) {
print "Jarring from $jar_man_path\n";
}
if ($main::options{chrome_files}) {
print "Installing files from $jar_man_path\n";
}
$jar_man_path = full_path_to($jar_man_path);
$dest_path = full_path_to($dest_path);
# if the jars hash is empty, nuke installed-chrome.txt
if (! scalar(%$jars))
{
print "Nuking installed-chrome.txt\n";
my($installed_chrome) = $dest_path.":installed-chrome.txt";
# unlink $installed_chrome;
}
my $jar_man_dir = "";
my $jar_man_file = "";
if ($jar_man_path =~ /(.+):([^:]+)$/)
{
$jar_man_dir = $1; # no trailing :
$jar_man_file = $2;
}
# Keep a hash of jar files, keyed on relative jar path (e.g. "packages/core.jar")
# Entries are open Archive::Zips (if zipping), and installed-chrome entries.
my($jar_id) = ""; # Current foo/bar.jar from jar.mn file
my($jar_file) = ""; # relative path to jar file (from $dest_path), with mac separators
my($full_jar_path);
open(FILE, "<$jar_man_path") || die "Error: could not open \"$jar_man_path\": $!";
while (<FILE>)
{
my($line) = $_;
chomp($line);
# print "$line\n";
if ($line =~ /^\s*\#.*$/) { # skip comments
next;
}
if ($line =~/^([\w\d.\-\_\\\/]+)\:\s*$/) # line start jar file entries
{
$jar_id = $1;
$jar_file = $jar_id;
$jar_file =~ s|/|:|g; # slash to colons
$full_jar_path = $dest_path.":".$jar_file;
setupJarFile($jar_id, $dest_path, $jars);
}
elsif ($line =~ /^(\+?)\s+([\w\d.\-\_\\\/]+)\s*(\([\w\d.\-\_\\\/]+\))?$\s*/) # jar file entry
{
my($override) = ($1 eq "+");
my($file_dest) = $2;
my($file_src) = $3;
if ($file_src) {
$file_src = substr($file_src, 1, -1); #strip the ()
} else {
$file_src = $file_dest;
}
$file_src =~ s|/|:|g;
if ($jar_file ne "") # if jar is open, add to jar
{
if ($file_dest =~ /([\w\d.\-\_]+)\/([\w\d.\-\_\\\/]+)contents.rdf/)
{
my $chrome_type = $1;
my $pkg_name = $2;
registerChromePackage($jar_file, $file_dest, $dest_path, $jars, $chrome_type, $pkg_name);
}
addToJarFile($jar_id, $jar_man_dir, $file_src, $full_jar_path, $file_dest, $override, $jars);
}
else
{
die "Error: bad jar.mn format at $line\n";
}
}
elsif ($line =~ /^\s*$/ ) # blank line
{
if ($jar_file ne "") #if a jar file is open, close it
{
closeJarFile($full_jar_path, $jars);
$jar_file = "";
$full_jar_path = "";
}
}
}
close(FILE);
if ($jar_file ne "") #if a jar file is open, close it
{
closeJarFile($full_jar_path, $jars);
}
}
1;

View File

@@ -1,228 +0,0 @@
#!perl -w
package Moz::MacCVS;
# package Mac::Apps::MacCVS; this should really be the name of the package
# but due to our directory hierarchy in mozilla, I am not doing it
require 5.004;
require Exporter;
use strict;
use Exporter;
use vars qw($VERSION @ISA @EXPORT);
use Cwd;
use File::Basename;
use Mac::StandardFile;
use Mac::AppleEvents;
use Mac::AppleEvents::Simple;
@ISA = qw(Exporter);
@EXPORT = qw(new describe checkout update);
$VERSION = "1.00";
# If you want to understand the gobbldeygook that's used to build Apple Events,
# you should start by reading the AEGizmos documentation.
# Architecture:
# cvs session object:
# name - session name
# session_file - session file
#
#
my($last_error) = 0;
my($gAppSig) = 'Mcvs'; # MacCVS Pro
#
# utility routines
#
sub _checkForEventError($)
{
my($evt) = @_;
if ($evt->{ERRNO} != 0)
{
print STDERR "Error. Script returned '$evt->{ERROR} (error $evt->{ERRNO})\n";
$last_error = $evt->{ERRNO};
return 0;
}
return 1; # success
}
#
# Session object methods
#
sub new
{
my ( $proto, $session_file) = @_;
my $class = ref($proto) || $proto;
my $self = {};
if ( defined($session_file) && ( -e $session_file) )
{
$self->{"name"} = basename( $session_file );
$self->{"session_file"} = $session_file;
bless $self, $class;
return $self;
}
else
{
print STDERR "MacCVS->new cvs file < $session_file > does not exist\n";
return;
}
}
# makes sure that the session is open
# assertSessionOpen()
# returns 1 on success
sub assertSessionOpen()
{
my ($self) = shift;
$last_error = 0;
my($prm) =
q"'----':obj {form:name, want:type(alis), seld:TEXT(@), from:'null'()}";
my($evt) = do_event(qw/aevt odoc/, $gAppSig, $prm, $self->{session_file});
return _checkForEventError($evt);
}
# prints the cvs object, used mostly for debugging
sub describe
{
my($self) = shift;
$last_error = 0;
print "MacCVS:: name: ", $self->{name}, " session file: ", $self->{session_file}, "\n";
}
# checkout( self, module, revision, date)
# MacCVS checkout command
# returns 1 on success.
sub checkout()
{
my($self, $module, $revision, $date ) = @_;
unless( defined ($module) ) { $module = ""; } # get rid of the pesky undefined warnings
unless( defined ($revision) ) { $revision = ""; }
unless( defined ($date) ) { $date = ""; }
$last_error = 0;
$self->assertSessionOpen() || die "Error: failed to open MacCVS session file at $self->{session_file}\n";
my($revstring) = ($revision ne "") ? $revision : "(none)";
my($datestring) = ($date ne "") ? $date : "(none)";
print "Checking out $module with revision $revstring, date $datestring\n";
my($prm) =
q"'----':obj {form:name, want:type(docu), seld:TEXT(@), from:'null'()}, ".
q"modl:'TEXT'(@), tagr:'TEXT'(@), tagd:'TEXT'(@) ";
my($evt) = do_event(qw/MCvs cout/, $gAppSig, $prm, $self->{name}, $module, $revision, $date);
return _checkForEventError($evt);
}
# update( self, branch tag, list of paths)
# MacCVS udate command
# returns 1 on success.
# NOTE: MacCVS Pro does not correctly support this stuff yet (as of version 2.7d5).
sub update()
{
my($self, $branch, $paths ) = @_;
$last_error = 0;
$self->assertSessionOpen() || die "Error: failed to open MacCVS session file at $self->{session_file}\n";
if ($branch eq "HEAD") {
$branch = "";
}
my($paths_list) = "";
my($path);
foreach $path (@$paths)
{
if ($paths_list ne "") {
$paths_list = $paths_list.", ";
}
$paths_list = $paths_list."Ò".$path."Ó";
}
my($prm) =
q"'----':obj {form:name, want:type(docu), seld:TEXT(@), from:'null'()}, ".
q"tagr:'TEXT'(@), tFls:[";
$prm = $prm.$paths_list."]";
my($evt) = do_event(qw/MCvs updt/, $gAppSig, $prm, $self->{name}, $branch);
return _checkForEventError($evt);
};
sub getLastError()
{
return $last_error;
}
1;
=pod
=head1 NAME
MacCVS - Interface to MacCVS
=head1 SYNOPSIS
use MacCVS;
$session = MacCVS->new( <session_file_path>) || die "cannot create session";
$session->checkout([module] [revision] [date]) || die "Could not check out";
=head1 DESCRIPTION
This is a MacCVS interface for talking to MacCVS Pro client.
MacCVSSession is the class used to manipulate the session
=item new
MacCVS->new( <cvs session file path>);
Creates a new session. Returns undef on failure.
=item checkout( <module> [revision] [date] )
cvs checkout command. Revision and date are optional
returns 0 on failure
=cut
=head1 SEE ALSO
=over
=item MacCVS Home Page
http://www.maccvs.org/
=back
=head1 AUTHORS
Aleks Totic atotic@netscape.com
Simon Fraser sfraser@netscape.com
=cut
__END__

View File

@@ -1,603 +0,0 @@
=head1 NAME
B<Moz> - routines for automating CodeWarrior builds, and some extra-curricular
activities related to building Mozilla
=head1 SYNOPSIS
use Moz;
OpenErrorLog(":::BuildLog");
StopForErrors();
$Moz::QUIET = 1;
InstallFromManifest(":projects:MANIFEST", $dist_dir);
BuildProjectClean(":projects:SomeProject.mcp", "SomeTarget");
MakeAlias(":projects:SomeProject.shlb", $dist_dir);
DontStopForErrors();
BuildProject(":projects:SomeOtherProject.mcp", "SomeTarget");
=head1 DESCRIPTION
B<Moz> comprises the routines needed to slap CodeWarrior around, force it
to build a sequence of projects, report the results, and a few other things.
This module should only contain functions that are generic to any build,
not just the Mozilla build.
=cut
package Moz::Moz;
require Exporter;
use Cwd;
use File::Copy;
use File::Path;
use File::Basename;
use Mac::Types;
use Mac::Events;
use Mac::Processes;
use ExtUtils::Manifest 'maniread';
use Moz::CodeWarriorLib;
@ISA = qw(Exporter);
@EXPORT = qw( LaunchCodeWarrior
GetCodeWarriorRelativePath
current_directory
full_path_to
DoBuildProject
ImportXMLProject
ExportProjectToXML
OpenErrorLog
MakeAlias
GetFileModDate
StopForErrors
DontStopForErrors
InstallFromManifest
InstallResources
RedirectOutputToFile
Delay
ActivateApplication
IsProcessRunning);
@EXPORT_OK = qw(CloseErrorLog QUIET);
sub current_directory()
{
my $current_directory = cwd();
chop($current_directory) if ( $current_directory =~ m/:$/ );
return $current_directory;
}
sub full_path_to($)
{
my ($path) = @_;
if ( $path =~ m/^[^:]+$/ )
{
$path = ":" . $path;
}
if ( $path =~ m/^:/ )
{
$path = current_directory() . $path;
}
return $path;
}
$logging = 0;
$recent_errors_file = "";
$stop_on_1st_error = 1;
$QUIET = 0;
=head2 Logging all the errors and warnings - C<OpenErrorLog($log_file)>, C<CloseErrorLog()>
The warnings and errors generated in the course of building projects can be logged to a file.
Tinderbox uses this facility to show why a remote build failed.
Logging is off by default.
Start logging at any point in your build process with C<OpenErrorLog($log_file)>.
Stop with C<CloseErrorLog()>.
You never need to close the log explicitly, unless you want to just log a couple of projects in the middle of a big list.
C<CloseErrorLog()> is not exported by default.
=cut
sub CloseErrorLog()
{
if ( $logging )
{
close(ERROR_LOG);
$logging = 0;
StopForErrors() if $stop_on_1st_error;
}
}
sub OpenErrorLog($)
{
my ($log_file) = @_;
CloseErrorLog();
if ( $log_file )
{
$log_file = full_path_to($log_file);
open(ERROR_LOG, ">$log_file") || die "Error: Can't open $log_file\n";
MacPerl::SetFileInfo("CWIE", "TEXT", $log_file);
$log_file =~ m/.+:(.+)/;
$recent_errors_file = full_path_to("$1.part");
$logging = 1;
}
}
=head2 Stopping before it's too late - C<StopForErrors()>, C<DontStopForErrors()>
When building a long list of projects, you decide whether to continue building subsequent projects when one fails.
By default, your build script will C<die> after the first project that generates an error while building.
Change this behavior with C<DontStopForErrors()>.
Re-enable it with C<StopForErrors()>.
=cut
sub StopForErrors()
{
$stop_on_1st_error = 1;
# Can't stop for errors unless we notice them.
# Can't notice them unless we are logging.
# If the user didn't explicitly request logging, log to a temporary file.
if ( ! $recent_errors_file )
{
OpenErrorLog("${TMPDIR}BuildResults");
}
}
sub DontStopForErrors()
{
$stop_on_1st_error = 0;
}
sub log_message($)
{
if ( $logging )
{
my ($message) = @_;
print ERROR_LOG $message;
}
}
sub log_message_with_time($)
{
if ( $logging )
{
my ($message) = @_;
my $time_stamp = localtime();
log_message("$message ($time_stamp)\n");
}
}
sub log_recent_errors($)
{
my ($project_name) = @_;
my $found_errors = 0;
if ( $logging )
{
open(RECENT_ERRORS, "<$recent_errors_file");
while( <RECENT_ERRORS> )
{
if ( /^Error/ || /^CouldnÕt find project file/ || /^Link Error/ )
{
# if (!$found_errors)
# print $_;
$found_errors = 1;
}
print ERROR_LOG $_;
}
close(RECENT_ERRORS);
unlink("$recent_errors_file");
}
if ( $stop_on_1st_error && $found_errors )
{
print ERROR_LOG "### Build failed.\n";
die "### Errors encountered building \"$project_name\".\n";
}
}
sub DoBuildProject($$$)
{
my ($project_path, $target_name, $clean_build) = @_;
$project_path = full_path_to($project_path);
# $project_path =~ m/.+:(.+)/;
# my $project_name = $1;
log_message_with_time("### Building \"$project_path\"");
# Check that the given project exists
if (! -e $project_path)
{
print ERROR_LOG "### Build failed.\n";
die "### Can't find project file \"$project_path\".\n";
}
print "Building \"$project_path\[$target_name\]\"\n";
$had_errors = Moz::CodeWarriorLib::build_project(
$project_path, $target_name, $recent_errors_file, $clean_build
);
WaitNextEvent();
# $had_errors =
#MacPerl::DoAppleScript(<<END_OF_APPLESCRIPT);
# tell (load script file "$CodeWarriorLib") to BuildProject("$project_path", "$project_name", "$target_name", "$recent_errors_file", $clean_build)
#END_OF_APPLESCRIPT
# Append any errors to the globally accumulated log file
# if ( $had_errors ) # Removed this test, because we want warnings, too. -- jrm
{
log_recent_errors($project_path);
}
}
sub ImportXMLProject($$)
{
my ($xml_path, $project_path) = @_;
# my ($codewarrior_ide_name) = Moz::CodeWarriorLib::getCodeWarriorIDEName();
# my $ascript = <<EOS;
# tell application "$codewarrior_ide_name"
# make new (project document) as ("$project_path") with data ("$xml_path")
# end tell
#EOS
# print $ascript."\n";
# my($result) = MacPerl::DoAppleScript($ascript);
# unless ($result) { die "Error: ImportXMLProject AppleScript failed $^E $result\n"; }
#
my($import_error) = Moz::CodeWarriorLib::import_project($xml_path, $project_path);
if ($import_error ne "") {
die "Error: ImportXMLProject failed with error $import_error\n";
}
}
sub ExportProjectToXML($$)
{
my ($project_path, $xml_path) = @_;
my (@suffix_list) = (".mcp");
my ($project_name, $project_dir, $suffix) = fileparse($project_path, @suffix_list);
if ($suffix eq "") { die "Project: $project_path doesn't look like a project file.\n"; }
if (-e $xml_path) {
print "$xml_path exists - not exporting $project_path\n";
}
else {
print "Exporting $project_path to $xml_path\n";
my($export_error) = Moz::CodeWarriorLib::export_project($project_path, $xml_path);
if ($export_error ne "") {
die "Error: export_project failed with error '$export_error'\n";
}
if (! -e $xml_path) {
die "Error: XML export to $xml_path failed\n";
}
}
}
=head2 Miscellaneous
C<MakeAlias($old_file, $new_file)> functions like C<symlink()>, except with better argument defaulting and more explicit error messages.
=cut
sub MakeAlias($$)
{
my ($old_file, $new_file) = @_;
# if the directory to hold $new_file doesn't exist, create it
if ( ($new_file =~ m/(.+:)/) && !-d $1 )
{
mkpath($1);
}
# if a leaf name wasn't specified for $new_file, use the leaf from $old_file
if ( ($new_file =~ m/:$/) && ($old_file =~ m/.+:(.+)/) )
{
$new_file .= $1;
}
my $message = "Can't create a Finder alias (at \"$new_file\")\n for \"$old_file\"; because ";
die "Error: $message \"$old_file\" doesn't exist.\n" unless -e $old_file;
die "Error: $message I won't replace an existing (non-alias) file with an alias.\n" if ( -e $new_file && ! -l $new_file );
# now: $old_file exists; $new_file doesn't (or else, is an alias already)
if ( -l $new_file )
{
# ...then see if it already points to $old_file
my $current_target = full_path_to(readlink($new_file));
my $new_target = full_path_to($old_file);
return if ( $current_target eq $new_target );
# if the desired alias already exists and points to the right thing, then we're done
unlink $new_file;
}
symlink($old_file, $new_file) || die "Error: $message symlink returned an unexpected error.\n";
}
=pod
C<InstallFromManifest()>
=cut
sub InstallFromManifest($;$$)
{
my ($manifest_file, $dest_dir, $flat) = @_;
$flat = 0 unless defined($flat); # if $flat, all rel. paths in MANIFEST get aliased to the root of $dest_dir
$dest_dir ||= ":";
$manifest_file =~ m/(.+):/;
my $source_dir = $1;
chop($dest_dir) if $dest_dir =~ m/:$/;
#Mac::Events->import();
WaitNextEvent();
if ($flat)
{
print "Doing manifest on \"$manifest_file\" FLAT\n" unless $QUIET;
}
else
{
print "Doing manifest on \"$manifest_file\"\n" unless $QUIET;
}
my $read = maniread(full_path_to($manifest_file));
foreach $file (keys %$read)
{
next unless $file;
$subdir = ":";
if (!$flat && ($file =~ /:.+:/ ))
{
$subdir = $&;
}
$file = ":$file" unless $file =~ m/^:/;
MakeAlias("$source_dir$file", "$dest_dir$subdir");
}
}
=pod
C<InstallResources()>
=cut
# parameters are path to MANIFEST file, destination dir, true (to make copies) or false (to make aliases)
sub InstallResources($;$;$)
{
my ($manifest_file, $dest_dir, $copy_files) = @_;
$dest_dir ||= ":";
mkpath($dest_dir) if !-d $dest_dir;
$manifest_file =~ m/(.+):/;
my $source_dir = $1;
chop($dest_dir) if $dest_dir =~ m/:$/;
WaitNextEvent();
print "Installing resources from \"$manifest_file\"\n" unless $QUIET;
my $read = maniread(full_path_to($manifest_file));
foreach $file (keys %$read)
{
next unless $file;
if ($copy_files)
{
copy("$source_dir:$file", "$dest_dir:$file");
}
else
{
MakeAlias("$source_dir:$file", "$dest_dir:$file");
}
}
}
#//--------------------------------------------------------------------------------------------------
#// Delay
#//--------------------------------------------------------------------------------------------------
sub Delay($)
{
my ($delay_seconds) = @_;
$now = time;
$exit_time = $now + $delay_seconds;
while ($exit_time > $now) {
$now = time;
}
}
#//--------------------------------------------------------------------------------------------------
#// GetFileModDate
#//--------------------------------------------------------------------------------------------------
sub GetFileModDate($)
{
my($filePath)=@_;
my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
$atime,$mtime,$ctime,$blksize,$blocks) = stat($filePath);
return $mtime;
}
#//--------------------------------------------------------------------------------------------------
#// LaunchCodeWarrior
#//--------------------------------------------------------------------------------------------------
sub LaunchCodeWarrior($)
{
my($idepath_file) = @_; # full path to IDE location file
my($cur_dir) = cwd();
# this both launches and writes the IDE path file
Moz::CodeWarriorLib::activate($idepath_file);
chdir($cur_dir);
}
#//--------------------------------------------------------------------------------------------------
#// GetCodeWarriorRelativePath
#//--------------------------------------------------------------------------------------------------
sub GetCodeWarriorRelativePath($)
{
my($rel_path) = @_;
return Moz::CodeWarriorLib::getCodeWarriorPath($rel_path);
}
#//--------------------------------------------------------------------------------------------------
#// RedirectOutputToFile
#//--------------------------------------------------------------------------------------------------
sub RedirectOutputToFile($)
{
my($log_file) = @_;
# ensure that folders in the path exist
my($logdir) = "";
my($logfile) = $log_file;
if ($log_file =~ /(.+?:)([^:]+)$/) # ? for non-greedy match
{
$logdir = $1;
$logfile = $2;
mkpath($logdir);
}
print "Output is now being redirected to the file '$log_file'\n";
open(STDOUT, "> $log_file") || die "Can't redirect stdout";
open(STDERR, ">&STDOUT") || die "Can't dup stdout";
select(STDERR); $| = 1; # make unbuffered
select(STDOUT); $| = 1; # make unbuffered
MacPerl::SetFileInfo("CWIE", "TEXT", $log_file);
}
#//--------------------------------------------------------------------------------------------------
#// ActivateApplication
#//--------------------------------------------------------------------------------------------------
sub ActivateApplication($)
{
my ($appSignature) = @_;
my ($psi, $found);
my ($appPSN);
$found = 0;
foreach $psi (values(%Process))
{
if ($psi->processSignature() eq $appSignature)
{
$appPSN = $psi->processNumber();
$found = 1;
last;
}
}
if ($found == 0 || SameProcess($appPSN, GetFrontProcess()))
{
return;
}
SetFrontProcess($appPSN);
while (GetFrontProcess() != $appPSN)
{
WaitNextEvent();
}
}
#//--------------------------------------------------------------------------------------------------
#// IsProcessRunning
#//--------------------------------------------------------------------------------------------------
sub IsProcessRunning($)
{
my($processName, $psn, $psi) = @_;
while ( ($psn, $psi) = each(%Process) ) {
if ($psi->processName eq $processName) { return 1; }
}
return 0;
}
1;
=head1 AUTHORS
Scott Collins <scc@netscape.com>, Simon Fraser <sfraser@netscape.com>, Chris Yeh <cyeh@netscape.com>
=head1 SEE ALSO
BuildMozillaDebug.pl (et al), BuildList.pm, CodeWarriorLib (an AppleScript library)
=head1 COPYRIGHT
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):
=cut

View File

@@ -1,272 +0,0 @@
package Moz::Prefs;
require 5.004;
require Exporter;
# Package that attempts to read a file from the Preferences folder,
# and get build settings out of it
use strict;
use Exporter;
use File::Path;
use Mac::Files;
use vars qw(@ISA @EXPORT);
@ISA = qw(Exporter);
@EXPORT = qw(ReadMozUserPrefs);
#-------------------------------------------------------------------------------
#
# GetPrefsFolder
#
#-------------------------------------------------------------------------------
sub GetPrefsFolder()
{
my($prefs_folder) = FindFolder(kOnSystemDisk, kPreferencesFolderType, 1);
return $prefs_folder.":Mozilla build prefs";
}
#-------------------------------------------------------------------------------
#
# SetArrayValue
#
#-------------------------------------------------------------------------------
sub SetArrayValue($$$)
{
my($array_ref, $index1, $index2) = @_;
my($index);
foreach $index (@$array_ref)
{
if ($index->[0] eq $index1)
{
$index->[1] = $index2;
return 1;
}
}
return 0;
}
#-------------------------------------------------------------------------------
#
# WriteDefaultPrefsFile
#
#-------------------------------------------------------------------------------
sub WriteDefaultPrefsFile($)
{
my($file_path) = @_;
my($file_contents);
$file_contents = <<'EOS';
% You can use this file to customize the Mozilla build system.
% The following kinds of lines are allowable:
% Comment lines, which start with a '%' in the first column
% Lines which modify the default build settings. For the list of flags,
% see MozBuildFlags.pm. Examples are:
%
% build pull 0 % don't pull
% options mng 1 % turn mng on
%
% Line containing the special 'buildfrom' flag, which specifies
% where to start the build. Example:
%
% buildfrom nglayout % where to start the build
%
% Lines which specify the location of the files used to store paths
% to the CodeWarrior IDE, and the MacCVS Pro session file. Note quoting
% of paths containing whitespace. Examples:
%
% filepath idepath ::codewarrior.txt
% filepath sessionpath ":Some folder:MacCVS session path.txt"
%
% Lines which modify the build settings like %main::DEBUG.
% Any lines which do not match either of the above are assumed
% to set variables on $main::. Examples:
%
% MOZILLA_OFFICIAL 1
%
EOS
$file_contents =~ s/%/#/g;
local(*PREFS_FILE);
open(PREFS_FILE, "> $file_path") || die "Could not write default prefs file\n";
print PREFS_FILE ($file_contents);
close(PREFS_FILE);
MacPerl::SetFileInfo("McPL", "TEXT", $file_path);
}
#-------------------------------------------------------------------------------
#
# HandlePrefSet
#
#-------------------------------------------------------------------------------
sub HandlePrefSet($$$$)
{
my($flags, $name, $value, $desc) = @_;
if (SetArrayValue($flags, $name, $value)) {
print "Prefs set $desc flag '$name' to '$value'\n";
} else {
die "$desc setting '$name' is not a valid option\n";
}
}
#-------------------------------------------------------------------------------
#
# HandleBuildFromPref
#
#-------------------------------------------------------------------------------
sub HandleBuildFromPref($$)
{
my($build_array, $name) = @_;
my($setting) = 0;
my($index);
foreach $index (@$build_array)
{
if ($index->[0] eq $name) {
$setting = 1;
}
$index->[1] = $setting;
}
if ($setting == 1) {
print "Building from $name onwards, as specified by prefs\n";
} else {
printf "Failed to find buildfrom setting '$name'\n";
}
}
#-------------------------------------------------------------------------------
#
# ReadPrefsFile
#
#-------------------------------------------------------------------------------
sub ReadPrefsFile($$$$$)
{
my($file_path, $build_flags, $options_flags, $filepath_flags, $create_if_missing) = @_;
local(*PREFS_FILE);
if (open(PREFS_FILE, "< $file_path"))
{
print "Reading build prefs from '$file_path'\n";
while (<PREFS_FILE>)
{
my($line) = $_;
chomp($line);
if ($line =~ /^\#/ || $line =~ /^\s*$/) { # ignore comments and empty lines
next;
}
if (($line =~ /^\s*([^#\s]+)\s+([^#\s]+)\s+\"(.+)\"(\s+#.+)?/) ||
($line =~ /^\s*([^#\s]+)\s+([^#\s]+)\s+\'(.+)\'(\s+#.+)?/) ||
($line =~ /^\s*([^#\s]+)\s+([^#\s]+)\s+([^#\s]+)(\s+#.+)?/))
{
my($array_name) = $1;
my($option_name) = $2;
my($option_value) = $3;
# print "Read '$array_name' '$option_name' '$option_value'\n";
if ($array_name eq "build")
{
HandlePrefSet($build_flags, $option_name, $option_value, "Build");
}
elsif ($array_name eq "options")
{
HandlePrefSet($options_flags, $option_name, $option_value, "Options");
}
elsif ($array_name eq "filepath" && $option_name && $option_value)
{
HandlePrefSet($filepath_flags, $option_name, $option_value, "Filepath");
}
else
{
print "Unknown pref option at $line\n";
}
}
elsif ($line =~ /^\s*buildfrom\s+([^#\s]+)(\s+#.+)?/)
{
my($build_start) = $1;
HandleBuildFromPref($build_flags, $build_start);
}
elsif ($line =~ /^\s*([^#\s]+)\s+([^#\s]+)(\s+#.+)?/)
{
my($build_var) = $1;
my($var_setting) = $2;
print "Setting \$main::$build_var to $var_setting\n";
eval "\$main::$build_var = \"$var_setting\"";
}
else
{
print "Unrecognized input line at $line\n";
}
}
close(PREFS_FILE);
}
elsif ($create_if_missing)
{
print "No prefs file found at $file_path; using defaults\n";
my($folder_path) = $file_path;
$folder_path =~ s/[^:]+$//;
mkpath($folder_path);
WriteDefaultPrefsFile($file_path);
}
}
#-------------------------------------------------------------------------------
#
# ReadMozUserPrefs
#
#-------------------------------------------------------------------------------
sub ReadMozUserPrefs($$$$)
{
my($prefs_file_name, $build_flags, $options_flags, $filepath_flags) = @_;
if ($prefs_file_name eq "") { return; }
# if local prefs exist, just use those. Othewise, look in the prefs folder
if (-e $prefs_file_name)
{
# read local prefs
ReadPrefsFile($prefs_file_name, $build_flags, $options_flags, $filepath_flags, 0);
}
else
{
# first read prefs folder prefs
my($prefs_path) = GetPrefsFolder();
$prefs_path .= ":$prefs_file_name";
ReadPrefsFile($prefs_path, $build_flags, $options_flags, $filepath_flags, 1);
}
}
1;

View File

@@ -1,932 +0,0 @@
#!/usr/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.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):
# Simon Fraser <sfraser@netscape.com>
#
package Moz::ProjectXML;
require 5.004;
require Exporter;
use strict;
use Exporter;
use Cwd;
use XML::DOM;
use vars qw(@ISA @EXPORT);
@ISA = qw(Exporter);
@EXPORT = qw(
ParseXMLDocument
DisposeXMLDocument
WriteXMLDocument
CleanupPro5XML
GetTargetsList
CloneTarget
SetAsSharedLibraryTarget
SetAsStaticLibraryTarget
AddTarget
RemoveTarget
GetTargetSetting
SetTargetSetting
getChildElementTextContents
);
#--------------------------------------------------------------------------------------------------
# A module for reading, manipulating, and writing XML-format CodeWarrior project files.
#
# Sample usage:
#
# use ProjectXML;
#
# my $doc = ProjectXML::ParseXMLDocument("Test.mcp.xml");
# ProjectXML::CloneTarget($doc, "Test.shlb", "Test.lib");
# ProjectXML::SetAsStaticLibraryTarget($doc, "Test.lib", "TestOutput.lib");
# ProjectXML::WriteXMLDocument($doc, "Test_out.xml");
# ProjectXML::DisposeXMLDocument($doc);
#
#--------------------------------------------------------------------------------------------------
#//--------------------------------------------------------------------------------------------------
#// ParseXMLDocument
#// Note that the caller must call DisposeXMLDocument on the returned doc
#//--------------------------------------------------------------------------------------------------
sub ParseXMLDocument($)
{
my($doc_path) = @_;
my $parser = new XML::DOM::Parser(ErrorContext => 2);
my $doc = $parser->parsefile($doc_path);
return $doc;
}
#//--------------------------------------------------------------------------------------------------
#// DisposeXMLDocument
#// Needed to avoid memory leaks - cleanup circular references for garbage collection
#//--------------------------------------------------------------------------------------------------
sub DisposeXMLDocument($)
{
my($doc) = @_;
$doc->dispose();
}
#//--------------------------------------------------------------------------------------------------
#// WriteXMLDocument
#//--------------------------------------------------------------------------------------------------
sub _pro5_tag_compression($$)
{
return 1; # Pro 5 is broken and can't import XML with <foo/> style tags
}
sub _pro6plus_tag_compression($$)
{
return 0; # Pro 6 can deal with empty XML tags like <foo/>
}
sub WriteXMLDocument($$$)
{
my($doc, $file_path, $ide_version) = @_;
if ($ide_version eq "4.0")
{
XML::DOM::setTagCompression(\&_pro5_tag_compression);
}
else
{
XML::DOM::setTagCompression(\&_pro6plus_tag_compression);
}
$doc->printToFile($file_path);
}
#//--------------------------------------------------------------------------------------------------
#// CleanupPro5XML
#// XML Projects exported by Pro 5 contain garbage data under the MWMerge_MacOS_skipResources
#// setting. This routine cleans this up, saving the result to a new file
#//--------------------------------------------------------------------------------------------------
sub CleanupPro5XML($$)
{
my($xml_path, $out_path) = @_;
local(*XML_FILE);
open(XML_FILE, "< $xml_path") || die "Error: failed to open file $xml_path\n";
local(*CLEANED_FILE);
open(CLEANED_FILE, "> $out_path") || die "Error: failed to open file $out_path for writing\n";
my $in_skip_resources_settings = 0;
while(<XML_FILE>)
{
my($line) = $_;
if ($line =~ /^<\?codewarrior/) # is processing inst line
{
my $test_line = $line;
chomp($test_line);
my $out_line = $test_line;
if ($test_line =~ /^<\?codewarrior\s+exportversion=\"(.+)\"\s+ideversion=\"(.+)\"\s*\?>$/)
{
my $export_version = $1;
my $ide_version = $2;
$ide_version = "4.0_mozilla"; # pseudo IDE version so we know we touched it
$out_line = "<?codewarrior exportversion=\"".$export_version."\" ideversion=\"".$ide_version."\"?>";
}
print CLEANED_FILE "$out_line\n";
next;
}
if ($line =~ /MWMerge_MacOS_skipResources/)
{
$in_skip_resources_settings = 1;
print CLEANED_FILE "$line";
}
elsif($in_skip_resources_settings && $line =~ /<!-- Settings for/)
{
# leaving bad settings lines. Write closing tag
print CLEANED_FILE " <!-- Corrupted setting entries removed by script -->\n";
print CLEANED_FILE " </SETTING>\n\n";
print CLEANED_FILE "$line";
$in_skip_resources_settings = 0;
}
elsif (!$in_skip_resources_settings)
{
print CLEANED_FILE "$line";
}
}
close(XML_FILE);
close(CLEANED_FILE);
}
#--------------------------------------------------------------------------------------------------
# SniffProjectXMLIDEVersion
#
#--------------------------------------------------------------------------------------------------
sub SniffProjectXMLIDEVersion($)
{
my($xml_path) = @_;
my $found_version = "";
local(*XML_FILE);
open(XML_FILE, "< $xml_path") || die "Error: failed to open file $xml_path\n";
while(<XML_FILE>)
{
my($line) = $_;
chomp($line);
if ($line =~ /^<\?codewarrior/) # is processing inst line
{
unless ($line =~ /^<\?codewarrior\s+exportversion=\"(.+)\"\s+ideversion=\"(.+)\"\s*\?>$/)
{
die "Error: Failed to find ideversion in $xml_path in line $line\n";
}
my $export_version = $1;
my $ide_version = $2;
$found_version = $ide_version;
last;
}
}
close(XML_FILE);
return $found_version;
}
#//--------------------------------------------------------------------------------------------------
#// GetTargetsList
#// Returns an array of target names
#//--------------------------------------------------------------------------------------------------
sub GetTargetsList($)
{
my($doc) = @_;
my $nodes = $doc->getElementsByTagName("TARGET");
my $n = $nodes->getLength;
my @target_names;
for (my $i = 0; $i < $n; $i++)
{
my ($node) = $nodes->item($i);
my($target_name) = getChildElementTextContents($node, "NAME");
push(@target_names, $target_name);
}
return @target_names;
}
#//--------------------------------------------------------------------------------------------------
#// CloneTarget
#// Clone the named target, renaming it to 'new_name'
#//--------------------------------------------------------------------------------------------------
sub CloneTarget($$$)
{
my($doc, $target_name, $new_name) = @_;
my $target_node = getTargetNode($doc, $target_name);
# clone here
my $target_clone = $target_node->cloneNode(1); # deep clone
# -- munge target settings --
# set the target name field
setChildElementTextContents($doc, $target_clone, "NAME", $new_name);
# set the targetname pref
setTargetNodeSetting($doc, $target_clone, "Targetname", $new_name);
# -- insert new target subtree --
my $target_list = $target_node->getParentNode();
$target_list->appendChild($target_clone);
# -- now add to targetorder --
my (@target_order_nodes) = getChildOfDocument($doc, "TARGETORDER");
my $target_order = @target_order_nodes[0];
my $new_order = $doc->createElement("ORDEREDTARGET");
my $order_name = $doc->createElement("NAME");
$new_order->appendChild($order_name);
setChildElementTextContents($doc, $new_order, "NAME", $new_name);
$target_order->appendChild($new_order);
}
#//--------------------------------------------------------------------------------------------------
#// SetAsSharedLibraryTarget
#//
#//--------------------------------------------------------------------------------------------------
sub SetAsSharedLibraryTarget($$$)
{
my($doc, $target_name, $output_name) = @_;
my $target_node = getTargetNode($doc, $target_name);
setTargetNodeSetting($doc, $target_node, "MWProject_PPC_type", "SharedLibrary");
setTargetNodeSetting($doc, $target_node, "MWProject_PPC_filetype", "1936223330"); #'shlb'
setTargetNodeSetting($doc, $target_node, "MWProject_PPC_outfile", $output_name);
}
#//--------------------------------------------------------------------------------------------------
#// AddFileToTarget
#//
#// Add a file to the specified target(s).
#//
#//--------------------------------------------------------------------------------------------------
sub AddFileToTarget($$$)
{
my($doc, $target_list, $file_name) = @_;
# the file must be added in 3 places:
# 1. in <TARGET><FILELIST><FILE> (with linkage flags if necessary)
# 2. in <TARGET><LINKORDER><FILEREF>
# 3. in <GROUPLIST><GROUP><FILEREF>
die "Write me\n";
}
#//--------------------------------------------------------------------------------------------------
#// RemoveFileFromTarget
#//
#// Remove a file from the specified target, removing it from the entire project
#// if no other targets reference it.
#//
#//--------------------------------------------------------------------------------------------------
sub RemoveFileFromTarget($$$)
{
my($doc, $target_node, $file_name) = @_;
# the file must be removed in 3 places:
# 1. in <TARGET><FILELIST><FILE>
# 2. in <TARGET><LINKORDER><FILEREF>
# 3. in <GROUPLIST><GROUP><FILEREF>
# first, remove from <FILELIST>
my $filelist_node = getFirstChildElement($target_node, "FILELIST");
unless ($filelist_node) { die "Error: failed to find FILELIST node\n"; }
my $file_node = getChildNodeByGrandchildContents($doc, $filelist_node, "FILE", "PATH", $file_name);
unless ($file_node) { return; }
$filelist_node->removeChild($file_node);
# next, remove from <LINKORDER>
my $linkorder_node = getFirstChildElement($target_node, "LINKORDER");
unless ($linkorder_node) { die "Error: failed to find LINKORDER node\n"; }
my $fileref_node = getChildNodeByGrandchildContents($doc, $linkorder_node, "FILEREF", "PATH", $file_name);
unless ($fileref_node) { die "Error: link order node for file $file_name not found\n"; }
$linkorder_node->removeChild($fileref_node);
# last, remove from <GROUPLIST>
# <GROUPLIST> is cross-target, so we have to be careful here.
my $grouplist_node = getChildOfDocument($doc, "GROUPLIST");
unless ($grouplist_node) { die "Error: failed to find GROUPLIST node\n"; }
# if the file isn't in any other targets, remove it from the groups
if (!GetFileInUse($doc, $file_name))
{
print "File $file_name is in no other targest. Removing from project\n";
my @group_nodes;
getChildElementsOfType($doc, $grouplist_node, "GROUP", \@group_nodes);
my $group_node;
foreach $group_node (@group_nodes)
{
my @fileref_nodes;
getChildElementsOfType($doc, $group_node, "FILEREF", \@fileref_nodes);
my $fileref_node;
foreach $fileref_node (@fileref_nodes)
{
my $path_name = getChildElementTextContents($fileref_node, "PATH");
if ($path_name eq $file_name)
{
print "Removing $file_name from project group list\n";
$group_node->removeChild($fileref_node);
last;
}
}
# can a file appear in more than one group?
}
}
}
#//--------------------------------------------------------------------------------------------------
#// SetAsStaticLibraryTarget
#//
#//--------------------------------------------------------------------------------------------------
sub SetAsStaticLibraryTarget($$$)
{
my($doc, $target_name, $output_name) = @_;
my $target_node = getTargetNode($doc, $target_name);
setTargetNodeSetting($doc, $target_node, "MWProject_PPC_type", "Library");
setTargetNodeSetting($doc, $target_node, "MWProject_PPC_filetype", "1061109567"); #'????'
setTargetNodeSetting($doc, $target_node, "MWProject_PPC_outfile", $output_name);
# static targets don't need any library linkage, so we can remove linkage
# with all .shlb and .Lib files.
my(@obsolete_files) = ("NSStdLibStubs", "InterfacesStubs", "InterfaceLib", "InternetConfigLib");
print " Removing libraries etc. from target\n";
# get all files in target
my @target_files = GetTargetFilesList($doc, $target_name);
my $target_file;
foreach $target_file (@target_files)
{
if ($target_file =~ /(\.shlb|\.lib|\.Lib|\.o|\.exp)$/)
{
RemoveFileFromTarget($doc, $target_node, $target_file);
}
}
print " Removing stub libraries from target\n";
# then remove files with known names
my $obs_file;
foreach $obs_file (@obsolete_files)
{
RemoveFileFromTarget($doc, $target_node, $obs_file);
}
}
#//--------------------------------------------------------------------------------------------------
#// AddTarget
#//
#//--------------------------------------------------------------------------------------------------
sub AddTarget($$)
{
my($doc, $target_name) = @_;
die "Write me\n";
}
#//--------------------------------------------------------------------------------------------------
#// RemoveTarget
#//
#//--------------------------------------------------------------------------------------------------
sub RemoveTarget($$)
{
my($doc, $target_name) = @_;
die "Write me\n";
}
#//--------------------------------------------------------------------------------------------------
#// GetTargetSetting
#// Get the value for the specified setting in the specified target
#//--------------------------------------------------------------------------------------------------
sub GetTargetSetting($$$)
{
my($doc, $target_name, $setting_name) = @_;
my $target_node = getTargetNode($doc, $target_name);
return getTargetNodeSetting($target_node, "VALUE");
}
#//--------------------------------------------------------------------------------------------------
#// SetTargetSetting
#// Set the value for the specified setting in the specified target
#//--------------------------------------------------------------------------------------------------
sub SetTargetSetting($$$$)
{
my($doc, $target_name, $setting_name, $new_value) = @_;
my $target_node = getTargetNode($doc, $target_name);
setTargetNodeSetting($doc, $target_node, "VALUE", $new_value);
}
#//--------------------------------------------------------------------------------------------------
#// GetTargetFilesList
#// Return an array of the files in the target (in filelist order)
#//--------------------------------------------------------------------------------------------------
sub GetTargetFilesList($$)
{
my($doc, $target_name) = @_;
my $target_node = getTargetNode($doc, $target_name);
my @files_list;
my $filelist_node = getFirstChildElement($target_node, "FILELIST");
unless ($filelist_node) { die "Error: failed to find FILELIST node\n"; }
my @file_nodes;
getChildElementsOfType($doc, $filelist_node, "FILE", \@file_nodes);
my $node;
foreach $node (@file_nodes)
{
my $file_name = getChildElementTextContents($node, "PATH");
push(@files_list, $file_name);
}
return @files_list;
}
#//--------------------------------------------------------------------------------------------------
#// FileIsInTarget
#//
#//--------------------------------------------------------------------------------------------------
sub FileIsInTarget($$$)
{
my($doc, $file_name, $target_name) = @_;
my $target_node = getTargetNode($doc, $target_name);
unless ($target_node) { die "Error: no target found called $target_name\n"; }
my $file_node = GetTargetFileNode($doc, $target_node, $file_name);
if ($file_node) {
return 1;
}
return 0;
}
#//--------------------------------------------------------------------------------------------------
#// GetFileTargetsList
#// Return an array of the targets that a file is in (expensive)
#//--------------------------------------------------------------------------------------------------
sub GetFileTargetsList($$)
{
my ($doc, $file_name) = @_;
my @target_list;
my @targets = GetTargetsList($doc);
my $target;
foreach $target (@targets)
{
if (FileIsInTarget($doc, $file_name, $target))
{
push(@target_list, $target);
}
}
return @target_list;
}
#//--------------------------------------------------------------------------------------------------
#// GetTargetFileNode
#//
#//--------------------------------------------------------------------------------------------------
sub GetTargetFileNode($$$)
{
my($doc, $target_node, $file_name) = @_;
my $filelist_node = getFirstChildElement($target_node, "FILELIST");
unless ($filelist_node) { die "Error: failed to find FILELIST node\n"; }
my $file_node = getChildNodeByGrandchildContents($doc, $filelist_node, "FILE", "PATH", $file_name);
return $file_node;
}
#//--------------------------------------------------------------------------------------------------
#// GetFileInUse
#// Return true if the file is used by any target
#//--------------------------------------------------------------------------------------------------
sub GetFileInUse($$)
{
my($doc, $file_name) = @_;
my $targetlist_node = getChildOfDocument($doc, "TARGETLIST");
my $target_node = $targetlist_node->getFirstChild();
while ($target_node)
{
if ($target_node->getNodeTypeName eq "ELEMENT_NODE" &&
$target_node->getTagName() eq "TARGET")
{
# if this is a target node
my $file_node = GetTargetFileNode($doc, $target_node, $file_name);
if ($file_node) {
return 1; # found it
}
}
$target_node = $target_node->getNextSibling();
}
# not found
return 0;
}
#//--------------------------------------------------------------------------------------------------
#// getChildOfDocument
#//--------------------------------------------------------------------------------------------------
sub getChildOfDocument($$)
{
my($doc, $child_type) = @_;
return getFirstChildElement($doc->getDocumentElement(), $child_type);
}
#//--------------------------------------------------------------------------------------------------
#// getFirstChildElement
#//--------------------------------------------------------------------------------------------------
sub getFirstChildElement($$)
{
my($node, $element_name) = @_;
my $found_node;
unless ($node) { die "getFirstChildElement called with empty node\n"; }
#look for the first "element_name" child
my $child_node = $node->getFirstChild();
while ($child_node)
{
if ($child_node->getNodeTypeName eq "ELEMENT_NODE" &&
$child_node->getTagName() eq $element_name)
{
$found_node = $child_node;
last;
}
$child_node = $child_node->getNextSibling();
}
return $found_node;
}
#//--------------------------------------------------------------------------------------------------
#// getChildElementsOfType
#//
#// Return an array of refs to child nodes of the given type
#//--------------------------------------------------------------------------------------------------
sub getChildElementsOfType($$$$)
{
my($doc, $node, $child_type, $array_ref) = @_;
my $child_node = $node->getFirstChild();
while ($child_node)
{
if ($child_node->getNodeTypeName eq "ELEMENT_NODE" &&
$child_node->getTagName() eq $child_type)
{
push(@$array_ref, $child_node);
}
$child_node = $child_node->getNextSibling();
}
}
#//--------------------------------------------------------------------------------------------------
#// getChildElementTextContents
#//--------------------------------------------------------------------------------------------------
#
# Given <FOOPY><NERD>Hi!</NERD></FOOPY>, where $node is <FOOPY>,
# returns "Hi!". If > 1 <NERD> node, returns the contents of the first.
#
sub getChildElementTextContents($$)
{
my($node, $tag_name) = @_;
my $first_element = getFirstChildElement($node, $tag_name);
my $text_node = $first_element->getFirstChild();
my $text_contents = "";
# concat adjacent text nodes
while ($text_node)
{
if ($text_node->getNodeTypeName() ne "TEXT_NODE")
{
last;
}
$text_contents = $text_contents.$text_node->getData();
$text_node = $text_node->getNextSibling();
}
return $text_contents;
}
#//--------------------------------------------------------------------------------------------------
#// setChildElementTextContents
#//--------------------------------------------------------------------------------------------------
sub setChildElementTextContents($$$$)
{
my($doc, $node, $tag_name, $contents_text) = @_;
my $first_element = getFirstChildElement($node, $tag_name);
my $new_text_node = $doc->createTextNode($contents_text);
# replace all child elements with a text element
removeAllChildren($first_element);
$first_element->appendChild($new_text_node);
}
#//--------------------------------------------------------------------------------------------------
#// getChildNodeByContents
#//
#// Consider <foo><bar><baz>Foopy</baz></bar><bar><baz>Loopy</baz></bar></foo>
#// This function, when called with getChildNodeByContents($foonode, "bar", "baz", "Loopy")
#// returns the second <bar> node.
#//--------------------------------------------------------------------------------------------------
sub getChildNodeByGrandchildContents($$$$$)
{
my($doc, $node, $child_type, $gc_type, $gc_contents) = @_; # gc = grandchild
my $found_node;
my $child_node = $node->getFirstChild();
while ($child_node)
{
if ($child_node->getNodeTypeName eq "ELEMENT_NODE" &&
$child_node->getTagName() eq $child_type)
{
# check for a child of this node of type
my $child_contents = getChildElementTextContents($child_node, $gc_type);
if ($child_contents eq $gc_contents)
{
$found_node = $child_node;
last;
}
}
$child_node = $child_node->getNextSibling();
}
return $found_node;
}
#//--------------------------------------------------------------------------------------------------
#// getTargetNode
#//--------------------------------------------------------------------------------------------------
sub getTargetNode($$)
{
my($doc, $target_name) = @_;
my $targetlist_node = getChildOfDocument($doc, "TARGETLIST");
return getChildNodeByGrandchildContents($doc, $targetlist_node, "TARGET", "NAME", $target_name);
}
#//--------------------------------------------------------------------------------------------------
#// getTargetNamedSettingNode
#//--------------------------------------------------------------------------------------------------
sub getTargetNamedSettingNode($$)
{
my($target_node, $setting_name) = @_;
my $setting_node;
my $settinglist_node = getFirstChildElement($target_node, "SETTINGLIST");
my $child_node = $settinglist_node->getFirstChild();
while ($child_node)
{
if ($child_node->getNodeTypeName ne "ELEMENT_NODE")
{
$child_node = $child_node->getNextSibling();
next;
}
if ($child_node->getTagName() eq "SETTING")
{
my $set_name = getChildElementTextContents($child_node, "NAME");
if ($set_name eq $setting_name)
{
$setting_node = $child_node;
last;
}
}
$child_node = $child_node->getNextSibling();
}
return $setting_node;
}
#//--------------------------------------------------------------------------------------------------
#// getTargetNodeSetting
#//--------------------------------------------------------------------------------------------------
sub getTargetNodeSetting($$)
{
my($target_node, $setting_name) = @_;
my $setting_node = getTargetNamedSettingNode($target_node, $setting_name);
return getChildElementTextContents($setting_node, "VALUE");
}
#//--------------------------------------------------------------------------------------------------
#// setTargetNodeSetting
#//--------------------------------------------------------------------------------------------------
sub setTargetNodeSetting($$$$)
{
my($doc, $target_node, $setting_name, $new_value) = @_;
my $setting_node = getTargetNamedSettingNode($target_node, $setting_name);
setChildElementTextContents($doc, $setting_node, "VALUE", $new_value);
}
#//--------------------------------------------------------------------------------------------------
#// elementInArray
#//--------------------------------------------------------------------------------------------------
sub elementInArray($$)
{
my($element, $array) = @_;
my $test;
foreach $test (@$array)
{
if ($test eq $element) {
return 1;
}
}
return 0;
}
#//--------------------------------------------------------------------------------------------------
#// removeAllChildren
#//--------------------------------------------------------------------------------------------------
sub removeAllChildren($)
{
my($node) = @_;
my $child_node = $node->getFirstChild();
while ($child_node)
{
$node->removeChild($child_node);
$child_node = $node->getFirstChild();
}
}
#//--------------------------------------------------------------------------------------------------
#// dumpNodeData
#//--------------------------------------------------------------------------------------------------
sub dumpNodeData($)
{
my($node) = @_;
unless ($node) { die "Null node passed to dumpNodeData\n"; }
print "Dumping node $node\n";
my($node_type) = $node->getNodeTypeName();
if ($node_type eq "ELEMENT_NODE")
{
my($node_name) = $node->getTagName();
print "Element $node_name\n";
}
elsif ($node_type eq "TEXT_NODE")
{
my($node_data) = $node->getData;
# my(@node_vals) = unpack("C*", $node_data);
print "Text '$node_data'\n"; # may contain LF chars
}
else
{
print "Node $node_type\n";
}
}
#//--------------------------------------------------------------------------------------------------
#// dumpNodeTree
#//--------------------------------------------------------------------------------------------------
sub dumpNodeTree($)
{
my($node) = @_;
my($child_node) = $node->getFirstChild();
unless ($child_node) { return; }
# recurse
dumpNodeData($child_node);
# then go through child nodes
while ($child_node)
{
dumpNodeTree($child_node);
$child_node = $child_node->getNextSibling();
}
}
1;

View File

@@ -1,90 +0,0 @@
#-------------------------------------------------------------------------------
# These 3 lists are the 'master lists' to control what gets built.
#
# Ordering in these arrays is important; it has to reflect the order in
# which the build occurs.
#
# Setting containing spaces must be quoted with double quotes.
#-------------------------------------------------------------------------------
build_flags
all 1
pull 0
dist 0
config 0
xpidl 0
idl 0
stubs 0
runtime 0
common 0
imglib 0
libimg2 0
necko 0
security 0
browserutils 0
intl 0
nglayout 0
accessiblity 0
editor 0
embedding 0
viewer 0
xpapp 0
extensions 0
plugins 0
mailnews 0
apprunner 0
resources 0
options_flags
pull_by_date 0
chrome_jars 1
chrome_files 0
use_jars 1
transformiix 1
mathml 0 MOZ_MATHML
svg 0 MOZ_SVG
# svg requires libart, which is an lgpl library. You need to pull it
# explicitly.
libart_lgpl 0
mng 1
ldap 1 MOZ_LDAP_XPCOM
ldap_experimental 0 MOZ_LDAP_XPCOM_EXPERIMENTAL
xmlextras 1
wsp 0 MOZ_WSP
inspector 1
mailextras 1
xptlink 0
psm 0 MOZ_PSM
embedding_test 1
embedding_chrome 0
embedding_xulprefs 0
embedding_xulsecurity 0
carbon 0 TARGET_CARBON
useimg2 1 USE_IMG2
lowmem 0 MOZ_MAC_LOWMEM
accessible 1 ACCESSIBILITY
bidi 1 IBMBIDI
p3p 0
jsd 1
venkman 1
moz_logging 1 MOZ_LOGGING
chatzilla 1
content_packs 1
xml_rpc 1
cview 1
help 1
timeline 0 MOZ_TIMELINE
static_build 0 MOZ_STATIC_COMPONENT_LIBS
string_debug 0 DEBUG_STRING
string_stats 0 DEBUG_STRING_STATS
xpctools 0 XPC_TOOLS_SUPPORT
smime 1
mdn 1
print_preview 1 NS_PRINT_PREVIEW
moz_xul 1 MOZ_XUL
filepath_flags
idepath ":CodeWarrior IDE Path.txt"
sessionpath ":Mozilla session path.txt"
buildlogfilepath ":Build Logs:Mozilla build log.txt" # this is a path
scriptlogfilepath ":Build Logs:Mozilla script log.txt"

File diff suppressed because it is too large Load Diff

View File

@@ -1,22 +0,0 @@
# List of modules to check out. Format is
# module, (tag), (date)
# where tag and date are optional (non-trailing commas are required)
#
# Examples:
# mozilla/nsprpub, NSPRPUB_CLIENT_TAG
# mozilla/gc, , 10/25/2000 12:00:00
#
mozilla/nsprpub, NETSCAPE_7_0_RTM
mozilla/security/nss, NETSCAPE_7_0_RTM
mozilla/security/manager, NETSCAPE_7_0_RTM
mozilla/accessible, NETSCAPE_7_0_RTM
mozilla/directory/c-sdk, NETSCAPE_7_0_RTM
mozilla/lib/mac/Instrumentation, NETSCAPE_7_0_RTM
mozilla/gfx2, NETSCAPE_7_0_RTM
mozilla/modules/libpr0n, NETSCAPE_7_0_RTM
SeaMonkeyAll, NETSCAPE_7_0_RTM
## You need this if you want to be able to use SVG
## Note that this library is under the LGPL, not the MPL
#mozilla/other-licenses/libart_lgpl

View File

@@ -1,79 +0,0 @@
#!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.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):
# Simon Fraser <sfraser@netscape.com>
#
require 5.004;
use strict;
use Cwd;
use Moz::BuildUtils;
use Moz::BuildCore;
#-------------------------------------------------------------
# Where have the build options gone?
#
# The various build flags have been centralized into one place.
# The master list of options is in MozBuildFlags.txt. However,
# you should never need to edit that file, or this one.
#
# To customize what gets built, or where to start the build,
# edit the $prefs_file_name file in
# System Folder:Preferences:Mozilla build prefs:
# Documentation is provided in that file.
#-------------------------------------------------------------
my($prefs_file_name) = "Mozilla pull prefs";
#-------------------------------------------------------------
# hashes to hold build options
#-------------------------------------------------------------
my(%build);
my(%options);
my(%filepaths);
my(%optiondefines);
# Hash of input files for this build. Eventually, there will be
# input files for manifests, and projects too.
my(%inputfiles) = (
"buildflags", "MozillaBuildFlags.txt",
"checkoutdata", "MozillaCheckoutList.txt",
"buildprogress", "",
"buildmodule", "MozillaBuildList.pm",
"checkouttime", "Mozilla last checkout"
);
#-------------------------------------------------------------
# end build hashes
#-------------------------------------------------------------
# set the build root directory, which is the the dir above mozilla
SetupBuildRootDir(":mozilla:build:mac:build_scripts");
# Set up all the flags on $main::, like DEBUG, CARBON etc.
# Override the defaults using the preferences files.
SetupDefaultBuildOptions(0, ":mozilla:dist:viewer:", "");
my($do_checkout) = 1;
my($do_build) = 0;
RunBuild($do_checkout, $do_build, \%inputfiles, $prefs_file_name);

View File

@@ -1,511 +0,0 @@
# 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):
DEPTH=.
!if !defined(MOZ_TOP)
#enable builds from changed top level directories
MOZ_TOP=mozilla
!endif
MOZ_SRC_FLIPPED = $(MOZ_SRC:\=/)
MOZ_DIST_FLIPPED = $(MOZ_SRC_FLIPPED)/mozilla/dist
!ifdef MOZ_DEBUG
MOZ_OBJDIR = WIN32_D.OBJ
!else
MOZ_OBJDIR = WIN32_O.OBJ
!endif
#
# Command macro defines
#
#//------------------------------------------------------------------------
#// Figure out how to do the pull.
#//------------------------------------------------------------------------
# uncomment these, modify branch tag, and check in to branch for milestones
MOZ_BRANCH=NETSCAPE_7_0_RTM
NSPR_CO_TAG=NETSCAPE_7_0_RTM
PSM_CO_TAG=NETSCAPE_7_0_RTM
NSS_CO_TAG=NETSCAPE_7_0_RTM
LDAPCSDK_CO_TAG=NETSCAPE_7_0_RTM
ACCESSIBLE_CO_TAG=NETSCAPE_7_0_RTM
IMGLIB2_CO_TAG=NETSCAPE_7_0_RTM
GFX2_CO_TAG=NETSCAPE_7_0_RTM
!ifdef MOZ_BRANCH
CVS_BRANCH=-r $(MOZ_BRANCH)
!endif
!ifdef MOZ_DATE
CVS_BRANCH=$(CVS_BRANCH) -D "$(MOZ_DATE)"
!endif
# default pull is "quiet" but it can be overridden with MOZ_CVS_VERBOSE
!ifndef MOZ_CVS_VERBOSE
CVS_FLAGS=-q
!endif
# honor any user-defined CVS flags
!ifdef MOZ_CVS_FLAGS
CVS_FLAGS=$(CVS_FLAGS) $(MOZ_CVS_FLAGS)
!endif
# let's be explicit about CVSROOT... some windows cvs clients
# are too stupid to correctly work without the -d option
#
# if they are too stupid, they should fail. I am
# commenting this out because this does not work
# under 4nt. (%'s are evaluted differently)
#
# If it breaks you, mail dougt@netscape.com
# and leaf@mozilla.org
#
!if 0
!if defined(CVSROOT)
CVS_FLAGS=$(CVS_FLAGS) -d "$(CVSROOT)"
!endif
!endif
!ifndef MOZ_CO_FLAGS
MOZ_CO_FLAGS = -P
!endif
CVSCO = cvs $(CVS_FLAGS) co $(MOZ_CO_FLAGS) $(CVS_BRANCH)
#//------------------------------------------------------------------------
#// Figure out how to pull NSPR.
#// If no NSPR_CO_TAG is specified, use the default static tag
#//------------------------------------------------------------------------
!ifndef NSPR_CO_FLAGS
NSPR_CO_FLAGS=$(MOZ_CO_FLAGS)
!endif
NSPR_CO_FLAGS=$(NSPR_CO_FLAGS) $(CVS_BRANCH)
CVSCO_NSPR = cvs $(CVS_FLAGS) co $(NSPR_CO_FLAGS)
#//------------------------------------------------------------------------
#// Figure out how to pull NSS and PSM libs.
#// If no NSS_CO_TAG or PSM_CO_TAG is specified, use the default static tag
#//------------------------------------------------------------------------
!ifndef NSS_CO_FLAGS
NSS_CO_FLAGS=$(MOZ_CO_FLAGS)
!endif
NSS_CO_FLAGS=$(NSS_CO_FLAGS) $(CVS_BRANCH)
CVSCO_NSS = cvs $(CVS_FLAGS) co $(NSS_CO_FLAGS)
!ifndef PSM_CO_FLAGS
PSM_CO_FLAGS=$(MOZ_CO_FLAGS)
!endif
PSM_CO_FLAGS=$(PSM_CO_FLAGS) $(CVS_BRANCH)
CVSCO_PSM = cvs $(CVS_FLAGS) co $(PSM_CO_FLAGS)
#//------------------------------------------------------------------------
#// Figure out how to pull LDAP C SDK client libs.
#// If no LDAPCSDK_CO_TAG is specified, use the default tag
#//------------------------------------------------------------------------
!ifndef LDAPCSDK_CO_FLAGS
LDAPCSDK_CO_FLAGS=$(MOZ_CO_FLAGS)
!endif
LDAPCSDK_CO_FLAGS=$(LDAPCSDK_CO_FLAGS) $(CVS_BRANCH)
CVSCO_LDAPCSDK = cvs $(CVS_FLAGS) co $(LDAPCSDK_CO_FLAGS)
#//------------------------------------------------------------------------
#// Figure out how to pull accessibility libs.
#// If no ACCESSIBLE_CO_TAG is specified, use the default tag
#//------------------------------------------------------------------------
!ifndef ACCESSIBLE_CO_FLAGS
ACCESSIBLE_CO_FLAGS=$(MOZ_CO_FLAGS)
!endif
ACCESSIBLE_CO_FLAGS=$(ACCESSIBLE_CO_FLAGS) $(CVS_BRANCH)
CVSCO_ACCESSIBLE = cvs $(CVS_FLAGS) co $(ACCESSIBLE_CO_FLAGS)
#//------------------------------------------------------------------------
#// Figure out how to pull new image library.
#// If no IMGLIB2_CO_TAG is specified, use the default tag
#//------------------------------------------------------------------------
!ifndef IMGLIB2_CO_FLAGS
IMGLIB2_CO_FLAGS=$(MOZ_CO_FLAGS)
!endif
IMGLIB2_CO_FLAGS=$(IMGLIB2_CO_FLAGS) $(CVS_BRANCH)
CVSCO_IMGLIB2 = cvs $(CVS_FLAGS) co $(IMGLIB2_CO_FLAGS)
#//------------------------------------------------------------------------
#// Figure out how to pull new image library.
#// If no GFX2_CO_TAG is specified, use the default tag
#//------------------------------------------------------------------------
!ifndef GFX2_CO_FLAGS
GFX2_CO_FLAGS=$(MOZ_CO_FLAGS)
!endif
GFX2_CO_FLAGS=$(GFX2_CO_FLAGS) $(CVS_BRANCH)
CVSCO_GFX2 = cvs $(CVS_FLAGS) co $(GFX2_CO_FLAGS)
#//------------------------------------------------------------------------
#// Figure out how to pull the internal libart
#// (only pulled and built if MOZ_INTERNAL_LIBART_LGPL is set)
#// If no MOZ_INTERNAL_LIBART_CO_TAG is specified, use the default tag
#//------------------------------------------------------------------------
!if defined(MOZ_SVG) && !defined(MOZ_INTERNAL_LIBART_LGPL)
ERR_MESSAGE = ^
You are trying to build Mozilla with SVG support (MOZ_SVG=1), but you ^
haven not specified that mozilla/other-licenses/libart_lgpl should be ^
pulled and built. At the moment Mozilla SVG builds need this patched ^
version of libart. You either need to disable SVG support (unset MOZ_SVG) ^
or enable pulling and building by setting MOZ_INTERNAL_LIBART_LGPL=1.^
^
If you choose to pull and build libart, note that it is only licensed^
under the terms of the LGPL, not the MPL. (Which is why you have to opt^
in explicitly.)
!endif
!if defined(MOZ_INTERNAL_LIBART_LGPL)
!ifndef MOZ_INTERNAL_LIBART_CO_FLAGS
MOZ_INTERNAL_LIBART_CO_FLAGS=$(MOZ_CO_FLAGS)
!endif
!if "$(MOZ_INTERNAL_LIBART_CO_TAG)" != ""
MOZ_INTERNAL_LIBART_CO_FLAGS=$(MOZ_INTERNAL_LIBART_CO_FLAGS) -r $(MOZ_INTERNAL_LIBART_CO_TAG)
!else
MOZ_INTERNAL_LIBART_CO_FLAGS=$(MOZ_INTERNAL_LIBART_CO_FLAGS) $(CVS_BRANCH)
!endif
CVSCO_MOZ_INTERNAL_LIBART = cvs $(CVS_FLAGS) co $(MOZ_INTERNAL_LIBART_CO_FLAGS)
!endif
## The master target
############################################################
pull_and_build_all: pull_all build_all_dep
## Rules for pulling the source from the cvs repository
############################################################
pull_clobber_and_build_all: pull_all clobber_all build_all
!if !defined(MOZ_INTERNAL_LIBART_LGPL)
pull_all: pull_nspr pull_psm pull_ldapcsdk pull_accessible pull_gfx2 pull_imglib2 pull_seamonkey
!else
pull_all: pull_nspr pull_psm pull_ldapcsdk pull_accessible pull_gfx2 pull_imglib2 pull_moz_internal_libart pull_seamonkey
!endif
pull_nspr: pull_clientmak
cd $(MOZ_SRC)\.
$(CVSCO_NSPR) mozilla/nsprpub
pull_nss:
cd $(MOZ_SRC)\.
$(CVSCO_NSS) mozilla/security/coreconf
$(CVSCO_NSS) mozilla/security/nss
pull_psm: pull_nss
cd $(MOZ_SRC)\.
$(CVSCO_PSM) mozilla/security/manager
$(CVSCO_PSM) mozilla/security/makefile.win
pull_ldapcsdk:
cd $(MOZ_SRC)\.
$(CVSCO_LDAPCSDK) mozilla/directory/c-sdk
pull_accessible:
cd $(MOZ_SRC)\.
$(CVSCO_ACCESSIBLE) mozilla/accessible
pull_gfx2:
cd $(MOZ_SRC)\.
$(CVSCO_GFX2) mozilla/gfx2
pull_imglib2:
cd $(MOZ_SRC)\.
$(CVSCO_IMGLIB2) mozilla/modules/libpr0n
!if defined(MOZ_INTERNAL_LIBART_LGPL)
pull_moz_internal_libart:
cd $(MOZ_SRC)\.
$(CVSCO_MOZ_INTERNAL_LIBART) mozilla/other-licenses/libart_lgpl
!endif
pull_xpconnect: pull_nspr
cd $(MOZ_SRC)\.
$(CVSCO) mozilla/include
$(CVSCO) mozilla/config
$(CVSCO) -l mozilla/js
$(CVSCO) -l mozilla/js/src
$(CVSCO) mozilla/js/src/fdlibm
$(CVSCO) mozilla/js/src/xpconnect
$(CVSCO) mozilla/modules/libreg
$(CVSCO) mozilla/xpcom
$(CVSCO) mozilla/string
# pull either layout only or seamonkey the browser
pull_layout:
cd $(MOZ_SRC)\.
$(CVSCO) RaptorWin
pull_seamonkey: pull_clientmak
cd $(MOZ_SRC)\.
$(CVSCO) SeaMonkeyAll
pull_clientmak:
cd $(MOZ_SRC)\.
$(CVSCO) mozilla/client.mak
############################################################
# nmake has to be hardcoded, or we have to depend on mozilla/config
# being pulled already to figure out what $(NMAKE) should be.
clobber_all: clobber_nspr clobber_ldapcsdk clobber_psm clobber_seamonkey
build_all: build_nspr build_ldapcsdk build_seamonkey
build_all_dep: depend libs
distclean:
@cd $(MOZ_SRC)\$(MOZ_TOP)\directory\c-sdk
gmake -f gmakefile.win distclean MOZ_SRC_FLIPPED=$(MOZ_SRC_FLIPPED)
@cd $(MOZ_SRC)\$(MOZ_TOP)\nsprpub
gmake -f gmakefile.win distclean MOZ_SRC_FLIPPED=$(MOZ_SRC_FLIPPED)
@cd $(MOZ_SRC)\$(MOZ_TOP)
nmake /f client.mak clobber_psm
nmake /f client.mak clobber_seamonkey
clobber_ldapcsdk:
@cd $(MOZ_SRC)\$(MOZ_TOP)\directory\c-sdk
gmake -f gmakefile.win clobber_all MOZ_SRC_FLIPPED=$(MOZ_SRC_FLIPPED) \
SHELL=sh
clobber_nspr:
@cd $(MOZ_SRC)\$(MOZ_TOP)\nsprpub
gmake -f gmakefile.win clobber_all MOZ_SRC_FLIPPED=$(MOZ_SRC_FLIPPED)
clobber_psm:
@cd $(MOZ_SRC)\$(MOZ_TOP)\security
nmake -f makefile.win clobber_all
clobber_xpconnect:
@cd $(MOZ_SRC)\$(MOZ_TOP)\.
-rd /s /q dist
@cd $(MOZ_SRC)\$(MOZ_TOP)\nsprpub
gmake -f gmakefile.win clobber_all MOZ_SRC_FLIPPED=$(MOZ_SRC_FLIPPED)
@cd $(MOZ_SRC)\$(MOZ_TOP)\include
nmake -f makefile.win clobber_all
@cd $(MOZ_SRC)\$(MOZ_TOP)\modules\libreg
nmake -f makefile.win clobber_all
@cd $(MOZ_SRC)\$(MOZ_TOP)\string
nmake -f makefile.win clobber_all
@cd $(MOZ_SRC)\$(MOZ_TOP)\xpcom
nmake -f makefile.win clobber_all
@cd $(MOZ_SRC)\$(MOZ_TOP)\js
nmake -f makefile.win clobber_all
@cd $(MOZ_SRC)\$(MOZ_TOP)\js\src\xpconnect
nmake -f makefile.win clobber_all
clobber_seamonkey:
@cd $(MOZ_SRC)\$(MOZ_TOP)\.
-rd /s /q dist
nmake -f makefile.win clobber_all
depend: export
@cd $(MOZ_SRC)\$(MOZ_TOP)\.
nmake -f makefile.win depend
depend_xpconnect:
@cd $(MOZ_SRC)\$(MOZ_TOP)\include
nmake -f makefile.win depend
@cd $(MOZ_SRC)\$(MOZ_TOP)\modules\libreg
nmake -f makefile.win depend
@cd $(MOZ_SRC)\$(MOZ_TOP)\string
nmake -f makefile.win depend
@cd $(MOZ_SRC)\$(MOZ_TOP)\xpcom
nmake -f makefile.win depend
@cd $(MOZ_SRC)\$(MOZ_TOP)\js\src
nmake -f makefile.win depend
@cd $(MOZ_SRC)\$(MOZ_TOP)\js\src\xpconnect
nmake -f makefile.win depend
build_nspr:
@cd $(MOZ_SRC)\$(MOZ_TOP)\nsprpub
gmake -f gmakefile.win MOZ_SRC_FLIPPED=$(MOZ_SRC_FLIPPED)
build_ldapcsdk:
@cd $(MOZ_SRC)\$(MOZ_TOP)\directory\c-sdk
gmake -f gmakefile.win MOZ_SRC_FLIPPED=$(MOZ_SRC_FLIPPED) SHELL=sh
build_psm:
@cd $(MOZ_SRC)\$(MOZ_TOP)\security
nmake -f makefile.win
build_xpconnect: build_nspr
@cd $(MOZ_SRC)\$(MOZ_TOP)\include
nmake -f makefile.win all
@cd $(MOZ_SRC)\$(MOZ_TOP)\modules\libreg
nmake -f makefile.win all
@cd $(MOZ_SRC)\$(MOZ_TOP)\xpcom
nmake -f makefile.win export
@cd $(MOZ_SRC)\$(MOZ_TOP)\string
nmake -f makefile.win all
@cd $(MOZ_SRC)\$(MOZ_TOP)\xpcom
nmake -f makefile.win libs
@cd $(MOZ_SRC)\$(MOZ_TOP)\js\src
nmake -f makefile.win all
@cd $(MOZ_SRC)\$(MOZ_TOP)\js\src\xpconnect
nmake -f makefile.win all
build_seamonkey:
@cd $(MOZ_SRC)\$(MOZ_TOP)\.
nmake -f makefile.win all
build_client:
@cd $(MOZ_SRC)\mozilla\.
nmake -f makefile.win all
build_layout:
@cd $(MOZ_SRC)\mozilla\.
nmake -f makefile.win all
build_dist:
@cd $(MOZ_SRC)\mozilla\.
nmake -f makefile.win all
libs:
@cd $(MOZ_SRC)\$(MOZ_TOP)\.
nmake -f makefile.win libs
export: build_nspr build_ldapcsdk
@cd $(MOZ_SRC)\$(MOZ_TOP)\.
nmake -f makefile.win export
clobber_dist:
@cd $(MOZ_SRC)\mozilla\.
nmake -f makefile.win clobber_all
clobber_client:
@cd $(MOZ_SRC)\mozilla\.
nmake -f makefile.win clobber_all
clobber_layout:
@cd $(MOZ_SRC)\mozilla\.
nmake -f makefile.win clobber_all
browse_info::
cd $(MOZ_SRC)\$(MOZ_TOP)
-dir /s /b *.sbr > sbrlist.tmp
-bscmake /Es /o mozilla.bsc @sbrlist.tmp
-rm sbrlist.tmp
regchrome::
@cd $(MOZ_SRC)\mozilla\.
nmake /f makefile.win regchrome
deliver::
@cd $(MOZ_SRC)\mozilla\.
nmake /f makefile.win splitsymbols
#//------------------------------------------------------------------------
#// Utility stuff...
#//------------------------------------------------------------------------
#//------------------------------------------------------------------------
# Verify that MOZ_SRC is set correctly
#//------------------------------------------------------------------------
# Check to see if it is set at all
!if "$(MOZ_SRC)"==""
MOZ_SRC = $(MAKEDIR)\..
!endif
#
# create a temp file at the root and make sure it is visible from MOZ_SRC
#
!if [copy $(MAKEDIR)\client.mak $(MAKEDIR)\xyzzy.tmp > NUL] == 0
!endif
!if !EXIST( $(MOZ_SRC)\mozilla\xyzzy.tmp )
ERR_MESSAGE=$(ERR_MESSAGE)^
MOZ_SRC isn't set correctly: [$(MOZ_SRC)\mozilla]!=[$(MAKEDIR)]
!endif
!if [del $(MAKEDIR)\xyzzy.tmp]
!endif
#//------------------------------------------------------------------------
# Verify that MOZ_BITS is set
#//------------------------------------------------------------------------
!if !defined(MOZ_BITS)
ERR_MESSAGE=$(ERR_MESSAGE)^
Environment variable MOZ_BITS isn't set.
!endif
!if !defined(MOZ_TOOLS)
ERR_MESSAGE=$(ERR_MESSAGE)^
Environment variable MOZ_TOOLS isn't set.
!endif
#//------------------------------------------------------------------------
#// Display error
#//------------------------------------------------------------------------
!if "$(ERR_MESSAGE)" != ""
ERR_MESSAGE = ^
client.mak: ^
$(ERR_MESSAGE) ^
^
client.mak: usage^
^
nmake -f client.mak [MOZ_BRANCH=<cvs_branch_name>] ^
[MOZ_DATE=<cvs_date>]^
[pull_and_build_all]^
[pull_all]^
[build_all]^
^
Environment variables:^
^
MOZ_BITS set to 32^
MOZ_TOOLS set to the directory containing the needed tools ^
!ERROR $(ERR_MESSAGE)
!endif

View File

@@ -1,650 +0,0 @@
# 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): Stephen Lamm
# Build the Mozilla client.
#
# This needs CVSROOT set to work, e.g.,
# setenv CVSROOT :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
# or
# setenv CVSROOT :pserver:username%somedomain.org@cvs.mozilla.org:/cvsroot
#
# To checkout and build a tree,
# 1. cvs co mozilla/client.mk
# 2. cd mozilla
# 3. gmake -f client.mk
#
# Other targets (gmake -f client.mk [targets...]),
# checkout
# build
# clean (realclean is now the same as clean)
# distclean
#
# See http://www.mozilla.org/build/unix.html for more information.
#
# Options:
# MOZ_OBJDIR - Destination object directory
# MOZ_CO_DATE - Date tag to use for checkout (default: none)
# MOZ_CO_MODULE - Module to checkout (default: SeaMonkeyAll)
# MOZ_CVS_FLAGS - Flags to pass cvs (default: -q -z3)
# MOZ_CO_FLAGS - Flags to pass after 'cvs co' (default: -P)
# MOZ_MAKE_FLAGS - Flags to pass to $(MAKE)
# MOZ_CO_BRANCH - Branch tag (Deprecated. Use MOZ_CO_TAG below.)
#
#######################################################################
# Checkout Tags
#
# For branches, uncomment the MOZ_CO_TAG line with the proper tag,
# and commit this file on that tag.
MOZ_CO_TAG = NETSCAPE_7_0_RTM
NSPR_CO_TAG = NETSCAPE_7_0_RTM
PSM_CO_TAG = NETSCAPE_7_0_RTM
NSS_CO_TAG = NETSCAPE_7_0_RTM
LDAPCSDK_CO_TAG = NETSCAPE_7_0_RTM
ACCESSIBLE_CO_TAG = NETSCAPE_7_0_RTM
GFX2_CO_TAG = NETSCAPE_7_0_RTM
IMGLIB2_CO_TAG = NETSCAPE_7_0_RTM
BUILD_MODULES = all
#######################################################################
# Defines
#
CVS = cvs
CWD := $(shell pwd)
ifeq "$(CWD)" "/"
CWD := /.
endif
ifneq (, $(wildcard client.mk))
# Ran from mozilla directory
ROOTDIR := $(shell dirname $(CWD))
TOPSRCDIR := $(CWD)
else
# Ran from mozilla/.. directory (?)
ROOTDIR := $(CWD)
TOPSRCDIR := $(CWD)/mozilla
endif
# on os2, TOPSRCDIR may have two forward slashes in a row, which doesn't
# work; replace first instance with one forward slash
TOPSRCDIR := $(shell echo "$(TOPSRCDIR)" | sed -e 's%//%/%')
ifndef TOPSRCDIR_MOZ
TOPSRCDIR_MOZ=$(TOPSRCDIR)
endif
# if ROOTDIR equals only drive letter (i.e. "C:"), set to "/"
DIRNAME := $(shell echo "$(ROOTDIR)" | sed -e 's/^.://')
ifeq ($(DIRNAME),)
ROOTDIR := /.
endif
AUTOCONF := autoconf
MKDIR := mkdir
SH := /bin/sh
ifndef MAKE
MAKE := gmake
endif
CONFIG_GUESS_SCRIPT := $(wildcard $(TOPSRCDIR)/build/autoconf/config.guess)
ifdef CONFIG_GUESS_SCRIPT
CONFIG_GUESS = $(shell $(CONFIG_GUESS_SCRIPT))
else
_IS_FIRST_CHECKOUT := 1
endif
####################################
# CVS
# Add the CVS root to CVS_FLAGS if needed
CVS_ROOT_IN_TREE := $(shell cat $(TOPSRCDIR)/CVS/Root 2>/dev/null)
ifneq ($(CVS_ROOT_IN_TREE),)
ifneq ($(CVS_ROOT_IN_TREE),$(CVSROOT))
CVS_FLAGS := -d $(CVS_ROOT_IN_TREE)
endif
endif
CVSCO = $(strip $(CVS) $(CVS_FLAGS) co $(CVS_CO_FLAGS))
CVSCO_LOGFILE := $(ROOTDIR)/cvsco.log
CVSCO_LOGFILE := $(shell echo $(CVSCO_LOGFILE) | sed s%//%/%)
ifdef MOZ_CO_TAG
CVS_CO_FLAGS := -r $(MOZ_CO_TAG)
endif
####################################
# Load mozconfig Options
# See build pages, http://www.mozilla.org/build/unix.html,
# for how to set up mozconfig.
MOZCONFIG_LOADER := mozilla/build/autoconf/mozconfig2client-mk
MOZCONFIG_FINDER := mozilla/build/autoconf/mozconfig-find
MOZCONFIG_MODULES := mozilla/build/unix/modules.mk
run_for_side_effects := \
$(shell cd $(ROOTDIR); \
if test "$(_IS_FIRST_CHECKOUT)"; then \
$(CVSCO) $(MOZCONFIG_FINDER) $(MOZCONFIG_LOADER) $(MOZCONFIG_MODULES); \
else true; \
fi; \
$(MOZCONFIG_LOADER) $(TOPSRCDIR) mozilla/.mozconfig.mk > mozilla/.mozconfig.out)
include $(TOPSRCDIR)/.mozconfig.mk
include $(TOPSRCDIR)/build/unix/modules.mk
####################################
# Options that may come from mozconfig
# Change CVS flags if anonymous root is requested
ifdef MOZ_CO_USE_MIRROR
CVS_FLAGS := -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
endif
# MOZ_CVS_FLAGS - Basic CVS flags
ifeq "$(origin MOZ_CVS_FLAGS)" "undefined"
CVS_FLAGS := $(CVS_FLAGS) -q -z 3
else
CVS_FLAGS := $(MOZ_CVS_FLAGS)
endif
# This option is deprecated. The best way to have client.mk pull a tag
# is to set MOZ_CO_TAG (see above) and commit that change on the tag.
ifdef MOZ_CO_BRANCH
$(warning Use MOZ_CO_TAG instead of MOZ_CO_BRANCH)
CVS_CO_FLAGS := -r $(MOZ_CO_BRANCH)
endif
# MOZ_CO_FLAGS - Anything that we should use on all checkouts
ifeq "$(origin MOZ_CO_FLAGS)" "undefined"
CVS_CO_FLAGS := $(CVS_CO_FLAGS) -P
else
CVS_CO_FLAGS := $(CVS_CO_FLAGS) $(MOZ_CO_FLAGS)
endif
ifdef MOZ_CO_DATE
CVS_CO_DATE_FLAGS := -D "$(MOZ_CO_DATE)"
endif
ifdef MOZ_OBJDIR
OBJDIR := $(MOZ_OBJDIR)
MOZ_MAKE := $(MAKE) $(MOZ_MAKE_FLAGS) -C $(OBJDIR)
else
OBJDIR := $(TOPSRCDIR)
MOZ_MAKE := $(MAKE) $(MOZ_MAKE_FLAGS)
endif
####################################
# CVS defines for PSM
#
PSM_CO_MODULE= mozilla/security/manager
PSM_CO_FLAGS := -P -A
ifdef MOZ_CO_FLAGS
PSM_CO_FLAGS := $(MOZ_CO_FLAGS)
endif
ifdef PSM_CO_TAG
PSM_CO_FLAGS := $(PSM_CO_FLAGS) -r $(PSM_CO_TAG)
endif
CVSCO_PSM = $(CVS) $(CVS_FLAGS) co $(PSM_CO_FLAGS) $(CVS_CO_DATE_FLAGS) $(PSM_CO_MODULE)
####################################
# CVS defines for NSS
#
NSS_CO_MODULE = mozilla/security/nss \
mozilla/security/coreconf \
$(NULL)
NSS_CO_FLAGS := -P
ifdef MOZ_CO_FLAGS
NSS_CO_FLAGS := $(MOZ_CO_FLAGS)
endif
ifdef NSS_CO_TAG
NSS_CO_FLAGS := $(NSS_CO_FLAGS) -r $(NSS_CO_TAG)
endif
# Cannot pull static tags by date
ifeq ($(NSS_CO_TAG),NSS_CLIENT_TAG)
CVSCO_NSS = $(CVS) $(CVS_FLAGS) co $(NSS_CO_FLAGS) $(NSS_CO_MODULE)
else
CVSCO_NSS = $(CVS) $(CVS_FLAGS) co $(NSS_CO_FLAGS) $(CVS_CO_DATE_FLAGS) $(NSS_CO_MODULE)
endif
####################################
# CVS defines for NSPR
#
NSPR_CO_MODULE = mozilla/nsprpub
NSPR_CO_FLAGS := -P
ifdef MOZ_CO_FLAGS
NSPR_CO_FLAGS := $(MOZ_CO_FLAGS)
endif
ifdef NSPR_CO_TAG
NSPR_CO_FLAGS := $(NSPR_CO_FLAGS) -r $(NSPR_CO_TAG)
endif
# Cannot pull static tags by date
ifeq ($(NSPR_CO_TAG),NSPRPUB_CLIENT_TAG)
CVSCO_NSPR = $(CVS) $(CVS_FLAGS) co $(NSPR_CO_FLAGS) $(NSPR_CO_MODULE)
else
CVSCO_NSPR = $(CVS) $(CVS_FLAGS) co $(NSPR_CO_FLAGS) $(CVS_CO_DATE_FLAGS) $(NSPR_CO_MODULE)
endif
####################################
# CVS defines for the C LDAP SDK
#
LDAPCSDK_CO_MODULE = mozilla/directory/c-sdk
LDAPCSDK_CO_FLAGS := -P
ifdef MOZ_CO_FLAGS
LDAPCSDK_CO_FLAGS := $(MOZ_CO_FLAGS)
endif
ifdef LDAPCSDK_CO_TAG
LDAPCSDK_CO_FLAGS := $(LDAPCSDK_CO_FLAGS) -r $(LDAPCSDK_CO_TAG)
endif
CVSCO_LDAPCSDK = $(CVS) $(CVS_FLAGS) co $(LDAPCSDK_CO_FLAGS) $(CVS_CO_DATE_FLAGS) $(LDAPCSDK_CO_MODULE)
####################################
# CVS defines for the C LDAP SDK
#
ACCESSIBLE_CO_MODULE = mozilla/accessible
ACCESSIBLE_CO_FLAGS := -P
ifdef MOZ_CO_FLAGS
ACCESSIBLE_CO_FLAGS := $(MOZ_CO_FLAGS)
endif
ifdef ACCESSIBLE_CO_TAG
ACCESSIBLE_CO_FLAGS := $(ACCESSIBLE_CO_FLAGS) -r $(ACCESSIBLE_CO_TAG)
endif
CVSCO_ACCESSIBLE = $(CVS) $(CVS_FLAGS) co $(ACCESSIBLE_CO_FLAGS) $(CVS_CO_DATE_FLAGS) $(ACCESSIBLE_CO_MODULE)
####################################
# CVS defines for gfx2
#
GFX2_CO_MODULE = mozilla/gfx2
GFX2_CO_FLAGS := -P
ifdef MOZ_CO_FLAGS
GFX2_CO_FLAGS := $(MOZ_CO_FLAGS)
endif
ifdef GFX2_CO_TAG
GFX2_CO_FLAGS := $(GFX2_CO_FLAGS) -r $(GFX2_CO_TAG)
endif
CVSCO_GFX2 = $(CVS) $(CVS_FLAGS) co $(GFX2_CO_FLAGS) $(CVS_CO_DATE_FLAGS) $(GFX2_CO_MODULE)
####################################
# CVS defines for new image library
#
IMGLIB2_CO_MODULE = mozilla/modules/libpr0n
IMGLIB2_CO_FLAGS := -P
ifdef MOZ_CO_FLAGS
IMGLIB2_CO_FLAGS := $(MOZ_CO_FLAGS)
endif
ifdef IMGLIB2_CO_TAG
IMGLIB2_CO_FLAGS := $(IMGLIB2_CO_FLAGS) -r $(IMGLIB2_CO_TAG)
endif
CVSCO_IMGLIB2 = $(CVS) $(CVS_FLAGS) co $(IMGLIB2_CO_FLAGS) $(CVS_CO_DATE_FLAGS) $(IMGLIB2_CO_MODULE)
####################################
# CVS defines for standalone modules
#
ifneq ($(BUILD_MODULES),all)
MOZ_CO_MODULE := $(filter-out $(NSPRPUB_DIR) security directory/c-sdk, $(BUILD_MODULE_CVS))
MOZ_CO_MODULE += allmakefiles.sh client.mk aclocal.m4 configure configure.in
MOZ_CO_MODULE += Makefile.in
MOZ_CO_MODULE := $(addprefix mozilla/, $(MOZ_CO_MODULE))
NOSUBDIRS_MODULE := $(addprefix mozilla/, $(BUILD_MODULE_CVS_NS))
ifneq ($(NOSUBDIRS_MODULE),)
CVSCO_NOSUBDIRS := $(CVSCO) -l $(CVS_CO_DATE_FLAGS) $(NOSUBDIRS_MODULE)
endif
ifeq (,$(filter $(NSPRPUB_DIR), $(BUILD_MODULE_CVS)))
CVSCO_NSPR :=
endif
ifeq (,$(filter security security/manager, $(BUILD_MODULE_CVS)))
CVSCO_PSM :=
CVSCO_NSS :=
endif
ifeq (,$(filter directory/c-sdk, $(BUILD_MODULE_CVS)))
CVSCO_LDAPCSDK :=
endif
ifeq (,$(filter accessible, $(BUILD_MODULE_CVS)))
CVSCO_ACCESSIBLE :=
endif
ifeq (,$(filter gfx2, $(BUILD_MODULE_CVS)))
CVSCO_GFX2 :=
endif
ifeq (,$(filter modules/libpr0n, $(BUILD_MODULE_CVS)))
CVSCO_IMGLIB2 :=
endif
endif
####################################
# CVS defines for SeaMonkey
#
ifeq ($(MOZ_CO_MODULE),)
MOZ_CO_MODULE := SeaMonkeyAll
endif
CVSCO_SEAMONKEY := $(CVSCO) $(CVS_CO_DATE_FLAGS) $(MOZ_CO_MODULE)
####################################
# CVS defined for libart (pulled and built if MOZ_INTERNAL_LIBART_LGPL is set)
#
CVSCO_LIBART := $(CVSCO) $(CVS_CO_DATE_FLAGS) mozilla/other-licenses/libart_lgpl
ifdef MOZ_INTERNAL_LIBART_LGPL
FASTUPDATE_LIBART := fast_update $(CVSCO_LIBART)
CHECKOUT_LIBART := cvs_co $(CVSCO_LIBART)
else
CHECKOUT_LIBART := true
FASTUPDATE_LIBART := true
endif
####################################
# CVS defines for Calendar (pulled and built if MOZ_CALENDAR is set)
#
CVSCO_CALENDAR := $(CVSCO) $(CVS_CO_DATE_FLAGS) mozilla/calendar
ifdef MOZ_CALENDAR
FASTUPDATE_CALENDAR := fast_update $(CVSCO_CALENDAR)
CHECKOUT_CALENDAR := cvs_co $(CVSCO_CALENDAR)
else
CHECKOUT_CALENDAR := true
FASTUPDATE_CALENDAR := true
endif
# because some cygwin tools can't handle native dos-drive paths & vice-versa
# force configure to use a relative path for --srcdir
# need a better check for win32
# and we need to get OBJDIR earlier
ifdef MOZ_TOOLS
_tmpobjdir := $(shell cygpath -u $(OBJDIR))
_abs2rel := $(shell cygpath -w $(TOPSRCDIR)/build/unix/abs2rel.pl | sed -e 's|\\|/|g')
_OBJ2SRCPATH := $(shell $(_abs2rel) $(TOPSRCDIR) $(_tmpobjdir))
endif
#######################################################################
# Rules
#
# Print out any options loaded from mozconfig.
all build checkout clean depend distclean export libs install realclean::
@if test -f .mozconfig.out; then \
cat .mozconfig.out; \
rm -f .mozconfig.out; \
else true; \
fi
ifdef _IS_FIRST_CHECKOUT
all:: checkout build
else
all:: checkout alldep
endif
# Windows equivalents
pull_all: checkout
build_all: build
build_all_dep: alldep
build_all_depend: alldep
clobber clobber_all: clean
pull_and_build_all: checkout alldep
# Do everything from scratch
everything: checkout clean build
####################################
# CVS checkout
#
checkout::
# @: Backup the last checkout log.
@if test -f $(CVSCO_LOGFILE) ; then \
mv $(CVSCO_LOGFILE) $(CVSCO_LOGFILE).old; \
else true; \
fi
ifdef RUN_AUTOCONF_LOCALLY
@echo "Removing local configures" ; \
cd $(ROOTDIR) && \
$(RM) -f mozilla/configure mozilla/nsprpub/configure \
mozilla/directory/c-sdk/configure
endif
@echo "checkout start: "`date` | tee $(CVSCO_LOGFILE)
@echo '$(CVSCO) mozilla/client.mk mozilla/build/unix/modules.mk'; \
cd $(ROOTDIR) && \
$(CVSCO) mozilla/client.mk mozilla/build/unix/modules.mk
@cd $(ROOTDIR) && $(MAKE) -f mozilla/client.mk real_checkout
real_checkout:
# @: Start the checkout. Split the output to the tty and a log file. \
# : If it fails, touch an error file because "tee" hides the error.
@failed=.cvs-failed.tmp; rm -f $$failed*; \
cvs_co() { echo "$$@" ; \
("$$@" || touch $$failed) 2>&1 | tee -a $(CVSCO_LOGFILE) && \
if test -f $$failed; then false; else true; fi; }; \
cvs_co $(CVSCO_NSPR) && \
cvs_co $(CVSCO_NSS) && \
cvs_co $(CVSCO_PSM) && \
cvs_co $(CVSCO_LDAPCSDK) && \
cvs_co $(CVSCO_ACCESSIBLE) && \
cvs_co $(CVSCO_GFX2) && \
cvs_co $(CVSCO_IMGLIB2) && \
$(CHECKOUT_CALENDAR) && \
$(CHECKOUT_LIBART) && \
cvs_co $(CVSCO_SEAMONKEY) && \
cvs_co $(CVSCO_NOSUBDIRS)
@echo "checkout finish: "`date` | tee -a $(CVSCO_LOGFILE)
# @: Check the log for conflicts. ;
@conflicts=`egrep "^C " $(CVSCO_LOGFILE)` ;\
if test "$$conflicts" ; then \
echo "$(MAKE): *** Conflicts during checkout." ;\
echo "$$conflicts" ;\
echo "$(MAKE): Refer to $(CVSCO_LOGFILE) for full log." ;\
false; \
else true; \
fi
ifdef RUN_AUTOCONF_LOCALLY
@echo Generating configures using $(AUTOCONF) ; \
cd $(TOPSRCDIR) && $(AUTOCONF) && \
cd $(TOPSRCDIR)/nsprpub && $(AUTOCONF) && \
cd $(TOPSRCDIR)/directory/c-sdk && $(AUTOCONF)
endif
fast-update:
# @: Backup the last checkout log.
@if test -f $(CVSCO_LOGFILE) ; then \
mv $(CVSCO_LOGFILE) $(CVSCO_LOGFILE).old; \
else true; \
fi
ifdef RUN_AUTOCONF_LOCALLY
@echo "Removing local configures" ; \
cd $(ROOTDIR) && \
$(RM) -f mozilla/configure mozilla/nsprpub/configure \
mozilla/directory/c-sdk/configure
endif
@echo "checkout start: "`date` | tee $(CVSCO_LOGFILE)
@echo '$(CVSCO) mozilla/client.mk mozilla/build/unix/modules.mk'; \
cd $(ROOTDIR) && \
$(CVSCO) mozilla/client.mk mozilla/build/unix/modules.mk
@cd $(TOPSRCDIR) && \
$(MAKE) -f client.mk real_fast-update
real_fast-update:
# @: Start the update. Split the output to the tty and a log file. \
# : If it fails, touch an error file because "tee" hides the error.
@failed=.fast_update-failed.tmp; rm -f $$failed*; \
fast_update() { (config/cvsco-fast-update.pl $$@ || touch $$failed) 2>&1 | tee -a $(CVSCO_LOGFILE) && \
if test -f $$failed; then false; else true; fi; }; \
cvs_co() { echo "$$@" ; \
("$$@" || touch $$failed) 2>&1 | tee -a $(CVSCO_LOGFILE) && \
if test -f $$failed; then false; else true; fi; }; \
fast_update $(CVSCO_NSPR) && \
cd $(ROOTDIR) && \
failed=mozilla/.fast_update-failed.tmp && \
cvs_co $(CVSCO_NSS) && \
failed=.fast_update-failed.tmp && \
cd mozilla && \
fast_update $(CVSCO_PSM) && \
fast_update $(CVSCO_LDAPCSDK) && \
fast_update $(CVSCO_ACCESSIBLE) && \
fast_update $(CVSCO_GFX2) && \
fast_update $(CVSCO_IMGLIB2) && \
$(FASTUPDATE_CALENDAR) && \
$(FASTUPDATE_LIBART) && \
fast_update $(CVSCO_SEAMONKEY) && \
fast_update $(CVSCO_NOSUBDIRS)
@echo "fast_update finish: "`date` | tee -a $(CVSCO_LOGFILE)
# @: Check the log for conflicts. ;
@conflicts=`egrep "^C " $(CVSCO_LOGFILE)` ;\
if test "$$conflicts" ; then \
echo "$(MAKE): *** Conflicts during fast-update." ;\
echo "$$conflicts" ;\
echo "$(MAKE): Refer to $(CVSCO_LOGFILE) for full log." ;\
false; \
else true; \
fi
ifdef RUN_AUTOCONF_LOCALLY
@echo Generating configures using $(AUTOCONF) ; \
cd $(TOPSRCDIR) && $(AUTOCONF) && \
cd $(TOPSRCDIR)/nsprpub && $(AUTOCONF) && \
cd $(TOPSRCDIR)/directory/c-sdk && $(AUTOCONF)
endif
####################################
# Web configure
WEBCONFIG_FILE := $(HOME)/.mozconfig
MOZCONFIG2CONFIGURATOR := build/autoconf/mozconfig2configurator
webconfig:
@cd $(TOPSRCDIR); \
url=`$(MOZCONFIG2CONFIGURATOR) $(TOPSRCDIR)`; \
echo Running mozilla with the following url: ;\
echo ;\
echo $$url ;\
mozilla -remote "openURL($$url)" || \
netscape -remote "openURL($$url)" || \
mozilla $$url || \
netscape $$url ;\
echo ;\
echo 1. Fill out the form on the browser. ;\
echo 2. Save the results to $(WEBCONFIG_FILE)
#####################################################
# First Checkout
ifdef _IS_FIRST_CHECKOUT
# First time, do build target in a new process to pick up new files.
build::
$(MAKE) -f $(TOPSRCDIR)/client.mk build
else
#####################################################
# After First Checkout
####################################
# Configure
CONFIG_STATUS := $(wildcard $(OBJDIR)/config.status)
CONFIG_CACHE := $(wildcard $(OBJDIR)/config.cache)
ifdef RUN_AUTOCONF_LOCALLY
EXTRA_CONFIG_DEPS := \
$(TOPSRCDIR)/aclocal.m4 \
$(wildcard $(TOPSRCDIR)/build/autoconf/*.m4) \
$(NULL)
$(TOPSRCDIR)/configure: $(TOPSRCDIR)/configure.in $(EXTRA_CONFIG_DEPS)
@echo Generating $@ using autoconf
cd $(TOPSRCDIR); $(AUTOCONF)
endif
CONFIG_STATUS_DEPS_L10N := $(wildcard $(TOPSRCDIR)/l10n/makefiles.all)
CONFIG_STATUS_DEPS := \
$(TOPSRCDIR)/configure \
$(TOPSRCDIR)/allmakefiles.sh \
$(TOPSRCDIR)/.mozconfig.mk \
$(wildcard $(TOPSRCDIR)/nsprpub/configure) \
$(wildcard $(TOPSRCDIR)/directory/c-sdk/configure) \
$(wildcard $(TOPSRCDIR)/mailnews/makefiles) \
$(CONFIG_STATUS_DEPS_L10N) \
$(wildcard $(TOPSRCDIR)/themes/makefiles) \
$(NULL)
# configure uses the program name to determine @srcdir@. Calling it without
# $(TOPSRCDIR) will set @srcdir@ to "."; otherwise, it is set to the full
# path of $(TOPSRCDIR).
ifeq ($(TOPSRCDIR),$(OBJDIR))
CONFIGURE := ./configure
else
CONFIGURE := $(TOPSRCDIR)/configure
endif
ifdef _OBJ2SRCPATH
CONFIGURE_ARGS := --srcdir=$(_OBJ2SRCPATH) $(CONFIGURE_ARGS)
endif
$(OBJDIR)/Makefile $(OBJDIR)/config.status: $(CONFIG_STATUS_DEPS)
@if test ! -d $(OBJDIR); then $(MKDIR) $(OBJDIR); else true; fi
@echo cd $(OBJDIR);
@echo $(CONFIGURE) $(CONFIGURE_ARGS)
@cd $(OBJDIR) && $(CONFIGURE_ENV_ARGS) $(CONFIGURE) $(CONFIGURE_ARGS) \
|| ( echo "*** Fix above errors and then restart with\
\"$(MAKE) -f client.mk build\"" && exit 1 )
@touch $(OBJDIR)/Makefile
ifdef CONFIG_STATUS
$(OBJDIR)/config/autoconf.mk: $(TOPSRCDIR)/config/autoconf.mk.in
cd $(OBJDIR); \
CONFIG_FILES=config/autoconf.mk ./config.status
endif
####################################
# Depend
depend:: $(OBJDIR)/Makefile $(OBJDIR)/config.status
$(MOZ_MAKE) export && $(MOZ_MAKE) depend
####################################
# Build it
build:: $(OBJDIR)/Makefile $(OBJDIR)/config.status
$(MOZ_MAKE)
####################################
# Other targets
# Pass these target onto the real build system
install export libs clean realclean distclean alldep:: $(OBJDIR)/Makefile $(OBJDIR)/config.status
$(MOZ_MAKE) $@
cleansrcdir:
@cd $(TOPSRCDIR); \
if [ -f webshell/embed/gtk/Makefile ]; then \
$(MAKE) -C webshell/embed/gtk distclean; \
fi; \
if [ -f Makefile ]; then \
$(MAKE) distclean ; \
else \
echo "Removing object files from srcdir..."; \
rm -fr `find . -type d \( -name .deps -print -o -name CVS \
-o -exec test ! -d {}/CVS \; \) -prune \
-o \( -name '*.[ao]' -o -name '*.so' \) -type f -print`; \
build/autoconf/clean-config.sh; \
fi;
# (! IS_FIRST_CHECKOUT)
endif
.PHONY: checkout real_checkout depend build export libs alldep install clean realclean distclean cleansrcdir pull_all build_all clobber clobber_all pull_and_build_all everything

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__ */

View File

@@ -0,0 +1,88 @@
/* -*- 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 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Sean Su <ssu@netscape.com>
*/
/* This is a hack for vc5.0. It needs to be set *before* any shell
* include files. The INITGUID definition turns off the inclusion
* of shlguid.h in shlobj.h so it has to be done explicitly.
*/
#if (_MSC_VER == 1100)
#define INITGUID
#include "objbase.h"
DEFINE_OLEGUID(IID_IPersistFile, 0x0000010BL, 0, 0);
#endif
#include <shlobj.h>
#include <shlguid.h>
#include "nsWinShortcut.h"
HRESULT CreateALink(LPCSTR lpszPathObj, LPCSTR lpszPathLink, LPCSTR lpszDesc, LPCSTR lpszWorkingPath, LPCSTR lpszArgs, LPCSTR lpszIconFullPath, int iIcon)
{
HRESULT hres;
IShellLink *psl;
char lpszFullPath[MAX_BUF];
lstrcpy(lpszFullPath, lpszPathLink);
lstrcat(lpszFullPath, "\\");
lstrcat(lpszFullPath, lpszDesc);
lstrcat(lpszFullPath, ".lnk");
CreateDirectory(lpszPathLink, NULL);
CoInitialize(NULL);
// Get a pointer to the IShellLink interface.
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *)&psl);
if(SUCCEEDED(hres))
{
IPersistFile* ppf;
// Set the path to the shortcut target, and add the
// description.
psl->SetPath(lpszPathObj);
psl->SetDescription(lpszDesc);
if(lpszWorkingPath)
psl->SetWorkingDirectory(lpszWorkingPath);
if(lpszArgs)
psl->SetArguments(lpszArgs);
psl->SetIconLocation(lpszIconFullPath, iIcon);
// Query IShellLink for the IPersistFile interface for saving the
// shortcut in persistent storage.
hres = psl->QueryInterface(IID_IPersistFile, (LPVOID FAR *)&ppf);
if(SUCCEEDED(hres))
{
WORD wsz[MAX_BUF];
// Ensure that the string is ANSI.
MultiByteToWideChar(CP_ACP, 0, lpszFullPath, -1, (wchar_t *)wsz, MAX_BUF);
// Save the link by calling IPersistFile::Save.
hres = ppf->Save((wchar_t *)wsz, TRUE);
ppf->Release();
}
psl->Release();
}
CoUninitialize();
return hres;
}

View File

@@ -0,0 +1,43 @@
/* -*- 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 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Sean Su <ssu@netscape.com>
*/
#ifndef _SHORTCUT_H_
#define _SHORTCUT_H_
#ifndef MAX_BUF
#define MAX_BUF 4096
#endif
#ifdef __cplusplus
extern "C"
{
#endif
long CreateALink(LPCSTR lpszPathObj, LPCSTR lpszPathLink, LPCSTR lpszDesc, LPCSTR lpszWorkingPath, LPCSTR lpszArgs, LPCSTR lpszIconFullPath, int iIcon);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,195 @@
/* -*- 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):
* Daniel Veditz <dveditz@netscape.com>
*/
#include "nscore.h"
#include "nsXPITriggerInfo.h"
#include "nsDebug.h"
#include "nsIServiceManager.h"
#include "nsIEventQueueService.h"
static NS_DEFINE_IID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
//
// nsXPITriggerItem
//
MOZ_DECL_CTOR_COUNTER(nsXPITriggerItem);
nsXPITriggerItem::nsXPITriggerItem( const PRUnichar* aName,
const PRUnichar* aURL,
PRInt32 aFlags )
: mName(aName), mFlags(aFlags)
{
MOZ_COUNT_CTOR(nsXPITriggerItem);
nsString URL(aURL);
PRInt32 pos = URL.FindChar('?');
if ( pos == -1 ) {
// no arguments
mURL = URL;
mArguments = "";
}
else
{
URL.Left(mURL,pos);
URL.Right(mArguments, URL.Length()-pos+1);
}
}
nsXPITriggerItem::~nsXPITriggerItem()
{
MOZ_COUNT_DTOR(nsXPITriggerItem);
}
PRBool nsXPITriggerItem::IsRelativeURL()
{
PRInt32 cpos = mURL.FindChar(':');
if (cpos == kNotFound)
return PR_TRUE;
PRInt32 spos = mURL.FindChar('/');
return (cpos > spos);
}
//
// nsXPITriggerInfo
//
MOZ_DECL_CTOR_COUNTER(nsXPITriggerInfo);
nsXPITriggerInfo::nsXPITriggerInfo()
: mCx(0), mGlobal(JSVAL_NULL), mCbval(JSVAL_NULL)
{
MOZ_COUNT_CTOR(nsXPITriggerInfo);
}
nsXPITriggerInfo::~nsXPITriggerInfo()
{
nsXPITriggerItem* item;
for(PRUint32 i=0; i < Size(); i++)
{
item = Get(i);
if (item)
delete item;
}
mItems.Clear();
if ( mCx && !JSVAL_IS_NULL(mGlobal) )
JS_RemoveRoot( mCx, &mGlobal );
if ( mCx && !JSVAL_IS_NULL(mCbval) )
JS_RemoveRoot( mCx, &mCbval );
MOZ_COUNT_DTOR(nsXPITriggerInfo);
}
void nsXPITriggerInfo::SaveCallback( JSContext *aCx, jsval aVal )
{
NS_ASSERTION( mCx == 0, "callback set twice, memory leak" );
mCx = aCx;
mGlobal = OBJECT_TO_JSVAL(JS_GetGlobalObject( mCx ));
mCbval = aVal;
mThread = PR_GetCurrentThread();
if ( !JSVAL_IS_NULL(mGlobal) )
JS_AddRoot( mCx, &mGlobal );
if ( !JSVAL_IS_NULL(mCbval) )
JS_AddRoot( mCx, &mCbval );
}
static void destroyTriggerEvent(XPITriggerEvent* event)
{
delete event;
}
static void* handleTriggerEvent(XPITriggerEvent* event)
{
jsval ret;
void* mark;
jsval* args;
args = JS_PushArguments( event->cx, &mark, "Wi",
event->URL.GetUnicode(),
event->status );
if ( args )
{
JS_CallFunctionValue( event->cx,
JSVAL_TO_OBJECT(event->global),
event->cbval,
2,
args,
&ret );
JS_PopArguments( event->cx, mark );
}
return 0;
}
void nsXPITriggerInfo::SendStatus(const PRUnichar* URL, PRInt32 status)
{
nsCOMPtr<nsIEventQueue> eq;
nsresult rv;
if ( mCx && mGlobal && mCbval )
{
NS_WITH_SERVICE(nsIEventQueueService, EQService, kEventQueueServiceCID, &rv);
if ( NS_SUCCEEDED( rv ) )
{
rv = EQService->GetThreadEventQueue(mThread, getter_AddRefs(eq));
if ( NS_SUCCEEDED(rv) )
{
// create event and post it
XPITriggerEvent* event = new XPITriggerEvent();
if (event)
{
PL_InitEvent(&event->e, 0,
(PLHandleEventProc)handleTriggerEvent,
(PLDestroyEventProc)destroyTriggerEvent);
event->URL = URL;
event->status = status;
event->cx = mCx;
event->global = mGlobal;
event->cbval = mCbval;
eq->PostEvent(&event->e);
}
else
rv = NS_ERROR_OUT_OF_MEMORY;
}
}
if ( NS_FAILED( rv ) )
{
// couldn't get event queue -- maybe window is gone or
// some similarly catastrophic occurrance
}
}
}

View File

@@ -0,0 +1,105 @@
/* -*- 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):
* Daniel Veditz <dveditz@netscape.com>
*/
#ifndef nsXPITriggerInfo_h
#define nsXPITriggerInfo_h
#include "nsString.h"
#include "nsVoidArray.h"
#include "nsCOMPtr.h"
#include "nsISupportsUtils.h"
#include "nsIXPINotifier.h"
#include "nsIFileSpec.h"
#include "jsapi.h"
#include "prthread.h"
#include "plevent.h"
typedef struct XPITriggerEvent {
PLEvent e;
nsString URL;
PRInt32 status;
JSContext* cx;
jsval global;
jsval cbval;
} XPITriggerEvent;
class nsXPITriggerItem
{
public:
nsXPITriggerItem( const PRUnichar* name, const PRUnichar* URL, PRInt32 flags = 0);
~nsXPITriggerItem();
nsString mName;
nsString mURL;
nsString mArguments;
PRInt32 mFlags;
nsCOMPtr<nsIFileSpec> mFile;
PRBool IsFileURL() { return mURL.Equals("file:/",PR_FALSE,6); }
PRBool IsRelativeURL();
private:
//-- prevent inadvertent copies and assignments
nsXPITriggerItem& operator=(const nsXPITriggerItem& rhs);
nsXPITriggerItem(const nsXPITriggerItem& rhs);
};
class nsXPITriggerInfo
{
public:
nsXPITriggerInfo();
~nsXPITriggerInfo();
void Add( nsXPITriggerItem *aItem )
{ if ( aItem ) mItems.AppendElement( (void*)aItem ); }
nsXPITriggerItem* Get( PRUint32 aIndex )
{ return (nsXPITriggerItem*)mItems.ElementAt(aIndex);}
void SaveCallback( JSContext *aCx, jsval aVal );
PRUint32 Size() { return mItems.Count(); }
void SendStatus(const PRUnichar* URL, PRInt32 status);
private:
nsVoidArray mItems;
JSContext *mCx;
jsval mGlobal;
jsval mCbval;
PRThread* mThread;
//-- prevent inadvertent copies and assignments
nsXPITriggerInfo& operator=(const nsXPITriggerInfo& rhs);
nsXPITriggerInfo(const nsXPITriggerInfo& rhs);
};
#endif /* nsXPITriggerInfo_h */

View File

@@ -0,0 +1,715 @@
/* -*- 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):
* Daniel Veditz <dveditz@netscape.com>
* Pierre Phaneuf <pp@ludusdesign.com>
*/
#include "nscore.h"
#include "nsFileSpec.h"
#include "pratom.h"
#include "nsISupports.h"
#include "nsIServiceManager.h"
#include "nsIURL.h"
#include "nsNetUtil.h"
#include "nsIBufferInputStream.h"
#include "nsIInputStream.h"
#include "nsIStreamListener.h"
#include "nsISoftwareUpdate.h"
#include "nsSoftwareUpdateIIDs.h"
#include "nsXPITriggerInfo.h"
#include "nsXPInstallManager.h"
#include "nsInstallProgressDialog.h"
#include "nsInstallResources.h"
#include "nsSpecialSystemDirectory.h"
#include "nsFileStream.h"
#include "nsProxyObjectManager.h"
#include "nsIDOMWindow.h"
#include "nsIAppShellComponentImpl.h"
#include "nsIPrompt.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kAppShellServiceCID, NS_APPSHELL_SERVICE_CID );
static NS_DEFINE_IID(kProxyObjectManagerCID, NS_PROXYEVENT_MANAGER_CID);
static NS_DEFINE_IID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
static NS_DEFINE_CID(kDialogParamBlockCID, NS_DialogParamBlock_CID);
#include "nsIEventQueueService.h"
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
#define XPINSTALL_BUNDLE_URL "chrome://xpinstall/locale/xpinstall.properties"
nsXPInstallManager::nsXPInstallManager()
: mTriggers(0), mItem(0), mNextItem(0), mNumJars(0),
mFinalizing(PR_FALSE), mCancelled(PR_FALSE), mContentLength(0)
{
NS_INIT_ISUPPORTS();
// we need to own ourself because we have a longer
// lifetime than the scriptlet that created us.
NS_ADDREF_THIS();
// get the resourced xpinstall string bundle
mStringBundle = nsnull;
nsIStringBundleService *service;
nsresult rv = nsServiceManager::GetService( kStringBundleServiceCID,
NS_GET_IID(nsIStringBundleService),
(nsISupports**) &service );
if (NS_SUCCEEDED(rv) && service)
{
nsILocale* locale = nsnull;
rv = service->CreateBundle( XPINSTALL_BUNDLE_URL, locale,
getter_AddRefs(mStringBundle) );
nsServiceManager::ReleaseService( kStringBundleServiceCID, service );
}
}
nsXPInstallManager::~nsXPInstallManager()
{
if (mTriggers)
delete mTriggers;
}
NS_IMPL_THREADSAFE_ADDREF( nsXPInstallManager );
NS_IMPL_THREADSAFE_RELEASE( nsXPInstallManager );
NS_IMETHODIMP
nsXPInstallManager::QueryInterface(REFNSIID aIID,void** aInstancePtr)
{
if (!aInstancePtr)
return NS_ERROR_NULL_POINTER;
if (aIID.Equals(NS_GET_IID(nsIXPINotifier)))
*aInstancePtr = NS_STATIC_CAST(nsIXPINotifier*,this);
else if (aIID.Equals(NS_GET_IID(nsIStreamListener)))
*aInstancePtr = NS_STATIC_CAST(nsIStreamListener*,this);
else if (aIID.Equals(NS_GET_IID(nsPIXPIManagerCallbacks)))
*aInstancePtr = NS_STATIC_CAST(nsPIXPIManagerCallbacks*,this);
else if (aIID.Equals(NS_GET_IID(nsIProgressEventSink)))
*aInstancePtr = NS_STATIC_CAST(nsIProgressEventSink*,this);
else if (aIID.Equals(NS_GET_IID(nsIInterfaceRequestor)))
*aInstancePtr = NS_STATIC_CAST(nsIInterfaceRequestor*,this);
else if (aIID.Equals(NS_GET_IID(nsISupports)))
*aInstancePtr = NS_STATIC_CAST( nsISupports*, NS_STATIC_CAST(nsIXPINotifier*,this));
else
*aInstancePtr = 0;
nsresult status;
if ( !*aInstancePtr )
status = NS_NOINTERFACE;
else
{
NS_ADDREF_THIS();
status = NS_OK;
}
return status;
}
NS_IMETHODIMP
nsXPInstallManager::InitManager(nsXPITriggerInfo* aTriggers)
{
nsresult rv = NS_OK;
nsCOMPtr<nsIDialogParamBlock> ioParamBlock;
PRBool OKtoInstall = PR_FALSE;
mTriggers = aTriggers;
if ( !mTriggers || mTriggers->Size() == 0 )
{
rv = NS_ERROR_INVALID_POINTER;
NS_RELEASE_THIS();
return rv;
}
//-----------------------------------------------------
// Create the nsIDialogParamBlock to pass the trigger
// list to the dialog
//-----------------------------------------------------
rv = nsComponentManager::CreateInstance(kDialogParamBlockCID,
nsnull,
NS_GET_IID(nsIDialogParamBlock),
getter_AddRefs(ioParamBlock));
if ( NS_SUCCEEDED( rv ) )
{
LoadDialogWithNames(ioParamBlock);
// 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))
{
void* stackPtr;
jsval *argv = JS_PushArguments( jsContext,
&stackPtr,
"sss%ip",
"chrome://xpinstall/content/institems.xul",
"_blank",
"chrome,modal",
(const nsIID*)(&NS_GET_IID(nsIDialogParamBlock)),
(nsISupports*)ioParamBlock);
if (argv)
{
nsCOMPtr<nsIDOMWindow> newWindow;
rv = hiddenWindow->OpenDialog( jsContext,
argv,
4,
getter_AddRefs( newWindow));
if (NS_SUCCEEDED(rv))
{
JS_PopArguments( jsContext, stackPtr);
//Now get which button was pressed from the ParamBlock
PRInt32 buttonPressed = 0;
ioParamBlock->GetInt( 0, &buttonPressed );
OKtoInstall = buttonPressed ? PR_FALSE : PR_TRUE;
}
}
else
{
rv = NS_ERROR_FAILURE; // fix, better error code??
}
}
}
}
// --- create and open the progress dialog
if (NS_SUCCEEDED(rv) && OKtoInstall)
{
nsInstallProgressDialog* dlg;
nsCOMPtr<nsISupports> Idlg;
dlg = new nsInstallProgressDialog(this);
if ( dlg )
{
rv = dlg->QueryInterface( NS_GET_IID(nsIXPIProgressDlg),
getter_AddRefs(Idlg) );
if (NS_SUCCEEDED(rv))
{
NS_WITH_SERVICE( nsIProxyObjectManager, pmgr, kProxyObjectManagerCID, &rv);
if (NS_SUCCEEDED(rv))
{
rv = pmgr->GetProxyObject( NS_UI_THREAD_EVENTQ, NS_GET_IID(nsIXPIProgressDlg),
Idlg, PROXY_SYNC | PROXY_ALWAYS, getter_AddRefs(mProxy) );
}
if (NS_SUCCEEDED(rv))
{
rv = mProxy->Open(ioParamBlock);
}
}
}
else
rv = NS_ERROR_OUT_OF_MEMORY;
}
PRInt32 cbstatus = 0; // callback status
if (NS_SUCCEEDED(rv) && !OKtoInstall )
cbstatus = nsInstall::USER_CANCELLED;
else if (!NS_SUCCEEDED(rv))
cbstatus = nsInstall::UNEXPECTED_ERROR;
if ( cbstatus != 0 )
{
// --- inform callbacks of error
for (PRUint32 i = 0; i < mTriggers->Size(); i++)
{
mTriggers->SendStatus( mTriggers->Get(i)->mURL.GetUnicode(),
cbstatus );
}
// -- must delete ourselves if not continuing
NS_RELEASE_THIS();
}
return rv;
}
NS_IMETHODIMP nsXPInstallManager::DialogOpened(nsISupports* aWindow)
{
nsresult rv;
nsCOMPtr<nsIDOMWindow> win = do_QueryInterface(aWindow, &rv);
DownloadNext();
return rv;
}
NS_IMETHODIMP nsXPInstallManager::DownloadNext()
{
nsresult rv;
mContentLength = 0;
if (mCancelled)
{
Shutdown();
return NS_OK; // don't try to download anymore
}
if ( mNextItem < mTriggers->Size() )
{
// download the next item in list
mItem = (nsXPITriggerItem*)mTriggers->Get(mNextItem++);
NS_ASSERTION( mItem, "bogus Trigger slipped through" );
NS_ASSERTION( mItem->mURL.Length() > 0, "bogus trigger");
if ( !mItem || mItem->mURL.Length() == 0 )
{
// XXX serious problem with trigger! try to carry on
rv = DownloadNext();
}
else if ( mItem->IsFileURL() )
{
// don't need to download, just point at local file
rv = NS_NewFileSpecWithSpec( nsFileSpec(nsFileURL(mItem->mURL)),
getter_AddRefs(mItem->mFile) );
if (NS_FAILED(rv))
{
// serious problem with trigger! try to carry on
mTriggers->SendStatus( mItem->mURL.GetUnicode(),
nsInstall::DOWNLOAD_ERROR );
mItem->mFile = 0;
}
rv = DownloadNext();
}
else
{
// We have one to download
// --- figure out a temp file name
nsSpecialSystemDirectory temp(nsSpecialSystemDirectory::OS_TemporaryDirectory);
PRInt32 pos = mItem->mURL.RFindChar('/');
if ( pos != -1 )
{
nsString jarleaf;
mItem->mURL.Right( jarleaf, mItem->mURL.Length() - pos);
temp += jarleaf;
}
else
temp += "xpinstall.xpi";
temp.MakeUnique();
rv = NS_NewFileSpecWithSpec( temp, getter_AddRefs(mItem->mFile) );
if (NS_SUCCEEDED(rv))
{
// --- start the download
nsCOMPtr<nsIURI> pURL;
rv = NS_NewURI(getter_AddRefs(pURL), mItem->mURL);
if (NS_SUCCEEDED(rv))
{
nsCOMPtr<nsIChannel> channel;
rv = NS_OpenURI(getter_AddRefs(channel), pURL, nsnull, nsnull, this);
if (NS_SUCCEEDED(rv))
{
rv = channel->AsyncRead(this, nsnull);
}
}
}
if (NS_FAILED(rv))
{
// announce failure
mTriggers->SendStatus( mItem->mURL.GetUnicode(),
nsInstall::DOWNLOAD_ERROR );
mItem->mFile = 0;
// carry on with the next one
rv = DownloadNext();
}
}
}
else
{
// all downloaded, queue them for installation
// can't cancel from here on cause we can't undo installs in a multitrigger
if (mProxy)
mProxy->StartInstallPhase();
NS_WITH_SERVICE(nsISoftwareUpdate, softupdate, nsSoftwareUpdate::GetCID(), &rv);
if (NS_SUCCEEDED(rv))
{
for (PRUint32 i = 0; i < mTriggers->Size(); ++i)
{
mItem = (nsXPITriggerItem*)mTriggers->Get(i);
if ( mItem && mItem->mFile )
{
rv = softupdate->InstallJar(mItem->mFile,
mItem->mURL.GetUnicode(),
mItem->mArguments.GetUnicode(),
mItem->mFlags,
this );
if (NS_SUCCEEDED(rv))
PR_AtomicIncrement(&mNumJars);
else
mTriggers->SendStatus( mItem->mURL.GetUnicode(),
nsInstall::UNEXPECTED_ERROR );
}
}
}
else
{
; // XXX gotta clean up all those files...
}
if ( mNumJars == 0 )
{
// We must clean ourself up now -- we won't be called back
Shutdown();
}
}
return rv;
}
NS_IMETHODIMP
nsXPInstallManager::CancelInstall()
{
mCancelled = PR_TRUE; // set by dialog thread
return NS_OK;
}
void nsXPInstallManager::Shutdown()
{
if (mProxy)
{
// proxy exists: we're being called from script thread
mProxy->Close();
}
// Clean up downloaded files
nsXPITriggerItem* item;
nsFileSpec tmpSpec;
for (PRUint32 i = 0; i < mTriggers->Size(); i++ )
{
item = NS_STATIC_CAST(nsXPITriggerItem*, mTriggers->Get(i));
if ( item && item->mFile && !item->IsFileURL() )
{
item->mFile->GetFileSpec(&tmpSpec);
tmpSpec.Delete(PR_FALSE);
}
}
NS_RELEASE_THIS();
}
/*-----------------------------------------------------
** LoadDialogWithNames loads the param block for the
** javascript/xul dialog with the list of modules to
** be installed and their source locations
**----------------------------------------------------*/
void nsXPInstallManager::LoadDialogWithNames(nsIDialogParamBlock* ioParamBlock)
{
nsXPITriggerItem *triggerItem;
nsString moduleName, URL;
PRInt32 offset = 0, numberOfDialogTreeElements = 0;
PRUint32 i=0, paramIndex=0;
//Must multiply the number of triggers by 2 because
//the dialog contains the name and url as 2 separate elements
numberOfDialogTreeElements = (mTriggers->Size() * 2);
ioParamBlock->SetNumberStrings(numberOfDialogTreeElements);
ioParamBlock->SetInt(0,2); //set the Ok and Cancel buttons
ioParamBlock->SetInt(1,numberOfDialogTreeElements);
for (i=0; i < mTriggers->Size(); i++)
{
triggerItem = mTriggers->Get(i);
//Check to see if this trigger item has a pretty name
if(!(moduleName = triggerItem->mName).IsEmpty())
{
ioParamBlock->SetString(paramIndex, moduleName.ToNewUnicode());
paramIndex++;
URL = triggerItem->mURL;
offset = URL.RFind("/");
if (offset != -1)
{
URL.Cut(offset + 1, URL.Length() - 1);
ioParamBlock->SetString(paramIndex, URL.ToNewUnicode());
}
paramIndex++;
}
else
{
//triggerItem does not have a pretty name so parse the url for the file name
//then use that as the pretty name
moduleName = triggerItem->mURL;
URL = triggerItem->mURL;
offset = moduleName.RFind("/");
if (offset != -1)
{
moduleName.Cut(0, offset + 1);
ioParamBlock->SetString(paramIndex, moduleName.ToNewUnicode());
paramIndex++;
URL.Cut(offset + 1, URL.Length() - 1);
ioParamBlock->SetString(paramIndex, URL.ToNewUnicode());
}
paramIndex++;
}
}
}
NS_IMETHODIMP
nsXPInstallManager::OnStartRequest(nsIChannel* channel, nsISupports *ctxt)
{
nsresult rv = NS_ERROR_FAILURE;
NS_ASSERTION( mItem && mItem->mFile, "XPIMgr::OnStartRequest bad state");
if ( mItem && mItem->mFile )
{
rv = mItem->mFile->OpenStreamForWriting();
}
return rv;
}
NS_IMETHODIMP
nsXPInstallManager::OnStopRequest(nsIChannel* channel, nsISupports *ctxt,
nsresult status, const PRUnichar *errorMsg)
{
nsresult rv;
switch( status )
{
case NS_BINDING_SUCCEEDED:
rv = NS_OK;
break;
case NS_BINDING_FAILED:
case NS_BINDING_ABORTED:
rv = status;
// XXX need to note failure, both to send back status
// to the callback, and also so we don't try to install
// this probably corrupt file.
break;
default:
rv = NS_ERROR_ILLEGAL_VALUE;
}
if ( mItem->mFile )
mItem->mFile->CloseStream();
if (!NS_SUCCEEDED(rv))
{
if ( mItem->mFile )
{
nsFileSpec fspec;
nsresult rv2 ;
rv2 = mItem->mFile->GetFileSpec(&fspec);
if ( NS_SUCCEEDED(rv2) && fspec.Exists() )
fspec.Delete(0);
mItem->mFile = 0;
}
mTriggers->SendStatus( mItem->mURL.GetUnicode(),
nsInstall::DOWNLOAD_ERROR );
}
DownloadNext();
return rv;
}
NS_IMETHODIMP
nsXPInstallManager::OnDataAvailable(nsIChannel* channel, nsISupports *ctxt,
nsIInputStream *pIStream,
PRUint32 sourceOffset,
PRUint32 length)
{
PRUint32 amt;
PRInt32 result;
nsresult err;
char buffer[8*1024];
if (mCancelled)
{
// returning an error will stop the download. We may get extra
// OnData calls if they were already queued so beware
return NS_ERROR_FAILURE;
}
do
{
err = pIStream->Read(buffer, sizeof(buffer), &amt);
if (amt == 0) break;
if (NS_FAILED(err))
{
//printf("pIStream->Read Failed! %d", err);
return err;
}
err = mItem->mFile->Write( buffer, amt, &result);
//printf("mItem->mFile->Write err:%d amt:%d result:%d\n", err, amt, result);
if (NS_FAILED(err) || result != (PRInt32)amt)
{
//printf("mItem->mFile->Write Failed! err:%d amt:%d result:%d\n", err, amt, result);
return NS_ERROR_FAILURE;
}
length -= amt;
} while (length > 0);
return NS_OK;
}
NS_IMETHODIMP
nsXPInstallManager::OnProgress(nsIChannel *channel, nsISupports *ctxt, PRUint32 aProgress, PRUint32 aProgressMax)
{
if (!mCancelled)
{
nsresult rv = NS_OK;
char mode = 'n'; // downloads use a "normal" progress bar
if (mContentLength < 1) {
NS_ASSERTION(channel, "should have a channel");
rv = channel->GetContentLength(&mContentLength);
if (NS_FAILED(rv)) return rv;
}
return mProxy->SetProgress(aProgress, mContentLength, mode);
}
return NS_OK;
}
NS_IMETHODIMP
nsXPInstallManager::OnStatus(nsIChannel *channel, nsISupports *ctxt, const PRUnichar *aMsg)
{
if (!mCancelled)
return mProxy->SetActionText(aMsg);
return NS_OK;
}
// nsIInterfaceRequestor method
NS_IMETHODIMP
nsXPInstallManager::GetInterface(const nsIID & eventSinkIID, void* *_retval)
{
return QueryInterface(eventSinkIID, (void**)_retval);
}
// IXPINotifier methods
NS_IMETHODIMP
nsXPInstallManager::BeforeJavascriptEvaluation(const PRUnichar *URL)
{
nsresult rv = NS_OK;
mFinalizing = PR_FALSE;
mProxy->SetProgress( 0, 0, 'u' ); // turn on the barber pole
PRUnichar tmp[] = { '\0' };
mProxy->SetActionText(tmp);
return rv;
}
NS_IMETHODIMP
nsXPInstallManager::AfterJavascriptEvaluation(const PRUnichar *URL)
{
PR_AtomicDecrement( &mNumJars );
if ( mNumJars == 0 )
Shutdown();
return NS_OK;
}
NS_IMETHODIMP
nsXPInstallManager::InstallStarted(const PRUnichar *URL, const PRUnichar *UIPackageName)
{
mProxy->SetActionText(nsnull);
return mProxy->SetHeading( nsString(UIPackageName).GetUnicode() );
}
NS_IMETHODIMP
nsXPInstallManager::ItemScheduled(const PRUnichar *message)
{
return mProxy->SetActionText( nsString(message).GetUnicode() );
}
NS_IMETHODIMP
nsXPInstallManager::FinalizeProgress(const PRUnichar *message, PRInt32 itemNum, PRInt32 totNum)
{
if (!mFinalizing)
{
mFinalizing = PR_TRUE;
if (mStringBundle)
{
nsString rsrcName = "FinishingInstallMsg";
const PRUnichar* ucRsrcName = rsrcName.GetUnicode();
PRUnichar* ucRsrcVal = nsnull;
nsresult rv = mStringBundle->GetStringFromName(ucRsrcName, &ucRsrcVal);
if (NS_SUCCEEDED(rv) && ucRsrcVal)
{
mProxy->SetActionText( ucRsrcVal );
nsCRT::free(ucRsrcVal);
}
}
}
return mProxy->SetProgress( itemNum, totNum, 'n' );
}
NS_IMETHODIMP
nsXPInstallManager::FinalStatus(const PRUnichar *URL, PRInt32 status)
{
mTriggers->SendStatus( URL, status );
return NS_OK;
}
NS_IMETHODIMP
nsXPInstallManager::LogComment(const PRUnichar* comment)
{
return NS_OK;
}

View File

@@ -0,0 +1,104 @@
/* -*- 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):
* Daniel Veditz <dveditz@netscape.com>
*/
#ifndef _NS_XPINSTALLMANAGER_H
#define _NS_XPINSTALLMANAGER_H
#include "nsInstall.h"
#include "nscore.h"
#include "nsISupports.h"
#include "nsString.h"
#include "nsIURL.h"
#include "nsIInputStream.h"
#include "nsIStreamListener.h"
#include "nsIXPINotifier.h"
#include "nsXPITriggerInfo.h"
#include "nsIXPIProgressDlg.h"
#include "nsISoftwareUpdate.h"
#include "nsCOMPtr.h"
#include "nsIWebShell.h"
#include "nsIWebShellWindow.h"
#include "nsIProgressEventSink.h"
#include "nsIInterfaceRequestor.h"
#include "nsPIXPIManagerCallbacks.h"
#include "nsIDialogParamBlock.h"
class nsXPInstallManager : public nsIXPINotifier,
public nsIStreamListener,
public nsIProgressEventSink,
public nsIInterfaceRequestor,
public nsPIXPIManagerCallbacks
{
public:
nsXPInstallManager();
virtual ~nsXPInstallManager();
NS_DECL_ISUPPORTS
NS_IMETHOD InitManager( nsXPITriggerInfo* aTrigger );
// nsIStreamObserver
NS_DECL_NSISTREAMOBSERVER
// nsIStreamListener
NS_DECL_NSISTREAMLISTENER
// IXPINotifier methods
NS_DECL_NSIXPINOTIFIER
// nsIProgressEventSink
NS_DECL_NSIPROGRESSEVENTSINK
// nsIInterfaceRequestor
NS_DECL_NSIINTERFACEREQUESTOR
//nsPIXPIMANAGERCALLBACKS
NS_DECL_NSPIXPIMANAGERCALLBACKS
private:
NS_IMETHOD DownloadNext();
void Shutdown();
void LoadDialogWithNames(nsIDialogParamBlock* ioParamBlock);
nsXPITriggerInfo* mTriggers;
nsXPITriggerItem* mItem;
PRUint32 mNextItem;
PRInt32 mNumJars;
PRBool mFinalizing;
PRBool mCancelled;
PRInt32 mContentLength;
nsCOMPtr<nsIXPIProgressDlg> mProxy;
nsCOMPtr<nsIStringBundle> mStringBundle;
};
#endif

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