NS_IMETHOD Run() override
  {
    nsresult res;

    MOZ_ASSERT(!NS_IsMainThread());

    {
      mozilla::MonitorAutoLock mon(mDict->mMonitorSave);

      nsCOMPtr<nsIOutputStream> outStream;
      NS_NewSafeLocalFileOutputStream(getter_AddRefs(outStream), mFile,
                                      PR_CREATE_FILE | PR_WRONLY | PR_TRUNCATE,
                                      0664);

      // Get a buffered output stream 4096 bytes big, to optimize writes.
      nsCOMPtr<nsIOutputStream> bufferedOutputStream;
      res = NS_NewBufferedOutputStream(getter_AddRefs(bufferedOutputStream),
                                       outStream.forget(), 4096);
      if (NS_FAILED(res)) {
        return res;
      }

      uint32_t bytesWritten;
      nsAutoCString utf8Key;
      for (uint32_t i = 0; i < mDictWords.Length(); ++i) {
        CopyUTF16toUTF8(mDictWords[i], utf8Key);

        bufferedOutputStream->Write(utf8Key.get(), utf8Key.Length(),
                                    &bytesWritten);
        bufferedOutputStream->Write("\n", 1, &bytesWritten);
      }
      nsCOMPtr<nsISafeOutputStream> safeStream =
        do_QueryInterface(bufferedOutputStream);
      NS_ASSERTION(safeStream, "expected a safe output stream!");
      if (safeStream) {
        res = safeStream->Finish();
        if (NS_FAILED(res)) {
          NS_WARNING("failed to save personal dictionary file! possible data loss");
        }
      }

      // Save is done, reset the state variable and notify those who are waiting.
      mDict->mSavePending = false;
      mon.Notify();

      // Leaving the block where 'mon' was declared will call the destructor
      // and unlock.
    }

    // Release the dictionary on the main thread.
    NS_ReleaseOnMainThreadSystemGroup(
      "mozPersonalDictionarySave::mDict",
      mDict.forget().downcast<mozIPersonalDictionary>());

    return NS_OK;
  }
