/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. #ifdef MOZ_LOGGING
  40. // sorry, this has to be before the pre-compiled header
  41. #define FORCE_PR_LOG /* Allow logging in the release build */
  42. #endif
  43. #include "nsReadConfig.h"
  44. #include "nsAppDirectoryServiceDefs.h"
  45. #include "nsIAppStartup.h"
  46. #include "nsDirectoryServiceDefs.h"
  47. #include "nsIAutoConfig.h"
  48. #include "nsIComponentManager.h"
  49. #include "nsIFile.h"
  50. #include "nsIObserverService.h"
  51. #include "nsIPrefBranch.h"
  52. #include "nsIPrefService.h"
  53. #include "nsIPromptService.h"
  54. #include "nsIServiceManager.h"
  55. #include "nsIStringBundle.h"
  56. #include "nsToolkitCompsCID.h"
  57. #include "nsXPIDLString.h"
  58. #include "nsNetUtil.h"
  59. #include "prmem.h"
  60. #include "nsString.h"
  61. #include "nsCRT.h"
  62. #include "nspr.h"
  63. extern PRLogModuleInfo *MCD;
  64. extern nsresult EvaluateAdminConfigScript(const char *js_buffer, size_t length,
  65. const char *filename,
  66. bool bGlobalContext,
  67. bool bCallbacks,
  68. bool skipFirstLine);
  69. extern nsresult CentralizedAdminPrefManagerInit();
  70. extern nsresult CentralizedAdminPrefManagerFinish();
  71. static void DisplayError(void)
  72. {
  73. nsresult rv;
  74. nsCOMPtr<nsIPromptService> promptService = do_GetService("@mozilla.org/embedcomp/prompt-service;1");
  75. if (!promptService)
  76. return;
  77. nsCOMPtr<nsIStringBundleService> bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID);
  78. if (!bundleService)
  79. return;
  80. nsCOMPtr<nsIStringBundle> bundle;
  81. bundleService->CreateBundle("chrome://autoconfig/locale/autoconfig.properties",
  82. getter_AddRefs(bundle));
  83. if (!bundle)
  84. return;
  85. nsXPIDLString title;
  86. rv = bundle->GetStringFromName(NS_LITERAL_STRING("readConfigTitle").get(), getter_Copies(title));
  87. if (NS_FAILED(rv))
  88. return;
  89. nsXPIDLString err;
  90. rv = bundle->GetStringFromName(NS_LITERAL_STRING("readConfigMsg").get(), getter_Copies(err));
  91. if (NS_FAILED(rv))
  92. return;
  93. promptService->Alert(nsnull, title.get(), err.get());
  94. }
  95. // nsISupports Implementation
  96. NS_IMPL_THREADSAFE_ISUPPORTS2(nsReadConfig, nsIReadConfig, nsIObserver)
  97. nsReadConfig::nsReadConfig() :
  98. mRead(false)
  99. {
  100. if (!MCD)
  101. MCD = PR_NewLogModule("MCD");
  102. }
  103. nsresult nsReadConfig::Init()
  104. {
  105. nsresult rv;
  106. nsCOMPtr<nsIObserverService> observerService =
  107. do_GetService("@mozilla.org/observer-service;1", &rv);
  108. if (observerService) {
  109. rv = observerService->AddObserver(this, NS_PREFSERVICE_READ_TOPIC_ID, false);
  110. }
  111. return(rv);
  112. }
  113. nsReadConfig::~nsReadConfig()
  114. {
  115. CentralizedAdminPrefManagerFinish();
  116. }
  117. NS_IMETHODIMP nsReadConfig::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *someData)
  118. {
  119. nsresult rv = NS_OK;
  120. if (!nsCRT::strcmp(aTopic, NS_PREFSERVICE_READ_TOPIC_ID)) {
  121. rv = readConfigFile();
  122. if (NS_FAILED(rv)) {
  123. DisplayError();
  124. nsCOMPtr<nsIAppStartup> appStartup =
  125. do_GetService(NS_APPSTARTUP_CONTRACTID);
  126. if (appStartup)
  127. appStartup->Quit(nsIAppStartup::eAttemptQuit);
  128. }
  129. }
  130. return rv;
  131. }
  132. nsresult nsReadConfig::readConfigFile()
  133. {
  134. nsresult rv = NS_OK;
  135. nsXPIDLCString lockFileName;
  136. nsXPIDLCString lockVendor;
  137. PRUint32 fileNameLen = 0;
  138. nsCOMPtr<nsIPrefBranch> defaultPrefBranch;
  139. nsCOMPtr<nsIPrefService> prefService =
  140. do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
  141. if (NS_FAILED(rv))
  142. return rv;
  143. rv = prefService->GetDefaultBranch(nsnull, getter_AddRefs(defaultPrefBranch));
  144. if (NS_FAILED(rv))
  145. return rv;
  146. // This preference is set in the all.js or all-ns.js (depending whether
  147. // running mozilla or netscp6)
  148. rv = defaultPrefBranch->GetCharPref("general.config.filename",
  149. getter_Copies(lockFileName));
  150. PR_LOG(MCD, PR_LOG_DEBUG, ("general.config.filename = %s\n", lockFileName.get()));
  151. if (NS_FAILED(rv))
  152. return rv;
  153. // This needs to be read only once.
  154. //
  155. if (!mRead) {
  156. // Initiate the new JS Context for Preference management
  157. rv = CentralizedAdminPrefManagerInit();
  158. if (NS_FAILED(rv))
  159. return rv;
  160. // Open and evaluate function calls to set/lock/unlock prefs
  161. rv = openAndEvaluateJSFile("prefcalls.js", 0, false, false);
  162. if (NS_FAILED(rv))
  163. return rv;
  164. // Evaluate platform specific directives
  165. rv = openAndEvaluateJSFile("platform.js", 0, false, false);
  166. if (NS_FAILED(rv))
  167. return rv;
  168. mRead = true;
  169. }
  170. // If the lockFileName is NULL return ok, because no lockFile will be used
  171. // Once the config file is read, we should check that the vendor name
  172. // is consistent By checking for the vendor name after reading the config
  173. // file we allow for the preference to be set (and locked) by the creator
  174. // of the cfg file meaning the file can not be renamed (successfully).
  175. nsCOMPtr<nsIPrefBranch> prefBranch;
  176. rv = prefService->GetBranch(nsnull, getter_AddRefs(prefBranch));
  177. NS_ENSURE_SUCCESS(rv, rv);
  178. PRInt32 obscureValue = 0;
  179. (void) defaultPrefBranch->GetIntPref("general.config.obscure_value", &obscureValue);
  180. PR_LOG(MCD, PR_LOG_DEBUG, ("evaluating .cfg file %s with obscureValue %d\n", lockFileName.get(), obscureValue));
  181. rv = openAndEvaluateJSFile(lockFileName.get(), obscureValue, true, true);
  182. if (NS_FAILED(rv))
  183. {
  184. PR_LOG(MCD, PR_LOG_DEBUG, ("error evaluating .cfg file %s %x\n", lockFileName.get(), rv));
  185. return rv;
  186. }
  187. rv = prefBranch->GetCharPref("general.config.filename",
  188. getter_Copies(lockFileName));
  189. if (NS_FAILED(rv))
  190. // There is NO REASON we should ever get here. This is POST reading
  191. // of the config file.
  192. return NS_ERROR_FAILURE;
  193. rv = prefBranch->GetCharPref("general.config.vendor",
  194. getter_Copies(lockVendor));
  195. // If vendor is not NULL, do this check
  196. if (NS_SUCCEEDED(rv)) {
  197. fileNameLen = PL_strlen(lockFileName);
  198. // lockVendor and lockFileName should be the same with the addtion of
  199. // .cfg to the filename by checking this post reading of the cfg file
  200. // this value can be set within the cfg file adding a level of security.
  201. if (PL_strncmp(lockFileName, lockVendor, fileNameLen - 4) != 0)
  202. return NS_ERROR_FAILURE;
  203. }
  204. // get the value of the autoconfig url
  205. nsXPIDLCString urlName;
  206. rv = prefBranch->GetCharPref("autoadmin.global_config_url",
  207. getter_Copies(urlName));
  208. if (NS_SUCCEEDED(rv) && !urlName.IsEmpty()) {
  209. // Instantiating nsAutoConfig object if the pref is present
  210. mAutoConfig = do_CreateInstance(NS_AUTOCONFIG_CONTRACTID, &rv);
  211. if (NS_FAILED(rv))
  212. return NS_ERROR_OUT_OF_MEMORY;
  213. rv = mAutoConfig->SetConfigURL(urlName);
  214. if (NS_FAILED(rv))
  215. return NS_ERROR_FAILURE;
  216. }
  217. return NS_OK;
  218. } // ReadConfigFile
  219. nsresult nsReadConfig::openAndEvaluateJSFile(const char *aFileName, PRInt32 obscureValue,
  220. bool isEncoded,
  221. bool isBinDir)
  222. {
  223. nsresult rv;
  224. nsCOMPtr<nsIInputStream> inStr;
  225. if (isBinDir) {
  226. nsCOMPtr<nsIFile> jsFile;
  227. rv = NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR,
  228. getter_AddRefs(jsFile));
  229. if (NS_FAILED(rv))
  230. return rv;
  231. rv = jsFile->AppendNative(nsDependentCString(aFileName));
  232. if (NS_FAILED(rv))
  233. return rv;
  234. rv = NS_NewLocalFileInputStream(getter_AddRefs(inStr), jsFile);
  235. if (NS_FAILED(rv))
  236. return rv;
  237. } else {
  238. nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
  239. if (NS_FAILED(rv))
  240. return rv;
  241. nsCAutoString location("resource://gre/defaults/autoconfig/");
  242. location += aFileName;
  243. nsCOMPtr<nsIURI> uri;
  244. rv = ioService->NewURI(location, nsnull, nsnull, getter_AddRefs(uri));
  245. if (NS_FAILED(rv))
  246. return rv;
  247. nsCOMPtr<nsIChannel> channel;
  248. rv = ioService->NewChannelFromURI(uri, getter_AddRefs(channel));
  249. if (NS_FAILED(rv))
  250. return rv;
  251. rv = channel->Open(getter_AddRefs(inStr));
  252. if (NS_FAILED(rv))
  253. return rv;
  254. }
  255. PRUint32 fs, amt = 0;
  256. inStr->Available(&fs);
  257. char *buf = (char *)PR_Malloc(fs * sizeof(char));
  258. if (!buf)
  259. return NS_ERROR_OUT_OF_MEMORY;
  260. rv = inStr->Read(buf, fs, &amt);
  261. NS_ASSERTION((amt == fs), "failed to read the entire configuration file!!");
  262. if (NS_SUCCEEDED(rv)) {
  263. if (obscureValue > 0) {
  264. // Unobscure file by subtracting some value from every char.
  265. for (PRUint32 i = 0; i < amt; i++)
  266. buf[i] -= obscureValue;
  267. }
  268. rv = EvaluateAdminConfigScript(buf, amt, aFileName,
  269. false, true,
  270. isEncoded ? true:false);
  271. }
  272. inStr->Close();
  273. PR_Free(buf);
  274. return rv;
  275. }