1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
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/
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
15 * The Original Code is mozilla.org code.
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.
23 * Michiel van Leeuwen (mvl@exedo.nl)
24 * Daniel Witte (dwitte@stanford.edu)
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.
38 * ***** END LICENSE BLOCK ***** */
40 #include "nsPermissionManager.h"
41 #include "nsPermission.h"
43 #include "nsNetUtil.h"
44 #include "nsCOMArray.h"
45 #include "nsArrayEnumerator.h"
46 #include "nsILineInputStream.h"
47 #include "nsIIDNService.h"
48 #include "nsAppDirectoryServiceDefs.h"
50 #include "mozIStorageService.h"
51 #include "mozIStorageStatement.h"
52 #include "mozIStorageConnection.h"
53 #include "mozStorageHelper.h"
54 #include "mozStorageCID.h"
56 ////////////////////////////////////////////////////////////////////////////////
58 #define PL_ARENA_CONST_ALIGN_MASK 3
61 static PLArenaPool
*gHostArena
= nsnull
;
63 // making sHostArena 512b for nice allocation
64 // growing is quite cheap
65 #define HOST_ARENA_SIZE 512
67 // equivalent to strdup() - does no error checking,
68 // we're assuming we're only called with a valid pointer
70 ArenaStrDup(const char* str
, PLArenaPool
* aArena
)
73 const PRUint32 size
= strlen(str
) + 1;
74 PL_ARENA_ALLOCATE(mem
, aArena
, size
);
76 memcpy(mem
, str
, size
);
77 return static_cast<char*>(mem
);
80 nsHostEntry::nsHostEntry(const char* aHost
)
82 mHost
= ArenaStrDup(aHost
, gHostArena
);
85 // XXX this can fail on OOM
86 nsHostEntry::nsHostEntry(const nsHostEntry
& toCopy
)
88 , mPermissions(toCopy
.mPermissions
)
92 ////////////////////////////////////////////////////////////////////////////////
93 // nsPermissionManager Implementation
95 static const char kPermissionsFileName
[] = "permissions.sqlite";
96 #define HOSTS_SCHEMA_VERSION 1
98 static const char kHostpermFileName
[] = "hostperm.1";
100 static const char kPermissionChangeNotification
[] = PERM_CHANGE_NOTIFICATION
;
102 NS_IMPL_ISUPPORTS3(nsPermissionManager
, nsIPermissionManager
, nsIObserver
, nsISupportsWeakReference
)
104 nsPermissionManager::nsPermissionManager()
109 nsPermissionManager::~nsPermissionManager()
111 RemoveAllFromMemory();
115 nsPermissionManager::Init()
119 if (!mHostTable
.Init()) {
120 return NS_ERROR_OUT_OF_MEMORY
;
123 // ignore failure here, since it's non-fatal (we can run fine without
124 // persistent storage - e.g. if there's no profile).
125 // XXX should we tell the user about this?
128 mObserverService
= do_GetService("@mozilla.org/observer-service;1", &rv
);
129 if (NS_SUCCEEDED(rv
)) {
130 mObserverService
->AddObserver(this, "profile-before-change", PR_TRUE
);
131 mObserverService
->AddObserver(this, "profile-do-change", PR_TRUE
);
138 nsPermissionManager::InitDB()
140 nsCOMPtr
<nsIFile
> permissionsFile
;
141 NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR
, getter_AddRefs(permissionsFile
));
142 if (!permissionsFile
)
143 return NS_ERROR_UNEXPECTED
;
145 nsresult rv
= permissionsFile
->AppendNative(NS_LITERAL_CSTRING(kPermissionsFileName
));
146 NS_ENSURE_SUCCESS(rv
, rv
);
148 nsCOMPtr
<mozIStorageService
> storage
= do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID
);
150 return NS_ERROR_UNEXPECTED
;
152 // cache a connection to the hosts database
153 rv
= storage
->OpenDatabase(permissionsFile
, getter_AddRefs(mDBConn
));
154 NS_ENSURE_SUCCESS(rv
, rv
);
157 mDBConn
->GetConnectionReady(&ready
);
159 // delete and try again
160 rv
= permissionsFile
->Remove(PR_FALSE
);
161 NS_ENSURE_SUCCESS(rv
, rv
);
163 rv
= storage
->OpenDatabase(permissionsFile
, getter_AddRefs(mDBConn
));
164 NS_ENSURE_SUCCESS(rv
, rv
);
166 mDBConn
->GetConnectionReady(&ready
);
168 return NS_ERROR_UNEXPECTED
;
171 PRBool tableExists
= PR_FALSE
;
172 mDBConn
->TableExists(NS_LITERAL_CSTRING("moz_hosts"), &tableExists
);
175 NS_ENSURE_SUCCESS(rv
, rv
);
178 // table already exists; check the schema version before reading
179 PRInt32 dbSchemaVersion
;
180 rv
= mDBConn
->GetSchemaVersion(&dbSchemaVersion
);
181 NS_ENSURE_SUCCESS(rv
, rv
);
183 switch (dbSchemaVersion
) {
185 // every time you increment the database schema, you need to implement
186 // the upgrading code from the previous version to the new one.
187 // fall through to current version
190 case HOSTS_SCHEMA_VERSION
:
195 NS_WARNING("couldn't get schema version!");
197 // the table may be usable; someone might've just clobbered the schema
198 // version. we can treat this case like a downgrade using the codepath
199 // below, by verifying the columns we care about are all there. for now,
200 // re-set the schema version in the db, in case the checks succeed (if
201 // they don't, we're dropping the table anyway).
202 rv
= mDBConn
->SetSchemaVersion(HOSTS_SCHEMA_VERSION
);
203 NS_ENSURE_SUCCESS(rv
, rv
);
205 // fall through to downgrade check
208 // if columns have been added to the table, we can still use the ones we
209 // understand safely. if columns have been deleted or altered, just
210 // blow away the table and start from scratch! if you change the way
211 // a column is interpreted, make sure you also change its name so this
212 // check will catch it.
215 // check if all the expected columns exist
216 nsCOMPtr
<mozIStorageStatement
> stmt
;
217 rv
= mDBConn
->CreateStatement(NS_LITERAL_CSTRING(
218 "SELECT host, type, permission FROM moz_hosts"), getter_AddRefs(stmt
));
219 if (NS_SUCCEEDED(rv
))
222 // our columns aren't there - drop the table!
223 rv
= mDBConn
->ExecuteSimpleSQL(NS_LITERAL_CSTRING("DROP TABLE moz_hosts"));
224 NS_ENSURE_SUCCESS(rv
, rv
);
227 NS_ENSURE_SUCCESS(rv
, rv
);
233 // make operations on the table asynchronous, for performance
234 mDBConn
->ExecuteSimpleSQL(NS_LITERAL_CSTRING("PRAGMA synchronous = OFF"));
236 // cache frequently used statements (for insertion, deletion, and updating)
237 rv
= mDBConn
->CreateStatement(NS_LITERAL_CSTRING(
238 "INSERT INTO moz_hosts "
239 "(id, host, type, permission) "
240 "VALUES (?1, ?2, ?3, ?4)"), getter_AddRefs(mStmtInsert
));
241 NS_ENSURE_SUCCESS(rv
, rv
);
243 rv
= mDBConn
->CreateStatement(NS_LITERAL_CSTRING(
244 "DELETE FROM moz_hosts "
245 "WHERE id = ?1"), getter_AddRefs(mStmtDelete
));
246 NS_ENSURE_SUCCESS(rv
, rv
);
248 rv
= mDBConn
->CreateStatement(NS_LITERAL_CSTRING(
250 "SET permission = ?2 WHERE id = ?1"), getter_AddRefs(mStmtUpdate
));
251 NS_ENSURE_SUCCESS(rv
, rv
);
253 // check whether to import or just read in the db
260 // sets the schema version and creates the moz_hosts table.
262 nsPermissionManager::CreateTable()
264 // set the schema version, before creating the table
265 nsresult rv
= mDBConn
->SetSchemaVersion(HOSTS_SCHEMA_VERSION
);
266 if (NS_FAILED(rv
)) return rv
;
269 return mDBConn
->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
270 "CREATE TABLE moz_hosts ("
271 " id INTEGER PRIMARY KEY"
274 ",permission INTEGER"
279 nsPermissionManager::Add(nsIURI
*aURI
,
281 PRUint32 aPermission
)
283 NS_ENSURE_ARG_POINTER(aURI
);
284 NS_ENSURE_ARG_POINTER(aType
);
289 rv
= GetHost(aURI
, host
);
290 NS_ENSURE_SUCCESS(rv
, rv
);
292 return AddInternal(host
, nsDependentCString(aType
), aPermission
, 0, eNotify
, eWriteToDB
);
296 nsPermissionManager::AddInternal(const nsAFlatCString
&aHost
,
297 const nsAFlatCString
&aType
,
298 PRUint32 aPermission
,
300 NotifyOperationType aNotifyOperation
,
301 DBOperationType aDBOperation
)
304 gHostArena
= new PLArenaPool
;
306 return NS_ERROR_OUT_OF_MEMORY
;
307 PL_INIT_ARENA_POOL(gHostArena
, "PermissionHostArena", HOST_ARENA_SIZE
);
310 // look up the type index
311 PRInt32 typeIndex
= GetTypeIndex(aType
.get(), PR_TRUE
);
312 NS_ENSURE_TRUE(typeIndex
!= -1, NS_ERROR_OUT_OF_MEMORY
);
314 // When an entry already exists, PutEntry will return that, instead
315 // of adding a new one
316 nsHostEntry
*entry
= mHostTable
.PutEntry(aHost
.get());
317 if (!entry
) return NS_ERROR_FAILURE
;
318 if (!entry
->GetKey()) {
319 mHostTable
.RawRemoveEntry(entry
);
320 return NS_ERROR_OUT_OF_MEMORY
;
323 // figure out the transaction type, and get any existing permission value
325 PRInt32 index
= entry
->GetPermissionIndex(typeIndex
);
326 PRUint32 oldPermission
;
328 if (aPermission
== nsIPermissionManager::UNKNOWN_ACTION
)
331 op
= eOperationAdding
;
334 oldPermission
= entry
->GetPermissions()[index
].mPermission
;
336 if (aPermission
== oldPermission
)
338 else if (aPermission
== nsIPermissionManager::UNKNOWN_ACTION
)
339 op
= eOperationRemoving
;
341 op
= eOperationChanging
;
344 // do the work for adding, deleting, or changing a permission:
345 // update the in-memory list, write to the db, and notify consumers.
354 case eOperationAdding
:
356 if (aDBOperation
== eWriteToDB
) {
357 // we'll be writing to the database - generate a known unique id
360 // we're reading from the database - use the id already assigned
364 entry
->GetPermissions().AppendElement(nsPermissionEntry(typeIndex
, aPermission
, id
));
366 if (aDBOperation
== eWriteToDB
)
367 UpdateDB(op
, mStmtInsert
, id
, aHost
, aType
, aPermission
);
369 if (aNotifyOperation
== eNotify
) {
370 NotifyObserversWithPermission(aHost
,
371 mTypeArray
[typeIndex
],
373 NS_LITERAL_STRING("added").get());
379 case eOperationRemoving
:
381 id
= entry
->GetPermissions()[index
].mID
;
382 entry
->GetPermissions().RemoveElementAt(index
);
384 // If no more types are present, remove the entry
385 if (entry
->GetPermissions().IsEmpty())
386 mHostTable
.RawRemoveEntry(entry
);
388 if (aDBOperation
== eWriteToDB
)
389 UpdateDB(op
, mStmtDelete
, id
, EmptyCString(), EmptyCString(), 0);
391 if (aNotifyOperation
== eNotify
) {
392 NotifyObserversWithPermission(aHost
,
393 mTypeArray
[typeIndex
],
395 NS_LITERAL_STRING("deleted").get());
401 case eOperationChanging
:
403 id
= entry
->GetPermissions()[index
].mID
;
404 entry
->GetPermissions()[index
].mPermission
= aPermission
;
406 if (aDBOperation
== eWriteToDB
)
407 UpdateDB(op
, mStmtUpdate
, id
, EmptyCString(), EmptyCString(), aPermission
);
409 if (aNotifyOperation
== eNotify
) {
410 NotifyObserversWithPermission(aHost
,
411 mTypeArray
[typeIndex
],
413 NS_LITERAL_STRING("changed").get());
424 nsPermissionManager::Remove(const nsACString
&aHost
,
427 NS_ENSURE_ARG_POINTER(aType
);
429 // AddInternal() handles removal, just let it do the work
430 return AddInternal(PromiseFlatCString(aHost
),
431 nsDependentCString(aType
),
432 nsIPermissionManager::UNKNOWN_ACTION
,
439 nsPermissionManager::RemoveAll()
441 nsresult rv
= RemoveAllInternal();
442 NotifyObservers(nsnull
, NS_LITERAL_STRING("cleared").get());
447 nsPermissionManager::RemoveAllInternal()
449 RemoveAllFromMemory();
453 nsresult rv
= mDBConn
->ExecuteSimpleSQL(NS_LITERAL_CSTRING("DELETE FROM moz_hosts"));
455 NS_WARNING("db delete failed");
464 nsPermissionManager::TestExactPermission(nsIURI
*aURI
,
466 PRUint32
*aPermission
)
468 return CommonTestPermission(aURI
, aType
, aPermission
, PR_TRUE
);
472 nsPermissionManager::TestPermission(nsIURI
*aURI
,
474 PRUint32
*aPermission
)
476 return CommonTestPermission(aURI
, aType
, aPermission
, PR_FALSE
);
480 nsPermissionManager::CommonTestPermission(nsIURI
*aURI
,
482 PRUint32
*aPermission
,
483 PRBool aExactHostMatch
)
485 NS_ENSURE_ARG_POINTER(aURI
);
486 NS_ENSURE_ARG_POINTER(aType
);
489 *aPermission
= nsIPermissionManager::UNKNOWN_ACTION
;
492 nsresult rv
= GetHost(aURI
, host
);
493 // no host doesn't mean an error. just return the default
494 if (NS_FAILED(rv
)) return NS_OK
;
496 PRInt32 typeIndex
= GetTypeIndex(aType
, PR_FALSE
);
497 // If type == -1, the type isn't known,
498 // so just return NS_OK
499 if (typeIndex
== -1) return NS_OK
;
501 nsHostEntry
*entry
= GetHostEntry(host
, typeIndex
, aExactHostMatch
);
503 *aPermission
= entry
->GetPermission(typeIndex
);
508 // Get hostentry for given host string and permission type.
509 // walk up the domain if needed.
510 // return null if nothing found.
512 nsPermissionManager::GetHostEntry(const nsAFlatCString
&aHost
,
514 PRBool aExactHostMatch
)
519 entry
= mHostTable
.GetEntry(aHost
.get() + offset
);
521 if (entry
->GetPermission(aType
) != nsIPermissionManager::UNKNOWN_ACTION
)
524 // reset entry, to be able to return null on failure
528 break; // do not try super domains
530 offset
= aHost
.FindChar('.', offset
) + 1;
532 // walk up the domaintree (we stop as soon as we find a match,
533 // which will be the most specific domain we have an entry for).
534 } while (offset
> 0);
538 // helper struct for passing arguments into hash enumeration callback.
539 struct nsGetEnumeratorData
541 nsGetEnumeratorData(nsCOMArray
<nsIPermission
> *aArray
, const nsTArray
<nsCString
> *aTypes
)
545 nsCOMArray
<nsIPermission
> *array
;
546 const nsTArray
<nsCString
> *types
;
549 static PLDHashOperator
550 AddPermissionsToList(nsHostEntry
*entry
, void *arg
)
552 nsGetEnumeratorData
*data
= static_cast<nsGetEnumeratorData
*>(arg
);
554 for (PRUint32 i
= 0; i
< entry
->GetPermissions().Length(); ++i
) {
555 nsPermissionEntry
&permEntry
= entry
->GetPermissions()[i
];
557 nsPermission
*perm
= new nsPermission(entry
->GetHost(),
558 data
->types
->ElementAt(permEntry
.mType
),
559 permEntry
.mPermission
);
561 data
->array
->AppendObject(perm
);
564 return PL_DHASH_NEXT
;
567 NS_IMETHODIMP
nsPermissionManager::GetEnumerator(nsISimpleEnumerator
**aEnum
)
569 // roll an nsCOMArray of all our permissions, then hand out an enumerator
570 nsCOMArray
<nsIPermission
> array
;
571 nsGetEnumeratorData
data(&array
, &mTypeArray
);
573 mHostTable
.EnumerateEntries(AddPermissionsToList
, &data
);
575 return NS_NewArrayEnumerator(aEnum
, array
);
578 NS_IMETHODIMP
nsPermissionManager::Observe(nsISupports
*aSubject
, const char *aTopic
, const PRUnichar
*someData
)
580 if (!nsCRT::strcmp(aTopic
, "profile-before-change")) {
581 // The profile is about to change,
582 // or is going away because the application is shutting down.
583 if (!nsCRT::strcmp(someData
, NS_LITERAL_STRING("shutdown-cleanse").get())) {
584 // clear the permissions file
587 RemoveAllFromMemory();
590 else if (!nsCRT::strcmp(aTopic
, "profile-do-change")) {
591 // the profile has already changed; init the db from the new location
598 //*****************************************************************************
599 //*** nsPermissionManager private methods
600 //*****************************************************************************
603 nsPermissionManager::RemoveAllFromMemory()
609 PL_FinishArenaPool(gHostArena
);
616 // Returns -1 on failure
618 nsPermissionManager::GetTypeIndex(const char *aType
,
621 for (PRUint32 i
= 0; i
< mTypeArray
.Length(); ++i
)
622 if (mTypeArray
[i
].Equals(aType
))
626 // Not found, but that is ok - we were just looking.
630 // This type was not registered before.
631 // append it to the array, without copy-constructing the string
632 nsCString
*elem
= mTypeArray
.AppendElement();
637 return mTypeArray
.Length() - 1;
640 // wrapper function for mangling (host,type,perm) triplet into an nsIPermission.
642 nsPermissionManager::NotifyObserversWithPermission(const nsACString
&aHost
,
643 const nsCString
&aType
,
644 PRUint32 aPermission
,
645 const PRUnichar
*aData
)
647 nsCOMPtr
<nsIPermission
> permission
=
648 new nsPermission(aHost
, aType
, aPermission
);
650 NotifyObservers(permission
, aData
);
653 // notify observers that the permission list changed. there are four possible
655 // "deleted" means a permission was deleted. aPermission is the deleted permission.
656 // "added" means a permission was added. aPermission is the added permission.
657 // "changed" means a permission was altered. aPermission is the new permission.
658 // "cleared" means the entire permission list was cleared. aPermission is null.
660 nsPermissionManager::NotifyObservers(nsIPermission
*aPermission
,
661 const PRUnichar
*aData
)
663 if (mObserverService
)
664 mObserverService
->NotifyObservers(aPermission
,
665 kPermissionChangeNotification
,
670 nsPermissionManager::Read()
674 nsCOMPtr
<mozIStorageStatement
> stmt
;
675 rv
= mDBConn
->CreateStatement(NS_LITERAL_CSTRING(
676 "SELECT id, host, type, permission "
677 "FROM moz_hosts"), getter_AddRefs(stmt
));
678 NS_ENSURE_SUCCESS(rv
, rv
);
681 nsCAutoString host
, type
;
684 while (NS_SUCCEEDED(stmt
->ExecuteStep(&hasResult
)) && hasResult
) {
685 // explicitly set our entry id counter for use in AddInternal(),
686 // and keep track of the largest id so we know where to pick up.
687 id
= stmt
->AsInt64(0);
691 rv
= stmt
->GetUTF8String(1, host
);
692 NS_ENSURE_SUCCESS(rv
, rv
);
694 rv
= stmt
->GetUTF8String(2, type
);
695 NS_ENSURE_SUCCESS(rv
, rv
);
697 permission
= stmt
->AsInt32(3);
699 rv
= AddInternal(host
, type
, permission
, id
, eDontNotify
, eNoDBOperation
);
700 NS_ENSURE_SUCCESS(rv
, rv
);
706 static const char kMatchTypeHost
[] = "host";
709 nsPermissionManager::Import()
713 nsCOMPtr
<nsIFile
> permissionsFile
;
714 rv
= NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR
, getter_AddRefs(permissionsFile
));
715 if (NS_FAILED(rv
)) return rv
;
717 rv
= permissionsFile
->AppendNative(NS_LITERAL_CSTRING(kHostpermFileName
));
718 NS_ENSURE_SUCCESS(rv
, rv
);
720 nsCOMPtr
<nsIInputStream
> fileInputStream
;
721 rv
= NS_NewLocalFileInputStream(getter_AddRefs(fileInputStream
),
723 if (NS_FAILED(rv
)) return rv
;
725 nsCOMPtr
<nsILineInputStream
> lineInputStream
= do_QueryInterface(fileInputStream
, &rv
);
726 NS_ENSURE_SUCCESS(rv
, rv
);
728 // start a transaction on the storage db, to optimize insertions.
729 // transaction will automically commit on completion
730 mozStorageTransaction
transaction(mDBConn
, PR_TRUE
);
733 * matchtype \t type \t permission \t host
734 * Only "host" is supported for matchtype
735 * type is a string that identifies the type of permission (e.g. "cookie")
736 * permission is an integer between 1 and 15
739 nsCAutoString buffer
;
740 PRBool isMore
= PR_TRUE
;
741 while (isMore
&& NS_SUCCEEDED(lineInputStream
->ReadLine(buffer
, &isMore
))) {
742 if (buffer
.IsEmpty() || buffer
.First() == '#') {
746 nsCStringArray lineArray
;
748 // Split the line at tabs
749 lineArray
.ParseString(buffer
.get(), "\t");
751 if (lineArray
[0]->EqualsLiteral(kMatchTypeHost
) &&
752 lineArray
.Count() == 4) {
755 PRUint32 permission
= lineArray
[2]->ToInteger(&error
);
759 // hosts might be encoded in UTF8; switch them to ACE to be consistent
760 if (!IsASCII(*lineArray
[3])) {
761 rv
= NormalizeToACE(*lineArray
[3]);
766 rv
= AddInternal(*lineArray
[3], *lineArray
[1], permission
, 0, eDontNotify
, eWriteToDB
);
767 NS_ENSURE_SUCCESS(rv
, rv
);
771 // we're done importing - delete the old file
772 permissionsFile
->Remove(PR_FALSE
);
778 nsPermissionManager::NormalizeToACE(nsCString
&aHost
)
780 // lazily init the IDN service
783 mIDNService
= do_GetService(NS_IDNSERVICE_CONTRACTID
, &rv
);
784 NS_ENSURE_SUCCESS(rv
, rv
);
787 return mIDNService
->ConvertUTF8toACE(aHost
, aHost
);
791 nsPermissionManager::GetHost(nsIURI
*aURI
, nsACString
&aResult
)
793 nsCOMPtr
<nsIURI
> innerURI
= NS_GetInnermostURI(aURI
);
794 if (!innerURI
) return NS_ERROR_FAILURE
;
796 nsresult rv
= innerURI
->GetAsciiHost(aResult
);
798 if (NS_FAILED(rv
) || aResult
.IsEmpty())
799 return NS_ERROR_UNEXPECTED
;
805 nsPermissionManager::UpdateDB(OperationType aOp
,
806 mozIStorageStatement
* aStmt
,
808 const nsACString
&aHost
,
809 const nsACString
&aType
,
810 PRUint32 aPermission
)
814 // no statement is ok - just means we don't have a profile
819 case eOperationAdding
:
821 rv
= aStmt
->BindInt64Parameter(0, aID
);
822 if (NS_FAILED(rv
)) break;
824 rv
= aStmt
->BindUTF8StringParameter(1, aHost
);
825 if (NS_FAILED(rv
)) break;
827 rv
= aStmt
->BindUTF8StringParameter(2, aType
);
828 if (NS_FAILED(rv
)) break;
830 rv
= aStmt
->BindInt32Parameter(3, aPermission
);
834 case eOperationRemoving
:
836 rv
= aStmt
->BindInt64Parameter(0, aID
);
840 case eOperationChanging
:
842 rv
= aStmt
->BindInt64Parameter(0, aID
);
843 if (NS_FAILED(rv
)) break;
845 rv
= aStmt
->BindInt32Parameter(1, aPermission
);
851 NS_NOTREACHED("need a valid operation in UpdateDB()!");
852 rv
= NS_ERROR_UNEXPECTED
;
857 if (NS_SUCCEEDED(rv
)) {
859 rv
= aStmt
->ExecuteStep(&hasResult
);
864 NS_WARNING("db change failed!");