Exemplo n.º 1
0
int main(int argc,char** argv)
{
  rfbFontDataPtr font;
  rfbScreenInfoPtr s=rfbGetScreen(&argc,argv,640,480,8,3,3);
  int i,j;

  s->frameBuffer=(char*)malloc(640*480*3);
  rfbInitServer(s);

  for(j=0;j<480;j++)
    for(i=0;i<640;i++) {
      s->frameBuffer[(j*640+i)*3+0]=j*256/480;
      s->frameBuffer[(j*640+i)*3+1]=i*256/640;
      s->frameBuffer[(j*640+i)*3+2]=(i+j)*256/(480+640);
    }

  rfbScreen = s;
  font=rfbLoadConsoleFont(DEFAULTFONT);
  if(!font) {
    rfbErr("Couldn't find %s\n",DEFAULTFONT);
    exit(1);
  }
  
  for(j=0;j<0 && rfbIsActive(s);j++)
    rfbProcessEvents(s,900000);

  i = rfbSelectBox(s,font,fontlist,10,20,200,300,0xffdfdf,0x602040,2,showFont);
  rfbLog("Selection: %d: %s\n",i,(i>=0)?fontlist[i]:"cancelled");

  rfbFreeFont(font);
  free(s->frameBuffer);
  rfbScreenCleanup(s);

  return(0);
}
Exemplo n.º 2
0
void FUNCNAME(rfbScreenInfoPtr screen) {
    if (screen->serverFormat.bitsPerPixel == 32)
        CONCAT2E(FUNCNAME,32)(screen);
    else if (screen->serverFormat.bitsPerPixel == 16)
        CONCAT2E(FUNCNAME,16)(screen);
    else if (screen->serverFormat.bitsPerPixel == 8)
        CONCAT2E(FUNCNAME,8)(screen);
    else {
        rfbErr("Unsupported pixel depth: %d\n",
               screen->serverFormat.bitsPerPixel);
        return;
    }
}
Exemplo n.º 3
0
/*
 * getBgColour() gets the most prevalent colour in a byte array.
 */
