static rfbClientPtr rfbNewClient(int sock)
{
  rfbProtocolVersionMsg pv;
  rfbClientPtr cl;
  BoxRec box;
  rfbSockAddr addr;
  socklen_t addrlen = sizeof(struct sockaddr_storage);
  char addrStr[INET6_ADDRSTRLEN];
  char *env = NULL;
  int np = sysconf(_SC_NPROCESSORS_CONF);

  if (rfbClientHead == NULL)
    /* no other clients - make sure we don't think any keys are pressed */
    KbdReleaseAllKeys();

  cl = (rfbClientPtr)rfbAlloc0(sizeof(rfbClientRec));

  if (rfbClientHead == NULL && captureFile) {
    cl->captureFD = open(captureFile, O_CREAT | O_EXCL | O_WRONLY,
                         S_IRUSR | S_IWUSR);
    if (cl->captureFD < 0)
      rfbLogPerror("Could not open capture file");
    else
      rfbLog("Opened capture file %s\n", captureFile);
  } else
    cl->captureFD = -1;

  cl->sock = sock;
  getpeername(sock, &addr.u.sa, &addrlen);
  cl->host = strdup(sockaddr_string(&addr, addrStr, INET6_ADDRSTRLEN));

  /* Dispatch client input to rfbProcessClientProtocolVersion(). */
  cl->state = RFB_PROTOCOL_VERSION;

  cl->preferredEncoding = rfbEncodingTight;
  cl->correMaxWidth = 48;
  cl->correMaxHeight = 48;

  REGION_INIT(pScreen, &cl->copyRegion, NullBox, 0);

  box.x1 = box.y1 = 0;
  box.x2 = rfbFB.width;
  box.y2 = rfbFB.height;
  REGION_INIT(pScreen, &cl->modifiedRegion, &box, 0);

  REGION_INIT(pScreen, &cl->requestedRegion, NullBox, 0);

  cl->deferredUpdateStart = gettime();

  cl->format = rfbServerFormat;
  cl->translateFn = rfbTranslateNone;

  cl->tightCompressLevel = TIGHT_DEFAULT_COMPRESSION;
  cl->tightSubsampLevel = TIGHT_DEFAULT_SUBSAMP;
  cl->tightQualityLevel = -1;
  cl->imageQualityLevel = -1;

  cl->next = rfbClientHead;
  cl->prev = NULL;
  if (rfbClientHead)
    rfbClientHead->prev = cl;
  rfbClientHead = cl;

  rfbResetStats(cl);

  cl->zlibCompressLevel = 5;

  sprintf(pv, rfbProtocolVersionFormat, 3, 8);

  if (WriteExact(cl, pv, sz_rfbProtocolVersionMsg) < 0) {
    rfbLogPerror("rfbNewClient: write");
    rfbCloseClient(cl);
    return NULL;
  }

  if ((env = getenv("TVNC_PROFILE")) != NULL && !strcmp(env, "1"))
    rfbProfile = TRUE;

  if ((env = getenv("TVNC_ICEDEBUG")) != NULL && !strcmp(env, "1"))
    rfbInterframeDebug = TRUE;

  if ((env = getenv("TVNC_ICEBLOCKSIZE")) != NULL) {
    int iceBlockSize = atoi(env);
    if (iceBlockSize >= 0) rfbICEBlockSize = iceBlockSize;
  }

  if ((env = getenv("TVNC_COMBINERECT")) != NULL) {
    int combine = atoi(env);
    if (combine > 0 && combine <= 65000) rfbCombineRect = combine;
  }

  cl->firstUpdate = TRUE;
  /* The TigerVNC Viewer won't enable remote desktop resize until it receives
     a desktop resize message from the server, so we give it one with the
     first FBU. */
  cl->reason = rfbEDSReasonServer;
  cl->result = rfbEDSResultSuccess;

  if (rfbAutoLosslessRefresh > 0.0) {
    REGION_INIT(pScreen, &cl->lossyRegion, NullBox, 0);
    if ((env = getenv("TVNC_ALRALL")) != NULL && !strcmp(env, "1"))
      putImageOnly = FALSE;
    if ((env = getenv("TVNC_ALRCOPYRECT")) != NULL && !strcmp(env, "0"))
      alrCopyRect = FALSE;
    REGION_INIT(pScreen, &cl->alrRegion, NullBox, 0);
    REGION_INIT(pScreen, &cl->alrEligibleRegion, NullBox, 0);
  }

  if ((env = getenv("TVNC_MT")) != NULL && !strcmp(env, "0"))
    rfbMT = FALSE;

  if ((env = getenv("TVNC_NTHREADS")) != NULL && strlen(env) >= 1) {
    int temp = atoi(env);
    if (temp >= 1 && temp <= MAX_ENCODING_THREADS)
      rfbNumThreads = temp;
    else
      rfbLog("WARNING: Invalid value of TVNC_NTHREADS (%s) ignored\n", env);
  }

  if (np == -1 && rfbMT) {
    rfbLog("WARNING: Could not determine CPU count.  Multithreaded encoding disabled.\n");
    rfbMT = FALSE;
  }
  if (!rfbMT) rfbNumThreads = 1;
  else if (rfbNumThreads < 1) rfbNumThreads = min(np, 4);
  if (rfbNumThreads > np) {
    rfbLog("NOTICE: Encoding thread count has been clamped to CPU count\n");
    rfbNumThreads = np;
  }

  if (rfbIdleTimeout > 0)
    IdleTimerCancel();

  cl->baseRTT = cl->minRTT = (unsigned)-1;
  gettimeofday(&cl->lastWrite, NULL);
  REGION_INIT(pScreen, &cl->cuRegion, NullBox, 0);

  if (rfbInterframe == 1) {
    if (!InterframeOn(cl)) {
      rfbCloseClient(cl);
      return NULL;
    }
  } else
    InterframeOff(cl);

  return cl;
}