PageRenderTime 37ms CodeModel.GetById 14ms app.highlight 19ms RepoModel.GetById 2ms app.codeStats 0ms

/extensions/pref/autoconfig/src/nsReadConfig.cpp

http://github.com/zpao/v8monkey
C++ | 339 lines | 214 code | 64 blank | 61 comment | 40 complexity | fea3d7420191ba2a6e87f9f7e732d764 MD5 | raw file
  1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  2/* ***** BEGIN LICENSE BLOCK *****
  3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  4 *
  5 * The contents of this file are subject to the Mozilla Public License Version
  6 * 1.1 (the "License"); you may not use this file except in compliance with
  7 * the License. You may obtain a copy of the License at
  8 * http://www.mozilla.org/MPL/
  9 *
 10 * Software distributed under the License is distributed on an "AS IS" basis,
 11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 12 * for the specific language governing rights and limitations under the
 13 * License.
 14 *
 15 * The Original Code is mozilla.org code.
 16 *
 17 * The Initial Developer of the Original Code is
 18 * Netscape Communications Corporation.
 19 * Portions created by the Initial Developer are Copyright (C) 1998
 20 * the Initial Developer. All Rights Reserved.
 21 *
 22 * Contributor(s):
 23 *   Mitesh Shah <mitesh@netscape.com>
 24 *   Chip Clark  <chipc@netscape.com>
 25 *
 26 * Alternatively, the contents of this file may be used under the terms of
 27 * either the GNU General Public License Version 2 or later (the "GPL"), or
 28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 29 * in which case the provisions of the GPL or the LGPL are applicable instead
 30 * of those above. If you wish to allow use of your version of this file only
 31 * under the terms of either the GPL or the LGPL, and not to allow others to
 32 * use your version of this file under the terms of the MPL, indicate your
 33 * decision by deleting the provisions above and replace them with the notice
 34 * and other provisions required by the GPL or the LGPL. If you do not delete
 35 * the provisions above, a recipient may use your version of this file under
 36 * the terms of any one of the MPL, the GPL or the LGPL.
 37 *
 38 * ***** END LICENSE BLOCK ***** */
 39
 40#ifdef MOZ_LOGGING
 41// sorry, this has to be before the pre-compiled header
 42#define FORCE_PR_LOG /* Allow logging in the release build */
 43#endif
 44#include "nsReadConfig.h"
 45#include "nsAppDirectoryServiceDefs.h"
 46#include "nsIAppStartup.h"
 47#include "nsDirectoryServiceDefs.h"
 48#include "nsIAutoConfig.h"
 49#include "nsIComponentManager.h"
 50#include "nsIFile.h"
 51#include "nsIObserverService.h"
 52#include "nsIPrefBranch.h"
 53#include "nsIPrefService.h"
 54#include "nsIPromptService.h"
 55#include "nsIServiceManager.h"
 56#include "nsIStringBundle.h"
 57#include "nsToolkitCompsCID.h"
 58#include "nsXPIDLString.h"
 59#include "nsNetUtil.h"
 60#include "prmem.h"
 61#include "nsString.h"
 62#include "nsCRT.h"
 63#include "nspr.h"
 64
 65extern PRLogModuleInfo *MCD;
 66
 67extern nsresult EvaluateAdminConfigScript(const char *js_buffer, size_t length,
 68                                          const char *filename, 
 69                                          bool bGlobalContext, 
 70                                          bool bCallbacks, 
 71                                          bool skipFirstLine);
 72extern nsresult CentralizedAdminPrefManagerInit();
 73extern nsresult CentralizedAdminPrefManagerFinish();
 74
 75
 76static void DisplayError(void)
 77{
 78    nsresult rv;
 79
 80    nsCOMPtr<nsIPromptService> promptService = do_GetService("@mozilla.org/embedcomp/prompt-service;1");
 81    if (!promptService)
 82        return;
 83
 84    nsCOMPtr<nsIStringBundleService> bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID);
 85    if (!bundleService)
 86        return;
 87
 88    nsCOMPtr<nsIStringBundle> bundle;
 89    bundleService->CreateBundle("chrome://autoconfig/locale/autoconfig.properties",
 90                                getter_AddRefs(bundle));
 91    if (!bundle)
 92        return;
 93
 94    nsXPIDLString title;
 95    rv = bundle->GetStringFromName(NS_LITERAL_STRING("readConfigTitle").get(), getter_Copies(title));
 96    if (NS_FAILED(rv))
 97        return;
 98
 99    nsXPIDLString err;
