Adding AutoConfig Feature
r=bnesse and sr=alecf
This commit is contained in:
mitesh%netscape.com 2001-05-04 20:45:20 +00:00
Родитель af5c64a49e
Коммит 1e1ffa36cf
9 изменённых файлов: 681 добавлений и 2 удалений

Просмотреть файл

@ -29,6 +29,7 @@ include $(DEPTH)/config/autoconf.mk
MODULE = pref
XPIDLSRCS = \
nsIAutoConfig.idl \
nsIPref.idl \
nsIPrefBranch.idl \
nsIPrefBranchInternal.idl \

Просмотреть файл

@ -25,6 +25,7 @@ DEPTH=..\..\..
EXPORTS=prefldap.h
XPIDLSRCS = \
.\nsIAutoConfig.idl \
.\nsIPref.idl \
.\nsIPrefBranch.idl \
.\nsIPrefBranchInternal.idl \

Просмотреть файл

@ -0,0 +1,47 @@
/* -*- Mode: IDL; 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):
* Mitesh Shah <mitesh@netscape.com>
*
*/
#include "nsISupports.idl"
%{C++
#define NS_AUTOCONFIG_CID\
{ 0xe036c738,\
0x1dd1,\
0x11b2,\
{ 0x93, 0x92, 0x9d, 0x94, 0xaa, 0x74, 0xb0, 0xc5 }\
}
#define NS_AUTOCONFIG_CONTRACTID \
"@mozilla.org/autoconfig;1"
#define NS_AUTOCONFIG_CLASSNAME "AutoConfig Module"
%}
[uuid (80DB54AE-13F2-11d5-BE44-00108335A220)]
interface nsIAutoConfig : nsISupports {
void downloadAutoCfg();
};

Просмотреть файл

@ -40,6 +40,7 @@ CPPSRCS = nsPref.cpp \
nsPrefBranch.cpp \
nsPrefService.cpp \
nsPrefsFactory.cpp \
nsAutoConfig.cpp \
$(NULL)
PREF_JS_EXPORTS = \

Просмотреть файл

@ -75,6 +75,7 @@ OBJS = \
.\$(OBJDIR)\nsPrefBranch.obj \
.\$(OBJDIR)\nsPrefService.obj \
.\$(OBJDIR)\nsPrefsFactory.obj \
.\$(OBJDIR)\nsAutoConfig.obj \
$(NULL)
#//------------------------------------------------------------------------

Просмотреть файл