Пример #2
0
nsresult
nsCertOverrideService::Write()
{
    nsAutoMonitor lock(monitor);

    if (!mSettingsFile) {
        return NS_ERROR_NULL_POINTER;
    }

    nsresult rv;
    nsCOMPtr<nsIOutputStream> fileOutputStream;
    rv = NS_NewSafeLocalFileOutputStream(getter_AddRefs(fileOutputStream),
                                         mSettingsFile,
                                         -1,
                                         0600);
    if (NS_FAILED(rv)) {
        NS_ERROR("failed to open cert_warn_settings.txt for writing");
        return rv;
    }

    // get a buffered output stream 4096 bytes big, to optimize writes
    nsCOMPtr<nsIOutputStream> bufferedOutputStream;
    rv = NS_NewBufferedOutputStream(getter_AddRefs(bufferedOutputStream), fileOutputStream, 4096);
    if (NS_FAILED(rv)) {
        return rv;
    }

    static const char kHeader[] =
        "# PSM Certificate Override Settings file" NS_LINEBREAK
        "# This is a generated file!  Do not edit." NS_LINEBREAK;

    /* see ::Read for file format */

    bufferedOutputStream->Write(kHeader, sizeof(kHeader) - 1, &rv);

    nsIOutputStream *rawStreamPtr = bufferedOutputStream;
    mSettingsTable.EnumerateEntries(WriteEntryCallback, rawStreamPtr);

    // All went ok. Maybe except for problems in Write(), but the stream detects
    // that for us
    nsCOMPtr<nsISafeOutputStream> safeStream = do_QueryInterface(bufferedOutputStream);
    NS_ASSERTION(safeStream, "expected a safe output stream!");
    if (safeStream) {
        rv = safeStream->Finish();
        if (NS_FAILED(rv)) {
            NS_WARNING("failed to save cert warn settings file! possible dataloss");
            return rv;
        }
    }

    return NS_OK;
}
Пример #3
0
nsresult
LookupCache::WriteFile()
{
  nsCOMPtr<nsIFile> storeFile;
  nsresult rv = mStoreDirectory->Clone(getter_AddRefs(storeFile));
  NS_ENSURE_SUCCESS(rv, rv);
  rv = storeFile->AppendNative(mTableName + NS_LITERAL_CSTRING(CACHE_SUFFIX));
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIOutputStream> out;
  rv = NS_NewSafeLocalFileOutputStream(getter_AddRefs(out), storeFile,
                                       PR_WRONLY | PR_TRUNCATE | PR_CREATE_FILE);
  NS_ENSURE_SUCCESS(rv, rv);

  UpdateHeader();
  LOG(("Writing %d completions", mHeader.numCompletions));

  uint32_t written;
  rv = out->Write(reinterpret_cast<char*>(&mHeader), sizeof(mHeader), &written);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = WriteTArray(out, mCompletions);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsISafeOutputStream> safeOut = do_QueryInterface(out);
  rv = safeOut->Finish();
  NS_ENSURE_SUCCESS(rv, rv);

  rv = EnsureSizeConsistent();
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIFile> psFile;
  rv = mStoreDirectory->Clone(getter_AddRefs(psFile));
  NS_ENSURE_SUCCESS(rv, rv);

  rv = psFile->AppendNative(mTableName + NS_LITERAL_CSTRING(PREFIXSET_SUFFIX));
  NS_ENSURE_SUCCESS(rv, rv);

  rv = mPrefixSet->StoreToFile(psFile);
  NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "failed to store the prefixset");

  return NS_OK;
}
Пример #4
0
/* void Save (); */
NS_IMETHODIMP mozPersonalDictionary::Save()
{
    nsCOMPtr<nsIFile> theFile;
    nsresult res;

    if(!mDirty) return NS_OK;

    //FIXME Deinst  -- get dictionary name from prefs;
    res = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(theFile));
    if(NS_FAILED(res)) return res;
    if(!theFile)return NS_ERROR_FAILURE;
    res = theFile->Append(NS_LITERAL_STRING(MOZ_PERSONAL_DICT_NAME));
    if(NS_FAILED(res)) return res;

    nsCOMPtr<nsIOutputStream> outStream;
    NS_NewSafeLocalFileOutputStream(getter_AddRefs(outStream), theFile, PR_CREATE_FILE | PR_WRONLY | PR_TRUNCATE ,0664);

    // get a buffered output stream 4096 bytes big, to optimize writes
    nsCOMPtr<nsIOutputStream> bufferedOutputStream;
    res = NS_NewBufferedOutputStream(getter_AddRefs(bufferedOutputStream), outStream, 4096);
    if (NS_FAILED(res)) return res;

    nsTArray<nsString> array(mDictionaryTable.Count());
    mDictionaryTable.EnumerateEntries(AddHostToStringArray, &array);

    uint32_t bytesWritten;
    nsAutoCString utf8Key;
    for (uint32_t i = 0; i < array.Length(); ++i ) {
        CopyUTF16toUTF8(array[i], utf8Key);

        bufferedOutputStream->Write(utf8Key.get(), utf8Key.Length(), &bytesWritten);
        bufferedOutputStream->Write("\n", 1, &bytesWritten);
    }
    nsCOMPtr<nsISafeOutputStream> safeStream = do_QueryInterface(bufferedOutputStream);
    NS_ASSERTION(safeStream, "expected a safe output stream!");
    if (safeStream) {
        res = safeStream->Finish();
        if (NS_FAILED(res)) {
            NS_WARNING("failed to save personal dictionary file! possible data loss");
        }
    }
    return res;
}
Пример #5
0
/*
 * Generate a unique 32-bit key for this user, which we will
 * use to rehash all prefixes. This ensures that different users
 * will get hash collisions on different prefixes, which in turn
 * avoids that "unlucky" URLs get mysterious slowdowns, and that
 * the servers get spammed if any such URL should get slashdotted.
 * https://bugzilla.mozilla.org/show_bug.cgi?id=669407#c10
 */
