Пример #1
0
int main(int argc, char **argv)
#endif
{
    PRTime ct;
    PRExplodedTime et;
    PRStatus rv;
    char *sp1 = "Sat, 1 Jan 3001 00:00:00";  /* no time zone */
    char *sp2 = "Fri, 31 Dec 3000 23:59:60";  /* no time zone, not normalized */

#if _MSC_VER >= 1400 && !defined(WINCE)
    /* Run this test in the US Pacific Time timezone. */
    _putenv_s("TZ", "PST8PDT");
    _tzset();
#endif

    rv = PR_ParseTimeString(sp1, PR_FALSE, &ct);
    printf("rv = %d\n", rv);
    PR_ExplodeTime(ct, PR_GMTParameters, &et);
    PrintExplodedTime(&et);
    printf("\n");

    rv = PR_ParseTimeString(sp2, PR_FALSE, &ct);
    printf("rv = %d\n", rv);
    PR_ExplodeTime(ct, PR_GMTParameters, &et);
    PrintExplodedTime(&et);
    printf("\n");

    return 0;
}
Пример #2
0
PRTime
rdf_ParseDate(const nsACString &aTime)
{
    PRTime t;
    PR_ParseTimeString(PromiseFlatCString(aTime).get(), PR_TRUE, &t);

    PRInt32 usec = 0;

    nsACString::const_iterator begin, digit, end;
    aTime.BeginReading(begin);
    aTime.EndReading(end);

    // Walk backwards until we find a `+', run out of string, or a
    // non-numeric character.
    digit = end;
    while (--digit != begin && *digit != '+') {
        if (*digit < '0' || *digit > '9')
            break;
    }

    if (digit != begin && *digit == '+') {
        // There's a usec field specified (or, at least, something
        // that looks close enough. Parse it, and add it to the time.
        while (++digit != end) {
            usec *= 10;
            usec += *digit - '0';
        }

        PRTime temp;
        LL_I2L(temp, usec);
        LL_ADD(t, t, temp);
    }

    return t;
}
Пример #3
0
nsresult 
nsPolicyReference::ProcessExpiryElement(nsIDOMNodeList* aNodeList)
{
  NS_ENSURE_ARG_POINTER(aNodeList);
  
  PRUint32 count;
  aNodeList->GetLength(&count);
  if (count > 0) {
    nsCOMPtr<nsIDOMNode> node;
    aNodeList->Item(0, getter_AddRefs(node)); // There ought to be only one EXPIRY element
    NS_ENSURE_TRUE(node, NS_ERROR_UNEXPECTED);
    
    nsAutoString date;
    nsP3PUtils::GetAttributeValue(node, "date", date); // absdate
    if (!date.IsEmpty()) {
      char* cdate = ToNewCString(date);
      NS_ENSURE_TRUE(*cdate, NS_ERROR_OUT_OF_MEMORY);
       
      PRTime prdate;
      if (PR_ParseTimeString(cdate, PR_TRUE, &prdate) == PR_SUCCESS) {
        if (prdate < PR_Now()) {
          mError = POLICY_LIFE_EXPIRED;
        }
      }
      nsMemory::Free(cdate);
    }
  }

  return NS_OK;
}
Пример #4
0
nsresult
nsNNTPNewsgroupList::AddHeader(const char *header, const char *value)
{
  nsresult rv = NS_OK;
  // The From, Date, and Subject headers have special requirements.
  if (PL_strcmp(header, "from") == 0)
  {
    rv = m_newMsgHdr->SetAuthor(value);
  }
  else if (PL_strcmp(header, "date") == 0)
  {
    PRTime date;
    PRStatus status = PR_ParseTimeString (value, false, &date);
    if (PR_SUCCESS == status)
      rv = m_newMsgHdr->SetDate(date);
  }
  else if (PL_strcmp(header, "subject") == 0)
  {
    const char *subject = value;
    uint32_t subjectLen = strlen(value);

    uint32_t flags = 0;
    // ### should call IsHeaderRead here...
    /* strip "Re: " */
    nsCString modifiedSubject;
    if (NS_MsgStripRE(&subject, &subjectLen, getter_Copies(modifiedSubject)))
      // this will make sure read flags agree with newsrc
     (void) m_newMsgHdr->OrFlags(nsMsgMessageFlags::HasRe, &flags);

    if (! (flags & nsMsgMessageFlags::Read))
      rv = m_newMsgHdr->OrFlags(nsMsgMessageFlags::New, &flags);

    rv = m_newMsgHdr->SetSubject(modifiedSubject.IsEmpty() ? subject :
      modifiedSubject.get());
  }
  else if (PL_strcmp(header, "message-id") == 0)
  {
    rv = m_newMsgHdr->SetMessageId(value);
  }
  else if (PL_strcmp(header, "references") == 0)
  {
    rv = m_newMsgHdr->SetReferences(value);
  }
  else if (PL_strcmp(header, "bytes") == 0)
  {
    rv = m_newMsgHdr->SetMessageSize(atol(value));
  }
  else if (PL_strcmp(header, "lines") == 0)
  {
    rv = m_newMsgHdr->SetLineCount(atol(value));
  }
  else if (m_filterHeaders.Contains(nsDependentCString(header)))
  {
    rv = m_newMsgHdr->SetStringProperty(header, value);
  }
  return rv;
}
Пример #5
0
static void
testParseTimeString(PRTime t)
{
    PRExplodedTime et;
    PRTime t2;
    char timeString[128];
    char buf[128];
    PRInt32 totalOffset;
    PRInt32 hourOffset, minOffset;
    const char *sign;
    PRInt64 usec_per_sec;

    /* Truncate the microsecond part of PRTime */
    LL_I2L(usec_per_sec, PR_USEC_PER_SEC);
    LL_DIV(t, t, usec_per_sec);
    LL_MUL(t, t, usec_per_sec);

    PR_ExplodeTime(t, PR_LocalTimeParameters, &et);

    /* Print day of the week, month, day, hour, minute, and second */
    PR_snprintf(timeString, 128, "%s %s %ld %02ld:%02ld:%02ld ",
	    dayOfWeek[et.tm_wday], month[et.tm_month], et.tm_mday,
	    et.tm_hour, et.tm_min, et.tm_sec);
    /* Print time zone */
    totalOffset = et.tm_params.tp_gmt_offset + et.tm_params.tp_dst_offset;
    if (totalOffset == 0) {
	strcat(timeString, "GMT ");  /* I wanted to use "UTC" here, but
                                      * PR_ParseTimeString doesn't 
                                      * understand "UTC".  */
    } else {
        sign = "+";
        if (totalOffset < 0) {
	    totalOffset = -totalOffset;
	    sign = "-";
        }
        hourOffset = totalOffset / 3600;
        minOffset = (totalOffset % 3600) / 60;
        PR_snprintf(buf, 128, "%s%02ld%02ld ", sign, hourOffset, minOffset);
	strcat(timeString, buf);
    }
    /* Print year */
    PR_snprintf(buf, 128, "%hd", et.tm_year);
    strcat(timeString, buf);

    if (PR_ParseTimeString(timeString, PR_FALSE, &t2) == PR_FAILURE) {
	fprintf(stderr, "PR_ParseTimeString() failed\n");
	exit(1);
    }
    if (LL_NE(t, t2)) {
	fprintf(stderr, "PR_ParseTimeString() incorrect\n");
	PR_snprintf(buf, 128, "t is %lld, t2 is %lld, time string is %s\n",
                t, t2, timeString);
	fprintf(stderr, "%s\n", buf);
	exit(1);
    }
}
NS_IMETHODIMP nsScriptableDateFormat::FormatDateTime(
                            const char16_t *aLocale, 
                            nsDateFormatSelector dateFormatSelector, 
                            nsTimeFormatSelector timeFormatSelector, 
                            int32_t year, 
                            int32_t month, 
                            int32_t day, 
                            int32_t hour, 
                            int32_t minute, 
                            int32_t second, 
                            char16_t **dateTimeString)
{
  // We can't have a valid date with the year, month or day
  // being lower than 1.
  if (year < 1 || month < 1 || day < 1)
    return NS_ERROR_INVALID_ARG;

  nsresult rv;
  *dateTimeString = nullptr;

  tm tmTime;
  time_t timetTime;

  memset(&tmTime, 0, sizeof(tmTime));
  tmTime.tm_year = year - 1900;
  tmTime.tm_mon = month - 1;
  tmTime.tm_mday = day;
  tmTime.tm_hour = hour;
  tmTime.tm_min = minute;
  tmTime.tm_sec = second;
  tmTime.tm_yday = tmTime.tm_wday = 0;
  tmTime.tm_isdst = -1;
  timetTime = mktime(&tmTime);

  if ((time_t)-1 != timetTime) {
    rv = mozilla::DateTimeFormat::FormatTime(dateFormatSelector, timeFormatSelector,
                                             timetTime, mStringOut);
  }
  else {
    // if mktime fails (e.g. year <= 1970), then try NSPR.
    PRTime prtime;
    char string[32];
    SprintfLiteral(string, "%.2d/%.2d/%d %.2d:%.2d:%.2d", month, day, year, hour, minute, second);
    if (PR_SUCCESS != PR_ParseTimeString(string, false, &prtime))
      return NS_ERROR_INVALID_ARG;

    rv = mozilla::DateTimeFormat::FormatPRTime(dateFormatSelector, timeFormatSelector,
                                               prtime, mStringOut);
  }
  if (NS_SUCCEEDED(rv))
    *dateTimeString = ToNewUnicode(mStringOut);

  return rv;
}
Пример #7
0
void
assignHeaderSlot (RDFFile f, char* slot, char* value)
{
  if (startsWith(slot, "expiresOn")) {
    if (f->expiryTime == NULL)  f->expiryTime = (PRTime*)getMem(sizeof(PRTime));
    if (PR_ParseTimeString (value, 0, f->expiryTime) !=  PR_SUCCESS) {
      freeMem(f->expiryTime);
      f->expiryTime = NULL;
    }
  } else if (!(startsWith(slot, "RDFVersion"))) {
    assignSlot(f->top, slot, value, f);
  }	
}
Пример #8
0
NS_METHOD
LocalSearchDataSource::parseDate(const nsAString& aDate,
                                 PRInt64 *aResult)
{
    // date is in the form of msec since epoch, but use NSPR to
    // parse the time
    PRTime *outTime = static_cast<PRTime*>(aResult);
    PRStatus err;
    err = PR_ParseTimeString(NS_ConvertUTF16toUTF8(aDate).get(),
                             PR_FALSE, // PR_FALSE == use current timezone
                             outTime);
    NS_ENSURE_TRUE(err == 0, NS_ERROR_FAILURE);
    
    return NS_OK;
}
Пример #9
0
nsresult
nsHttpResponseHead::ParseDateHeader(nsHttpAtom header, uint32_t *result) const
{
    const char *val = PeekHeader(header);
    if (!val)
        return NS_ERROR_NOT_AVAILABLE;

    PRTime time;
    PRStatus st = PR_ParseTimeString(val, true, &time);
    if (st != PR_SUCCESS)
        return NS_ERROR_NOT_AVAILABLE;

    *result = PRTimeToSeconds(time);
    return NS_OK;
}
nsresult
nsHttpResponseHead::GetExpiresValue(PRUint32 *result)
{
    const char *val = PeekHeader(nsHttp::Expires);
    if (!val)
        return NS_ERROR_NOT_AVAILABLE;

    PRTime time;
    PRStatus st = PR_ParseTimeString(val, PR_TRUE, &time);
    if (st != PR_SUCCESS) {
        // parsing failed... RFC 2616 section 14.21 says we should treat this
        // as an expiration time in the past.
        *result = 0;
        return NS_OK;
    }

    if (LL_CMP(time, <, LL_Zero()))
        *result = 0;
    else
nsresult
mozSqlResultODBC::BuildRows()
{
  while (SQL_SUCCEEDED(SQLFetch(mResult))) {
    nsCOMPtr<nsIRDFResource> resource;
    nsresult rv = gRDFService->GetAnonymousResource(getter_AddRefs(resource));
    if (NS_FAILED(rv)) return rv;

    Row* row = Row::Create(mAllocator, resource, mColumnInfo);

    for (PRInt32 j = 0; j < mColumnInfo.Count(); j++) {
      SQLINTEGER indicator;
      SQLCHAR buf[512];
      if(SQL_SUCCEEDED(SQLGetData(mResult, j+1, SQL_C_TCHAR, buf, sizeof(buf), &indicator)) && indicator != SQL_NULL_DATA) {
        char* value = (char*)buf;
        Cell* cell = row->mCells[j];
        cell->SetNull(PR_FALSE);
        PRInt32 type = cell->GetType();
        if (type == mozISqlResult::TYPE_STRING)
          cell->SetString(ToNewUnicode(nsDependentCString(value)));
        else if (type == mozISqlResult::TYPE_INT)
          PR_sscanf(value, "%d", &cell->mInt);
        else if (type == mozISqlResult::TYPE_FLOAT)
          PR_sscanf(value, "%f", &cell->mFloat);
        else if (type == mozISqlResult::TYPE_DECIMAL)
          PR_sscanf(value, "%f", &cell->mFloat);
        else if (type == mozISqlResult::TYPE_DATE ||
                 type == mozISqlResult::TYPE_TIME ||
                 type == mozISqlResult::TYPE_DATETIME)
          PR_ParseTimeString(value, PR_FALSE, &cell->mDate);
        else if (type == mozISqlResult::TYPE_BOOL)
          cell->mBool = !strcmp(value, "t");

      }
    }

    mRows.AppendElement(row);
    nsVoidKey key(resource);
    mSources.Put(&key, row);
  }

  return NS_OK;
}
Пример #12
0
 // static
 bool Time::FromString(const wchar_t* time_string, Time* parsed_time)
 {
     DCHECK((time_string!=NULL) && (parsed_time!=NULL));
     std::string ascii_time_string = SysWideToUTF8(time_string);
     if(ascii_time_string.length() == 0)
     {
         return false;
     }
     PRTime result_time = 0;
     PRStatus result = PR_ParseTimeString(ascii_time_string.c_str(),
         PR_FALSE, &result_time);
     if(PR_SUCCESS != result)
     {
         return false;
     }
     result_time += kTimeTToMicrosecondsOffset;
     *parsed_time = Time(result_time);
     return true;
 }
nsresult
mozSqlResultMysql::BuildRows()
{
  MYSQL_ROW resultrow;
  while ((resultrow = mysql_fetch_row(mResult))){
    nsCOMPtr<nsIRDFResource> resource;
    nsresult rv = gRDFService->GetAnonymousResource(getter_AddRefs(resource));
    if (NS_FAILED(rv)) return rv;

    Row* row = Row::Create(mAllocator, resource, mColumnInfo);

    for (PRInt32 j = 0; j < mColumnInfo.Count(); j++) {
      char* value = resultrow[j];
      if (value){
        Cell* cell = row->mCells[j];
        cell->SetNull(PR_FALSE);
        PRInt32 type = cell->GetType();
        if (type == mozISqlResult::TYPE_STRING)
          cell->SetString(UTF8ToNewUnicode(nsDependentCString(value)));
        else if (type == mozISqlResult::TYPE_INT)
          PR_sscanf(value, "%d", &cell->mInt);
        else if (type == mozISqlResult::TYPE_FLOAT)
          PR_sscanf(value, "%f", &cell->mFloat);
        else if (type == mozISqlResult::TYPE_DECIMAL)
          PR_sscanf(value, "%f", &cell->mFloat);
        else if (type == mozISqlResult::TYPE_DATE ||
                 type == mozISqlResult::TYPE_TIME ||
                 type == mozISqlResult::TYPE_DATETIME)
          PR_ParseTimeString(value, PR_FALSE, &cell->mDate);
        else if (type == mozISqlResult::TYPE_BOOL)
          cell->mBool = !strcmp(value, "t");
      }
    }

    mRows.AppendElement(row);
    nsVoidKey key(resource);
    mSources.Put(&key, row);
  }

  return NS_OK;
}
Пример #14
0
nsresult
nsHttpResponseHead::GetExpiresValue(uint32_t *result) const
{
    const char *val = PeekHeader(nsHttp::Expires);
    if (!val)
        return NS_ERROR_NOT_AVAILABLE;

    PRTime time;
    PRStatus st = PR_ParseTimeString(val, true, &time);
    if (st != PR_SUCCESS) {
        // parsing failed... RFC 2616 section 14.21 says we should treat this
        // as an expiration time in the past.
        *result = 0;
        return NS_OK;
    }

    if (time < 0)
        *result = 0;
    else
        *result = PRTimeToSeconds(time);
    return NS_OK;
}
NS_IMETHODIMP nsScriptableDateFormat::FormatDateTime(
                            const char16_t *aLocale, 
                            nsDateFormatSelector dateFormatSelector, 
                            nsTimeFormatSelector timeFormatSelector, 
                            int32_t year, 
                            int32_t month, 
                            int32_t day, 
                            int32_t hour, 
                            int32_t minute, 
                            int32_t second, 
                            char16_t **dateTimeString)
{
  // We can't have a valid date with the year, month or day
  // being lower than 1.
  if (year < 1 || month < 1 || day < 1)
    return NS_ERROR_INVALID_ARG;

  nsresult rv;
  nsAutoString localeName(aLocale);
  *dateTimeString = nullptr;

  nsCOMPtr<nsILocale> locale;
  // re-initialise locale pointer only if the locale was given explicitly
  if (!localeName.IsEmpty()) {
    // get locale service
    nsCOMPtr<nsILocaleService> localeService(do_GetService(kLocaleServiceCID, &rv));
    NS_ENSURE_SUCCESS(rv, rv);
    // get locale
    rv = localeService->NewLocale(localeName, getter_AddRefs(locale));
    NS_ENSURE_SUCCESS(rv, rv);
  }

  nsCOMPtr<nsIDateTimeFormat> dateTimeFormat(do_CreateInstance(kDateTimeFormatCID, &rv));
  NS_ENSURE_SUCCESS(rv, rv);

  tm tmTime;
  time_t timetTime;

  memset(&tmTime, 0, sizeof(tmTime));
  tmTime.tm_year = year - 1900;
  tmTime.tm_mon = month - 1;
  tmTime.tm_mday = day;
  tmTime.tm_hour = hour;
  tmTime.tm_min = minute;
  tmTime.tm_sec = second;
  tmTime.tm_yday = tmTime.tm_wday = 0;
  tmTime.tm_isdst = -1;
  timetTime = mktime(&tmTime);

  if ((time_t)-1 != timetTime) {
    rv = dateTimeFormat->FormatTime(locale, dateFormatSelector, timeFormatSelector, 
                                     timetTime, mStringOut);
  }
  else {
    // if mktime fails (e.g. year <= 1970), then try NSPR.
    PRTime prtime;
    char string[32];
    sprintf(string, "%.2d/%.2d/%d %.2d:%.2d:%.2d", month, day, year, hour, minute, second);
    if (PR_SUCCESS != PR_ParseTimeString(string, false, &prtime))
      return NS_ERROR_INVALID_ARG;

    rv = dateTimeFormat->FormatPRTime(locale, dateFormatSelector, timeFormatSelector, 
                                      prtime, mStringOut);
  }
  if (NS_SUCCEEDED(rv))
    *dateTimeString = ToNewUnicode(mStringOut);

  return rv;
}
Пример #16
0
nsresult
nsNNTPNewsgroupList::ParseLine(char *line, uint32_t * message_number)
{
  nsresult rv = NS_OK;
  nsCOMPtr <nsIMsgDBHdr> newMsgHdr;
  char *dateStr = nullptr;  // keep track of date str, for filters
  char *authorStr = nullptr; // keep track of author str, for filters

  if (!line || !message_number) {
    return NS_ERROR_NULL_POINTER;
  }

  char *next = line;

#define GET_TOKEN()                           \
  line = next;                                \
  next = (line ? PL_strchr (line, '\t') : 0); \
  if (next) *next++ = 0

  GET_TOKEN (); /* message number */
  *message_number = atol(line);

  if (atol(line) == 0) /* bogus xover data */
    return NS_ERROR_UNEXPECTED;

  m_newsDB->CreateNewHdr(*message_number, getter_AddRefs(newMsgHdr));

  NS_ASSERTION(newMsgHdr, "CreateNewHdr didn't fail, but it returned a null newMsgHdr");
  if (!newMsgHdr)
    return NS_ERROR_NULL_POINTER;

  GET_TOKEN (); /* subject */
  if (line) {
    const char *subject = line;  /* #### const evilness */
    uint32_t subjectLen = strlen(line);

    uint32_t flags = 0;
    // ### should call IsHeaderRead here...
    /* strip "Re: " */
    nsCString modifiedSubject;
    if (NS_MsgStripRE(&subject, &subjectLen, getter_Copies(modifiedSubject)))
      (void) newMsgHdr->OrFlags(nsMsgMessageFlags::HasRe, &flags);
    
    // this will make sure read flags agree with newsrc
    if (! (flags & nsMsgMessageFlags::Read))
      rv = newMsgHdr->OrFlags(nsMsgMessageFlags::New, &flags);

    rv = newMsgHdr->SetSubject(modifiedSubject.IsEmpty() ? subject : modifiedSubject.get());

    if (NS_FAILED(rv))
      return rv;
  }

  GET_TOKEN (); /* author */
  if (line) {
    authorStr = line;
    rv = newMsgHdr->SetAuthor(line);
    if (NS_FAILED(rv))
      return rv;
  }

  GET_TOKEN ();
  if (line) {
    dateStr = line;
    PRTime date;
    PRStatus status = PR_ParseTimeString (line, false, &date);
    if (PR_SUCCESS == status) {
      rv = newMsgHdr->SetDate(date); /* date */
      if (NS_FAILED(rv))
        return rv;
    }
  }

  GET_TOKEN (); /* message id */
  if (line) {
    char *strippedId = line;
    if (strippedId[0] == '<')
      strippedId++;
    char * lastChar = strippedId + PL_strlen(strippedId) -1;

    if (*lastChar == '>')
      *lastChar = '\0';

    rv = newMsgHdr->SetMessageId(strippedId);
    if (NS_FAILED(rv))
      return rv;
  }

  GET_TOKEN (); /* references */
  if (line) {
    rv = newMsgHdr->SetReferences(line);
    if (NS_FAILED(rv))
      return rv;
  }

  GET_TOKEN (); /* bytes */
  if (line) {
    uint32_t msgSize = 0;
    msgSize = (line) ? atol (line) : 0;

    rv = newMsgHdr->SetMessageSize(msgSize);
    if (NS_FAILED(rv)) return rv;
  }

  GET_TOKEN (); /* lines */
  if (line) {
    uint32_t numLines = 0;
    numLines = line ? atol (line) : 0;
    rv = newMsgHdr->SetLineCount(numLines);
    if (NS_FAILED(rv)) return rv;
  }

  GET_TOKEN (); /* xref */

  m_newHeaders.AppendObject(newMsgHdr);
  return NS_OK;
}
Пример #17
0
// This is the function that looks for the first folder to purge. It also
// applies retention settings to any folder that hasn't had retention settings
// applied in mMinDelayBetweenPurges minutes (default, 8 hours).
// However, if we've spent more than .5 seconds in this loop, don't
// apply any more retention settings because it might lock up the UI.
// This might starve folders later on in the hierarchy, since we always
// start at the top, but since we also apply retention settings when you
// open a folder, or when you compact all folders, I think this will do
// for now, until we have a cleanup on shutdown architecture.
nsresult nsMsgPurgeService::PerformPurge()
{
    PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("performing purge"));

    nsresult rv;

    nsCOMPtr <nsIMsgAccountManager> accountManager = do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
    NS_ENSURE_SUCCESS(rv,rv);
    bool keepApplyingRetentionSettings = true;

    nsCOMPtr<nsISupportsArray> allServers;
    rv = accountManager->GetAllServers(getter_AddRefs(allServers));
    if (NS_SUCCEEDED(rv) && allServers)
    {
        PRUint32 numServers;
        rv = allServers->Count(&numServers);
        PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("%d servers", numServers));
        nsCOMPtr<nsIMsgFolder> folderToPurge;
        PRIntervalTime startTime = PR_IntervalNow();
        PRInt32 purgeIntervalToUse;
        PRTime oldestPurgeTime = 0; // we're going to pick the least-recently purged folder

        // apply retention settings to folders that haven't had retention settings
        // applied in mMinDelayBetweenPurges minutes (default 8 hours)
        // Because we get last purge time from the folder cache,
        // this code won't open db's for folders until it decides it needs
        // to apply retention settings, and since nsIMsgFolder::ApplyRetentionSettings
        // will close any db's it opens, this code won't leave db's open.
        for (PRUint32 serverIndex=0; serverIndex < numServers; serverIndex++)
        {
            nsCOMPtr <nsIMsgIncomingServer> server =
                do_QueryElementAt(allServers, serverIndex, &rv);
            if (NS_SUCCEEDED(rv) && server)
            {
                if (keepApplyingRetentionSettings)
                {
                    nsCOMPtr <nsIMsgFolder> rootFolder;
                    rv = server->GetRootFolder(getter_AddRefs(rootFolder));
                    NS_ENSURE_SUCCESS(rv, rv);

                    nsCOMPtr <nsISupportsArray> childFolders = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID, &rv);
                    NS_ENSURE_SUCCESS(rv, rv);
                    rv = rootFolder->ListDescendents(childFolders);

                    PRUint32 cnt = 0;
                    childFolders->Count(&cnt);

                    nsCOMPtr<nsISupports> supports;
                    nsCOMPtr<nsIUrlListener> urlListener;
                    nsCOMPtr<nsIMsgFolder> childFolder;

                    for (PRUint32 index = 0; index < cnt; index++)
                    {
                        childFolder = do_QueryElementAt(childFolders, index);
                        if (childFolder)
                        {
                            PRUint32 folderFlags;
                            (void) childFolder->GetFlags(&folderFlags);
                            if (folderFlags & nsMsgFolderFlags::Virtual)
                                continue;
                            PRTime curFolderLastPurgeTime = 0;
                            nsCString curFolderLastPurgeTimeString, curFolderUri;
                            rv = childFolder->GetStringProperty("LastPurgeTime", curFolderLastPurgeTimeString);
                            if (NS_FAILED(rv))
                                continue; // it is ok to fail, go on to next folder

                            if (!curFolderLastPurgeTimeString.IsEmpty())
                            {
                                PRInt64 theTime;
                                PR_ParseTimeString(curFolderLastPurgeTimeString.get(), PR_FALSE, &theTime);
                                curFolderLastPurgeTime = theTime;
                            }

                            childFolder->GetURI(curFolderUri);
                            PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("%s curFolderLastPurgeTime=%s (if blank, then never)", curFolderUri.get(), curFolderLastPurgeTimeString.get()));

                            // check if this folder is due to purge
                            // has to have been purged at least mMinDelayBetweenPurges minutes ago
                            // we don't want to purge the folders all the time - once a day is good enough
                            PRInt64 minDelayBetweenPurges(mMinDelayBetweenPurges);
                            PRInt64 microSecondsPerMinute(60000000);
                            PRTime nextPurgeTime = curFolderLastPurgeTime + (minDelayBetweenPurges * microSecondsPerMinute);
                            if (nextPurgeTime < PR_Now())
                            {
                                PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("purging %s", curFolderUri.get()));
                                childFolder->ApplyRetentionSettings();
                            }
                            PRIntervalTime elapsedTime;
                            LL_SUB(elapsedTime, PR_IntervalNow(), startTime);
                            // check if more than 500 milliseconds have elapsed in this purge process
                            if (PR_IntervalToMilliseconds(elapsedTime) > 500)
                            {
                                keepApplyingRetentionSettings = PR_FALSE;
                                break;
                            }
                        }
                    }
                }
                nsCString type;
                nsresult rv = server->GetType(type);
                NS_ENSURE_SUCCESS(rv, rv);

                nsCAutoString contractid(NS_MSGPROTOCOLINFO_CONTRACTID_PREFIX);
                contractid.Append(type);

                nsCOMPtr<nsIMsgProtocolInfo> protocolInfo =
                    do_GetService(contractid.get(), &rv);
                NS_ENSURE_SUCCESS(rv, PR_FALSE);

                nsCString realHostName;
                server->GetRealHostName(realHostName);
                PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] %s (%s)", serverIndex, realHostName.get(), type.get()));

                nsCOMPtr <nsISpamSettings> spamSettings;
                rv = server->GetSpamSettings(getter_AddRefs(spamSettings));
                NS_ENSURE_SUCCESS(rv, rv);

                PRInt32 spamLevel;
                spamSettings->GetLevel(&spamLevel);
                PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] spamLevel=%d (if 0, don't purge)", serverIndex, spamLevel));
                if (!spamLevel)
                    continue;

                // check if we are set up to purge for this server
                // if not, skip it.
                bool purgeSpam;
                spamSettings->GetPurge(&purgeSpam);

                PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] purgeSpam=%s (if false, don't purge)", serverIndex, purgeSpam ? "true" : "false"));
                if (!purgeSpam)
                    continue;

                // check if the spam folder uri is set for this server
                // if not skip it.
                nsCString junkFolderURI;
                rv = spamSettings->GetSpamFolderURI(getter_Copies(junkFolderURI));
                NS_ENSURE_SUCCESS(rv,rv);

                PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] junkFolderURI=%s (if empty, don't purge)", serverIndex, junkFolderURI.get()));
                if (junkFolderURI.IsEmpty())
                    continue;

                // if the junk folder doesn't exist
                // because the folder pane isn't built yet, for example
                // skip this account
                nsCOMPtr<nsIMsgFolder> junkFolder;
                GetExistingFolder(junkFolderURI, getter_AddRefs(junkFolder));

                PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] %s exists? %s (if doesn't exist, don't purge)", serverIndex, junkFolderURI.get(), junkFolder ? "true" : "false"));
                if (!junkFolder)
                    continue;

                PRTime curJunkFolderLastPurgeTime = 0;
                nsCString curJunkFolderLastPurgeTimeString;
                rv = junkFolder->GetStringProperty("curJunkFolderLastPurgeTime", curJunkFolderLastPurgeTimeString);
                if (NS_FAILED(rv))
                    continue; // it is ok to fail, junk folder may not exist

                if (!curJunkFolderLastPurgeTimeString.IsEmpty())
                {
                    PRInt64 theTime;
                    PR_ParseTimeString(curJunkFolderLastPurgeTimeString.get(), PR_FALSE, &theTime);
                    curJunkFolderLastPurgeTime = theTime;
                }

                PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] %s curJunkFolderLastPurgeTime=%s (if blank, then never)", serverIndex, junkFolderURI.get(), curJunkFolderLastPurgeTimeString.get()));

                // check if this account is due to purge
                // has to have been purged at least mMinDelayBetweenPurges minutes ago
                // we don't want to purge the folders all the time
                PRTime nextPurgeTime = curJunkFolderLastPurgeTime + mMinDelayBetweenPurges * 60000000 /* convert mMinDelayBetweenPurges to into microseconds */;
                if (nextPurgeTime < PR_Now())
                {
                    PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] last purge greater than min delay", serverIndex));

                    nsCOMPtr <nsIMsgIncomingServer> junkFolderServer;
                    rv = junkFolder->GetServer(getter_AddRefs(junkFolderServer));
                    NS_ENSURE_SUCCESS(rv,rv);

                    bool serverBusy = false;
                    bool serverRequiresPassword = true;
                    bool passwordPromptRequired;
                    bool canSearchMessages = false;
                    junkFolderServer->GetPasswordPromptRequired(&passwordPromptRequired);
                    junkFolderServer->GetServerBusy(&serverBusy);
                    junkFolderServer->GetServerRequiresPasswordForBiff(&serverRequiresPassword);
                    junkFolderServer->GetCanSearchMessages(&canSearchMessages);
                    // Make sure we're logged on before doing the search (assuming we need to be)
                    // and make sure the server isn't already in the middle of downloading new messages
                    // and make sure a search isn't already going on
                    PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] (search in progress? %s)", serverIndex, mSearchSession ? "true" : "false"));
                    PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] (server busy? %s)", serverIndex, serverBusy ? "true" : "false"));
                    PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] (serverRequiresPassword? %s)", serverIndex, serverRequiresPassword ? "true" : "false"));
                    PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] (passwordPromptRequired? %s)", serverIndex, passwordPromptRequired ? "true" : "false"));
                    if (canSearchMessages && !mSearchSession && !serverBusy && (!serverRequiresPassword || !passwordPromptRequired))
                    {
                        PRInt32 purgeInterval;
                        spamSettings->GetPurgeInterval(&purgeInterval);

                        if ((oldestPurgeTime == 0) || (curJunkFolderLastPurgeTime < oldestPurgeTime))
                        {
                            PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] purging! searching for messages older than %d days", serverIndex, purgeInterval));
                            oldestPurgeTime = curJunkFolderLastPurgeTime;
                            purgeIntervalToUse = purgeInterval;
                            folderToPurge = junkFolder;
                            // if we've never purged this folder, do it...
                            if (curJunkFolderLastPurgeTime == 0)
                                break;
                        }
                    }
                    else {
                        NS_ASSERTION(canSearchMessages, "unexpected, you should be able to search");
                        PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] not a good time for this server, try again later", serverIndex));
                    }
                }
                else {
                    PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] last purge too recent", serverIndex));
                }
            }
        }
        if (folderToPurge)
            rv = SearchFolderToPurge(folderToPurge, purgeIntervalToUse);
    }

    // set up timer to check accounts again
    SetupNextPurge();
    return rv;
}
nsresult nsPluginStreamListenerPeer::SetUpStreamListener(nsIRequest *request,
                                                         nsIURI* aURL)
{
  nsresult rv = NS_OK;

  // If we don't yet have a stream listener, we need to get
  // one from the plugin.
  // NOTE: this should only happen when a stream was NOT created
  // with GetURL or PostURL (i.e. it's the initial stream we
  // send to the plugin as determined by the SRC or DATA attribute)
  if (!mPStreamListener) {
    if (!mPluginInstance) {
      return NS_ERROR_FAILURE;
    }

    nsRefPtr<nsNPAPIPluginStreamListener> streamListener;
    rv = mPluginInstance->NewStreamListener(nullptr, nullptr,
                                            getter_AddRefs(streamListener));
    if (NS_FAILED(rv) || !streamListener) {
      return NS_ERROR_FAILURE;
    }

    mPStreamListener = static_cast<nsNPAPIPluginStreamListener*>(streamListener.get());
  }

  mPStreamListener->SetStreamListenerPeer(this);

  // get httpChannel to retrieve some info we need for nsIPluginStreamInfo setup
  nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
  nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel);

  /*
   * Assumption
   * By the time nsPluginStreamListenerPeer::OnDataAvailable() gets
   * called, all the headers have been read.
   */
  if (httpChannel) {
    // Reassemble the HTTP response status line and provide it to our
    // listener.  Would be nice if we could get the raw status line,
    // but nsIHttpChannel doesn't currently provide that.
    // Status code: required; the status line isn't useful without it.
    uint32_t statusNum;
    if (NS_SUCCEEDED(httpChannel->GetResponseStatus(&statusNum)) &&
        statusNum < 1000) {
      // HTTP version: provide if available.  Defaults to empty string.
      nsCString ver;
      nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal =
      do_QueryInterface(channel);
      if (httpChannelInternal) {
        uint32_t major, minor;
        if (NS_SUCCEEDED(httpChannelInternal->GetResponseVersion(&major,
                                                                 &minor))) {
          ver = nsPrintfCString("/%lu.%lu", major, minor);
        }
      }

      // Status text: provide if available.  Defaults to "OK".
      nsCString statusText;
      if (NS_FAILED(httpChannel->GetResponseStatusText(statusText))) {
        statusText = "OK";
      }

      // Assemble everything and pass to listener.
      nsPrintfCString status("HTTP%s %lu %s", ver.get(), statusNum,
                             statusText.get());
      static_cast<nsIHTTPHeaderListener*>(mPStreamListener)->StatusLine(status.get());
    }

    // Also provide all HTTP response headers to our listener.
    httpChannel->VisitResponseHeaders(this);

    mSeekable = false;
    // first we look for a content-encoding header. If we find one, we tell the
    // plugin that stream is not seekable, because the plugin always sees
    // uncompressed data, so it can't make meaningful range requests on a
    // compressed entity.  Also, we force the plugin to use
    // nsPluginStreamType_AsFile stream type and we have to save decompressed
    // file into local plugin cache, because necko cache contains original
    // compressed file.
    nsAutoCString contentEncoding;
    if (NS_SUCCEEDED(httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("Content-Encoding"),
                                                    contentEncoding))) {
      mUseLocalCache = true;
    } else {
      // set seekability (seekable if the stream has a known length and if the
      // http server accepts byte ranges).
      uint32_t length;
      GetLength(&length);
      if (length) {
        nsAutoCString range;
        if (NS_SUCCEEDED(httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("accept-ranges"), range)) &&
            range.Equals(NS_LITERAL_CSTRING("bytes"), nsCaseInsensitiveCStringComparator())) {
          mSeekable = true;
        }
      }
    }

    // we require a content len
    // get Last-Modified header for plugin info
    nsAutoCString lastModified;
    if (NS_SUCCEEDED(httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("last-modified"), lastModified)) &&
        !lastModified.IsEmpty()) {
      PRTime time64;
      PR_ParseTimeString(lastModified.get(), true, &time64);  //convert string time to integer time

      // Convert PRTime to unix-style time_t, i.e. seconds since the epoch
      double fpTime = double(time64);
      mModified = (uint32_t)(fpTime * 1e-6 + 0.5);
    }
  }

  MOZ_ASSERT(!mRequest);
  mRequest = request;

  rv = mPStreamListener->OnStartBinding(this);

  mStartBinding = true;

  if (NS_FAILED(rv))
    return rv;

  int32_t streamType = NP_NORMAL;
  mPStreamListener->GetStreamType(&streamType);

  if (streamType != STREAM_TYPE_UNKNOWN) {
    OnStreamTypeSet(streamType);
  }

  return NS_OK;
}
Пример #19
0
NS_IMETHODIMP 
nsCRLManager::ImportCrl (PRUint8 *aData, PRUint32 aLength, nsIURI * aURI, PRUint32 aType, PRBool doSilentDonwload, const PRUnichar* crlKey)
{
  nsNSSShutDownPreventionLock locker;
  nsresult rv;
  PRArenaPool *arena = NULL;
  CERTCertificate *caCert;
  SECItem derName = { siBuffer, NULL, 0 };
  SECItem derCrl;
  CERTSignedData sd;
  SECStatus sec_rv;
  CERTSignedCrl *crl;
  nsCAutoString url;
  nsCOMPtr<nsICRLInfo> crlData;
  PRBool importSuccessful;
  PRInt32 errorCode;
  nsString errorMessage;
  
  nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
  if (NS_FAILED(rv)) return rv;
	         
  aURI->GetSpec(url);
  arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  if (!arena) {
    goto loser;
  }
  memset(&sd, 0, sizeof(sd));

  derCrl.data = (unsigned char*)aData;
  derCrl.len = aLength;
  sec_rv = CERT_KeyFromDERCrl(arena, &derCrl, &derName);
  if (sec_rv != SECSuccess) {
    goto loser;
  }

  caCert = CERT_FindCertByName(CERT_GetDefaultCertDB(), &derName);
  if (!caCert) {
    if (aType == SEC_KRL_TYPE){
      goto loser;
    }
  } else {
    sec_rv = SEC_ASN1DecodeItem(arena,
                            &sd, SEC_ASN1_GET(CERT_SignedDataTemplate), 
                            &derCrl);
    if (sec_rv != SECSuccess) {
      goto loser;
    }
    sec_rv = CERT_VerifySignedData(&sd, caCert, PR_Now(),
                               nsnull);
    if (sec_rv != SECSuccess) {
      goto loser;
    }
  }
  
  crl = SEC_NewCrl(CERT_GetDefaultCertDB(), const_cast<char*>(url.get()), &derCrl,
                   aType);
  
  if (!crl) {
    goto loser;
  }

  crlData = new nsCRLInfo(crl);
  SSL_ClearSessionCache();
  SEC_DestroyCrl(crl);
  
  importSuccessful = PR_TRUE;
  goto done;

loser:
  importSuccessful = PR_FALSE;
  errorCode = PR_GetError();
  switch (errorCode) {
    case SEC_ERROR_CRL_EXPIRED:
      nssComponent->GetPIPNSSBundleString("CrlImportFailureExpired", errorMessage);
      break;

	case SEC_ERROR_CRL_BAD_SIGNATURE:
      nssComponent->GetPIPNSSBundleString("CrlImportFailureBadSignature", errorMessage);
      break;

	case SEC_ERROR_CRL_INVALID:
      nssComponent->GetPIPNSSBundleString("CrlImportFailureInvalid", errorMessage);
      break;

	case SEC_ERROR_OLD_CRL:
      nssComponent->GetPIPNSSBundleString("CrlImportFailureOld", errorMessage);
      break;

	case SEC_ERROR_CRL_NOT_YET_VALID:
      nssComponent->GetPIPNSSBundleString("CrlImportFailureNotYetValid", errorMessage);
      break;

    default:
      nssComponent->GetPIPNSSBundleString("CrlImportFailureReasonUnknown", errorMessage);
      errorMessage.AppendInt(errorCode,16);
      break;
  }

done:
          
  if(!doSilentDonwload){
    if (!importSuccessful){
      nsString message;
      nsString temp;
      nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
      nsCOMPtr<nsIPrompt> prompter;
      if (wwatch){
        wwatch->GetNewPrompter(0, getter_AddRefs(prompter));
        nssComponent->GetPIPNSSBundleString("CrlImportFailure1x", message);
        message.Append(NS_LITERAL_STRING("\n").get());
        message.Append(errorMessage);
        nssComponent->GetPIPNSSBundleString("CrlImportFailure2", temp);
        message.Append(NS_LITERAL_STRING("\n").get());
        message.Append(temp);
     
        if(prompter) {
          nsPSMUITracker tracker;
          if (!tracker.isUIForbidden()) {
            prompter->Alert(0, message.get());
          }
        }
      }
    } else {
      nsCOMPtr<nsICertificateDialogs> certDialogs;
      // Not being able to display the success dialog should not
      // be a fatal error, so don't return a failure code.
      {
        nsPSMUITracker tracker;
        if (tracker.isUIForbidden()) {
          rv = NS_ERROR_NOT_AVAILABLE;
        }
        else {
          rv = ::getNSSDialogs(getter_AddRefs(certDialogs),
            NS_GET_IID(nsICertificateDialogs), NS_CERTIFICATEDIALOGS_CONTRACTID);
        }
      }
      if (NS_SUCCEEDED(rv)) {
        nsCOMPtr<nsIInterfaceRequestor> cxt = new PipUIContext();
        certDialogs->CrlImportStatusDialog(cxt, crlData);
      }
    }
  } else {
    if(crlKey == nsnull){
      return NS_ERROR_FAILURE;
    }
    nsCOMPtr<nsIPrefService> prefSvc = do_GetService(NS_PREFSERVICE_CONTRACTID,&rv);
    nsCOMPtr<nsIPrefBranch> pref = do_GetService(NS_PREFSERVICE_CONTRACTID,&rv);
    if (NS_FAILED(rv)){
      return rv;
    }
    
    nsCAutoString updateErrCntPrefStr(CRL_AUTOUPDATE_ERRCNT_PREF);
    updateErrCntPrefStr.AppendWithConversion(crlKey);
    if(importSuccessful){
      PRUnichar *updateTime;
      nsCAutoString updateTimeStr;
      nsCString updateURL;
      PRInt32 timingTypePref;
      double dayCnt;
      char *dayCntStr;
      nsCAutoString updateTypePrefStr(CRL_AUTOUPDATE_TIMIINGTYPE_PREF);
      nsCAutoString updateTimePrefStr(CRL_AUTOUPDATE_TIME_PREF);
      nsCAutoString updateUrlPrefStr(CRL_AUTOUPDATE_URL_PREF);
      nsCAutoString updateDayCntPrefStr(CRL_AUTOUPDATE_DAYCNT_PREF);
      nsCAutoString updateFreqCntPrefStr(CRL_AUTOUPDATE_FREQCNT_PREF);
      updateTypePrefStr.AppendWithConversion(crlKey);
      updateTimePrefStr.AppendWithConversion(crlKey);
      updateUrlPrefStr.AppendWithConversion(crlKey);
      updateDayCntPrefStr.AppendWithConversion(crlKey);
      updateFreqCntPrefStr.AppendWithConversion(crlKey);

      pref->GetIntPref(updateTypePrefStr.get(),&timingTypePref);
      
      //Compute and update the next download instant
      if(timingTypePref == TYPE_AUTOUPDATE_TIME_BASED){
        pref->GetCharPref(updateDayCntPrefStr.get(),&dayCntStr);
      }else{
        pref->GetCharPref(updateFreqCntPrefStr.get(),&dayCntStr);
      }
      dayCnt = atof(dayCntStr);
      nsMemory::Free(dayCntStr);

      PRBool toBeRescheduled = PR_FALSE;
      if(NS_SUCCEEDED(ComputeNextAutoUpdateTime(crlData, timingTypePref, dayCnt, &updateTime))){
        updateTimeStr.AssignWithConversion(updateTime);
        nsMemory::Free(updateTime);
        pref->SetCharPref(updateTimePrefStr.get(),updateTimeStr.get());
        //Now, check if this update time is already in the past. This would
        //imply we have downloaded the same crl, or there is something wrong
        //with the next update date. We will not reschedule this crl in this
        //session anymore - or else, we land into a loop. It would anyway be
        //imported once the browser is restarted.
        PRTime nextTime;
        PR_ParseTimeString(updateTimeStr.get(),PR_TRUE, &nextTime);
        if(LL_CMP(nextTime, > , PR_Now())){
          toBeRescheduled = PR_TRUE;
        }
      }
      
      //Update the url to download from, next time
      crlData->GetLastFetchURL(updateURL);
      pref->SetCharPref(updateUrlPrefStr.get(),updateURL.get());
      
      pref->SetIntPref(updateErrCntPrefStr.get(),0);
      
      if (toBeRescheduled) {
        nsAutoString hashKey(crlKey);
        nssComponent->RemoveCrlFromList(hashKey);
        nssComponent->DefineNextTimer();
      }

    } else{
Пример #20
0
    else if (matchMethod.EqualsLiteral("isless"))
        found = (val < matchVal);

    return found;
}

NS_METHOD
LocalSearchDataSource::parseDate(const nsAString& aDate,
                                 PRInt64 *aResult)
{
    // date is in the form of msec since epoch, but use NSPR to
    // parse the time
    PRTime *outTime = NS_STATIC_CAST(PRTime*,aResult);
    PRStatus err;
    err = PR_ParseTimeString(NS_ConvertUCS2toUTF8(aDate).get(),
                             PR_FALSE, // PR_FALSE == use current timezone
                             outTime);
    NS_ENSURE_TRUE(err == 0, NS_ERROR_FAILURE);
    
    return NS_OK;
}


PRBool
LocalSearchDataSource::dateMatches(nsIRDFDate *aDate,
                                   const nsAString& method,
                                   const PRInt64& matchDate)
{
    PRInt64 date;
    aDate->GetValue(&date);
    PRBool matches = PR_FALSE;
nsresult
nsDirIndexParser::ParseData(nsIDirIndex *aIdx, char* aDataStr) {
  // Parse a "201" data line, using the field ordering specified in
  // mFormat.

  if (!mFormat) {
    // Ignore if we haven't seen a format yet.
    return NS_OK;
  }

  nsresult rv = NS_OK;

  nsCAutoString filename;

  for (PRInt32 i = 0; mFormat[i] != -1; ++i) {
    // If we've exhausted the data before we run out of fields, just
    // bail.
    if (! *aDataStr)
      break;

    while (*aDataStr && nsCRT::IsAsciiSpace(*aDataStr))
      ++aDataStr;

    char    *value = aDataStr;

    if (*aDataStr == '"' || *aDataStr == '\'') {
      // it's a quoted string. snarf everything up to the next quote character
      const char quotechar = *(aDataStr++);
      ++value;
      while (*aDataStr && *aDataStr != quotechar)
        ++aDataStr;
      *aDataStr++ = '\0';

      if (! aDataStr) {
        NS_WARNING("quoted value not terminated");
      }
    } else {
      // it's unquoted. snarf until we see whitespace.
      value = aDataStr;
      while (*aDataStr && (!nsCRT::IsAsciiSpace(*aDataStr)))
        ++aDataStr;
      *aDataStr++ = '\0';
    }

    fieldType t = fieldType(mFormat[i]);
    switch (t) {
    case FIELD_FILENAME: {
      // don't unescape at this point, so that UnEscapeAndConvert() can
      filename = value;
      
      PRBool  success = PR_FALSE;
      
      nsAutoString entryuri;
      
      if (gTextToSubURI) {
        PRUnichar   *result = nsnull;
        if (NS_SUCCEEDED(rv = gTextToSubURI->UnEscapeAndConvert(mEncoding.get(), filename.get(),
                                                                &result)) && (result)) {
          if (*result) {
            aIdx->SetLocation(filename.get());
            if (!mHasDescription)
              aIdx->SetDescription(result);
            success = PR_TRUE;
          }
          NS_Free(result);
        } else {
          NS_WARNING("UnEscapeAndConvert error");
        }
      }
      
      if (!success) {
        // if unsuccessfully at charset conversion, then
        // just fallback to unescape'ing in-place
        // XXX - this shouldn't be using UTF8, should it?
        // when can we fail to get the service, anyway? - bbaetz
        aIdx->SetLocation(filename.get());
        if (!mHasDescription) {
          aIdx->SetDescription(NS_ConvertUTF8toUTF16(value).get());
        }
      }
    }
      break;
    case FIELD_DESCRIPTION:
      nsUnescape(value);
      aIdx->SetDescription(NS_ConvertUTF8toUTF16(value).get());
      break;
    case FIELD_CONTENTLENGTH:
      {
        PRInt64 len;
        PRInt32 status = PR_sscanf(value, "%lld", &len);
        if (status == 1)
          aIdx->SetSize(len);
        else
          aIdx->SetSize(LL_MAXUINT); // LL_MAXUINT means unknown
      }
      break;
    case FIELD_LASTMODIFIED:
      {
        PRTime tm;
        nsUnescape(value);
        if (PR_ParseTimeString(value, PR_FALSE, &tm) == PR_SUCCESS) {
          aIdx->SetLastModified(tm);
        }
      }
      break;
    case FIELD_CONTENTTYPE:
      aIdx->SetContentType(value);
      break;
    case FIELD_FILETYPE:
      // unescape in-place
      nsUnescape(value);
      if (!nsCRT::strcasecmp(value, "directory")) {
        aIdx->SetType(nsIDirIndex::TYPE_DIRECTORY);
      } else if (!nsCRT::strcasecmp(value, "file")) {
        aIdx->SetType(nsIDirIndex::TYPE_FILE);
      } else if (!nsCRT::strcasecmp(value, "symbolic-link")) {
        aIdx->SetType(nsIDirIndex::TYPE_SYMLINK);
      } else {
        aIdx->SetType(nsIDirIndex::TYPE_UNKNOWN);
      }
      break;
    case FIELD_UNKNOWN:
      // ignore
      break;
    }
  }

  return NS_OK;
}
nsresult nsPluginStreamListenerPeer::SetUpStreamListener(nsIRequest *request,
                                                         nsIURI* aURL)
{
  nsresult rv = NS_OK;

  // If we don't yet have a stream listener, we need to get
  // one from the plugin.
  // NOTE: this should only happen when a stream was NOT created
  // with GetURL or PostURL (i.e. it's the initial stream we
  // send to the plugin as determined by the SRC or DATA attribute)
  if (!mPStreamListener) {
    if (!mPluginInstance) {
      return NS_ERROR_FAILURE;
    }

    RefPtr<nsNPAPIPluginStreamListener> streamListener;
    rv = mPluginInstance->NewStreamListener(nullptr, nullptr,
                                            getter_AddRefs(streamListener));
    if (NS_FAILED(rv) || !streamListener) {
      return NS_ERROR_FAILURE;
    }

    mPStreamListener = static_cast<nsNPAPIPluginStreamListener*>(streamListener.get());
  }

  mPStreamListener->SetStreamListenerPeer(this);

  // get httpChannel to retrieve some info we need for nsIPluginStreamInfo setup
  nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
  nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel);

  /*
   * Assumption
   * By the time nsPluginStreamListenerPeer::OnDataAvailable() gets
   * called, all the headers have been read.
   */
  if (httpChannel) {
    // Reassemble the HTTP response status line and provide it to our
    // listener.  Would be nice if we could get the raw status line,
    // but nsIHttpChannel doesn't currently provide that.
    // Status code: required; the status line isn't useful without it.
    uint32_t statusNum;
    if (NS_SUCCEEDED(httpChannel->GetResponseStatus(&statusNum)) &&
        statusNum < 1000) {
      // HTTP version: provide if available.  Defaults to empty string.
      nsCString ver;
      nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal =
      do_QueryInterface(channel);
      if (httpChannelInternal) {
        uint32_t major, minor;
        if (NS_SUCCEEDED(httpChannelInternal->GetResponseVersion(&major,
                                                                 &minor))) {
          ver = nsPrintfCString("/%" PRIu32 ".%" PRIu32, major, minor);
        }
      }

      // Status text: provide if available.  Defaults to "OK".
      nsCString statusText;
      if (NS_FAILED(httpChannel->GetResponseStatusText(statusText))) {
        statusText = "OK";
      }

      // Assemble everything and pass to listener.
      nsPrintfCString status("HTTP%s %" PRIu32 " %s", ver.get(), statusNum,
                             statusText.get());
      static_cast<nsIHTTPHeaderListener*>(mPStreamListener)->StatusLine(status.get());
    }

    // Also provide all HTTP response headers to our listener.
    rv = httpChannel->VisitResponseHeaders(this);
    MOZ_ASSERT(NS_SUCCEEDED(rv));

    // we require a content len
    // get Last-Modified header for plugin info
    nsAutoCString lastModified;
    if (NS_SUCCEEDED(httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("last-modified"), lastModified)) &&
        !lastModified.IsEmpty()) {
      PRTime time64;
      PR_ParseTimeString(lastModified.get(), true, &time64);  //convert string time to integer time

      // Convert PRTime to unix-style time_t, i.e. seconds since the epoch
      double fpTime = double(time64);
      mModified = (uint32_t)(fpTime * 1e-6 + 0.5);
    }
  }

  MOZ_ASSERT(!mRequest);
  mRequest = request;

  rv = mPStreamListener->OnStartBinding(this);

  mStartBinding = true;

  if (NS_FAILED(rv))
    return rv;

  return NS_OK;
}