@ -0,0 +1,493 @@
/* -*- 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):
* Mitesh Shah <mitesh@netscape.com>
*
*/
#include "nsAutoConfig.h"
#include "nsIURI.h"
#include "nsIHTTPChannel.h"
#include "nsIFileStreams.h"
#include "nsDirectoryServiceDefs.h"
#include "prmem.h"
#include "jsapi.h"
#include "prefapi.h"
#include "nsIProfile.h"
#include "nsIObserverService.h"
#include "nsIEventQueueService.h"
#include "nsLiteralString.h"
NS_IMPL_THREADSAFE_ISUPPORTS4(nsAutoConfig, nsIAutoConfig, nsITimerCallback, nsIStreamListener,nsIObserver)
nsAutoConfig::nsAutoConfig()
{
/* member initializers and constructor code */
NS_INIT_REFCNT();
}
nsresult nsAutoConfig::Init()
{
/* member initializers and constructor code */
nsresult rv=NS_OK;
mLoaded = PR_FALSE;
// Registering the object as an observer to the profile-after-change topic
nsCOMPtr<nsIObserverService> observerService =
do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
if (observerService) {
rv = observerService->AddObserver(this,
NS_LITERAL_STRING("profile-after-change").get());
if (NS_FAILED(rv)) return rv;
}
nsCOMPtr<nsIPrefService> prefs =
do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
rv = prefs->GetBranch(nsnull,getter_AddRefs(mPrefBranch));
if (NS_FAILED(rv)) return rv;
return NS_OK;
}
nsAutoConfig::~nsAutoConfig()
{
nsresult rv;
nsCOMPtr<nsIObserverService> observerService =
do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv);
if (observerService)
rv = observerService->RemoveObserver(this,
NS_LITERAL_STRING("profile-after-change").get());
}
NS_IMETHODIMP
nsAutoConfig::OnStartRequest(nsIRequest* request, nsISupports* context)
{
return NS_OK;
}
NS_IMETHODIMP
nsAutoConfig::OnDataAvailable(nsIRequest* request,
nsISupports* context,
nsIInputStream *aIStream,
PRUint32 aSourceOffset,
PRUint32 aLength)
{
PRUint32 amt, size;
nsresult rv;
char buf[1025];
while (aLength) {
size = PR_MIN(aLength, sizeof(buf));
rv = aIStream->Read(buf, size, &amt);
if (NS_FAILED(rv)) {
NS_ASSERTION((NS_BASE_STREAM_WOULD_BLOCK != rv),
"The stream should never block.");
return rv;
}
mBuf.Append(buf,amt);
aLength -= amt;
}
return NS_OK;
}
NS_IMETHODIMP
nsAutoConfig::OnStopRequest(nsIRequest* request, nsISupports* context,
nsresult aStatus)
{
nsresult rv;
// If the request is failed, go read the failover.jsc file
if (NS_FAILED(aStatus)) {
return readOfflineFile();
}
//Checking for the http response, if failure go read the failover file.
nsCOMPtr<nsIHTTPChannel> pHTTPCon(do_QueryInterface(request));
if (pHTTPCon) {
PRUint32 httpStatus;
pHTTPCon->GetResponseStatus(&httpStatus);
if (httpStatus != 200)
return readOfflineFile();
}
// Send the autoconfig.jsc to javascript engine.
PRBool success = PREF_EvaluateConfigScript(mBuf.get(), mBuf.Length(),nsnull,
PR_FALSE,PR_TRUE,PR_FALSE);
if (success) {
rv = writeFailoverFile(); /* Write the autoconfig.jsc to
failover.jsc (cached copy) */
if(NS_FAILED(rv))
NS_WARNING("Error writing failover.jsc file");
// Clean up the previous read.
// If there is a timer, these methods will be called again.
mBuf.Truncate(0);
mLoaded = PR_TRUE; //Releasing the deadlock
return NS_OK;
}
else {
NS_WARNING("Error reading autoconfig.jsc from the network, reading the offline version");
// Clean up the previous read so it will be ready for
// the next updated read.
mBuf.Truncate(0);
return readOfflineFile();
}
}
// Notify method as a TimerCallBack function
NS_IMETHODIMP_(void) nsAutoConfig::Notify(nsITimer *timer)
{
DownloadAutoCfg();
}
/* Observe() is called twice: once at the instantiation time and other
after the profile is set. It doesn't do anything but return NS_OK during the
creation time. Second time it calls DownloadAutoCfg().
*/
NS_IMETHODIMP nsAutoConfig::Observe(nsISupports *aSubject, const PRUnichar *aTopic, const PRUnichar *someData)
{
nsresult rv = NS_OK;
if (!nsCRT::strcmp(aTopic, NS_LITERAL_STRING("profile-after-change").get()))
{
// Getting the current profile name since we already have the
// pointer to the object.
nsCOMPtr<nsIProfile> profile = do_QueryInterface(aSubject);
if (profile) {
nsXPIDLString profileName;
rv = profile->GetCurrentProfile(getter_Copies(profileName));
if (NS_SUCCEEDED(rv))
// setting the member variable to the current profile name
mCurrProfile.AssignWithConversion(profileName);
else
return rv;
}
return DownloadAutoCfg();
}
else if (!nsCRT::strcmp(aTopic, NS_LITERAL_STRING("app-startup").get()))
{
// This is the object instantiation, do nothing and return NS_OK;
return NS_OK;
}
return NS_OK;
}
NS_IMETHODIMP nsAutoConfig::DownloadAutoCfg()
{
nsresult rv = NS_OK;
nsCAutoString emailAddr;
nsXPIDLCString urlName;
PRBool appendMail=PR_FALSE, offline=PR_FALSE;
static PRBool firstTime = PR_TRUE;
// get the value of the autoconfig url
rv = mPrefBranch->GetCharPref("autoadmin.global_config_url",
getter_Copies(urlName));
if(NS_FAILED(rv) || (nsCRT::strlen(urlName) == 0))
return NS_OK; /* Return ok if there is no config url set. */
// Check to see if the network is online/offline
nsCOMPtr<nsIIOService> ios =
do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
rv = ios->GetOffline(&offline);
if (NS_FAILED(rv)) return rv;
if (offline) {
PRBool offlineFailover = PR_FALSE;
rv = mPrefBranch->GetBoolPref("autoadmin.offline_failover",
&offlineFailover);
// Read the failover.jsc if the network is offline and the pref says so
if ( offlineFailover ) {
return readOfflineFile();
}
}
nsCAutoString cfgUrl(urlName);
/* Append user's identity at the end of the URL if the pref says so.
First we are checking for the user's email address but if it is not
available in the case where the client is used without messenger, user's
profile name will be used as an unique identifier
*/
rv = mPrefBranch->GetBoolPref("autoadmin.append_emailaddr", &appendMail);
if (NS_SUCCEEDED(rv) && appendMail) {
rv = getEmailAddr(emailAddr);
if (NS_SUCCEEDED(rv) && emailAddr) {
/* Adding the unique identifier at the end of autoconfig URL.
In this case the autoconfig URL is a script and
emailAddr as passed as an argument */
cfgUrl.Append("?");
cfgUrl.Append(emailAddr);
}
}
// Getting an event queue. If we start an AsyncOpen, the thread
// needs to wait before the reading of autoconfig is done
nsCOMPtr<nsIEventQueue> currentThreadQ;
if (firstTime) {
nsCOMPtr<nsIEventQueueService> service =
do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
rv = service->GetThreadEventQueue(NS_CURRENT_THREAD,getter_AddRefs(currentThreadQ));
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
}
mLoaded = PR_FALSE;
// create a new url
nsCOMPtr<nsIURI> url;
nsCOMPtr<nsIChannel> channel;
rv = NS_NewURI(getter_AddRefs(url), cfgUrl, nsnull, nsnull);
if(NS_FAILED(rv)) return rv;
// open a channel for the url
rv = NS_OpenURI(getter_AddRefs(channel),url, nsnull, nsnull);
if(NS_FAILED(rv)) return rv;
rv = channel->AsyncOpen(this, nsnull);
if (NS_FAILED(rv)) {
readOfflineFile();
return rv;
}
// Set a repeating timer if the pref is set.
// This is to be done only once.
if (firstTime) {
firstTime = PR_FALSE;
PRInt32 minutes = 0;
rv = mPrefBranch->GetIntPref("autoadmin.refresh_interval",
&minutes);
if(NS_SUCCEEDED(rv) && minutes > 0) {
// Create a new timer and pass this nsAutoConfig
// object as a timer callback.
nsCOMPtr<nsITimer> timer;
timer = do_CreateInstance("@mozilla.org/timer;1",&rv);
if (NS_FAILED(rv)) return rv;
rv = timer->Init(this, minutes*60*1000, NS_PRIORITY_NORMAL,
NS_TYPE_REPEATING_SLACK);
if (NS_FAILED(rv)) return rv;
}
// process events until we're finished. AutoConfig.jsc reading needs
// to be finished before the browser starts loading up
// We are waiting for the mLoaded which will be set through
// onStopRequest or readOfflineFile methods
// There is a possibility of deadlock so we need to make sure
// that mLoaded will be set to true in any case (success/failure)
PLEvent *event;
while (!mLoaded) {
rv = currentThreadQ->WaitForEvent(&event);
NS_ASSERTION(NS_SUCCEEDED(rv),"-->nsAutoConfig::DownloadAutoCfg: currentThreadQ->WaitForEvent failed...");
if (NS_FAILED(rv)) return rv;
rv = currentThreadQ->HandleEvent(event);
NS_ASSERTION(NS_SUCCEEDED(rv), "-->nsAutoConfig::DownloadAutoCfg: currentThreadQ->HandleEvent failed...");
if (NS_FAILED(rv)) return rv;
}
} //first_time
return NS_OK;
} // nsPref::DownloadAutoCfg()
nsresult nsAutoConfig::readOfflineFile()
{
PRBool failCache = PR_TRUE;
nsresult rv;
PRBool offline;
rv = mPrefBranch->GetBoolPref("autoadmin.failover_to_cached", &failCache);
if (failCache == PR_FALSE) {
// disable network connections and return.
nsCOMPtr<nsIIOService> ios =
do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv)) return reportError();
rv = ios->GetOffline(&offline);
if (NS_FAILED(rv)) return reportError();
if (!offline) {
rv = ios->SetOffline(PR_TRUE);
if (NS_FAILED(rv)) return reportError();
}
// lock the "network.online" prference so user cannot toggle back to
// online mode.
rv = mPrefBranch->SetBoolPref("network.online", PR_FALSE);
if (NS_FAILED(rv)) return reportError();
mPrefBranch->LockPref("network.online");
mLoaded = PR_TRUE;
return NS_OK;
}
// failCache = true
// Open the file and read the content.
// execute the javascript file
nsCOMPtr<nsIFile> failoverFile;
rv = NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR,
getter_AddRefs(failoverFile));
if (NS_FAILED(rv)) return reportError();
#ifdef XP_MAC
failoverFile->Append("Essential Files");
#endif
failoverFile->Append("failover.jsc");
rv = evaluateLocalFile(failoverFile);
if (NS_FAILED(rv))
NS_WARNING("Couldn't open failover.jsc, going back to default prefs");
mLoaded = PR_TRUE;
return NS_OK;
}
nsresult nsAutoConfig::evaluateLocalFile(nsIFile* file)
{
nsresult rv;
nsCOMPtr<nsIInputStream> inStr;
rv = NS_NewLocalFileInputStream(getter_AddRefs(inStr), file);
if (NS_FAILED(rv)) return rv;
PRInt64 fileSize;
PRUint32 fs, amt=0;
file->GetFileSize(&fileSize);
LL_L2UI(fs, fileSize); // Converting 64 bit structure to unsigned int
char* buf = (char *) PR_Malloc(fs*sizeof(char)) ;
if(!buf)
return NS_ERROR_OUT_OF_MEMORY;
rv = inStr->Read(buf, fs, &amt);
if (NS_FAILED(rv))
NS_ASSERTION((NS_BASE_STREAM_WOULD_BLOCK != rv),
"The stream should never block.");
if (!PREF_EvaluateConfigScript(buf,fs,nsnull, PR_FALSE, PR_TRUE, PR_FALSE)){
PR_FREEIF(buf);
return NS_ERROR_FAILURE;
}
inStr->Close();
PR_FREEIF(buf);
return NS_OK;
}
nsresult nsAutoConfig::writeFailoverFile()
{
nsresult rv;
nsCOMPtr<nsIFile> failoverFile;
nsCOMPtr<nsIOutputStream> outStr;
PRUint32 amt;
rv = NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR,
getter_AddRefs(failoverFile));
if (NS_FAILED(rv)) return rv;
#ifdef XP_MAC
failoverFile->Append("Essential Files");
#endif
failoverFile->Append("failover.jsc");
rv = NS_NewLocalFileOutputStream(getter_AddRefs(outStr), failoverFile);
if (NS_FAILED(rv)) return rv;
rv = outStr->Write(mBuf.get(),mBuf.Length(),&amt);
outStr->Close();
return rv;
}
nsresult nsAutoConfig::getEmailAddr(nsAWritableCString & emailAddr)
{
nsresult rv;
nsXPIDLCString prefValue;
/* Getting an email address through set of three preferences:
First getting a default account with
"mail.accountmanager.defaultaccount"
second getting an associated id with the default account
Third getting an email address with id
*/
rv = mPrefBranch->GetCharPref("mail.accountmanager.defaultaccount",
getter_Copies(prefValue));
// Checking prefValue and its length. Since by default the preference
// is set to nothing
if (NS_SUCCEEDED(rv) && nsCRT::strlen(prefValue) > 0) {
emailAddr = NS_LITERAL_CSTRING("mail.account.") +
nsLocalCString(prefValue) + NS_LITERAL_CSTRING(".identities");
rv = mPrefBranch->GetCharPref(PromiseFlatCString(emailAddr).get(),
getter_Copies(prefValue));
if (NS_FAILED(rv) || nsCRT::strlen(prefValue) < 0) return rv;
emailAddr = NS_LITERAL_CSTRING("mail.identity.") +
nsLocalCString(prefValue) + NS_LITERAL_CSTRING(".useremail");
rv = mPrefBranch->GetCharPref(PromiseFlatCString(emailAddr).get(),
getter_Copies(prefValue));
if (NS_FAILED(rv) || nsCRT::strlen(prefValue) < 0) return rv;
emailAddr = nsLocalCString(prefValue);
}
else {
if (mCurrProfile) {
emailAddr = mCurrProfile;
}
}
return NS_OK;
}
nsresult nsAutoConfig::reportError()
{
NS_ERROR("AutoConfig::readOfflineFile() failed");
mLoaded = PR_TRUE; //Releasing lock to avoid deadlock in DownloadAutoCfg()
return NS_ERROR_FAILURE;
}