static uint32_t
getBgColour(char *data, int size, int bpp)
{
    
#define NUMCLRS 256
  
  static int counts[NUMCLRS];
  int i,j,k;

  int maxcount = 0;
  uint8_t maxclr = 0;

  if (bpp != 8) {
    if (bpp == 16) {
      return ((uint16_t *)data)[0];
    } else if (bpp == 32) {
      return ((uint32_t *)data)[0];
    } else {
      rfbLog("getBgColour: bpp %d?\n",bpp);
      return 0;
    }
  }

  for (i=0; i<NUMCLRS; i++) {
    counts[i] = 0;
  }

  for (j=0; j<size; j++) {
    k = (int)(((uint8_t *)data)[j]);
    if (k >= NUMCLRS) {
      rfbErr("getBgColour: unusual colour = %d\n", k);
      return 0;
    }
    counts[k] += 1;
    if (counts[k] > maxcount) {
      maxcount = counts[k];
      maxclr = ((uint8_t *)data)[j];
    }
  }
  
  return maxclr;
}
Exemplo n.º 4
0
rfbBool sraRgnIteratorNext(sraRectangleIterator* i,sraRect* r)
{
  /* is the subspan finished? */
  while(sraNextSpan(i) == i->sPtrs[i->ptrPos+1]) {
    i->ptrPos -= 2;
    if(i->ptrPos < 0) /* the end */
      return(0);
  }

  i->sPtrs[i->ptrPos] = sraNextSpan(i);

  /* is this a new subspan? */
  while(i->sPtrs[i->ptrPos]->subspan) {
    if(i->ptrPos+2 > i->ptrSize) { /* array is too small */
      i->ptrSize += DEFSTEP;
      i->sPtrs = (sraSpan**)realloc(i->sPtrs, sizeof(sraSpan*)*i->ptrSize);
    }
    i->ptrPos =+ 2;
    if(sraReverse(i)) {
      i->sPtrs[i->ptrPos]   =   i->sPtrs[i->ptrPos-2]->subspan->back._prev;
      i->sPtrs[i->ptrPos+1] = &(i->sPtrs[i->ptrPos-2]->subspan->front);
    } else {
      i->sPtrs[i->ptrPos]   =   i->sPtrs[i->ptrPos-2]->subspan->front._next;
      i->sPtrs[i->ptrPos+1] = &(i->sPtrs[i->ptrPos-2]->subspan->back);
    }
  }

  if((i->ptrPos%4)!=2) {
    rfbErr("sraRgnIteratorNext: offset is wrong (%d%%4!=2)\n",i->ptrPos);
    return FALSE;
  }

  r->y1 = i->sPtrs[i->ptrPos-2]->start;
  r->y2 = i->sPtrs[i->ptrPos-2]->end;
  r->x1 = i->sPtrs[i->ptrPos]->start;
  r->x2 = i->sPtrs[i->ptrPos]->end;

  return(-1);
}
Exemplo n.º 5
0
static int __rfbssl_read(rfbClientPtr cl, char *buf, int bufsize, int peek)
{
    int ret = 0;
    struct rfbssl_ctx *ctx = (struct rfbssl_ctx *)cl->sslctx;

    rfbssl_gc_peekbuf(ctx, bufsize);

    if (ctx->peeklen) {
	/* If we have any peek data, simply return that. */
	ret = bufsize < ctx->peeklen ? bufsize : ctx->peeklen;
	memcpy (buf, ctx->peekbuf + ctx->peekstart, ret);
	if (!peek) {
	    ctx->peeklen -= ret;
	    if (ctx->peeklen != 0)
		ctx->peekstart += ret;
	    else
		ctx->peekstart = 0;
	}
    }

    if (ret < bufsize) {
	int n;
	/* read the remaining data */
	if ((n = rfbssl_do_read(cl, buf + ret, bufsize - ret)) <= 0) {
	    rfbErr("rfbssl_%s: %s error\n", __func__, peek ? "peek" : "read");
	    return n;
	}
	if (peek) {
	    memcpy(ctx->peekbuf + ctx->peekstart + ctx->peeklen, buf + ret, n);
	    ctx->peeklen += n;
	}
	ret += n;
    }

    return ret;
}
Exemplo n.º 6
0
static void
httpProcessInput(rfbScreenInfoPtr rfbScreen)
{
#ifdef LIBVNCSERVER_IPv6
    struct sockaddr_storage addr;
    char host[1024];
#else
    struct sockaddr_in addr;
#endif
    socklen_t addrlen = sizeof(addr);
    char fullFname[512];
    char params[1024];
    char *ptr;
    char *fname;
    unsigned int maxFnameLen;
    FILE* fd;
    rfbBool performSubstitutions = FALSE;
    char str[256+32];
#ifndef WIN32
    char* user=getenv("USER");
#endif
   
    cl.sock=rfbScreen->httpSock;

    if (strlen(rfbScreen->httpDir) > 255) {
	rfbErr("-httpd directory too long\n");
	httpCloseSock(rfbScreen);
	return;
    }
    strcpy(fullFname, rfbScreen->httpDir);
    fname = &fullFname[strlen(fullFname)];
    maxFnameLen = 511 - strlen(fullFname);

    buf_filled=0;

    /* Read data from the HTTP client until we get a complete request. */
    while (1) {
	ssize_t got;

        if (buf_filled > sizeof (buf)) {
	    rfbErr("httpProcessInput: HTTP request is too long\n");
	    httpCloseSock(rfbScreen);
	    return;
	}

	got = read (rfbScreen->httpSock, buf + buf_filled,
			    sizeof (buf) - buf_filled - 1);

	if (got <= 0) {
	    if (got == 0) {
		rfbErr("httpd: premature connection close\n");
	    } else {
#ifdef WIN32
	        errno=WSAGetLastError();
#endif
		if (errno == EAGAIN) {
		    return;
		}
		rfbLogPerror("httpProcessInput: read");
	    }
	    httpCloseSock(rfbScreen);
	    return;
	}

	buf_filled += got;
	buf[buf_filled] = '\0';

	/* Is it complete yet (is there a blank line)? */
	if (strstr (buf, "\r\r") || strstr (buf, "\n\n") ||
	    strstr (buf, "\r\n\r\n") || strstr (buf, "\n\r\n\r"))
	    break;
    }


    /* Process the request. */
    if(rfbScreen->httpEnableProxyConnect) {
	const static char* PROXY_OK_STR = "HTTP/1.0 200 OK\r\nContent-Type: octet-stream\r\nPragma: no-cache\r\n\r\n";
	if(!strncmp(buf, "CONNECT ", 8)) {
	    if(atoi(strchr(buf, ':')+1)!=rfbScreen->port) {
		rfbErr("httpd: CONNECT format invalid.\n");
		rfbWriteExact(&cl,INVALID_REQUEST_STR, strlen(INVALID_REQUEST_STR));
		httpCloseSock(rfbScreen);
		return;
	    }
	    /* proxy connection */
	    rfbLog("httpd: client asked for CONNECT\n");
	    rfbWriteExact(&cl,PROXY_OK_STR,strlen(PROXY_OK_STR));
	    rfbNewClientConnection(rfbScreen,rfbScreen->httpSock);
	    rfbScreen->httpSock = -1;
	    return;
	}
	if (!strncmp(buf, "GET ",4) && !strncmp(strchr(buf,'/'),"/proxied.connection HTTP/1.", 27)) {
	    /* proxy connection */
	    rfbLog("httpd: client asked for /proxied.connection\n");
	    rfbWriteExact(&cl,PROXY_OK_STR,strlen(PROXY_OK_STR));
	    rfbNewClientConnection(rfbScreen,rfbScreen->httpSock);
	    rfbScreen->httpSock = -1;
	    return;
	}	   
    }

    if (strncmp(buf, "GET ", 4)) {
	rfbErr("httpd: no GET line\n");
	httpCloseSock(rfbScreen);
	return;
    } else {
	/* Only use the first line. */
	buf[strcspn(buf, "\n\r")] = '\0';
    }

    if (strlen(buf) > maxFnameLen) {
	rfbErr("httpd: GET line too long\n");
	httpCloseSock(rfbScreen);
	return;
    }

    if (sscanf(buf, "GET %s HTTP/1.", fname) != 1) {
	rfbErr("httpd: couldn't parse GET line\n");
	httpCloseSock(rfbScreen);
	return;
    }

    if (fname[0] != '/') {
	rfbErr("httpd: filename didn't begin with '/'\n");
	rfbWriteExact(&cl, NOT_FOUND_STR, strlen(NOT_FOUND_STR));
	httpCloseSock(rfbScreen);
	return;
    }


    getpeername(rfbScreen->httpSock, (struct sockaddr *)&addr, &addrlen);
#ifdef LIBVNCSERVER_IPv6
    if(getnameinfo((struct sockaddr*)&addr, addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST) != 0) {
      rfbLogPerror("httpProcessInput: error in getnameinfo");
    }
    rfbLog("httpd: get '%s' for %s\n", fname+1, host);
#else
    rfbLog("httpd: get '%s' for %s\n", fname+1,
	   inet_ntoa(addr.sin_addr));
#endif

    /* Extract parameters from the URL string if necessary */

    params[0] = '\0';
    ptr = strchr(fname, '?');
    if (ptr != NULL) {
       *ptr = '\0';
       if (!parseParams(&ptr[1], params, 1024)) {
           params[0] = '\0';
           rfbErr("httpd: bad parameters in the URL\n");
       }
    }


    /* If we were asked for '/', actually read the file index.vnc */

    if (strcmp(fname, "/") == 0) {
	strcpy(fname, "/index.vnc");
	rfbLog("httpd: defaulting to '%s'\n", fname+1);
    }

    /* Substitutions are performed on files ending .vnc */

    if (strlen(fname) >= 4 && strcmp(&fname[strlen(fname)-4], ".vnc") == 0) {
	performSubstitutions = TRUE;
    }

    /* Open the file */

    if ((fd = fopen(fullFname, "r")) == 0) {
        rfbLogPerror("httpProcessInput: open");
        rfbWriteExact(&cl, NOT_FOUND_STR, strlen(NOT_FOUND_STR));
        httpCloseSock(rfbScreen);
        return;
    }

    if(performSubstitutions) /* is the 'index.vnc' file */
      rfbWriteExact(&cl, OK_STR_HTML, strlen(OK_STR_HTML));
    else
      rfbWriteExact(&cl, OK_STR, strlen(OK_STR));

    while (1) {
	int n = fread(buf, 1, BUF_SIZE-1, fd);
	if (n < 0) {
	    rfbLogPerror("httpProcessInput: read");
	    fclose(fd);
	    httpCloseSock(rfbScreen);
	    return;
	}

	if (n == 0)
	    break;

	if (performSubstitutions) {

	    /* Substitute $WIDTH, $HEIGHT, etc with the appropriate values.
	       This won't quite work properly if the .vnc file is longer than
	       BUF_SIZE, but it's reasonable to assume that .vnc files will
	       always be short. */

	    char *ptr = buf;
	    char *dollar;
	    buf[n] = 0; /* make sure it's null-terminated */

	    while ((dollar = strchr(ptr, '$'))!=NULL) {
		rfbWriteExact(&cl, ptr, (dollar - ptr));

		ptr = dollar;

		if (compareAndSkip(&ptr, "$WIDTH")) {

		    sprintf(str, "%d", rfbScreen->width);
		    rfbWriteExact(&cl, str, strlen(str));

		} else if (compareAndSkip(&ptr, "$HEIGHT")) {

		    sprintf(str, "%d", rfbScreen->height);
		    rfbWriteExact(&cl, str, strlen(str));

		} else if (compareAndSkip(&ptr, "$APPLETWIDTH")) {

		    sprintf(str, "%d", rfbScreen->width);
		    rfbWriteExact(&cl, str, strlen(str));

		} else if (compareAndSkip(&ptr, "$APPLETHEIGHT")) {

		    sprintf(str, "%d", rfbScreen->height + 32);
		    rfbWriteExact(&cl, str, strlen(str));

		} else if (compareAndSkip(&ptr, "$PORT")) {

		    sprintf(str, "%d", rfbScreen->port);
		    rfbWriteExact(&cl, str, strlen(str));

		} else if (compareAndSkip(&ptr, "$DESKTOP")) {

		    rfbWriteExact(&cl, rfbScreen->desktopName, strlen(rfbScreen->desktopName));

		} else if (compareAndSkip(&ptr, "$DISPLAY")) {

		    sprintf(str, "%s:%d", rfbScreen->thisHost, rfbScreen->port-5900);
		    rfbWriteExact(&cl, str, strlen(str));

		} else if (compareAndSkip(&ptr, "$USER")) {
#ifndef WIN32
		    if (user) {
			rfbWriteExact(&cl, user,
				   strlen(user));
		    } else
#endif
			rfbWriteExact(&cl, "?", 1);
		} else if (compareAndSkip(&ptr, "$PARAMS")) {
		    if (params[0] != '\0')
			rfbWriteExact(&cl, params, strlen(params));
		} else {
		    if (!compareAndSkip(&ptr, "$$"))
			ptr++;

		    if (rfbWriteExact(&cl, "$", 1) < 0) {
			fclose(fd);
			httpCloseSock(rfbScreen);
			return;
		    }
		}
	    }
	    if (rfbWriteExact(&cl, ptr, (&buf[n] - ptr)) < 0)
		break;

	} else {

	    /* For files not ending .vnc, just write out the buffer */

	    if (rfbWriteExact(&cl, buf, n) < 0)
		break;
	}
    }

    fclose(fd);
    httpCloseSock(rfbScreen);
}
Exemplo n.º 7
0
int
rfbWriteExact(rfbClientPtr cl,
              const char *buf,
              int len)
{
    int sock = cl->sock;
    int n;
    fd_set fds;
    struct timeval tv;
    int totalTimeWaited = 0;

#undef DEBUG_WRITE_EXACT
#ifdef DEBUG_WRITE_EXACT
    rfbLog("WriteExact %d bytes\n",len);
    for(n=0; n<len; n++)
        fprintf(stderr,"%02x ",(unsigned char)buf[n]);
    fprintf(stderr,"\n");
#endif

    LOCK(cl->outputMutex);
    while (len > 0) {
        n = write(sock, buf, len);

        if (n > 0) {

            buf += n;
            len -= n;

        } else if (n == 0) {

            rfbErr("WriteExact: write returned 0?\n");
            return 0;

        } else {
#ifdef WIN32
            errno = WSAGetLastError();
#endif
            if (errno == EINTR)
                continue;

            if (errno != EWOULDBLOCK && errno != EAGAIN) {
                UNLOCK(cl->outputMutex);
                return n;
            }

            /* Retry every 5 seconds until we exceed rfbMaxClientWait.  We
               need to do this because select doesn't necessarily return
               immediately when the other end has gone away */

            FD_ZERO(&fds);
            FD_SET(sock, &fds);
            tv.tv_sec = 5;
            tv.tv_usec = 0;
            n = select(sock+1, NULL, &fds, NULL /* &fds */, &tv);
            if (n < 0) {
                if(errno==EINTR)
                    continue;
                rfbLogPerror("WriteExact: select");
                UNLOCK(cl->outputMutex);
                return n;
            }
            if (n == 0) {
                totalTimeWaited += 5000;
                if (totalTimeWaited >= rfbMaxClientWait) {
                    errno = ETIMEDOUT;
                    UNLOCK(cl->outputMutex);
                    return -1;
                }
            } else {
                totalTimeWaited = 0;
            }
        }
    }
    UNLOCK(cl->outputMutex);
    return 1;
}
Exemplo n.º 8
0
static void rfbssl_error(const char *msg, int e)
{
    rfbErr("%s: %s (%ld)\n", msg, gnutls_strerror(e), e);
}
Exemplo n.º 9
0
void rfbssl_log_func(int level, const char *msg)
{
    rfbErr("SSL: %s", msg);
}
Exemplo n.º 10
0
int
rfbConnectToTcpAddr(char *host,
                    int port)
{
    int sock;
#ifdef LIBVNCSERVER_IPv6
    struct addrinfo hints, *servinfo, *p;
    int rv;
    char port_str[8];

    snprintf(port_str, 8, "%d", port);

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;

    if ((rv = getaddrinfo(host, port_str, &hints, &servinfo)) != 0) {
        rfbErr("rfbConnectToTcpAddr: error in getaddrinfo: %s\n", gai_strerror(rv));
        return -1;
    }

    /* loop through all the results and connect to the first we can */
    for(p = servinfo; p != NULL; p = p->ai_next) {
        if ((sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0)
            continue;

        if (connect(sock, p->ai_addr, p->ai_addrlen) < 0) {
            closesocket(sock);
            continue;
        }

        break;
    }

    /* all failed */
    if (p == NULL) {
        rfbLogPerror("rfbConnectToTcoAddr: failed to connect\n");
        sock = -1; /* set return value */
    }

    /* all done with this structure now */
    freeaddrinfo(servinfo);
#else
    struct hostent *hp;
    struct sockaddr_in addr;

    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);

    if ((addr.sin_addr.s_addr = inet_addr(host)) == htonl(INADDR_NONE))
    {
	if (!(hp = gethostbyname(host))) {
	    errno = EINVAL;
	    return -1;
	}
	addr.sin_addr.s_addr = *(unsigned long *)hp->h_addr;
    }

    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
	return -1;
    }

    if (connect(sock, (struct sockaddr *)&addr, (sizeof(addr))) < 0) {
	closesocket(sock);
	return -1;
    }
