Пример #1
0
t_uint64 ReadQ (t_uint64 va)
{
t_uint64 pa;

if (va & 7) ABORT1 (va, EXC_ALIGN);                     /* must be Q aligned */
if (dmapen) pa = trans_d (va, cm_racc);                 /* mapping on? */
else pa = va;
return ReadPQ (pa);
}
Пример #2
0
t_uint64 ReadAccL (t_uint64 va, uint32 acc)
{
t_uint64 pa;

if (va & 3) ABORT1 (va, EXC_ALIGN);                     /* must be L aligned */
if (dmapen) pa = trans_d (va, acc);                     /* mapping on? */
else pa = va;
return ReadPL (pa);
}
Пример #3
0
void WriteAccQ (t_uint64 va, t_uint64 dat, uint32 acc)
{
t_uint64 pa;

if (va & 7) ABORT1 (va, EXC_ALIGN);                     /* must be Q aligned */
if (dmapen) pa = trans_d (va, acc);                     /* mapping on? */
else pa = va;
WritePQ (pa, dat);
return;
}
Пример #4
0
void WriteL (t_uint64 va, t_uint64 dat)
{
t_uint64 pa;

if (va & 3) ABORT1 (va, EXC_ALIGN);                     /* must be L aligned */
if (dmapen) pa = trans_d (va, cm_wacc);                 /* mapping on? */
else pa = va;
WritePL (pa, dat);
return;
}
Пример #5
0
NS_METHOD nsTableCellFrame::Reflow(nsPresContext*          aPresContext,
                                   nsHTMLReflowMetrics&     aDesiredSize,
                                   const nsHTMLReflowState& aReflowState,
                                   nsReflowStatus&          aStatus)
{
  DO_GLOBAL_REFLOW_COUNT("nsTableCellFrame", aReflowState.reason);
  DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
#if defined DEBUG_TABLE_REFLOW_TIMING
  nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState);