Просмотреть файл

@ -0,0 +1,63 @@
/* -*- 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):
* Mitesh Shah <mitesh@netscape.com>
*
*/
#include "nsIAutoConfig.h"
#include "nsITimer.h"
#include "nsITimerCallback.h"
#include "nsIFile.h"
#include "nsIObserver.h"
#include "nsNetUtil.h"
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#include "nsWeakReference.h"
class nsAutoConfig : public nsIAutoConfig,
public nsITimerCallback,
public nsIStreamListener,
public nsIObserver
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIAUTOCONFIG
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIOBSERVER
NS_IMETHOD_(void) Notify(nsITimer *timer);
nsAutoConfig();
virtual ~nsAutoConfig();
nsresult Init();
protected:
nsresult readOfflineFile();
nsresult evaluateLocalFile(nsIFile * file);
nsresult writeFailoverFile();
nsresult getEmailAddr(nsAWritableCString & emailAddr);
nsresult reportError();
nsCString mBuf, mCurrProfile;
nsCOMPtr<nsIPrefBranch> mPrefBranch;
PRBool mLoaded;
};

Просмотреть файл

@ -25,6 +25,9 @@
#include "nsPrefService.h"
#include "nsPrefBranch.h"
#include "nsIPref.h"
#include "nsAutoConfig.h"
#include "nsIAppStartupNotifier.h"
#include "nsICategoryManager.h"
// remove this when nsPref goes away
extern NS_IMETHODIMP nsPrefConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult);
@ -32,6 +35,49 @@ extern NS_IMETHODIMP nsPrefConstructor(nsISupports *aOuter, REFNSIID aIID, void
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrefService, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrefLocalizedString, Init)
// Factory constructor for nsAutoConfig. nsAutoConfig doesn't have a
//separate module so it is bundled with pref module.
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsAutoConfig,Init)
// Registering nsAutoConfig module as part of the app-startup category to
// get it instantiated.
static NS_METHOD
RegisterAutoConfig(nsIComponentManager *aCompMgr,
nsIFile *aPath,
const char *registryLocation,
const char *componentType,
const nsModuleComponentInfo *info)
{
nsresult rv;
nsCOMPtr<nsICategoryManager>
categoryManager(do_GetService("@mozilla.org/categorymanager;1", &rv));
if (NS_SUCCEEDED(rv)) {
rv = categoryManager->AddCategoryEntry(APPSTARTUP_CATEGORY,
"AutoConfig Module",
NS_AUTOCONFIG_CONTRACTID,
PR_TRUE, PR_TRUE,nsnull);
}
return rv;
}
static NS_METHOD
UnRegisterAutoConfig(nsIComponentManager *aCompMgr,
nsIFile *aPath,
const char *registryLocation,
const nsModuleComponentInfo *info)
{
nsresult rv;
nsCOMPtr<nsICategoryManager>
categoryManager(do_GetService("@mozilla.org/categorymanager;1", &rv));
if (NS_SUCCEEDED(rv)) {
rv = categoryManager->DeleteCategoryEntry(APPSTARTUP_CATEGORY,
"AutoConfig Module",
PR_TRUE,nsnull);
}
return rv;
}
// The list of components we register
static nsModuleComponentInfo components[] =
@ -56,6 +102,14 @@ static nsModuleComponentInfo components[] =
NS_PREF_CONTRACTID,
nsPrefConstructor
},
{
NS_AUTOCONFIG_CLASSNAME,
NS_AUTOCONFIG_CID,
NS_AUTOCONFIG_CONTRACTID,
nsAutoConfigConstructor,
RegisterAutoConfig,
UnRegisterAutoConfig
},
};
NS_IMPL_NSGETMODULE("nsPrefModule", components);

Просмотреть файл

@ -34,9 +34,27 @@ function setOfflineStatus(aToggleFlag)
var ioService = Components.classesByID["{9ac9e770-18bc-11d3-9337-00104ba0fd40}"]
.getService(Components.interfaces.nsIIOService);
var broadcaster = document.getElementById("Communicator:WorkMode");
if (aToggleFlag)
ioService.offline = !ioService.offline;
//Checking for a preference "network.online", if it's locked, disabling
// network icon and menu item
try {
var prefService = Components.classes["@mozilla.org/preferences-service;1"];
prefService = prefService.getService();
prefService = prefService.QueryInterface(Components.interfaces.nsIPrefService);
var prefBranch = prefService.getBranch(null);
var offlineLocked = prefBranch.prefIsLocked("network.online");
if (!offlineLocked ) {
if (aToggleFlag)
ioService.offline = !ioService.offline;
}
else {
broadcaster.setAttribute("disabled","true");
}
} catch(e) {
}
var bundle = srGetStrBundle("chrome://communicator/locale/utilityOverlay.properties");
if (ioService.offline && broadcaster)
{