#endif
    return sock;
}
Exemplo n.º 11
0
int
rfbListenOnTCP6Port(int port,
                    const char* iface)
{
#ifndef LIBVNCSERVER_IPv6
    rfbLogPerror("This LibVNCServer does not have IPv6 support");
    return -1;
#else
    int sock;
    int one = 1;
    int rv;
    struct addrinfo hints, *servinfo, *p;
    char port_str[8];

    snprintf(port_str, 8, "%d", port);

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_INET6;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE; /* fill in wildcard address if iface == NULL */

    if ((rv = getaddrinfo(iface, port_str, &hints, &servinfo)) != 0) {
        rfbErr("rfbListenOnTCP6Port error in getaddrinfo: %s\n", gai_strerror(rv));
        return -1;
    }
    
    /* loop through all the results and bind to the first we can */
    for(p = servinfo; p != NULL; p = p->ai_next) {
        if ((sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0) {
            continue;
        }

#ifdef IPV6_V6ONLY
	/* we have seperate IPv4 and IPv6 sockets since some OS's do not support dual binding */
	if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&one, sizeof(one)) < 0) {
	  rfbLogPerror("rfbListenOnTCP6Port error in setsockopt IPV6_V6ONLY");
	  closesocket(sock);
	  freeaddrinfo(servinfo);
	  return -1;
	}
#endif

	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)) < 0) {
	  rfbLogPerror("rfbListenOnTCP6Port: error in setsockopt SO_REUSEADDR");
	  closesocket(sock);
	  freeaddrinfo(servinfo);
	  return -1;
	}

	if (bind(sock, p->ai_addr, p->ai_addrlen) < 0) {
	  closesocket(sock);
	  continue;
	}

        break;
    }

    if (p == NULL)  {
        rfbLogPerror("rfbListenOnTCP6Port: error in bind IPv6 socket");
        freeaddrinfo(servinfo);
        return -1;
    }

    /* all done with this structure now */
    freeaddrinfo(servinfo);

    if (listen(sock, 32) < 0) {
        rfbLogPerror("rfbListenOnTCP6Port: error in listen on IPv6 socket");
	closesocket(sock);
	return -1;
    }

    return sock;
