Back to index

lightning-sunbird  0.9+nobinonly
nsComm4xProfile.cpp
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is mozilla.org code.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 2002
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *   Srilatha Moturi <srilatha@netscape.com>
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037  
00038 #include "nsCOMPtr.h"
00039 #include "nsComm4xProfile.h"
00040 #include "nsIFileStreams.h"
00041 #include "nsILineInputStream.h"
00042 #include "nsReadableUtils.h"
00043 #include "nsNetCID.h"
00044 #include "nsDirectoryServiceDefs.h"
00045 #include "NSReg.h"
00046 
00047 #if defined(XP_MACOSX)
00048 #define PREF_FILE_NAME_IN_4x "Netscape Preferences"
00049 #define OLDREG_NAME               "Netscape Registry"
00050 #define OLDREG_DIR                NS_MAC_PREFS_DIR
00051 #elif defined(XP_UNIX) && !defined(XP_MACOSX)
00052 #define PREF_FILE_NAME_IN_4x "preferences.js"
00053 #elif defined(XP_WIN) || defined(XP_OS2)
00054 #define PREF_FILE_NAME_IN_4x "prefs.js"
00055 #define OLDREG_NAME               "nsreg.dat"
00056 #ifdef XP_WIN
00057 #define OLDREG_DIR                NS_WIN_WINDOWS_DIR
00058 #else
00059 #define OLDREG_DIR                NS_OS2_DIR
00060 #endif
00061 #else
00062 /* this will cause a failure at run time, as it should, since we don't know
00063    how to migrate platforms other than Mac, Windows and UNIX */
00064 #define PREF_FILE_NAME_IN_4x ""
00065 #endif
00066 
00067 #ifndef MAXPATHLEN
00068 #ifdef _MAX_PATH
00069 #define MAXPATHLEN _MAX_PATH
00070 #elif defined(CCHMAXPATH)
00071 #define MAXPATHLEN CCHMAXPATH
00072 #else
00073 #define MAXPATHLEN 1024
00074 #endif
00075 #endif
00076 
00077 nsComm4xProfile::nsComm4xProfile()
00078 {
00079 }
00080 
00081 nsComm4xProfile::~nsComm4xProfile()
00082 {
00083 }
00084 
00085 NS_IMPL_ISUPPORTS1(nsComm4xProfile, nsIComm4xProfile)
00086 
00087 NS_IMETHODIMP
00088 nsComm4xProfile::GetProfileList(PRUint32 *length, PRUnichar ***profileNames)
00089 {
00090 // on win/mac/os2, NS4x uses a registry to determine profile locations
00091 #if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_OS2)
00092     nsresult rv;
00093 
00094     nsCOMPtr<nsIFile> regFile;
00095     rv = NS_GetSpecialDirectory(OLDREG_DIR, getter_AddRefs(regFile));
00096     NS_ENSURE_SUCCESS(rv, rv);
00097     regFile->AppendNative(NS_LITERAL_CSTRING(OLDREG_NAME));
00098   
00099     nsCAutoString path;
00100     rv = regFile->GetNativePath(path);
00101     NS_ENSURE_SUCCESS(rv, rv);
00102 
00103     if (NR_StartupRegistry())
00104       return NS_ERROR_FAILURE;
00105 
00106     HREG reg = nsnull;
00107     if (NR_RegOpen(path.get(), &reg)) {
00108       NR_ShutdownRegistry();
00109       return NS_ERROR_FAILURE;
00110     }
00111 
00112     PRInt32 numProfileEntries = 0;
00113     REGENUM enumstate = 0;
00114     PRInt32 localLength = 0;
00115 
00116     char profileName[MAXREGNAMELEN];
00117     while (!NR_RegEnumSubkeys(reg, ROOTKEY_USERS, &enumstate,
00118                               profileName, MAXREGNAMELEN, REGENUM_CHILDREN))
00119         numProfileEntries++;
00120 
00121     // reset our enumerator
00122     enumstate = 0;
00123 
00124     PRUnichar **outArray, **next;
00125     next = outArray = (PRUnichar **)nsMemory::Alloc(numProfileEntries * sizeof(PRUnichar *));
00126     if (!outArray)
00127         return NS_ERROR_OUT_OF_MEMORY;
00128 
00129     while (!NR_RegEnumSubkeys(reg, ROOTKEY_USERS, &enumstate,
00130                               profileName, MAXREGNAMELEN, REGENUM_CHILDREN)) {
00131         *next = ToNewUnicode(NS_ConvertUTF8toUTF16(profileName));
00132         next++;
00133         localLength++;
00134     }
00135 
00136     *profileNames = outArray;
00137     *length = localLength;
00138     return NS_OK;
00139 #else
00140     return NS_ERROR_FAILURE;
00141 #endif
00142 }
00143 
00144 #define PREF_NAME "user_pref(\"mail.directory\", \""
00145 #define PREF_LENGTH 29
00146 #define PREF_END "\")"
00147 NS_IMETHODIMP
00148 nsComm4xProfile::GetMailDir(const PRUnichar *aProfile, PRUnichar **_retval)
00149 {
00150     NS_ENSURE_ARG_POINTER(_retval);
00151     *_retval = nsnull;
00152 #if defined(XP_WIN) || defined(XP_OS2) || defined(XP_MACOSX)
00153     nsresult rv;
00154     nsCOMPtr <nsILocalFile> resolvedLocation = do_CreateInstance("@mozilla.org/file/local;1");
00155     // on macos, registry entries are UTF8 encoded
00156     NS_ConvertUTF16toUTF8 profileName(aProfile);
00157 
00158     nsCOMPtr<nsIFile> regFile;
00159     rv = NS_GetSpecialDirectory(OLDREG_DIR, getter_AddRefs(regFile));
00160     if (NS_FAILED(rv)) return rv;
00161 
00162     regFile->AppendNative(NS_LITERAL_CSTRING(OLDREG_NAME));
00163   
00164     nsCAutoString path;
00165     rv = regFile->GetNativePath(path);
00166     if (NS_FAILED(rv)) return rv;
00167 
00168     if (NR_StartupRegistry())
00169         return NS_ERROR_FAILURE;
00170 
00171     HREG reg = nsnull;
00172     RKEY profile = nsnull;
00173 
00174     if (NR_RegOpen(path.get(), &reg))
00175       goto cleanup;
00176 
00177     if (NR_RegGetKey(reg, ROOTKEY_USERS, profileName.get(), &profile))
00178         goto cleanup;
00179   
00180     char profilePath[MAXPATHLEN];
00181     if (NR_RegGetEntryString(reg, profile, "ProfileLocation", profilePath, MAXPATHLEN))
00182         goto cleanup;
00183 
00184     resolvedLocation->InitWithPath(NS_ConvertUTF8toUTF16(profilePath));
00185     if (resolvedLocation) {
00186         nsCOMPtr <nsIFile> file;
00187         rv = resolvedLocation->Clone(getter_AddRefs(file));
00188         if (NS_FAILED(rv)) return rv;
00189         nsCOMPtr <nsILocalFile> profileLocation;
00190         profileLocation = do_QueryInterface(file);
00191         rv = profileLocation->AppendNative(NS_LITERAL_CSTRING(PREF_FILE_NAME_IN_4x));
00192         if (NS_FAILED(rv)) return rv;
00193         PRBool exists = PR_FALSE;
00194         rv = profileLocation->Exists(&exists);
00195         if (NS_FAILED(rv)) return rv;
00196         if (exists) {
00197             nsXPIDLString prefValue;
00198             rv = GetPrefValue(profileLocation, PREF_NAME, PREF_END, getter_Copies(prefValue));
00199             if (NS_FAILED(rv)) return rv;
00200             if (prefValue) {
00201 #if defined(XP_MAC) || defined(XP_MACOSX)
00202                 rv = profileLocation->SetPersistentDescriptor(NS_ConvertUCS2toUTF8(prefValue));
00203                 if (NS_FAILED(rv)) return rv;
00204                 nsAutoString path;
00205                 rv = profileLocation->GetPath(path);
00206                 if (NS_FAILED(rv)) return rv;
00207                 *_retval = ToNewUnicode(path);
00208 #else
00209                 *_retval = ToNewUnicode(prefValue);
00210 #endif
00211             }
00212 #if defined(XP_WIN) || defined(XP_OS2) || defined(XP_MAC) || defined(XP_MACOSX)
00213             else {
00214                 nsCOMPtr <nsIFile> mailLocation;
00215                 rv =  resolvedLocation->Clone(getter_AddRefs(mailLocation));
00216                 if (NS_FAILED(rv)) return rv;
00217                 rv = mailLocation->AppendNative(NS_LITERAL_CSTRING("Mail"));
00218                 if (NS_FAILED(rv)) return rv;
00219                 nsAutoString path;
00220                 rv = mailLocation->GetPath(path);
00221                 if (NS_FAILED(rv)) return rv;
00222                 *_retval = ToNewUnicode(path);
00223             }
00224 #endif
00225         }
00226     }
00227 
00228 cleanup:
00229     if (reg)
00230         NR_RegClose(reg);
00231     NR_ShutdownRegistry();
00232     return rv;
00233 #else
00234     return NS_ERROR_FAILURE;
00235 #endif
00236 }
00237 
00238 nsresult nsComm4xProfile::GetPrefValue(nsILocalFile *filePath, const char * prefName, const char * prefEnd, PRUnichar ** retval)
00239 {
00240    nsString buffer;
00241    PRBool more = PR_TRUE;
00242    nsresult rv;
00243    nsCOMPtr<nsIFileInputStream> fileStream(do_CreateInstance(NS_LOCALFILEINPUTSTREAM_CONTRACTID, &rv));
00244    if (NS_FAILED(rv))
00245      return rv;
00246    rv = fileStream->Init(filePath, -1, -1, PR_FALSE);
00247    if (NS_FAILED(rv))
00248      return rv;
00249  
00250    nsCOMPtr<nsILineInputStream> lineStream(do_QueryInterface(fileStream, &rv));
00251    if (NS_FAILED(rv)) {
00252      return rv;
00253    }
00254    PRBool found = PR_FALSE;
00255    PRInt32 offset;
00256    PRInt32 endOffset;
00257    while (!found && more) {
00258       nsCAutoString cLine;
00259        rv = lineStream->ReadLine(cLine, &more);
00260        if (NS_FAILED(rv))
00261            break;
00262        CopyASCIItoUTF16(cLine, buffer);
00263        offset = buffer.Find(prefName,PR_FALSE, 0, -1);
00264        if (offset != kNotFound) {
00265            endOffset = buffer.Find(prefEnd,PR_FALSE, 0, -1);
00266            if (endOffset != kNotFound) {
00267                nsAutoString prefValue;
00268                buffer.Mid(prefValue, offset + PREF_LENGTH, endOffset-(offset + PREF_LENGTH));
00269                found = PR_TRUE;
00270                *retval = ToNewUnicode(prefValue);
00271                break;
00272            }
00273        }
00274   }
00275 
00276   fileStream->Close(); 
00277   return rv; 
00278 }
00279