#endif
  float p2t = aPresContext->ScaledPixelsToTwips();

  // work around pixel rounding errors, round down to ensure we don't exceed the avail height in
  nscoord availHeight = aReflowState.availableHeight;
  if (NS_UNCONSTRAINEDSIZE != availHeight) {
    availHeight = nsTableFrame::RoundToPixel(availHeight, p2t, eAlwaysRoundDown);
  }

  nsresult rv = NS_OK;

  // see if a special height reflow needs to occur due to having a pct height
  if (!NeedSpecialReflow()) 
    nsTableFrame::CheckRequestSpecialHeightReflow(aReflowState);

  // this should probably be cached somewhere
  nsCompatibility compatMode = aPresContext->CompatibilityMode();

  // Initialize out parameter
  if (aDesiredSize.mComputeMEW) {
    aDesiredSize.mMaxElementWidth = 0;
  }

  aStatus = NS_FRAME_COMPLETE;
  nsSize availSize(aReflowState.availableWidth, availHeight);

  PRBool noBorderBeforeReflow = GetContentEmpty() &&
    GetStyleTableBorder()->mEmptyCells != NS_STYLE_TABLE_EMPTY_CELLS_SHOW;
  /* XXX: remove tableFrame when border-collapse inherits */
  nsTableFrame* tableFrame = nsnull;
  rv = nsTableFrame::GetTableFrame(this, tableFrame); if (!tableFrame) ABORT1(NS_ERROR_NULL_POINTER);

  nsMargin borderPadding = aReflowState.mComputedPadding;
  nsMargin border;
  GetBorderWidth(p2t, border);
  if ((NS_UNCONSTRAINEDSIZE == availSize.width) || !noBorderBeforeReflow) {
    borderPadding += border;
  }
  
  nscoord topInset    = borderPadding.top;
  nscoord rightInset  = borderPadding.right;
  nscoord bottomInset = borderPadding.bottom;
  nscoord leftInset   = borderPadding.left;

  // reduce available space by insets, if we're in a constrained situation
  if (NS_UNCONSTRAINEDSIZE!=availSize.width)
    availSize.width -= leftInset+rightInset;
  if (NS_UNCONSTRAINEDSIZE!=availSize.height)
    availSize.height -= topInset+bottomInset;

  PRBool  isStyleChanged = PR_FALSE;
  if (eReflowReason_Incremental == aReflowState.reason) {
    // if the path has a reflow command then the cell must be the target of a style change 
    nsHTMLReflowCommand* command = aReflowState.path->mReflowCommand;
    if (command) {
      // if there are other reflow commands targeted at the cell's block, these will
      // be subsumed by the style change reflow
      nsReflowType type;
      command->GetType(type);
      if (eReflowType_StyleChanged == type) {
        isStyleChanged = PR_TRUE;
      }
      else NS_ASSERTION(PR_FALSE, "table cell target of illegal incremental reflow type");
    }
    // else the reflow command will be passed down to the child
  }

  // Try to reflow the child into the available space. It might not
  // fit or might need continuing.
  if (availSize.height < 0)
    availSize.height = 1;

  nsHTMLReflowMetrics kidSize(NS_UNCONSTRAINEDSIZE == aReflowState.availableWidth ||
                              aDesiredSize.mComputeMEW,
                              aDesiredSize.mFlags);
  kidSize.width=kidSize.height=kidSize.ascent=kidSize.descent=0;
  SetPriorAvailWidth(aReflowState.availableWidth);
  nsIFrame* firstKid = mFrames.FirstChild();
  NS_ASSERTION(firstKid, "Frame construction error, a table cell always has an inner cell frame");

  nscoord computedPaginatedHeight = 0;

  if (aReflowState.mFlags.mSpecialHeightReflow || 
      (HadSpecialReflow() && (eReflowReason_Incremental == aReflowState.reason))) {
    ((nsHTMLReflowState&)aReflowState).mComputedHeight = mRect.height - topInset - bottomInset;
    DISPLAY_REFLOW_CHANGE();
  }
  else if (aPresContext->IsPaginated()) {
    computedPaginatedHeight = CalcUnpaginagedHeight(aPresContext, (nsTableCellFrame&)*this, *tableFrame, topInset + bottomInset);
    if (computedPaginatedHeight > 0) {
      ((nsHTMLReflowState&)aReflowState).mComputedHeight = computedPaginatedHeight;
      DISPLAY_REFLOW_CHANGE();
    }
  }      
  else {
    SetHasPctOverHeight(PR_FALSE);
  }

  // If it was a style change targeted at us, then reflow the child with a style change reason
  nsReflowReason reason = aReflowState.reason;
  if (isStyleChanged) {
    reason = eReflowReason_StyleChange;
    // the following could be optimized with a fair amount of effort
    tableFrame->SetNeedStrategyInit(PR_TRUE);
  }

  nsHTMLReflowState kidReflowState(aPresContext, aReflowState, firstKid, availSize, reason);
  // mIPercentHeightObserver is for non table related frames inside cells in quirks mode
  kidReflowState.mPercentHeightObserver = (eCompatibility_NavQuirks == compatMode) ? (nsIPercentHeightObserver *)this : nsnull;

  // Assume the inner child will stay positioned exactly where it is. Later in
  // VerticallyAlignChild() we'll move it if it turns out to be wrong. This
  // avoids excessive movement and is more stable
  nsPoint kidOrigin;
  if (isStyleChanged || 
      (eReflowReason_Initial == aReflowState.reason) ||
      (eReflowReason_StyleChange == aReflowState.reason)) {
    kidOrigin.MoveTo(leftInset, topInset);
  } else {
    // handle percent padding-left which was 0 during initial reflow
    if (eStyleUnit_Percent == aReflowState.mStylePadding->mPadding.GetLeftUnit()) {
      nsRect kidRect = firstKid->GetRect();
      // only move in the x direction for the same reason as above
      kidOrigin.MoveTo(leftInset, kidRect.y);
      firstKid->SetPosition(nsPoint(leftInset, kidRect.y));
    }
    kidOrigin = firstKid->GetPosition();
  }