#endif
}
Exemplo n.º 12
0
int
rfbReadExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout)
{
    int sock = cl->sock;
    int n;
    fd_set fds;
    struct timeval tv;

    while (len > 0) {
#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
        if (cl->wsctx) {
            n = webSocketsDecode(cl, buf, len);
        } else if (cl->sslctx) {
	    n = rfbssl_read(cl, buf, len);
	} else {
            n = read(sock, buf, len);
        }
#else
        n = read(sock, buf, len);
#endif

        if (n > 0) {

            buf += n;
            len -= n;

        } else if (n == 0) {

            return 0;

        } else {
#ifdef WIN32
	    errno = WSAGetLastError();
#endif
	    if (errno == EINTR)
		continue;

#ifdef LIBVNCSERVER_ENOENT_WORKAROUND
	    if (errno != ENOENT)
#endif
            if (errno != EWOULDBLOCK && errno != EAGAIN) {
                return n;
            }

#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
	    if (cl->sslctx) {
		if (rfbssl_pending(cl))
		    continue;
	    }
#endif
            FD_ZERO(&fds);
            FD_SET(sock, &fds);
            tv.tv_sec = timeout / 1000;
            tv.tv_usec = (timeout % 1000) * 1000;
            n = select(sock+1, &fds, NULL, &fds, &tv);
            if (n < 0) {
                rfbLogPerror("ReadExact: select");
                return n;
            }
            if (n == 0) {
                rfbErr("ReadExact: select timeout\n");
                errno = ETIMEDOUT;
                return -1;
            }
        }
    }
#undef DEBUG_READ_EXACT
#ifdef DEBUG_READ_EXACT
    rfbLog("ReadExact %d bytes\n",len);
    for(n=0;n<len;n++)
	    fprintf(stderr,"%02x ",(unsigned char)buf[n]);
    fprintf(stderr,"\n");
#endif

    return 1;
}
Exemplo n.º 13
0
void
rfbHttpCheckFds(rfbScreenInfoPtr rfbScreen)
{
    int nfds;
    fd_set fds;
    struct timeval tv;
    struct sockaddr_in addr;
    socklen_t addrlen = sizeof(addr);

    if (!rfbScreen->httpDir)
	return;

    if (rfbScreen->httpListenSock < 0)
	return;

    FD_ZERO(&fds);
    FD_SET(rfbScreen->httpListenSock, &fds);
    if (rfbScreen->httpSock >= 0) {
	FD_SET(rfbScreen->httpSock, &fds);
    }
    tv.tv_sec = 0;
    tv.tv_usec = 0;
    nfds = select(max(rfbScreen->httpSock,rfbScreen->httpListenSock) + 1, &fds, NULL, NULL, &tv);
    if (nfds == 0) {
	return;
    }
    if (nfds < 0) {
#ifdef WIN32
		errno = WSAGetLastError();
#endif
	if (errno != EINTR)
		rfbLogPerror("httpCheckFds: select");
	return;
    }

    if ((rfbScreen->httpSock >= 0) && FD_ISSET(rfbScreen->httpSock, &fds)) {
	httpProcessInput(rfbScreen);
    }

    if (FD_ISSET(rfbScreen->httpListenSock, &fds)) {
        int flags;
	if (rfbScreen->httpSock >= 0) close(rfbScreen->httpSock);

	if ((rfbScreen->httpSock = accept(rfbScreen->httpListenSock,
			       (struct sockaddr *)&addr, &addrlen)) < 0) {
	    rfbLogPerror("httpCheckFds: accept");
	    return;
	}
#ifdef __MINGW32__
	rfbErr("O_NONBLOCK on MinGW32 NOT IMPLEMENTED");
#else
#ifdef USE_LIBWRAP
	if(!hosts_ctl("vnc",STRING_UNKNOWN,inet_ntoa(addr.sin_addr),
		      STRING_UNKNOWN)) {
	  rfbLog("Rejected HTTP connection from client %s\n",
		 inet_ntoa(addr.sin_addr));
#else
	flags = fcntl(rfbScreen->httpSock, F_GETFL);

	if (flags < 0 || fcntl(rfbScreen->httpSock, F_SETFL, flags | O_NONBLOCK) == -1) {
	    rfbLogPerror("httpCheckFds: fcntl");
#endif
	    close(rfbScreen->httpSock);
	    rfbScreen->httpSock = -1;
	    return;
	}

	flags=fcntl(rfbScreen->httpSock,F_GETFL);
	if(flags==-1 ||
	   fcntl(rfbScreen->httpSock,F_SETFL,flags|O_NONBLOCK)==-1) {
	  rfbLogPerror("httpCheckFds: fcntl");
	  close(rfbScreen->httpSock);
	  rfbScreen->httpSock=-1;
	  return;
	}
#endif

	/*AddEnabledDevice(httpSock);*/
    }
}


static void
httpCloseSock(rfbScreenInfoPtr rfbScreen)
{
    close(rfbScreen->httpSock);
    rfbScreen->httpSock = -1;
    buf_filled = 0;
}
Exemplo n.º 14
0
static rfbBool
rfbSendOneRectEncodingUltra(rfbClientPtr cl,
                           int x,
                           int y,
                           int w,
                           int h)
{
    rfbFramebufferUpdateRectHeader rect;
    rfbZlibHeader hdr;
    int deflateResult;
    int i;
    char *fbptr = (cl->scaledScreen->frameBuffer + (cl->scaledScreen->paddedWidthInBytes * y)
    	   + (x * (cl->scaledScreen->bitsPerPixel / 8)));

    int maxRawSize;
    lzo_uint maxCompSize;

    maxRawSize = (w * h * (cl->format.bitsPerPixel / 8));

    if (cl->beforeEncBufSize < maxRawSize) {
	cl->beforeEncBufSize = maxRawSize;
	if (cl->beforeEncBuf == NULL)
	    cl->beforeEncBuf = (char *)malloc(cl->beforeEncBufSize);
	else
	    cl->beforeEncBuf = (char *)realloc(cl->beforeEncBuf, cl->beforeEncBufSize);
    }

    /*
     * lzo requires output buffer to be slightly larger than the input
     * buffer, in the worst case.
     */
    maxCompSize = (maxRawSize + maxRawSize / 16 + 64 + 3);

    if (cl->afterEncBufSize < (int)maxCompSize) {
	cl->afterEncBufSize = maxCompSize;
	if (cl->afterEncBuf == NULL)
	    cl->afterEncBuf = (char *)malloc(cl->afterEncBufSize);
	else
	    cl->afterEncBuf = (char *)realloc(cl->afterEncBuf, cl->afterEncBufSize);
    }

    /* 
     * Convert pixel data to client format.
     */
    (*cl->translateFn)(cl->translateLookupTable, &cl->screen->serverFormat,
		       &cl->format, fbptr, cl->beforeEncBuf,
		       cl->scaledScreen->paddedWidthInBytes, w, h);

    if ( cl->compStreamInitedLZO == FALSE ) {
        cl->compStreamInitedLZO = TRUE;
        /* Work-memory needed for compression. Allocate memory in units
         * of `lzo_align_t' (instead of `char') to make sure it is properly aligned.
         */  
        cl->lzoWrkMem = malloc(sizeof(lzo_align_t) * (((LZO1X_1_MEM_COMPRESS) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t)));
    }

    /* Perform the compression here. */
    deflateResult = lzo1x_1_compress((unsigned char *)cl->beforeEncBuf, (lzo_uint)(w * h * (cl->format.bitsPerPixel / 8)), (unsigned char *)cl->afterEncBuf, &maxCompSize, cl->lzoWrkMem);
    /* maxCompSize now contains the compressed size */

    /* Find the total size of the resulting compressed data. */
    cl->afterEncBufLen = maxCompSize;

    if ( deflateResult != LZO_E_OK ) {
        rfbErr("lzo deflation error: %d\n", deflateResult);
        return FALSE;
    }

    /* Update statics */
    rfbStatRecordEncodingSent(cl, rfbEncodingUltra, sz_rfbFramebufferUpdateRectHeader + sz_rfbZlibHeader + cl->afterEncBufLen, maxRawSize);

    if (cl->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbZlibHeader
	> UPDATE_BUF_SIZE)
    {
	if (!rfbSendUpdateBuf(cl))
	    return FALSE;
    }

    rect.r.x = Swap16IfLE(x);
    rect.r.y = Swap16IfLE(y);
    rect.r.w = Swap16IfLE(w);
    rect.r.h = Swap16IfLE(h);
    rect.encoding = Swap32IfLE(rfbEncodingUltra);

    memcpy(&cl->updateBuf[cl->ublen], (char *)&rect,
	   sz_rfbFramebufferUpdateRectHeader);
    cl->ublen += sz_rfbFramebufferUpdateRectHeader;

    hdr.nBytes = Swap32IfLE(cl->afterEncBufLen);

    memcpy(&cl->updateBuf[cl->ublen], (char *)&hdr, sz_rfbZlibHeader);
    cl->ublen += sz_rfbZlibHeader;

    /* We might want to try sending the data directly... */
    for (i = 0; i < cl->afterEncBufLen;) {

	int bytesToCopy = UPDATE_BUF_SIZE - cl->ublen;

	if (i + bytesToCopy > cl->afterEncBufLen) {
	    bytesToCopy = cl->afterEncBufLen - i;
	}

	memcpy(&cl->updateBuf[cl->ublen], &cl->afterEncBuf[i], bytesToCopy);

	cl->ublen += bytesToCopy;
	i += bytesToCopy;

	if (cl->ublen == UPDATE_BUF_SIZE) {
	    if (!rfbSendUpdateBuf(cl))
		return FALSE;
	}
    }

    return TRUE;

}