/* copied from nsProtocolProxyService.cpp --- we should share this! */
static void
proxy_MaskIPv6Addr(PRIPv6Addr &addr, PRUint16 mask_len)
{
  if (mask_len == 128)
    return;

  if (mask_len > 96) {
    addr.pr_s6_addr32[3] = PR_htonl(
            PR_ntohl(addr.pr_s6_addr32[3]) & (~0L << (128 - mask_len)));
  }
  else if (mask_len > 64) {
    addr.pr_s6_addr32[3] = 0;
    addr.pr_s6_addr32[2] = PR_htonl(
            PR_ntohl(addr.pr_s6_addr32[2]) & (~0L << (96 - mask_len)));
  }
  else if (mask_len > 32) {
    addr.pr_s6_addr32[3] = 0;
    addr.pr_s6_addr32[2] = 0;
    addr.pr_s6_addr32[1] = PR_htonl(
            PR_ntohl(addr.pr_s6_addr32[1]) & (~0L << (64 - mask_len)));
  }
  else {
    addr.pr_s6_addr32[3] = 0;
    addr.pr_s6_addr32[2] = 0;
    addr.pr_s6_addr32[1] = 0;
    addr.pr_s6_addr32[0] = PR_htonl(
            PR_ntohl(addr.pr_s6_addr32[0]) & (~0L << (32 - mask_len)));
  }
}
예제 #2
0
SECStatus
tls13_ClientHandleTicketEarlyDataInfoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
                                         SECItem *data)
{
    PRUint32 utmp;
    SECStatus rv;

    SSL_TRC(3, ("%d: TLS13[%d]: handle early_data_info extension",
                SSL_GETPID(), ss->fd));

    /* The server must not send this extension when negotiating < TLS 1.3. */
    if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
        PORT_SetError(SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION);
        return SECFailure;
    }

    rv = ssl3_ExtConsumeHandshake(ss, &utmp, sizeof(utmp),
                                  &data->data, &data->len);
    if (rv != SECSuccess) {
        PORT_SetError(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET);
        return SECFailure;
    }
    if (data->len) {
        PORT_SetError(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET);
        return SECFailure;
    }

    xtnData->max_early_data_size = PR_ntohl(utmp);

    return SECSuccess;
}
예제 #3
0
PR_IMPLEMENT(PRUint64) PR_ntohll(PRUint64 n)
{
#ifdef IS_BIG_ENDIAN
    return n;
#else
    PRUint64 tmp;
    PRUint32 hi, lo;
    LL_L2UI(lo, n);
    LL_SHR(tmp, n, 32);
    LL_L2UI(hi, tmp);
    hi = PR_ntohl(hi);
    lo = PR_ntohl(lo);
    LL_UI2L(n, lo);
    LL_SHL(n, n, 32);
    LL_UI2L(tmp, hi);
    LL_ADD(n, n, tmp);
    return n;
#endif
}  /* ntohll */
예제 #4
0
nsresult
QTAtomReader::GetFairPlayUserID(PRUint32* aUserID)
{
  // Validate arguments.
  NS_ENSURE_ARG_POINTER(aUserID);

  // Function variables.
  PRUint32 atom[2];
  PRUint64 offset = 0;
  nsresult rv;

  // Get the starting end offset.
  PRInt64  fileSize;
  PRUint64 endOffset;
  rv = mFile->GetFileSize(&fileSize);
  NS_ENSURE_SUCCESS(rv, rv);
  endOffset = fileSize;

  // Set the atom header size.
  mAtomHdrSize = 8;

  // Get the sample description table atom.
  rv = AtomPathGet("/moov/trak/mdia/minf/stbl/stsd",
                   &atom,
                   &offset,
                   &endOffset);
  NS_ENSURE_SUCCESS(rv, rv);

  // Get the FairPlay DRM atom, skipping the sample description table
  // atom header.
  offset += 16;
  rv = AtomPathGet("/drms", &atom, &offset, &endOffset);
  NS_ENSURE_SUCCESS(rv, rv);

  // Get the FairPlay user ID atom, skipping the FairPlay DRM atom header.
  offset += 0x24;
  rv = AtomPathGet("/sinf/schi/user", &atom, &offset, &endOffset);
  NS_ENSURE_SUCCESS(rv, rv);

  // Read the user ID.
  PRUint32 userIDAtom[3];
  PRUint32 bytesRead;
  PRUint32 userID;
  rv = mSeekableStream->Seek(nsISeekableStream::NS_SEEK_SET, offset);
  NS_ENSURE_SUCCESS(rv, rv);
  rv = mInputStream->Read((char *) userIDAtom, sizeof(userIDAtom), &bytesRead);
  NS_ENSURE_SUCCESS(rv, rv);
  NS_ENSURE_TRUE(bytesRead >= sizeof(userIDAtom), NS_ERROR_FAILURE);
  userID = PR_ntohl(userIDAtom[2]);

  // Return results.
  *aUserID = userID;

  return NS_OK;
}
예제 #5
0
nsresult
QTAtomReader::GetIEKInfoUserIDs(nsTArray<PRUint32>& aUserIDList)
{
  PRUint32 atom[2];
  PRUint64 offset;
  nsresult rv;

  // Get the starting offsets.
  PRInt64  fileSize;
  PRUint64 endOffset;
  rv = mFile->GetFileSize(&fileSize);
  NS_ENSURE_SUCCESS(rv, rv);
  offset = 0x4C;
  endOffset = fileSize;

  // Get the root atom.
  rv = AtomPathGet("/sean", &atom, &offset, &endOffset);
  NS_ENSURE_SUCCESS(rv, rv);
  offset += mAtomHdrSize;

  // Get the FairPlay user IDs.
  while (1) {
    // Get the next FairPlay user ID atom.
    PRUint64 userIDEndOffset = endOffset;
    rv = AtomPathGet("/user", &atom, &offset, &userIDEndOffset);
    if (NS_FAILED(rv))
      break;

    // Read the user ID.
    PRUint32 userIDAtom[3];
    PRUint32 userID;
    PRUint32 bytesRead;
    rv = mSeekableStream->Seek(nsISeekableStream::NS_SEEK_SET, offset);
    NS_ENSURE_SUCCESS(rv, rv);
    rv = mInputStream->Read((char *) userIDAtom,
                            sizeof(userIDAtom),
                            &bytesRead);
    NS_ENSURE_SUCCESS(rv, rv);
    NS_ENSURE_TRUE(bytesRead >= sizeof(userIDAtom), NS_ERROR_FAILURE);
    userID = PR_ntohl(userIDAtom[2]);

    // Add the user ID to the list.
    aUserIDList.AppendElement(userID);

    // Advance past the user ID atom.
    offset += atom[0];
  }

  return NS_OK;
}
예제 #6
0
// function to test whether or not this is a loadable plugin
static PRBool IsLoadablePlugin(CFURLRef aURL)
{
  if (!aURL)
    return PR_FALSE;
  
  PRBool isLoadable = PR_FALSE;
  char path[PATH_MAX];
  if (CFURLGetFileSystemRepresentation(aURL, TRUE, (UInt8*)path, sizeof(path))) {
    UInt32 magic;
    int f = open(path, O_RDONLY);
    if (f != -1) {
      // Mach-O headers use the byte ordering of the architecture on which
      // they run, so test against the magic number in the byte order
      // we're compiling for. Fat headers are always big-endian, so swap
      // them to host before comparing to host representation of the magic
      if (read(f, &magic, sizeof(magic)) == sizeof(magic)) {
        if ((magic == MH_MAGIC) || (PR_ntohl(magic) == FAT_MAGIC))
          isLoadable = PR_TRUE;
      }
      close(f);
    }
  }
  return isLoadable;
}
예제 #7
0
// function to test whether or not this is a loadable plugin
static PRBool IsLoadablePlugin(CFURLRef aURL)
{
  if (!aURL)
    return PR_FALSE;
  
  PRBool isLoadable = PR_FALSE;
  char path[PATH_MAX];
  if (CFURLGetFileSystemRepresentation(aURL, TRUE, (UInt8*)path, sizeof(path))) {
    UInt32 magic;
    int f = open(path, O_RDONLY);
    if (f != -1) {
      // Mach-O headers use the byte ordering of the architecture on which
      // they run, so test against the magic number in the byte order
      // we're compiling for. Fat headers are always big-endian, so swap
      // them to host before comparing to host representation of the magic
      if (read(f, &magic, sizeof(magic)) == sizeof(magic)) {
        if ((magic == MH_MAGIC) || (PR_ntohl(magic) == FAT_MAGIC))
          isLoadable = PR_TRUE;
#ifdef __POWERPC__
        // if we're on ppc, we can use CFM plugins
        if (isLoadable == PR_FALSE) {
          UInt32 magic2;
          if (read(f, &magic2, sizeof(magic2)) == sizeof(magic2)) {
            UInt32 cfm_header1 = 0x4A6F7921; // 'Joy!'
            UInt32 cfm_header2 = 0x70656666; // 'peff'
            if (cfm_header1 == magic && cfm_header2 == magic2)
              isLoadable = PR_TRUE;
          }
        }
#endif
      }
      close(f);
    }
  }
  return isLoadable;
}
/* one copy of this function is launched in a separate thread for each
** connection to be made.
*/
SECStatus
do_connects(void *a, int connection)
{
	PRNetAddr  *addr = (PRNetAddr *)a;
	PRFileDesc *sslSocket;
	PRHostEnt   hostEntry;
	char        buffer[PR_NETDB_BUF_SIZE];
	PRStatus    prStatus;
	PRIntn      hostenum;
	PRInt32    ip;
	SECStatus   secStatus;

	/* Set up SSL secure socket. */
	sslSocket = setupSSLSocket(addr);
	if (sslSocket == NULL) {
		errWarn("setupSSLSocket");
		return SECFailure;
	}

	secStatus = SSL_SetPKCS11PinArg(sslSocket, &pwdata);
	if (secStatus != SECSuccess) {
		errWarn("SSL_SetPKCS11PinArg");
		return secStatus;
	}

	secStatus = SSL_SetURL(sslSocket, hostName);
	if (secStatus != SECSuccess) {
		errWarn("SSL_SetURL");
		return secStatus;
	}

	/* Prepare and setup network connection. */
	prStatus = PR_GetHostByName(hostName, buffer, sizeof(buffer), &hostEntry);
	if (prStatus != PR_SUCCESS) {
		errWarn("PR_GetHostByName");
		return SECFailure;
	}

	hostenum = PR_EnumerateHostEnt(0, &hostEntry, port, addr);
	if (hostenum == -1) {
		errWarn("PR_EnumerateHostEnt");
		return SECFailure;
	}

 	ip = PR_ntohl(addr->inet.ip);
	fprintf(stderr,
	 	"Connecting to host %s (addr %d.%d.%d.%d) on port %d\n",
			hostName, BYTE(3,ip), BYTE(2,ip), BYTE(1,ip), 
			BYTE(0,ip), PR_ntohs(addr->inet.port)); 

	prStatus = PR_Connect(sslSocket, addr, PR_INTERVAL_NO_TIMEOUT);
	if (prStatus != PR_SUCCESS) {
		errWarn("PR_Connect");
		return SECFailure;
	}

	/* Established SSL connection, ready to send data. */
#if 0
	secStatus = SSL_ForceHandshake(sslSocket);
	if (secStatus != SECSuccess) {
		errWarn("SSL_ForceHandshake");
		return secStatus;
	}
#endif

	secStatus = SSL_ResetHandshake(sslSocket, /* asServer */ PR_FALSE);
	if (secStatus != SECSuccess) {
		errWarn("SSL_ResetHandshake");
		prStatus = PR_Close(sslSocket);
		if (prStatus != PR_SUCCESS) {
			errWarn("PR_Close");
		}
		return secStatus;
	}

	secStatus = handle_connection(sslSocket, connection);
	if (secStatus != SECSuccess) {
		/* error already printed out in handle_connection */
		/* errWarn("handle_connection"); */
		prStatus = PR_Close(sslSocket);
		if (prStatus != PR_SUCCESS) {
			errWarn("PR_Close");
		}
		return secStatus;
	}

	PR_Close(sslSocket);
	return SECSuccess;
}
예제 #9
0
nsresult
QTAtomReader::AtomGet(PRUint32  aAtomType,
                      void*     aAtom,
                      PRUint64* aStartOffset,
                      PRUint64* aEndOffset)
{
  // Validate parameters.
  NS_ASSERTION(aAtom, "aAtom is null");
  NS_ASSERTION(aStartOffset, "aStartOffset is null");
  NS_ASSERTION(aEndOffset, "aEndOffset is null");

  // Function variables.
  PRUint32 atom[2];
  nsresult rv;

  // Get the offsets.
  PRUint64 offset = *aStartOffset;
  PRUint64 endOffset = *aEndOffset;

  // Search for the specified atom.
  bool found = PR_FALSE;
  while (offset < endOffset) {
    // Seek to the current offset.
    rv = mSeekableStream->Seek(nsISeekableStream::NS_SEEK_SET, offset);
    NS_ENSURE_SUCCESS(rv, rv);

    // Read the current atom.
    PRUint32 bytesRead;
    rv = mInputStream->Read((char *) atom, sizeof(atom), &bytesRead);
    NS_ENSURE_SUCCESS(rv, rv);
    NS_ENSURE_TRUE(bytesRead >= sizeof(atom), NS_ERROR_FAILURE);

    // Convert the atom fields to host byte order.
    atom[0] = PR_ntohl(atom[0]);
    atom[1] = PR_ntohl(atom[1]);

    // Get the atom fields.
    PRUint32 curAtomSize = atom[0];
    PRUint32 curAtomType = atom[1];

    // Validate atom size.
    NS_ENSURE_TRUE(curAtomSize >= mAtomHdrSize, NS_ERROR_FAILURE);

    // Check if the current atom is the one to get.
    if (curAtomType == aAtomType) {
      found = PR_TRUE;
      break;
    } else {
      offset += curAtomSize;
    }
  }

  // Check if the atom was found.
  if (!found)
    return NS_ERROR_FAILURE;

  // Return results.
  memcpy(aAtom, atom, sizeof(atom));
  *aStartOffset = offset;
  *aEndOffset = offset + atom[0];

  return NS_OK;
}
예제 #10
0
nsresult
CacheFileMetadata::ParseMetadata(uint32_t aMetaOffset, uint32_t aBufOffset)
{
  LOG(("CacheFileMetadata::ParseMetadata() [this=%p, metaOffset=%d, "
       "bufOffset=%d]", this, aMetaOffset, aBufOffset));

  nsresult rv;

  uint32_t metaposOffset = mBufSize - sizeof(uint32_t);
  uint32_t hashesOffset = aBufOffset + sizeof(uint32_t);
  uint32_t hashCount = aMetaOffset / kChunkSize;
  if (aMetaOffset % kChunkSize)
    hashCount++;
  uint32_t hashesLen = hashCount * sizeof(CacheHashUtils::Hash16_t);
  uint32_t hdrOffset = hashesOffset + hashesLen;
  uint32_t keyOffset = hdrOffset + sizeof(CacheFileMetadataHeader);

  LOG(("CacheFileMetadata::ParseMetadata() [this=%p]\n  metaposOffset=%d\n  "
       "hashesOffset=%d\n  hashCount=%d\n  hashesLen=%d\n  hdfOffset=%d\n  "
       "keyOffset=%d\n", this, metaposOffset, hashesOffset, hashCount,
       hashesLen,hdrOffset, keyOffset));

  if (keyOffset > metaposOffset) {
    LOG(("CacheFileMetadata::ParseMetadata() - Wrong keyOffset! [this=%p]",
         this));
    return NS_ERROR_FILE_CORRUPTED;
  }

  uint32_t elementsOffset = reinterpret_cast<CacheFileMetadataHeader *>(
                              mBuf + hdrOffset)->mKeySize + keyOffset + 1;

  if (elementsOffset > metaposOffset) {
    LOG(("CacheFileMetadata::ParseMetadata() - Wrong elementsOffset %d "
         "[this=%p]", elementsOffset, this));
    return NS_ERROR_FILE_CORRUPTED;
  }

  // check that key ends with \0
  if (mBuf[elementsOffset - 1] != 0) {
    LOG(("CacheFileMetadata::ParseMetadata() - Elements not null terminated. "
         "[this=%p]", this));
    return NS_ERROR_FILE_CORRUPTED;
  }

  nsAutoCString origKey;

  uint32_t keySize = reinterpret_cast<CacheFileMetadataHeader *>(
                       mBuf + hdrOffset)->mKeySize;

  if (mKeyIsHash) {
    // get the original key
    origKey.Assign(mBuf + keyOffset, keySize);
  }
  else {
    if (keySize != mKey.Length()) {
      LOG(("CacheFileMetadata::ParseMetadata() - Key collision (1), key=%s "
           "[this=%p]", nsCString(mBuf + keyOffset, keySize).get(), this));
      return NS_ERROR_FILE_CORRUPTED;
    }

    if (memcmp(mKey.get(), mBuf + keyOffset, mKey.Length()) != 0) {
      LOG(("CacheFileMetadata::ParseMetadata() - Key collision (2), key=%s "
           "[this=%p]", nsCString(mBuf + keyOffset, keySize).get(), this));
      return NS_ERROR_FILE_CORRUPTED;
    }
  }

  // check metadata hash (data from hashesOffset to metaposOffset)
  CacheHashUtils::Hash32_t hash;
  hash = CacheHashUtils::Hash(mBuf + hashesOffset,
                              metaposOffset - hashesOffset);

  if (hash != PR_ntohl(*(reinterpret_cast<uint32_t *>(mBuf + aBufOffset)))) {
    LOG(("CacheFileMetadata::ParseMetadata() - Metadata hash mismatch! Hash of "
         "the metadata is %x, hash in file is %x [this=%p]", hash,
         PR_ntohl(*(reinterpret_cast<uint32_t *>(mBuf + aBufOffset))), this));
    return NS_ERROR_FILE_CORRUPTED;
  }

  // check elements
  rv = CheckElements(mBuf + elementsOffset, metaposOffset - elementsOffset);
  if (NS_FAILED(rv))
    return rv;

  mHashArraySize = hashesLen;
  mHashCount = hashCount;
  if (mHashArraySize) {
    mHashArray = static_cast<CacheHashUtils::Hash16_t *>(
                   moz_xmalloc(mHashArraySize));
    memcpy(mHashArray, mBuf + hashesOffset, mHashArraySize);
  }

  memcpy(&mMetaHdr, mBuf + hdrOffset, sizeof(CacheFileMetadataHeader));
  mMetaHdr.mFetchCount++;
  MarkDirty();

  mElementsSize = metaposOffset - elementsOffset;
  memmove(mBuf, mBuf + elementsOffset, mElementsSize);
  mOffset = aMetaOffset;

  if (mKeyIsHash) {
    mKey = origKey;
    mKeyIsHash = false;
  }

  // TODO: shrink memory if buffer is too big

  DoMemoryReport(MemoryUsage());

  return NS_OK;
}
예제 #11
0
nsresult
CacheFileMetadata::OnDataRead(CacheFileHandle *aHandle, char *aBuf,
                              nsresult aResult)
{
  LOG(("CacheFileMetadata::OnDataRead() [this=%p, handle=%p, result=0x%08x]",
       this, aHandle, aResult));

  MOZ_ASSERT(mListener);

  nsresult rv, retval;
  nsCOMPtr<CacheFileMetadataListener> listener;

  if (NS_FAILED(aResult)) {
    if (mKeyIsHash) {
      LOG(("CacheFileMetadata::OnDataRead() - CacheFileIOManager::Read() "
           "failed, cannot create empty metadata since key is a hash. [this=%p,"
           " rv=0x%08x]", this, aResult));

      CacheFileIOManager::DoomFile(mHandle, nullptr);
      retval = aResult;
    }
    else {
      LOG(("CacheFileMetadata::OnDataRead() - CacheFileIOManager::Read() failed"
           ", creating empty metadata. [this=%p, rv=0x%08x]", this, aResult));

      InitEmptyMetadata();
      retval = NS_OK;
    }

    mListener.swap(listener);
    listener->OnMetadataRead(retval);
    return NS_OK;
  }

  // check whether we have read all necessary data
  uint32_t realOffset = PR_ntohl(*(reinterpret_cast<uint32_t *>(
                                 mBuf + mBufSize - sizeof(uint32_t))));

  int64_t size = mHandle->FileSize();
  MOZ_ASSERT(size != -1);

  if (realOffset >= size) {
    if (mKeyIsHash) {
      LOG(("CacheFileMetadata::OnDataRead() - Invalid realOffset, cannot create"
           "empty metadata since key is a hash. [this=%p, realOffset=%d, "
           "size=%lld]", this, realOffset, size));

      CacheFileIOManager::DoomFile(mHandle, nullptr);
      retval = NS_ERROR_FILE_CORRUPTED;
    }
    else {
      LOG(("CacheFileMetadata::OnDataRead() - Invalid realOffset, creating "
           "empty metadata. [this=%p, realOffset=%d, size=%lld]", this,
           realOffset, size));

      InitEmptyMetadata();
      retval = NS_OK;
    }

    mListener.swap(listener);
    listener->OnMetadataRead(retval);
    return NS_OK;
  }

  uint32_t usedOffset = size - mBufSize;

  if (realOffset < usedOffset) {
    uint32_t missing = usedOffset - realOffset;
    // we need to read more data
    mBuf = static_cast<char *>(moz_xrealloc(mBuf, mBufSize + missing));
    memmove(mBuf + missing, mBuf, mBufSize);
    mBufSize += missing;

    DoMemoryReport(MemoryUsage());

    LOG(("CacheFileMetadata::OnDataRead() - We need to read %d more bytes to "
         "have full metadata. [this=%p]", missing, this));

    rv = CacheFileIOManager::Read(mHandle, realOffset, mBuf, missing, this);
    if (NS_FAILED(rv)) {
      if (mKeyIsHash) {
        LOG(("CacheFileMetadata::OnDataRead() - CacheFileIOManager::Read() "
             "failed synchronously, cannot create empty metadata since key is "
             "a hash. [this=%p, rv=0x%08x]", this, rv));

        CacheFileIOManager::DoomFile(mHandle, nullptr);
        retval = rv;
      }
      else {
        LOG(("CacheFileMetadata::OnDataRead() - CacheFileIOManager::Read() "
             "failed synchronously, creating empty metadata. [this=%p, "
             "rv=0x%08x]", this, rv));

        InitEmptyMetadata();
        retval = NS_OK;
      }

      mListener.swap(listener);
      listener->OnMetadataRead(retval);
      return NS_OK;
    }

    return NS_OK;
  }

  // We have all data according to offset information at the end of the entry.
  // Try to parse it.
  rv = ParseMetadata(realOffset, realOffset - usedOffset);
  if (NS_FAILED(rv)) {
    if (mKeyIsHash) {
      LOG(("CacheFileMetadata::OnDataRead() - Error parsing metadata, cannot "
           "create empty metadata since key is a hash. [this=%p]", this));

      CacheFileIOManager::DoomFile(mHandle, nullptr);
      retval = rv;
    }
    else {
      LOG(("CacheFileMetadata::OnDataRead() - Error parsing metadata, creating "
           "empty metadata. [this=%p]", this));
      InitEmptyMetadata();
      retval = NS_OK;
    }
  }
  else {
    retval = NS_OK;
  }

  mListener.swap(listener);
  listener->OnMetadataRead(retval);

  return NS_OK;
}
예제 #12
0
int tmreader_eventloop(tmreader *tmr, const char *filename,
                       tmeventhandler eventhandler)
{
    FILE *fp;
    char buf[NS_TRACE_MALLOC_MAGIC_SIZE];
    tmevent event;
    static const char magic[] = NS_TRACE_MALLOC_MAGIC;

    if (strcmp(filename, "-") == 0) {
        fp = stdin;
    } else {
#if defined(XP_WIN32)
        fp = fopen(filename, "rb");
#else
        fp = fopen(filename, "r");
#endif
        if (!fp) {
            fprintf(stderr, "%s: can't open %s: %s.\n",
                    tmr->program, filename, strerror(errno));
            return 0;
        }
    }

    if (read(fileno(fp), buf, sizeof buf) != sizeof buf ||
        strncmp(buf, magic, sizeof buf) != 0) {
        fprintf(stderr, "%s: bad magic string %s at start of %s.\n",
                tmr->program, buf, filename);
        fprintf(stderr, "either the data file is out of date,\nor your tools are out of date.\n");
        return 0;
    }

    /* Read in ticks per second. Used to convert platform specific intervals to time values */
    if (read(fileno(fp), &tmr->ticksPerSec, sizeof tmr->ticksPerSec) != sizeof tmr->ticksPerSec) {
        fprintf(stderr, "%s: Cannot read ticksPerSec. Log file read error.\n",
                tmr->program);
        return 0;
    }
    tmr->ticksPerSec = PR_ntohl(tmr->ticksPerSec);
#ifdef DEBUG_dp
    printf("DEBUG: ticks per sec = %d\n", tmr->ticksPerSec);
#endif
    while (get_tmevent(fp, &event)) {
        switch (event.type) {
          case TM_EVENT_LIBRARY: {
            const void *key;
            PLHashNumber hash;
            PLHashEntry **hep, *he;

            key = (const void*) event.serial;
            hash = hash_serial(key);
            hep = PL_HashTableRawLookup(tmr->libraries, hash, key);
            he = *hep;
            PR_ASSERT(!he);
            if (he) exit(2);

            he = PL_HashTableRawAdd(tmr->libraries, hep, hash, key,
                                    event.u.libname);
            if (!he) {
                perror(tmr->program);
                return -1;
            }
            break;
          }

          case TM_EVENT_FILENAME: {
            const void *key;
            PLHashNumber hash;
            PLHashEntry **hep, *he;

            key = (const void*) event.serial;
            hash = hash_serial(key);
            hep = PL_HashTableRawLookup(tmr->filenames, hash, key);
            he = *hep;
            PR_ASSERT(!he);
            if (he) exit(2);

            he = PL_HashTableRawAdd(tmr->filenames, hep, hash, key,
                                    event.u.srcname);
            if (!he) {
                perror(tmr->program);
                return -1;
            }
            break;
          }

          case TM_EVENT_METHOD: {
            const void *key, *sourcekey;
            PLHashNumber hash, sourcehash;
            PLHashEntry **hep, *he, **sourcehep, *sourcehe;
            char *name, *head, *mark, save;
            tmgraphnode *comp, *lib;
            tmmethodnode *meth;

            key = (const void*) event.serial;
            hash = hash_serial(key);
            hep = PL_HashTableRawLookup(tmr->methods, hash, key);
            he = *hep;
            PR_ASSERT(!he);
            if (he) exit(2);

            name = event.u.method.name;
            he = PL_HashTableRawAdd(tmr->methods, hep, hash, key, name);
            if (!he) {
                perror(tmr->program);
                return -1;
            }
            meth = (tmmethodnode*) he;

            meth->linenumber = event.u.method.linenumber;
            sourcekey = (const void*)event.u.method.filename;
            sourcehash = hash_serial(sourcekey);
            sourcehep = PL_HashTableRawLookup(tmr->filenames, sourcehash, sourcekey);
            sourcehe = *sourcehep;
            meth->sourcefile = filename_name(sourcehe);

            head = name;
            mark = strchr(name, ':');
            if (!mark) {
                mark = name;
                while (*mark != '\0' && *mark == '_')
                    mark++;
                head = mark;
                mark = strchr(head, '_');
                if (!mark) {
                    mark = strchr(head, '+');
                    if (!mark)
                        mark = head + strlen(head);
                }
            }

            save = *mark;
            *mark = '\0';
            hash = PL_HashString(head);
            hep = PL_HashTableRawLookup(tmr->components, hash, head);
            he = *hep;
            if (he) {
                comp = (tmgraphnode*) he;
            } else {
                head = strdup(head);
                if (head) {
                    he = PL_HashTableRawAdd(tmr->components, hep, hash, head,
                                            head);
                }
                if (!he) {
                    perror(tmr->program);
                    return -1;
                }
                comp = (tmgraphnode*) he;

                key = (const void*) event.u.method.library;
                hash = hash_serial(key);
                lib = (tmgraphnode*)
                      *PL_HashTableRawLookup(tmr->libraries, hash, key);
                if (lib) {
                    comp->up = lib;
                    comp->next = lib->down;
                    lib->down = comp;
                }
            }
            *mark = save;

            meth->graphnode.up = comp;
            meth->graphnode.next = comp->down;
            comp->down = &(meth->graphnode);
            break;
          }

          case TM_EVENT_CALLSITE: {
            const void *key, *mkey;
            PLHashNumber hash, mhash;
            PLHashEntry **hep, *he;
            tmcallsite *site, *parent;
            tmmethodnode *meth;

            key = (const void*) event.serial;
            hash = hash_serial(key);
            hep = PL_HashTableRawLookup(tmr->callsites, hash, key);
            he = *hep;

            /* there should not be an entry here! */
            PR_ASSERT(!he);
            if (he) exit(2);

            if (event.u.site.parent == 0) {
                parent = &tmr->calltree_root;
            } else {
                parent = tmreader_callsite(tmr, event.u.site.parent);
                if (!parent) {
                    fprintf(stderr, "%s: no parent for %lu (%lu)!\n",
                            tmr->program, (unsigned long) event.serial,
                            (unsigned long) event.u.site.parent);
                    continue;
                }
            }

            he = PL_HashTableRawAdd(tmr->callsites, hep, hash, key, NULL);
            if (!he) {
                perror(tmr->program);
                return -1;
            }

            site = (tmcallsite*) he;
            site->parent = parent;
            site->siblings = parent->kids;
            parent->kids = site;
            site->kids = NULL;

            mkey = (const void*) event.u.site.method;
            mhash = hash_serial(mkey);
            meth = (tmmethodnode*)
                   *PL_HashTableRawLookup(tmr->methods, mhash, mkey);
            site->method = meth;
            site->offset = event.u.site.offset;
            site->allocs.bytes.direct = site->allocs.bytes.total = 0;
            site->allocs.calls.direct = site->allocs.calls.total = 0;
            site->frees.bytes.direct = site->frees.bytes.total = 0;
            site->frees.calls.direct = site->frees.calls.total = 0;
            break;
          }

          case TM_EVENT_MALLOC:
          case TM_EVENT_CALLOC:
          case TM_EVENT_REALLOC: {
            tmcallsite *site;
            uint32 size, oldsize;
            double delta, sqdelta, sqszdelta = 0;
            tmgraphnode *comp, *lib;
            tmmethodnode *meth;

            site = tmreader_callsite(tmr, event.serial);
            if (!site) {
                fprintf(stderr, "%s: no callsite for '%c' (%lu)!\n",
                        tmr->program, event.type, (unsigned long) event.serial);
                continue;
            }

            size = event.u.alloc.size;
            oldsize = event.u.alloc.oldsize;
            delta = (double)size - (double)oldsize;
            site->allocs.bytes.direct += (unsigned long)delta;
            if (event.type != TM_EVENT_REALLOC)
                site->allocs.calls.direct++;
            meth = site->method;
            if (meth) {
                meth->graphnode.allocs.bytes.direct += (unsigned long)delta;
                sqdelta = delta * delta;
                if (event.type == TM_EVENT_REALLOC) {
                    sqszdelta = ((double)size * size)
                              - ((double)oldsize * oldsize);
                    meth->graphnode.sqsum += sqszdelta;
                } else {
                    meth->graphnode.sqsum += sqdelta;
                    meth->graphnode.allocs.calls.direct++;
                }
                comp = meth->graphnode.up;
                if (comp) {
                    comp->allocs.bytes.direct += (unsigned long)delta;
                    if (event.type == TM_EVENT_REALLOC) {
                        comp->sqsum += sqszdelta;
                    } else {
                        comp->sqsum += sqdelta;
                        comp->allocs.calls.direct++;
                    }
                    lib = comp->up;
                    if (lib) {
                        lib->allocs.bytes.direct += (unsigned long)delta;
                        if (event.type == TM_EVENT_REALLOC) {
                            lib->sqsum += sqszdelta;
                        } else {
                            lib->sqsum += sqdelta;
                            lib->allocs.calls.direct++;
                        }
                    }
                }
            }
            break;
          }

          case TM_EVENT_FREE: {
            tmcallsite *site;
            uint32 size;
            tmgraphnode *comp, *lib;
            tmmethodnode *meth;

            site = tmreader_callsite(tmr, event.serial);
            if (!site) {
                fprintf(stderr, "%s: no callsite for '%c' (%lu)!\n",
                        tmr->program, event.type, (unsigned long) event.serial);
                continue;
            }
            size = event.u.alloc.size;
            site->frees.bytes.direct += size;
            site->frees.calls.direct++;
            meth = site->method;
            if (meth) {
                meth->graphnode.frees.bytes.direct += size;
                meth->graphnode.frees.calls.direct++;
                comp = meth->graphnode.up;
                if (comp) {
                    comp->frees.bytes.direct += size;
                    comp->frees.calls.direct++;
                    lib = comp->up;
                    if (lib) {
                        lib->frees.bytes.direct += size;
                        lib->frees.calls.direct++;
                    }
                }
            }
            break;
          }

          case TM_EVENT_STATS:
            break;
        }

        eventhandler(tmr, &event);
    }

    return 1;
}
static PRStatus ProcessRequest(PRFileDesc *fd, CSServer_t *server)
{
    PRStatus drv, rv;
    char buffer[1024];
    PRFileDesc *file = NULL;
    PRThread * me = PR_GetCurrentThread();
    PRInt32 bytes, descbytes, netbytes, filebytes = 0;
    CSDescriptor_t *descriptor = PR_NEW(CSDescriptor_t);
    PRIntervalTime timeout = PR_MillisecondsToInterval(DEFAULT_SERVER_TIMEOUT);

    TEST_LOG(
        cltsrv_log_file, TEST_LOG_VERBOSE,
        ("\tProcessRequest(0x%p): receiving desciptor\n", me));
    bytes = PR_Recv(
        fd, descriptor, sizeof(*descriptor), RECV_FLAGS, timeout);
    if (-1 == bytes)
    {
        rv = PR_FAILURE;
        if (Aborted(rv)) goto exit;
        if (PR_IO_TIMEOUT_ERROR == PR_GetError())
        {
            TEST_LOG(
                cltsrv_log_file, TEST_LOG_ERROR,
                ("\tProcessRequest(0x%p): receive timeout\n", me));
        }
        goto exit;
    }
    if (0 == bytes)
    {
        rv = PR_FAILURE;
        TEST_LOG(
            cltsrv_log_file, TEST_LOG_ERROR,
            ("\tProcessRequest(0x%p): unexpected end of file\n", me));
        goto exit;
    }
    descbytes = PR_ntohl(descriptor->size);
    TEST_ASSERT(sizeof(*descriptor) == bytes);

    TEST_LOG(
        cltsrv_log_file, TEST_LOG_VERBOSE, 
        ("\t\tProcessRequest(0x%p): read descriptor {%d, %s}\n",
        me, descbytes, descriptor->filename));

    file = PR_Open(
        descriptor->filename, (PR_CREATE_FILE | PR_WRONLY), 0666);
    if (NULL == file)
    {
        rv = PR_FAILURE;
        if (Aborted(rv)) goto aborted;
        if (PR_IO_TIMEOUT_ERROR == PR_GetError())
        {
            TEST_LOG(
                cltsrv_log_file, TEST_LOG_ERROR,
                ("\tProcessRequest(0x%p): open file timeout\n", me));
            goto aborted;
        }
    }
    TEST_ASSERT(NULL != file);

    filebytes = 0;
    while (filebytes < descbytes)
    {
        netbytes = sizeof(buffer);
        if ((descbytes - filebytes) < netbytes)
            netbytes = descbytes - filebytes;
        TEST_LOG(
            cltsrv_log_file, TEST_LOG_VERBOSE,
            ("\tProcessRequest(0x%p): receive %d bytes\n", me, netbytes));
        bytes = PR_Recv(fd, buffer, netbytes, RECV_FLAGS, timeout);
        if (-1 == bytes)
        {
            rv = PR_FAILURE;
            if (Aborted(rv)) goto aborted;
            if (PR_IO_TIMEOUT_ERROR == PR_GetError())
            {
                TEST_LOG(
                    cltsrv_log_file, TEST_LOG_ERROR,
                    ("\t\tProcessRequest(0x%p): receive data timeout\n", me));
                goto aborted;
            }
            /*
             * XXX: I got (PR_CONNECT_RESET_ERROR, ERROR_NETNAME_DELETED)
             * on NT here.  This is equivalent to ECONNRESET on Unix.
             *     -wtc
             */
            TEST_LOG(
                cltsrv_log_file, TEST_LOG_WARNING,
                ("\t\tProcessRequest(0x%p): unexpected error (%d, %d)\n",
                me, PR_GetError(), PR_GetOSError()));
            goto aborted;
        }
        if(0 == bytes)
        {
            TEST_LOG(
                cltsrv_log_file, TEST_LOG_WARNING,
                ("\t\tProcessRequest(0x%p): unexpected end of stream\n", me));
            rv = PR_FAILURE;
            goto aborted;
        }
        filebytes += bytes;
        netbytes = bytes;
        /* The byte count for PR_Write should be positive */
        MY_ASSERT(netbytes > 0);
        TEST_LOG(
            cltsrv_log_file, TEST_LOG_VERBOSE,
            ("\tProcessRequest(0x%p): write %d bytes to file\n", me, netbytes));
        bytes = PR_Write(file, buffer, netbytes);
        if (netbytes != bytes)
        {
            rv = PR_FAILURE;
            if (Aborted(rv)) goto aborted;
            if (PR_IO_TIMEOUT_ERROR == PR_GetError())
            {
                TEST_LOG(
                    cltsrv_log_file, TEST_LOG_ERROR,
                    ("\t\tProcessRequest(0x%p): write file timeout\n", me));
                goto aborted;
            }
        }
        TEST_ASSERT(bytes > 0);
    }

    PR_Lock(server->ml);
    server->operations += 1;
    server->bytesTransferred += filebytes;
    PR_Unlock(server->ml);

    rv = PR_Close(file);
    if (Aborted(rv)) goto aborted;
    TEST_ASSERT(PR_SUCCESS == rv);
    file = NULL;

    TEST_LOG(
        cltsrv_log_file, TEST_LOG_VERBOSE,
        ("\t\tProcessRequest(0x%p): opening %s\n", me, descriptor->filename));
    file = PR_Open(descriptor->filename, PR_RDONLY, 0);
    if (NULL == file)
    {
        rv = PR_FAILURE;
        if (Aborted(rv)) goto aborted;
        if (PR_IO_TIMEOUT_ERROR == PR_GetError())
        {
            TEST_LOG(
                cltsrv_log_file, TEST_LOG_ERROR,
                ("\t\tProcessRequest(0x%p): open file timeout\n",
                PR_GetCurrentThread()));
            goto aborted;
        }
        TEST_LOG(
            cltsrv_log_file, TEST_LOG_ERROR,
            ("\t\tProcessRequest(0x%p): other file open error (%u, %u)\n",
            me, PR_GetError(), PR_GetOSError()));
        goto aborted;
    }
    TEST_ASSERT(NULL != file);

    netbytes = 0;
    while (netbytes < descbytes)
    {
        filebytes = sizeof(buffer);
        if ((descbytes - netbytes) < filebytes)
            filebytes = descbytes - netbytes;
        TEST_LOG(
            cltsrv_log_file, TEST_LOG_VERBOSE,
            ("\tProcessRequest(0x%p): read %d bytes from file\n", me, filebytes));
        bytes = PR_Read(file, buffer, filebytes);
        if (filebytes != bytes)
        {
            rv = PR_FAILURE;
            if (Aborted(rv)) goto aborted;
            if (PR_IO_TIMEOUT_ERROR == PR_GetError())
                TEST_LOG(
                    cltsrv_log_file, TEST_LOG_ERROR,
                    ("\t\tProcessRequest(0x%p): read file timeout\n", me));
            else
                TEST_LOG(
                    cltsrv_log_file, TEST_LOG_ERROR,
                    ("\t\tProcessRequest(0x%p): other file error (%d, %d)\n",
                    me, PR_GetError(), PR_GetOSError()));
            goto aborted;
        }
        TEST_ASSERT(bytes > 0);
        netbytes += bytes;
        filebytes = bytes;
        TEST_LOG(
            cltsrv_log_file, TEST_LOG_VERBOSE,
            ("\t\tProcessRequest(0x%p): sending %d bytes\n", me, filebytes));
        bytes = PR_Send(fd, buffer, filebytes, SEND_FLAGS, timeout);
        if (filebytes != bytes)
        {
            rv = PR_FAILURE;
            if (Aborted(rv)) goto aborted;
            if (PR_IO_TIMEOUT_ERROR == PR_GetError())
            {
                TEST_LOG(
                    cltsrv_log_file, TEST_LOG_ERROR,
                    ("\t\tProcessRequest(0x%p): send data timeout\n", me));
                goto aborted;
            }
            break;
        }
       TEST_ASSERT(bytes > 0);
    }
    
    PR_Lock(server->ml);
    server->bytesTransferred += filebytes;
    PR_Unlock(server->ml);

    rv = PR_Shutdown(fd, PR_SHUTDOWN_BOTH);
    if (Aborted(rv)) goto aborted;

    rv = PR_Close(file);
    if (Aborted(rv)) goto aborted;
    TEST_ASSERT(PR_SUCCESS == rv);
    file = NULL;

aborted:
    PR_ClearInterrupt();
    if (NULL != file) PR_Close(file);
    drv = PR_Delete(descriptor->filename);
    TEST_ASSERT(PR_SUCCESS == drv);
exit:
    TEST_LOG(
        cltsrv_log_file, TEST_LOG_VERBOSE,
        ("\t\tProcessRequest(0x%p): Finished\n", me));

    PR_DELETE(descriptor);

#if defined(WIN95)
    PR_Sleep(PR_MillisecondsToInterval(200)); /* lth. see note [1] */
#endif
    return rv;
}  /* ProcessRequest */
예제 #14
0
int main()
{
    union {
        PRUint16 s;
        PRUint32 l;
        PRUint64 ll;
        unsigned char bytes[8];
    } un;

    un.s = s_h;
    printf("%u %u\n",
        un.bytes[0], un.bytes[1]);
    un.s = PR_htons(un.s);
    printf("%u %u\n",
        un.bytes[0], un.bytes[1]);
    if (memcmp(un.bytes, bytes_n, 2)) {
        fprintf(stderr, "PR_htons failed\n");
        exit(1);
    }
    un.s = PR_ntohs(un.s);
    printf("%u %u\n",
        un.bytes[0], un.bytes[1]);
    if (un.s != s_h) {
        fprintf(stderr, "PR_ntohs failed\n");
        exit(1);
    }

    un.l = l_h;
    printf("%u %u %u %u\n",
        un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3]);
    un.l = PR_htonl(un.l);
    printf("%u %u %u %u\n",
        un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3]);
    if (memcmp(un.bytes, bytes_n, 4)) {
        fprintf(stderr, "PR_htonl failed\n");
        exit(1);
    }
    un.l = PR_ntohl(un.l);
    printf("%u %u %u %u\n",
        un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3]);
    if (un.l != l_h) {
        fprintf(stderr, "PR_ntohl failed\n");
        exit(1);
    }

    un.ll = ll_h;
    printf("%u %u %u %u %u %u %u %u\n",
        un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3],
        un.bytes[4], un.bytes[5], un.bytes[6], un.bytes[7]);
    un.ll = PR_htonll(un.ll);
    printf("%u %u %u %u %u %u %u %u\n",
        un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3],
        un.bytes[4], un.bytes[5], un.bytes[6], un.bytes[7]);
    if (memcmp(un.bytes, bytes_n, 8)) {
        fprintf(stderr, "PR_htonll failed\n");
        exit(1);
    }
    un.ll = PR_ntohll(un.ll);
    printf("%u %u %u %u %u %u %u %u\n",
        un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3],
        un.bytes[4], un.bytes[5], un.bytes[6], un.bytes[7]);
    if (LL_NE(un.ll, ll_h)) {
        fprintf(stderr, "PR_ntohll failed\n");
        exit(1);
    }

    printf("PASS\n");
    return 0;
}