#if defined DEBUG_TABLE_REFLOW_TIMING
  nsTableFrame::DebugReflow(firstKid, (nsHTMLReflowState&)kidReflowState);
#endif
  nscoord priorBlockHeight = GetLastBlockHeight();
  ReflowChild(firstKid, aPresContext, kidSize, kidReflowState,
              kidOrigin.x, kidOrigin.y, 0, aStatus);
  SetLastBlockHeight(kidSize.height);
  if (isStyleChanged) {
    Invalidate(GetOverflowRect(), PR_FALSE);
  }

#if defined DEBUG_TABLE_REFLOW_TIMING
  nsTableFrame::DebugReflow(firstKid, (nsHTMLReflowState&)kidReflowState, &kidSize, aStatus);
#endif

#ifdef NS_DEBUG
  DebugCheckChildSize(firstKid, kidSize, availSize, (NS_UNCONSTRAINEDSIZE != aReflowState.availableWidth));
#endif

  // 0 dimensioned cells need to be treated specially in Standard/NavQuirks mode 
  // see testcase "emptyCells.html"
  if ((0 == kidSize.width) || (0 == kidSize.height)) { // XXX why was this &&
    SetContentEmpty(PR_TRUE);
    if (NS_UNCONSTRAINEDSIZE == kidReflowState.availableWidth &&
        GetStyleTableBorder()->mEmptyCells != NS_STYLE_TABLE_EMPTY_CELLS_SHOW) {
      // need to reduce the insets by border if the cell is empty
      leftInset   -= border.left;
      rightInset  -= border.right;
      topInset    -= border.top;
      bottomInset -= border.bottom;
    }
  }
  else {
    SetContentEmpty(PR_FALSE);
    if ((eReflowReason_Incremental == aReflowState.reason) && noBorderBeforeReflow) {
      // need to consider borders, since they were factored out above
      leftInset   += border.left;
      rightInset  += border.right;
      topInset    += border.top;
      bottomInset += border.bottom;
      kidOrigin.MoveTo(leftInset, topInset);
    }
  }

  const nsStylePosition* pos = GetStylePosition();

  // calculate the min cell width
  nscoord onePixel = NSIntPixelsToTwips(1, p2t);
  nscoord smallestMinWidth = 0;
  if (eCompatibility_NavQuirks == compatMode) {
    if ((pos->mWidth.GetUnit() != eStyleUnit_Coord)   &&
        (pos->mWidth.GetUnit() != eStyleUnit_Percent)) {
      if (PR_TRUE == GetContentEmpty()) {
        if (border.left > 0) 
          smallestMinWidth += onePixel;
        if (border.right > 0) 
          smallestMinWidth += onePixel;
      }
    }
  }
  PRInt32 colspan = tableFrame->GetEffectiveColSpan(*this);
  if (colspan > 1) {
    smallestMinWidth = PR_MAX(smallestMinWidth, colspan * onePixel);
    nscoord spacingX = tableFrame->GetCellSpacingX();
    nscoord spacingExtra = spacingX * (colspan - 1);
    smallestMinWidth += spacingExtra;
    if (aReflowState.mComputedPadding.left > 0) {
      smallestMinWidth -= onePixel;
    }
  }
 
  if ((0 == kidSize.width) && (NS_UNCONSTRAINEDSIZE != kidReflowState.availableWidth)) {
    // empty content has to be forced to the assigned width for resize or incremental reflow
    kidSize.width = kidReflowState.availableWidth;
  }
  if (0 == kidSize.height) {
    if ((pos->mHeight.GetUnit() != eStyleUnit_Coord) &&
        (pos->mHeight.GetUnit() != eStyleUnit_Percent)) {
      PRInt32 pixHeight = (eCompatibility_NavQuirks == compatMode) ? 1 : 0;
      kidSize.height = NSIntPixelsToTwips(pixHeight, p2t);
    }
  }
  // end 0 dimensioned cells

  kidSize.width = PR_MAX(kidSize.width, smallestMinWidth); 
  if (!tableFrame->IsAutoLayout()) {
    // a cell in a fixed layout table is constrained to the avail width
    // if we need to shorten the cell the previous non overflowing block
    // will get some overflow area
    if (kidSize.width > availSize.width) {
      kidSize.width = availSize.width;
      firstKid->FinishAndStoreOverflow(&kidSize);
    }
  }
  //if (eReflowReason_Resize == aReflowState.reason) {
  //  NS_ASSERTION(kidSize.width <= availSize.width, "child needed more space during resize reflow");
  //}
  // Place the child
  FinishReflowChild(firstKid, aPresContext, &kidReflowState, kidSize,
                    kidOrigin.x, kidOrigin.y, 0);
    
  // first, compute the height which can be set w/o being restricted by aMaxSize.height
  nscoord cellHeight = kidSize.height;

  if (NS_UNCONSTRAINEDSIZE != cellHeight) {
    cellHeight += topInset + bottomInset;
    // work around block rounding errors, round down to ensure we don't exceed the avail height in
    nsPixelRound roundMethod = (NS_UNCONSTRAINEDSIZE == availHeight) ? eAlwaysRoundUp : eAlwaysRoundDown;
    cellHeight = nsTableFrame::RoundToPixel(cellHeight, p2t, roundMethod); 
  }

  // next determine the cell's width
  nscoord cellWidth = kidSize.width;      // at this point, we've factored in the cell's style attributes

  // factor in border and padding
  if (NS_UNCONSTRAINEDSIZE != cellWidth) {
    cellWidth += leftInset + rightInset;    
  }
  cellWidth = nsTableFrame::RoundToPixel(cellWidth, p2t); // work around block rounding errors

  // set the cell's desired size and max element size
  aDesiredSize.width   = cellWidth;
  aDesiredSize.height  = cellHeight;
  aDesiredSize.ascent  = topInset;
  aDesiredSize.descent = bottomInset;

  aDesiredSize.ascent  += kidSize.ascent;
  aDesiredSize.descent += kidSize.descent;
  
  // the overflow area will be computed when the child will be vertically aligned

  if (aDesiredSize.mComputeMEW) {
    aDesiredSize.mMaxElementWidth =
      PR_MAX(smallestMinWidth, kidSize.mMaxElementWidth);
    if (NS_UNCONSTRAINEDSIZE != aDesiredSize.mMaxElementWidth) {
      aDesiredSize.mMaxElementWidth = nsTableFrame::RoundToPixel(
                  aDesiredSize.mMaxElementWidth + leftInset + rightInset, p2t);
    }
  }
  if (aDesiredSize.mFlags & NS_REFLOW_CALC_MAX_WIDTH) {
    aDesiredSize.mMaximumWidth = kidSize.mMaximumWidth;
    if (NS_UNCONSTRAINEDSIZE != aDesiredSize.mMaximumWidth) {
      aDesiredSize.mMaximumWidth += leftInset + rightInset;
      aDesiredSize.mMaximumWidth = nsTableFrame::RoundToPixel(aDesiredSize.mMaximumWidth, p2t);
    }
    // make sure the preferred width is at least as big as the max element width
    if (aDesiredSize.mComputeMEW) {
      aDesiredSize.mMaximumWidth = PR_MAX(aDesiredSize.mMaximumWidth, aDesiredSize.mMaxElementWidth);
    }
  }

  if (aReflowState.mFlags.mSpecialHeightReflow) {
    if (aDesiredSize.height > mRect.height) {
      // set a bit indicating that the pct height contents exceeded 
      // the height that they could honor in the pass 2 reflow
      SetHasPctOverHeight(PR_TRUE);
    }
    if (NS_UNCONSTRAINEDSIZE == aReflowState.availableHeight) {
      aDesiredSize.height = mRect.height;
    }
    SetNeedSpecialReflow(PR_FALSE);
    SetHadSpecialReflow(PR_TRUE);
  }
  else if (HadSpecialReflow()) {
    if (eReflowReason_Incremental == aReflowState.reason) {
      // with an unconstrained height, if the block height value hasn't changed, 
      // use the last height of the cell.
      if ((NS_UNCONSTRAINEDSIZE == aReflowState.availableHeight) && 
          (GetLastBlockHeight() == priorBlockHeight)) {
        aDesiredSize.height = mRect.height;
      }
    }
    // XXX should probably call SetHadSpecialReflow(PR_FALSE) when things change so that
    // nothing inside the cell has a percent height, but it is not easy determining this 
  }

  // remember the desired size for this reflow
  SetDesiredSize(aDesiredSize);