100    rv = bundle->GetStringFromName(NS_LITERAL_STRING("readConfigMsg").get(), getter_Copies(err));
101    if (NS_FAILED(rv))
102        return;
103
104    promptService->Alert(nsnull, title.get(), err.get());
105}
106
107// nsISupports Implementation
108
109NS_IMPL_THREADSAFE_ISUPPORTS2(nsReadConfig, nsIReadConfig, nsIObserver)
110
111nsReadConfig::nsReadConfig() :
112    mRead(false)
113{
114    if (!MCD)
115      MCD = PR_NewLogModule("MCD");
116}
117
118nsresult nsReadConfig::Init()
119{
120    nsresult rv;
121    
122    nsCOMPtr<nsIObserverService> observerService = 
123        do_GetService("@mozilla.org/observer-service;1", &rv);
124
125    if (observerService) {
126        rv = observerService->AddObserver(this, NS_PREFSERVICE_READ_TOPIC_ID, false);
127    }
128    return(rv);
129}
130
131nsReadConfig::~nsReadConfig()
132{
133    CentralizedAdminPrefManagerFinish();
134}
135
136NS_IMETHODIMP nsReadConfig::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *someData)
137{
138    nsresult rv = NS_OK;
139
140    if (!nsCRT::strcmp(aTopic, NS_PREFSERVICE_READ_TOPIC_ID)) {
141        rv = readConfigFile();
142        if (NS_FAILED(rv)) {
143            DisplayError();
144
145            nsCOMPtr<nsIAppStartup> appStartup =
146                do_GetService(NS_APPSTARTUP_CONTRACTID);
147            if (appStartup)
148                appStartup->Quit(nsIAppStartup::eAttemptQuit);
149        }
150    }
151    return rv;
152}
153
154
155nsresult nsReadConfig::readConfigFile()
156{
157    nsresult rv = NS_OK;
158    nsXPIDLCString lockFileName;
159    nsXPIDLCString lockVendor;
160    PRUint32 fileNameLen = 0;
161    
162    nsCOMPtr<nsIPrefBranch> defaultPrefBranch;
163    nsCOMPtr<nsIPrefService> prefService = 
164        do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
165    if (NS_FAILED(rv))
166        return rv;
167
168    rv = prefService->GetDefaultBranch(nsnull, getter_AddRefs(defaultPrefBranch));
169    if (NS_FAILED(rv))
170        return rv;
171        
172    // This preference is set in the all.js or all-ns.js (depending whether 
173    // running mozilla or netscp6)
174
175    rv = defaultPrefBranch->GetCharPref("general.config.filename", 
176                                  getter_Copies(lockFileName));
177
178
179    PR_LOG(MCD, PR_LOG_DEBUG, ("general.config.filename = %s\n", lockFileName.get()));
180    if (NS_FAILED(rv))
181        return rv;
182
183    // This needs to be read only once.
184    //
185    if (!mRead) {
186        // Initiate the new JS Context for Preference management
187        
188        rv = CentralizedAdminPrefManagerInit();
189        if (NS_FAILED(rv))
190            return rv;
191        
192        // Open and evaluate function calls to set/lock/unlock prefs
193        rv = openAndEvaluateJSFile("prefcalls.js", 0, false, false);
194        if (NS_FAILED(rv)) 
195            return rv;
196
197        // Evaluate platform specific directives
198        rv = openAndEvaluateJSFile("platform.js", 0, false, false);
199        if (NS_FAILED(rv)) 
200            return rv;
201
202        mRead = true;
203    }
204    // If the lockFileName is NULL return ok, because no lockFile will be used
205  
206  
207    // Once the config file is read, we should check that the vendor name 
208    // is consistent By checking for the vendor name after reading the config 
209    // file we allow for the preference to be set (and locked) by the creator 
210    // of the cfg file meaning the file can not be renamed (successfully).
211
212    nsCOMPtr<nsIPrefBranch> prefBranch;
213    rv = prefService->GetBranch(nsnull, getter_AddRefs(prefBranch));
214    NS_ENSURE_SUCCESS(rv, rv);
215
216    PRInt32 obscureValue = 0;
217    (void) defaultPrefBranch->GetIntPref("general.config.obscure_value", &obscureValue);
218    PR_LOG(MCD, PR_LOG_DEBUG, ("evaluating .cfg file %s with obscureValue %d\n", lockFileName.get(), obscureValue));
219    rv = openAndEvaluateJSFile(lockFileName.get(), obscureValue, true, true);
220    if (NS_FAILED(rv))
221    {
222      PR_LOG(MCD, PR_LOG_DEBUG, ("error evaluating .cfg file %s %x\n", lockFileName.get(), rv));
223      return rv;
224    }
225    
226    rv = prefBranch->GetCharPref("general.config.filename", 
227                                  getter_Copies(lockFileName));
228    if (NS_FAILED(rv))
229        // There is NO REASON we should ever get here. This is POST reading 
230        // of the config file.
231        return NS_ERROR_FAILURE;
232
233  
234    rv = prefBranch->GetCharPref("general.config.vendor", 
235                                  getter_Copies(lockVendor));
236    // If vendor is not NULL, do this check
237    if (NS_SUCCEEDED(rv)) {
238
239        fileNameLen = PL_strlen(lockFileName);
240    
241        // lockVendor and lockFileName should be the same with the addtion of 
242        // .cfg to the filename by checking this post reading of the cfg file 
243        // this value can be set within the cfg file adding a level of security.
244    
245        if (PL_strncmp(lockFileName, lockVendor, fileNameLen - 4) != 0)
246            return NS_ERROR_FAILURE;
247    }
248  
249    // get the value of the autoconfig url
250    nsXPIDLCString urlName;
251    rv = prefBranch->GetCharPref("autoadmin.global_config_url",
252                                  getter_Copies(urlName));
253    if (NS_SUCCEEDED(rv) && !urlName.IsEmpty()) {
254
255        // Instantiating nsAutoConfig object if the pref is present
256        mAutoConfig = do_CreateInstance(NS_AUTOCONFIG_CONTRACTID, &rv);
257        if (NS_FAILED(rv))
258            return NS_ERROR_OUT_OF_MEMORY;
259
260        rv = mAutoConfig->SetConfigURL(urlName);
261        if (NS_FAILED(rv))
262            return NS_ERROR_FAILURE;
263
264    }
265  
266    return NS_OK;
267} // ReadConfigFile
268
269
270nsresult nsReadConfig::openAndEvaluateJSFile(const char *aFileName, PRInt32 obscureValue,
271                                             bool isEncoded,
272                                             bool isBinDir)
273{
274    nsresult rv;
275
276    nsCOMPtr<nsIInputStream> inStr;
277    if (isBinDir) {
278        nsCOMPtr<nsIFile> jsFile;
279        rv = NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR, 
280                                    getter_AddRefs(jsFile));
281        if (NS_FAILED(rv)) 
282            return rv;
283
284        rv = jsFile->AppendNative(nsDependentCString(aFileName));
285        if (NS_FAILED(rv)) 
286            return rv;
287
288        rv = NS_NewLocalFileInputStream(getter_AddRefs(inStr), jsFile);
289        if (NS_FAILED(rv)) 
290            return rv;
291
292    } else {
293        nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
294        if (NS_FAILED(rv)) 
295            return rv;
296
297        nsCAutoString location("resource://gre/defaults/autoconfig/");
298        location += aFileName;
299
300        nsCOMPtr<nsIURI> uri;
301        rv = ioService->NewURI(location, nsnull, nsnull, getter_AddRefs(uri));
302        if (NS_FAILED(rv))
303            return rv;
304
305        nsCOMPtr<nsIChannel> channel;
306        rv = ioService->NewChannelFromURI(uri, getter_AddRefs(channel));
307        if (NS_FAILED(rv))
308            return rv;
309
310        rv = channel->Open(getter_AddRefs(inStr));
311        if (NS_FAILED(rv)) 
312            return rv;
313    }
314
315    PRUint32 fs, amt = 0;
316    inStr->Available(&fs);
317
318    char *buf = (char *)PR_Malloc(fs * sizeof(char));
319    if (!buf) 
320        return NS_ERROR_OUT_OF_MEMORY;
321
322    rv = inStr->Read(buf, fs, &amt);
323    NS_ASSERTION((amt == fs), "failed to read the entire configuration file!!");
324    if (NS_SUCCEEDED(rv)) {
325        if (obscureValue > 0) {
326
327            // Unobscure file by subtracting some value from every char. 
328            for (PRUint32 i = 0; i < amt; i++)
329                buf[i] -= obscureValue;
330        }
331        rv = EvaluateAdminConfigScript(buf, amt, aFileName,
332                                       false, true,
333                                       isEncoded ? true:false);
334    }
335    inStr->Close();
336    PR_Free(buf);
337    
338    return rv;
339}