nsresult
Classifier::InitKey()
{
  nsCOMPtr<nsIFile> storeFile;
  nsresult rv = mStoreDirectory->Clone(getter_AddRefs(storeFile));
  NS_ENSURE_SUCCESS(rv, rv);

  rv = storeFile->AppendNative(NS_LITERAL_CSTRING("classifier.hashkey"));
  NS_ENSURE_SUCCESS(rv, rv);

  bool exists;
  rv = storeFile->Exists(&exists);
  NS_ENSURE_SUCCESS(rv, rv);

  if (!exists) {
    // generate and store key
    nsCOMPtr<nsIRandomGenerator> rg =
      do_GetService("@mozilla.org/security/random-generator;1");
    NS_ENSURE_STATE(rg);

    PRUint8 *temp;
    nsresult rv = rg->GenerateRandomBytes(sizeof(mHashKey), &temp);
    NS_ENSURE_SUCCESS(rv, rv);
    memcpy(&mHashKey, temp, sizeof(mHashKey));
    NS_Free(temp);

    nsCOMPtr<nsIOutputStream> out;
    rv = NS_NewSafeLocalFileOutputStream(getter_AddRefs(out), storeFile,
                                       -1, -1, 0);
    NS_ENSURE_SUCCESS(rv, rv);

    PRUint32 written;
    rv = out->Write(reinterpret_cast<char*>(&mHashKey), sizeof(PRUint32), &written);
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsISafeOutputStream> safeOut = do_QueryInterface(out);
    rv = safeOut->Finish();
    NS_ENSURE_SUCCESS(rv, rv);

    LOG(("Initialized classifier, key = %X", mHashKey));
  } else {
    // read key
    nsCOMPtr<nsIInputStream> inputStream;
    rv = NS_NewLocalFileInputStream(getter_AddRefs(inputStream), storeFile,
                                    -1, -1, 0);
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(inputStream);
    nsresult rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);
    NS_ENSURE_SUCCESS(rv, rv);

    void *buffer = &mHashKey;
    rv = NS_ReadInputStreamToBuffer(inputStream,
                                    &buffer,
                                    sizeof(PRUint32));
    NS_ENSURE_SUCCESS(rv, rv);

    LOG(("Loaded classifier key = %X", mHashKey));
  }

  return NS_OK;
}
Пример #6
0
nsresult nsPrefService::WritePrefFile(nsIFile* aFile)
{
  const char                outHeader[] =
    "# Mozilla User Preferences"
    NS_LINEBREAK
    NS_LINEBREAK
    "/* Do not edit this file."
    NS_LINEBREAK
    " *"
    NS_LINEBREAK
    " * If you make changes to this file while the application is running,"
    NS_LINEBREAK
    " * the changes will be overwritten when the application exits."
    NS_LINEBREAK
    " *"
    NS_LINEBREAK
    " * To make a manual change to preferences, you can visit the URL about:config"
    NS_LINEBREAK
    " * For more information, see http://www.mozilla.org/unix/customizing.html#prefs"
    NS_LINEBREAK
    " */"
    NS_LINEBREAK
    NS_LINEBREAK;

  nsCOMPtr<nsIOutputStream> outStreamSink;
  nsCOMPtr<nsIOutputStream> outStream;
  PRUint32                  writeAmount;
  nsresult                  rv;

  if (!gHashTable.ops)
    return NS_ERROR_NOT_INITIALIZED;

  // execute a "safe" save by saving through a tempfile
  rv = NS_NewSafeLocalFileOutputStream(getter_AddRefs(outStreamSink),
                                       aFile,
                                       -1,
                                       0600);
  if (NS_FAILED(rv)) 
      return rv;
  rv = NS_NewBufferedOutputStream(getter_AddRefs(outStream), outStreamSink, 4096);
  if (NS_FAILED(rv)) 
      return rv;  

  char** valueArray = (char **)PR_Calloc(sizeof(char *), gHashTable.entryCount);
  if (!valueArray)
    return NS_ERROR_OUT_OF_MEMORY;
  
  pref_saveArgs saveArgs;
  saveArgs.prefArray = valueArray;
  saveArgs.saveTypes = SAVE_ALL;
  
  // get the lines that we're supposed to be writing to the file
  PL_DHashTableEnumerate(&gHashTable, pref_savePref, &saveArgs);
    
  /* Sort the preferences to make a readable file on disk */
  NS_QuickSort(valueArray, gHashTable.entryCount, sizeof(char *), pref_CompareStrings, NULL);
  
  // write out the file header
  outStream->Write(outHeader, sizeof(outHeader) - 1, &writeAmount);

  char** walker = valueArray;
  for (PRUint32 valueIdx = 0; valueIdx < gHashTable.entryCount; valueIdx++, walker++) {
    if (*walker) {
      outStream->Write(*walker, strlen(*walker), &writeAmount);
      outStream->Write(NS_LINEBREAK, NS_LINEBREAK_LEN, &writeAmount);
      NS_Free(*walker);
    }
  }
  PR_Free(valueArray);

  // tell the safe output stream to overwrite the real prefs file
  // (it'll abort if there were any errors during writing)
  nsCOMPtr<nsISafeOutputStream> safeStream = do_QueryInterface(outStream);
  NS_ASSERTION(safeStream, "expected a safe output stream!");
  if (safeStream) {
    rv = safeStream->Finish();
    if (NS_FAILED(rv)) {
      NS_WARNING("failed to save prefs file! possible dataloss");
      return rv;
    }
  }

  gDirty = PR_FALSE;
  return NS_OK;
}