#if defined DEBUG_TABLE_REFLOW_TIMING
  nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState, &aDesiredSize, aStatus);
#endif

  if (NS_UNCONSTRAINEDSIZE == aReflowState.availableWidth) {
    SetNeedPass2Reflow(PR_TRUE);
  }
  else if ((eReflowReason_Initial == aReflowState.reason) || 
           (eReflowReason_Resize  == aReflowState.reason)) { 
    SetNeedPass2Reflow(PR_FALSE);
  }

  NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
  return NS_OK;
}
int
main(int argc,
     char *argv[]) {

  char address[MAX_MACHINE_NAME + 1];
  IPAddress addresses[MAX_ADDRESSES];
  unsigned int addressesCount;
  char addressList[255 + 1];
  const char *c;
  char errorFile[127 + 1];
  char logFile[127 + 1];
  struct host_desc memoryDesc;
  double nextBeatTime;
  struct host_desc nsDesc;
  double now;
  int opt;
  extern char *optarg;
  char password[127 + 1];
  const char *USAGE =
    "nws_memory [-D] [-a name] [-d dir] [-el file] [-N host] [-p port] [-s size]";

  /* Set up default values that will be overwritten by command line args. */
  addressList[0] = '\0';
  errorFile[0] = '\0';
  fileSize = atoi(GetEnvironmentValue("MEMORY_SIZE",
                                      "~", ".nwsrc", DEFAULT_MEMORY_SIZE));
  journalFileSize = atoi(GetEnvironmentValue("JOURNAL_SIZE",
                                      "~", ".nwsrc", DEFAULT_JOURNAL_SIZE));
  logFile[0] = '\0';
  HostDValue(MyMachineName(), DefaultHostPort(MEMORY_HOST), &memoryDesc);
  SAFESTRCPY(memoryDir,
             GetEnvironmentValue("MEMORY_DIR", "~", ".nwsrc",
                                 DEFAULT_MEMORY_DIR));;
  SAFESTRCPY(nsDesc.host_name,
             GetEnvironmentValue("NAME_SERVER", "~", ".nwsrc", "noname"));
  HostDValue(nsDesc.host_name, DefaultHostPort(NAME_SERVER_HOST), &nsDesc);
  password[0] = '\0';
  memLogLocation.loc_type = MEMORY_LOG_LOCAL;
  debug = 0;

  while((int)(opt = getopt(argc, argv, SWITCHES)) != EOF) {

    switch(opt) {

    case 'a':
      SAFESTRCPY(addressList, optarg);
      break;

    case 'D':
      debug = 1;
      break;

    case 'd':
      SAFESTRCPY(memoryDir, optarg);
      break;

    case 'e':
      SAFESTRCPY(errorFile, optarg);
      break;

    case 'l':
      SAFESTRCPY(logFile, optarg);
      break;

    case 'N':
      HostDValue(optarg, DefaultHostPort(NAME_SERVER_HOST), &nsDesc);
      break;

    case 'p':
      memoryDesc.port = atoi(optarg);
      break;

    case 'P':
      fprintf(stdout, "Password? ");
      fscanf(stdin, "%s", password);
      break;

    case 's':
      fileSize = atoi(optarg);
      break;

    case 'j':
      journalFileSize = atoi(optarg);
      break;
#if defined(ENABLE_CACHE)
    case 'C':
      RC_entries = atoi(optarg);
      break;
#endif
    default:
      fprintf(stderr, "nws_memory: unrecognized switch\n%s\n", USAGE);
      exit(1);
      break;

    }

  }
#if defined(ENABLE_CACHE)
  /*
   * WARNING: these two had better be the same or the cache and backing
   * store could be inconsistent
   */
  RCMemorySize = fileSize;
  /*
   * make sure entries value is sane
   */
  if(RC_entries <= 0)
	  RC_entries = 0;
#endif

  if (debug) {
    DirectDiagnostics(DIAGINFO, stdout);
    DirectDiagnostics(DIAGLOG, stdout);
    DirectDiagnostics(DIAGWARN, stderr);
    DirectDiagnostics(DIAGERROR, stderr);
    DirectDiagnostics(DIAGFATAL, stderr);
  }

  for(addressesCount = 0, c = addressList;
      GETTOK(address, c, ",", &c);
      addressesCount++) {
    if(!IPAddressValue(address, &addresses[addressesCount])) {
      ABORT1("Unable to convert '%s' into an IP address\n", address);
    }
  }
  addressesCount += IPAddressValues(memoryDesc.host_name,
                                    &addresses[addressesCount],
                                    MAX_ADDRESSES - addressesCount);

  if(memoryDir[strlen(memoryDir) - 1] != '/') {
    strcat(memoryDir, "/");
  }
  if(!MakeDirectory(memoryDir, 0775, 1)) {
    ABORT1("Unable to establish %s as state directory\n", memoryDir);
  }
  SAFESTRCPY(memLogLocation.path,memoryDir);

  if(!EstablishHost(NameOfHost(&memoryDesc),
                    MEMORY_HOST,
                    addresses,
                    addressesCount,
                    memoryDesc.port,
                    errorFile,
                    logFile,
                    password,
                    &nsDesc,
                    NULL)) {
    exit(1);
  }

  vstrncpy(journalPath, sizeof(journalPath), 4,
           memoryDir, EstablishedRegistration(), ".", JOURNAL);

  fclose(stdin);
  signal(SIGPIPE, SocketFailure);
  RegisterListener(STORE_STATE, "STORE_STATE", &ProcessRequest);
  RegisterListener(FETCH_STATE, "FETCH_STATE", &ProcessRequest);
  RegisterListener(AUTOFETCH_BEGIN, "AUTOFETCH_BEGIN", &ProcessRequest);
  RegisterListener(MEMORY_CLEAN, "MEMORY_CLEAN", &ProcessRequest);
#ifdef WITH_NETLOGGER
  RegisterListener(MEMORY_LOGDEST, "MEMORY_LOGDEST", &ProcessRequest);
#endif
  NotifyOnDisconnection(&EndAutoFetch);
  nextBeatTime = CurrentTime();

  /* main service loop */
  while(1) {
    now = CurrentTime();
    if(now >= nextBeatTime) {
      RegisterHost(DEFAULT_HOST_BEAT * 2);
      nextBeatTime =
        now + (HostHealthy() ? DEFAULT_HOST_BEAT : SHORT_HOST_BEAT);
    }
    ListenForMessages(nextBeatTime - now);
  }

  /* return(0); Never reached */

}
int
main(int argc,
     char *argv[]) {

  char address[MAX_MACHINE_NAME + 1];
  IPAddress addresses[MAX_ADDRESSES];
  unsigned int addressesCount;
  char addressList[255 + 1];
  const char *c;
  unsigned long compressionFreq;
  char errorFile[127 + 1];
  char logFile[127 + 1];
  unsigned long nextCompression;
  struct host_desc nsDesc;
  char password[127 + 1];
  int opt;
  extern char *optarg;
  char registrationFileName[255 + 1];
  const char *USAGE =
    "nws_nameserver [-D] [-a name] [-c seconds] [-efl file] [-p port]";

  /* Set up default values that will be overwritten by command line args. */
  addressList[0] = '\0';
  compressionFreq = DEFAULT_COMPRESSION_FREQUENCY;
  errorFile[0] = '\0';
  logFile[0] = '\0';
  HostDValue(MyMachineName(), DefaultHostPort(NAME_SERVER_HOST), &nsDesc);
  SAFESTRCPY(registrationFileName, DEFAULT_FILE);
  password[0] = '\0';
  debug = 0;

  while((int)(opt = getopt(argc, argv, SWITCHES)) != EOF) {

    switch(opt) {

    case 'a':
      SAFESTRCPY(addressList, optarg);
      break;

    case 'c':
      compressionFreq = atol(optarg);
      break;

    case 'D':
      debug = 1;
      break;

    case 'e':
      SAFESTRCPY(errorFile, optarg);
      break;

    case 'f':
      SAFESTRCPY(registrationFileName, optarg);
      break;

    case 'l':
      SAFESTRCPY(logFile, optarg);
      break;

    case 'p':
      nsDesc.port = atoi(optarg);
      break;

    case 'P':
      fprintf(stdout, "Password? ");
      fscanf(stdin, "%s", password);
      break;

    default:
      fprintf(stderr, "nws_nameserver: unrecognized switch\n%s\n", USAGE);
      exit(1);
      break;

    }

  }

  if (debug) {
    DirectDiagnostics(DIAGINFO, stdout);
    DirectDiagnostics(DIAGLOG, stdout);
    DirectDiagnostics(DIAGWARN, stderr);
    DirectDiagnostics(DIAGERROR, stderr);
    DirectDiagnostics(DIAGFATAL, stderr);
  }

  addressesCount = IPAddressValues(nsDesc.host_name, addresses, MAX_ADDRESSES);
  for(c = addressList; GETTOK(address, c, ",", &c); ) {
    if(!IPAddressValue(address, &addresses[addressesCount++])) {
      ABORT1("Unable to convert '%s' into an IP address\n", address);
    }
  }

  registrationFile = fopen(registrationFileName, "r+");
  if(registrationFile == NULL) {
    registrationFile = fopen(registrationFileName, "w+");
  }
  
  if(registrationFile == NULL) {
    ABORT1("Unable to open %s for storing registrations\n",
           registrationFileName);
  }

  if(!EstablishHost(NameOfHost(&nsDesc),
                    NAME_SERVER_HOST,
                    addresses,
                    addressesCount,
                    nsDesc.port,
                    errorFile,
                    logFile,
                    password,
                    &nsDesc,
                    &NSExit)) {
    exit(1);
  }

  fclose(stdin);
  signal(SIGPIPE, SocketFailure);
  RegisterListener(NS_REGISTER, "NS_REGISTER", &ProcessRequest);
  RegisterListener(NS_SEARCH, "NS_SEARCH", &ProcessRequest);
  RegisterListener(NS_UNREGISTER, "NS_UNREGISTER", &ProcessRequest);
  nextCompression = CurrentTime() + compressionFreq;

  /* main service loop */
  while(1) {
    ListenForMessages(nextCompression - CurrentTime());
    if(CurrentTime() > nextCompression) {
      CompressRegistrations();
      nextCompression = CurrentTime() + compressionFreq;
    }
  }

  /* return 0; Never reached */

}