static void rfbSendSecurityTypeList(rfbClientPtr cl)
{
  int i, j, n;
  SecTypeData *s;
  RFBSecTypeData *r;
  Bool tightAdvertised = FALSE;

  /*
   * When no preference order was set using "permitted-security-types", the
   * default value of preferenceLimit (1) will cause us to execute the
   * outer loop once.  In this case, the s->preference members will all
   * be the default value (-1), and we skip the order testing.
   */
  n = 0;
  for (i = 0; i < preferenceLimit; i++) {
    for (s = secTypes; s->name != NULL; s++) {
      if (((s->preference != -1) && (i != s->preference)) || !s->enabled)
        continue;

      r = s->rfbSecType;

      if (n > MAX_SECURITY_TYPES)
        FatalError("rfbSendSecurityTypeList: # enabled security types > MAX_SECURITY_TYPES");

      /*
       * Check whether we have already advertised this security type
       */
      for (j = 0; j < n; j++) {
        if (cl->securityTypes[j + 1] == r->securityType)
          break;
      }

      if (j < n)
        continue;

      if (r->advertise && (cl->protocol_minor_ver >= r->protocolMinorVer)) {
        cl->securityTypes[++n] = r->securityType;
        if (r->securityType == rfbSecTypeTight)
          tightAdvertised = TRUE;
      }
    }
  }

  if (n == 0)
    FatalError("rfbSendSecurityTypeList: no security types enabled! This should not have happened!");

  if (!tightAdvertised) {
    /*
     * Make sure to advertise the Tight security type, in order to allow
     * TightVNC-compatible clients to enable other (non-auth) Tight
     * extensions.
     */
    if (n > MAX_SECURITY_TYPES)
      FatalError("rfbSendSecurityTypeList: # enabled security types > MAX_SECURITY_TYPES");

    rfbLog("rfbSendSecurityTypeList: advertise sectype tight\n");
    cl->securityTypes[++n] = rfbSecTypeTight;
  }

  cl->securityTypes[0] = (CARD8)n;

  /* Send the list */
  if (WriteExact(cl, (char *)cl->securityTypes, n + 1) < 0) {
    rfbLogPerror("rfbSendSecurityTypeList: write");
    rfbCloseClient(cl);
    return;
  }

  /* Dispatch client input to rfbProcessClientSecurityType() */
  cl->state = RFB_SECURITY_TYPE;
}
static void rfbSendSecurityTypeList(rfbClientPtr cl)
{
  int i, j, n;
  SecTypeData *s;
  RFBSecTypeData *r;
  Bool tightAdvertised = FALSE;

   
  n = 0;
  for (i = 0; i < preferenceLimit; i++) {
    for (s = secTypes; s->name != NULL; s++) {
      if (((s->preference != -1) && (i != s->preference)) || !s->enabled)
        continue;

      r = s->rfbSecType;

      if (n > MAX_SECURITY_TYPES)
        FatalError("rfbSendSecurityTypeList: # enabled security types > MAX_SECURITY_TYPES");

       
      for (j = 0; j < n; j++) {
        if (cl->securityTypes[j + 1] == r->securityType)
          break;
      }

      if (j < n)
        continue;

      if (r->advertise && (cl->protocol_minor_ver >= r->protocolMinorVer)) {
        cl->securityTypes[++n] = r->securityType;
        if (r->securityType == rfbSecTypeTight)
          tightAdvertised = TRUE;
      }
    }
  }

  if (n == 0)
    FatalError("rfbSendSecurityTypeList: no security types enabled! This should not have happened!");

  if (!tightAdvertised) {
     
    if (n > MAX_SECURITY_TYPES)
      FatalError("rfbSendSecurityTypeList: # enabled security types > MAX_SECURITY_TYPES");

    rfbLog("rfbSendSecurityTypeList: advertise sectype tight\n");
    cl->securityTypes[++n] = rfbSecTypeTight;
  }

  cl->securityTypes[0] = (CARD8)n;

   
  if (WriteExact(cl, (char *)cl->securityTypes, n + 1) < 0) {
    rfbLogPerror("rfbSendSecurityTypeList: write");
    rfbCloseClient(cl);
    return;
  }

   
  cl->state = RFB_SECURITY_TYPE;
}