Back to index

lightning-sunbird  0.9+nobinonly
nsLoggingProgressNotifier.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Mozilla Communicator client code, released
00016  * March 31, 1998.
00017  *
00018  * The Initial Developer of the Original Code is
00019  * Netscape Communications Corporation.
00020  * Portions created by the Initial Developer are Copyright (C) 1998
00021  * the Initial Developer. All Rights Reserved.
00022  *
00023  * Contributor(s):
00024  *   Douglas Turner <dougt@netscape.com>
00025  *   Pierre Phaneuf <pp@ludusdesign.com>
00026  *   Samir Gehani <sgehani@netscape.com>
00027  *
00028  * Alternatively, the contents of this file may be used under the terms of
00029  * either of the GNU General Public License Version 2 or later (the "GPL"),
00030  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00031  * in which case the provisions of the GPL or the LGPL are applicable instead
00032  * of those above. If you wish to allow use of your version of this file only
00033  * under the terms of either the GPL or the LGPL, and not to allow others to
00034  * use your version of this file under the terms of the MPL, indicate your
00035  * decision by deleting the provisions above and replace them with the notice
00036  * and other provisions required by the GPL or the LGPL. If you do not delete
00037  * the provisions above, a recipient may use your version of this file under
00038  * the terms of any one of the MPL, the GPL or the LGPL.
00039  *
00040  * ***** END LICENSE BLOCK ***** */
00041 
00042 #include "nsLoggingProgressNotifier.h"
00043 
00044 #include "nsInstall.h"
00045 
00046 #include "nsFileSpec.h"
00047 #include "nsFileStream.h"
00048 #include "nsDirectoryService.h"
00049 #include "nsDirectoryServiceDefs.h"
00050 #include "nsAppDirectoryServiceDefs.h"
00051 #include "nsILocalFile.h"
00052 #include "nsNativeCharsetUtils.h"
00053 
00054 #include "nspr.h"
00055 
00056 #ifdef XP_MAC
00057 #define INSTALL_LOG NS_LITERAL_CSTRING("Install Log")
00058 #else
00059 #define INSTALL_LOG NS_LITERAL_CSTRING("install.log")
00060 #endif
00061 
00062 
00063 nsLoggingProgressListener::nsLoggingProgressListener()
00064     : mLogStream(0)
00065 {
00066 }
00067 
00068 nsLoggingProgressListener::~nsLoggingProgressListener()
00069 {
00070     if (mLogStream)
00071     {
00072         NS_WARN_IF_FALSE(PR_FALSE, "We're being destroyed before script finishes!");
00073         mLogStream->close();
00074         delete mLogStream;
00075         mLogStream = 0;
00076     }
00077 }
00078 
00079 NS_IMPL_ISUPPORTS1(nsLoggingProgressListener, nsIXPIListener)
00080 
00081 NS_IMETHODIMP
00082 nsLoggingProgressListener::OnInstallStart(const PRUnichar *URL)
00083 {
00084     nsCOMPtr<nsIFile> iFile;
00085     nsFileSpec *logFile = nsnull;
00086     nsresult rv = NS_OK;
00087 
00088     // Not in stub installer
00089     if (!nsSoftwareUpdate::GetProgramDirectory())
00090     {
00091         nsCOMPtr<nsIProperties> dirSvc =
00092                  do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
00093         if (!dirSvc) return NS_ERROR_FAILURE;
00094         dirSvc->Get(NS_OS_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile),
00095                     getter_AddRefs(iFile));
00096     }
00097     // In stub installer
00098     else
00099     {
00100         rv = nsSoftwareUpdate::GetProgramDirectory()->Clone(
00101              getter_AddRefs(iFile));
00102     }
00103 
00104     if (NS_FAILED(rv)) return rv;
00105 
00106     if (!nsSoftwareUpdate::GetLogName())
00107         rv = iFile->AppendNative(INSTALL_LOG);
00108     else
00109         rv = iFile->AppendNative(nsDependentCString(nsSoftwareUpdate::GetLogName()));
00110 
00111     if (NS_FAILED(rv)) return rv;
00112 
00113     // create log file if it doesn't exist (to work around a mac filespec bug)
00114     PRBool bExists = PR_FALSE, bTryProfileDir = PR_FALSE, bWritable = PR_FALSE;
00115     rv = iFile->Exists(&bExists);
00116     if (NS_FAILED(rv)) return rv;
00117     if (!bExists)
00118     {
00119         rv = iFile->Create(nsIFile::NORMAL_FILE_TYPE, 0644);
00120         if (NS_FAILED(rv))
00121             bTryProfileDir = PR_TRUE;
00122 #ifdef XP_MAC
00123         else
00124         {
00125             nsCOMPtr<nsILocalFileMac> iMacFile = do_QueryInterface(iFile);
00126             iMacFile->SetFileType('TEXT');
00127             iMacFile->SetFileCreator('R*ch');
00128         }
00129 #endif
00130     }
00131 
00132     if (!bTryProfileDir)
00133     {
00134         rv = iFile->IsWritable(&bWritable);
00135         if (NS_FAILED(rv) || !bWritable)
00136             bTryProfileDir = PR_TRUE;
00137     }
00138 
00139     if (bTryProfileDir && !nsSoftwareUpdate::GetProgramDirectory())
00140     {   
00141         // failed to create the log file in the application directory
00142         // so try to create the log file in the user's profile directory
00143         // while we are not in the stub installer
00144         nsCOMPtr<nsIProperties> dirSvc =
00145                  do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
00146         if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
00147         dirSvc->Get(NS_APP_USER_PROFILE_50_DIR, NS_GET_IID(nsIFile),
00148                     getter_AddRefs(iFile));
00149         if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
00150 
00151         if (!nsSoftwareUpdate::GetLogName())
00152             rv = iFile->AppendNative(INSTALL_LOG);
00153         else
00154             rv = iFile->AppendNative(nsDependentCString(nsSoftwareUpdate::GetLogName()));
00155 
00156         if (NS_FAILED(rv)) return rv;
00157 
00158         bExists = PR_FALSE;
00159         bWritable = PR_FALSE;
00160         rv = iFile->Exists(&bExists);
00161         if (NS_FAILED(rv)) return rv;
00162         if (!bExists)
00163         {
00164             rv = iFile->Create(nsIFile::NORMAL_FILE_TYPE, 0644);
00165             if (NS_FAILED(rv)) return rv;
00166 
00167 #ifdef XP_MAC
00168             nsCOMPtr<nsILocalFileMac> iMacFile = do_QueryInterface(iFile);
00169             iMacFile->SetFileType('TEXT');
00170             iMacFile->SetFileCreator('R*ch');
00171 #endif
00172         }
00173 
00174         rv = iFile->IsWritable(&bWritable);
00175         if (NS_FAILED(rv) || !bWritable) return NS_ERROR_FAILURE;
00176     }
00177 
00178     rv = Convert_nsIFile_To_nsFileSpec(iFile, &logFile);
00179     if (NS_FAILED(rv)) return rv;
00180     if (!logFile) return NS_ERROR_NULL_POINTER;
00181 
00182     mLogStream = new nsOutputFileStream(*logFile, PR_WRONLY | PR_CREATE_FILE | PR_APPEND, 0744 );
00183     if (!mLogStream)
00184         return NS_ERROR_NULL_POINTER;
00185 
00186     char* time;
00187     GetTime(&time);
00188 
00189     mLogStream->seek(logFile->GetFileSize());
00190 
00191     *mLogStream << "-------------------------------------------------------------------------------" << nsEndl;
00192     *mLogStream << NS_ConvertUCS2toUTF8(URL).get() << "  --  " << time << nsEndl;
00193     *mLogStream << "-------------------------------------------------------------------------------" << nsEndl;
00194     *mLogStream << nsEndl;
00195 
00196     PL_strfree(time);
00197     if (logFile)
00198         delete logFile;
00199 
00200     return NS_OK;
00201 }
00202 
00203 NS_IMETHODIMP
00204 nsLoggingProgressListener::OnInstallDone(const PRUnichar *aURL, PRInt32 aStatus)
00205 {
00206     if (mLogStream == nsnull) return NS_ERROR_NULL_POINTER;
00207 
00208     *mLogStream << nsEndl;
00209 
00210     switch (aStatus)
00211     {
00212     case nsInstall::SUCCESS:
00213         *mLogStream << "     Install completed successfully";
00214         break;
00215 
00216     case nsInstall::REBOOT_NEEDED:
00217         *mLogStream << "     Install completed successfully, restart required";
00218         break;
00219 
00220     case nsInstall::INSTALL_CANCELLED:
00221         *mLogStream << "     Install cancelled by script";
00222         break;
00223 
00224     case nsInstall::USER_CANCELLED:
00225         *mLogStream << "     Install cancelled by user";
00226         break;
00227 
00228     default:
00229         *mLogStream << "     Install **FAILED** with error " << aStatus;
00230         break;
00231     }
00232 
00233     char* time;
00234     GetTime(&time);
00235 
00236     *mLogStream << "  --  " << time << nsEndl << nsEndl;
00237 
00238     PL_strfree(time);
00239 
00240     mLogStream->close();
00241     delete mLogStream;
00242     mLogStream = nsnull;
00243 
00244     return NS_OK;
00245 }
00246 
00247 NS_IMETHODIMP
00248 nsLoggingProgressListener::OnPackageNameSet(const PRUnichar *URL, const PRUnichar* UIPackageName, const PRUnichar* aVersion)
00249 {
00250     if (mLogStream == nsnull) return NS_ERROR_NULL_POINTER;
00251 
00252 //    char* time;
00253 //    GetTime(&time);
00254 
00255     nsCString name;
00256     nsCString version;
00257     nsCString uline;
00258 
00259     nsAutoString autostrName(UIPackageName);
00260     nsAutoString autostrVersion(aVersion);
00261 
00262     NS_CopyUnicodeToNative(autostrName, name);
00263     NS_CopyUnicodeToNative(autostrVersion, version);
00264 
00265     uline.SetCapacity(name.Length());
00266     for ( unsigned int i=0; i < name.Length(); ++i)
00267         uline.Append('-');
00268 
00269     *mLogStream << "     " << name.get() << " (version " << version.get() << ")" << nsEndl;
00270     *mLogStream << "     " << uline.get() << nsEndl;
00271 
00272     *mLogStream << nsEndl;
00273 //    *mLogStream << "     Starting Installation at " << time << nsEndl;
00274 //    *mLogStream << nsEndl;
00275 
00276 
00277 //    PL_strfree(time);
00278     return NS_OK;
00279 }
00280 
00281 NS_IMETHODIMP
00282 nsLoggingProgressListener::OnItemScheduled(const PRUnichar* message )
00283 {
00284     return NS_OK;
00285 }
00286 
00287 NS_IMETHODIMP
00288 nsLoggingProgressListener::OnFinalizeProgress(const PRUnichar* aMessage, PRInt32 aItemNum, PRInt32 aTotNum )
00289 {
00290     nsCString messageConverted;
00291 
00292     // this Lossy conversion is safe because the input source came from a
00293     // similar fake-ascii-to-not-really-unicode conversion.
00294     // If you use NS_CopyUnicodeToNative(), it'll crash under a true JA WinXP
00295     // system as opposed to a EN winXP system changed to JA.
00296     messageConverted.AssignWithConversion(aMessage);
00297 
00298     if (mLogStream == nsnull) return NS_ERROR_NULL_POINTER;
00299 
00300     *mLogStream << "     [" << (aItemNum) << "/" << aTotNum << "]\t" << messageConverted.get() << nsEndl;
00301     return NS_OK;
00302 }
00303 
00304 void
00305 nsLoggingProgressListener::GetTime(char** aString)
00306 {
00307     PRExplodedTime et;
00308     char line[256];
00309     PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &et);
00310     PR_FormatTimeUSEnglish(line, sizeof(line), "%Y-%m-%d %H:%M:%S", &et);
00311     *aString = PL_strdup(line);
00312 }
00313 
00314 NS_IMETHODIMP
00315 nsLoggingProgressListener::OnLogComment(const PRUnichar* aComment)
00316 {
00317     nsCString commentConverted;
00318 
00319     NS_CopyUnicodeToNative(nsDependentString(aComment), commentConverted);
00320     if (mLogStream == nsnull) return NS_ERROR_NULL_POINTER;
00321 
00322     *mLogStream << "     ** " << commentConverted.get() << nsEndl;
00323     return NS_OK;
00324 }
00325 
00326 nsresult
00327 Convert_nsIFile_To_nsFileSpec(nsIFile *aInIFile, nsFileSpec **aOutFileSpec)
00328 {
00329     nsresult rv = NS_OK;
00330 
00331     if (!aInIFile || !aOutFileSpec)
00332         return NS_ERROR_FAILURE;
00333 
00334     *aOutFileSpec = nsnull;
00335 
00336 #ifdef XP_MAC
00337     FSSpec fsSpec;
00338     nsCOMPtr<nsILocalFileMac> iFileMac;
00339 
00340     iFileMac = do_QueryInterface(aInIFile, &rv);
00341     if (NS_SUCCEEDED(rv))
00342     {
00343         iFileMac->GetFSSpec(&fsSpec);
00344         *aOutFileSpec = new nsFileSpec(fsSpec, PR_FALSE);
00345     }
00346 #else
00347     nsCAutoString path;
00348     rv = aInIFile->GetNativePath(path);
00349     if (NS_SUCCEEDED(rv))
00350     {
00351         *aOutFileSpec = new nsFileSpec(path.get(), PR_FALSE);
00352     }
00353     // NOTE: don't release path since nsFileSpec's mPath points to it
00354 #endif
00355 
00356     if (!*aOutFileSpec)
00357         rv = NS_ERROR_FAILURE;
00358 
00359     return rv;
00360 }
00361