diff --git a/ChangeLog b/ChangeLog index 9c05e45..31568e8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +2004-12-02 Johannes E. Schindelin + * make LibVNCServer compile & work on MinGW32 + 2004-11-30 "Leiradella, Andre V Matos Da Cunha" * libvncclient/sockets.c: return TRUE in every case of success diff --git a/TODO b/TODO index 113204f..ffd9ce8 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,7 @@ immediate: ---------- +MinGW32 doesn't do fcntl on sockets; use setsockopt instead... always undraw cursor after sending updates, but do not mark region as modified. add automatic tests (plasma?) if preferredEncoding is set outside of libvncserver, don't override it. diff --git a/client_examples/Makefile.am b/client_examples/Makefile.am index 12ec911..1a6cdc5 100644 --- a/client_examples/Makefile.am +++ b/client_examples/Makefile.am @@ -1,5 +1,5 @@ DEFINES=-I.. -g -Wall -LDADD = ../libvncclient/libvncclient.a +LDADD = ../libvncclient/libvncclient.a @WSOCKLIB@ if WITH_FFMPEG FFMPEG_HOME=@with_ffmpeg@ diff --git a/client_examples/SDLvncviewer.c b/client_examples/SDLvncviewer.c index 401c42f..9bfb1c9 100644 --- a/client_examples/SDLvncviewer.c +++ b/client_examples/SDLvncviewer.c @@ -1,4 +1,4 @@ -#include +#include #include static rfbBool resize(rfbClient* client) { @@ -186,6 +186,46 @@ void update(rfbClient* cl,int x,int y,int w,int h) { SDL_UpdateRect(cl->clientData, x, y, w, h); } +#ifdef __MINGW32__ +#define LOG_TO_FILE +#endif + +#ifdef LOG_TO_FILE +#include +static void +log_to_file(const char *format, ...) +{ + FILE* logfile; + static char* logfile_str=0; + va_list args; + char buf[256]; + time_t log_clock; + + if(!rfbEnableClientLogging) + return; + + if(logfile_str==0) { + logfile_str=getenv("VNCLOG"); + if(logfile_str==0) + logfile_str="vnc.log"; + } + + logfile=fopen(logfile_str,"a"); + + va_start(args, format); + + time(&log_clock); + strftime(buf, 255, "%d/%m/%Y %X ", localtime(&log_clock)); + fprintf(logfile,buf); + + vfprintf(logfile, format, args); + fflush(logfile); + + va_end(args); + fclose(logfile); +} +#endif + #ifdef mac #define main SDLmain #endif @@ -195,6 +235,10 @@ int main(int argc,char** argv) { int i,buttonMask=0; SDL_Event e; +#ifdef LOG_TO_FILE + rfbClientLog=rfbClientErr=log_to_file; +#endif + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE); cl=rfbGetClient(5,3,2); diff --git a/configure.ac b/configure.ac index 77ee436..58fdd7e 100644 --- a/configure.ac +++ b/configure.ac @@ -32,7 +32,6 @@ fi AH_TEMPLATE(FFMPEG, [Use ffmpeg (for vnc2mpg)]) AC_ARG_WITH(ffmpeg, [ --with-ffmpeg=dir set ffmpeg home directory],,) -#AM_DEFINE(FFMPEG, "$with_ffmpeg") AC_SUBST(with_ffmpeg) AM_CONDITIONAL(WITH_FFMPEG, test ! -z "$with_ffmpeg") @@ -143,6 +142,13 @@ AM_CONDITIONAL(HAVE_LIBSDL, test "x$with_sdl" = "xyes") AC_SUBST(SDL_CFLAGS) AC_SUBST(SDL_LIBS) +MINGW=`uname -s | grep MINGW 2>/dev/null` +AM_CONDITIONAL(MINGW, test ! -z "$MINGW" ) +if test ! -z "$MINGW"; then + WSOCKLIB="-lws2_32" +fi +AC_SUBST(WSOCKLIB) + # Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h sys/time.h sys/timeb.h syslog.h unistd.h]) diff --git a/contrib/Makefile.am b/contrib/Makefile.am index 5add61c..45a9510 100644 --- a/contrib/Makefile.am +++ b/contrib/Makefile.am @@ -1,5 +1,5 @@ DEFINES = -I .. -LDADD = ../libvncserver/libvncserver.a +LDADD = ../libvncserver/libvncserver.a @WSOCKLIB@ noinst_PROGRAMS=zippy diff --git a/examples/Makefile.am b/examples/Makefile.am index ff816ac..468e223 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -1,5 +1,5 @@ DEFINES=-I.. -g -Wall -LDADD = ../libvncserver/libvncserver.a +LDADD = ../libvncserver/libvncserver.a @WSOCKLIB@ if OSX MAC=mac diff --git a/examples/vncev.c b/examples/vncev.c index e032529..5d7fb1b 100644 --- a/examples/vncev.c +++ b/examples/vncev.c @@ -2,7 +2,9 @@ #include #include #include +#ifndef __MINGW32__ #include +#endif #include #include diff --git a/libvncclient/listen.c b/libvncclient/listen.c index a7e4259..dc6508c 100644 --- a/libvncclient/listen.c +++ b/libvncclient/listen.c @@ -23,9 +23,13 @@ #include #include +#ifdef __MINGW32__ +#include +#else #include -#include #include +#endif +#include #include /* @@ -36,6 +40,11 @@ void listenForIncomingConnections(rfbClient* client) { +#ifdef __MINGW32__ + /* FIXME */ + rfbClientErr("listenForIncomingConnections on MinGW32 NOT IMPLEMENTED\n"); + return; +#else int listenSocket; fd_set fds; @@ -77,7 +86,7 @@ listenForIncomingConnections(rfbClient* client) switch (fork()) { case -1: - rfbClientErr("fork"); + rfbClientErr("fork\n"); return; case 0: @@ -92,6 +101,7 @@ listenForIncomingConnections(rfbClient* client) } } } +#endif } diff --git a/libvncclient/rfbproto.c b/libvncclient/rfbproto.c index 0f12407..40783c6 100644 --- a/libvncclient/rfbproto.c +++ b/libvncclient/rfbproto.c @@ -25,7 +25,9 @@ #include #include +#ifndef __MINGW32__ #include +#endif #include #ifdef LIBVNCSERVER_HAVE_LIBZ #include diff --git a/libvncclient/sockets.c b/libvncclient/sockets.c index 13cb770..efe7eb9 100644 --- a/libvncclient/sockets.c +++ b/libvncclient/sockets.c @@ -22,15 +22,23 @@ */ #include -#include #include +#include +#include +#include +#ifdef WIN32 +#include +#define EWOULDBLOCK WSAEWOULDBLOCK +#define close closesocket +#define read(sock,buf,len) recv(sock,buf,len,0) +#define write(sock,buf,len) send(sock,buf,len,0) +#else +#include #include #include #include #include -#include -#include -#include +#endif void PrintInHex(char *buf, int len); @@ -81,7 +89,12 @@ ReadFromRFBServer(rfbClient* client, char *out, unsigned int n) diff.tv_usec+=1000000; } sleep (diff.tv_sec); +#ifndef __MINGW32__ + /* FIXME */ usleep (diff.tv_usec); +#else + rfbClientErr("usleep on MinGW32 NOT IMPLEMENTED\n"); +#endif } rec->tv=tv; @@ -114,13 +127,16 @@ ReadFromRFBServer(rfbClient* client, char *out, unsigned int n) int i = read(client->sock, client->buf + client->buffered, RFB_BUF_SIZE - client->buffered); if (i <= 0) { if (i < 0) { +#ifdef WIN32 + errno=WSAGetLastError(); +#endif if (errno == EWOULDBLOCK || errno == EAGAIN) { /* TODO: ProcessXtEvents(); */ i = 0; } else { - rfbClientErr("read"); + rfbClientErr("read (%d: %s)\n",errno,strerror(errno)); return FALSE; } } else { @@ -143,13 +159,16 @@ ReadFromRFBServer(rfbClient* client, char *out, unsigned int n) int i = read(client->sock, out, n); if (i <= 0) { if (i < 0) { +#ifdef WIN32 + errno=WSAGetLastError(); +#endif if (errno == EWOULDBLOCK || errno == EAGAIN) { /* TODO: ProcessXtEvents(); */ i = 0; } else { - rfbClientErr("read"); + rfbClientErr("read (%s)\n",strerror(errno)); return FALSE; } } else { @@ -200,12 +219,12 @@ WriteToRFBServer(rfbClient* client, char *buf, int n) FD_SET(client->sock,&fds); if (select(client->sock+1, NULL, &fds, NULL, NULL) <= 0) { - rfbClientErr("select"); + rfbClientErr("select\n"); return FALSE; } j = 0; } else { - rfbClientErr("write"); + rfbClientErr("write\n"); return FALSE; } } else { @@ -230,25 +249,41 @@ ConnectClientToTcpAddr(unsigned int host, int port) struct sockaddr_in addr; int one = 1; +#ifdef WIN32 + WSADATA trash; + static rfbBool WSAinitted=FALSE; + if(!WSAinitted) { + WSAinitted=TRUE; + int i=WSAStartup(MAKEWORD(2,0),&trash); + if(i!=0) { + rfbClientErr("Couldn't init Windows Sockets\n"); + return -1; + } + } +#endif + addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = host; sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { - rfbClientErr("ConnectToTcpAddr: socket"); +#ifdef WIN32 + errno=WSAGetLastError(); +#endif + rfbClientErr("ConnectToTcpAddr: socket (%s)\n",strerror(errno)); return -1; } if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - rfbClientErr("ConnectToTcpAddr: connect"); + rfbClientErr("ConnectToTcpAddr: connect\n"); close(sock); return -1; } if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one)) < 0) { - rfbClientErr("ConnectToTcpAddr: setsockopt"); + rfbClientErr("ConnectToTcpAddr: setsockopt\n"); close(sock); return -1; } @@ -274,7 +309,7 @@ FindFreeTcpPort(void) sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { - rfbClientErr(": FindFreeTcpPort: socket"); + rfbClientErr(": FindFreeTcpPort: socket\n"); return 0; } @@ -308,25 +343,25 @@ ListenAtTcpPort(int port) sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { - rfbClientErr("ListenAtTcpPort: socket"); + rfbClientErr("ListenAtTcpPort: socket\n"); return -1; } if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&one, sizeof(one)) < 0) { - rfbClientErr("ListenAtTcpPort: setsockopt"); + rfbClientErr("ListenAtTcpPort: setsockopt\n"); close(sock); return -1; } if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - rfbClientErr("ListenAtTcpPort: bind"); + rfbClientErr("ListenAtTcpPort: bind\n"); close(sock); return -1; } if (listen(sock, 5) < 0) { - rfbClientErr("ListenAtTcpPort: listen"); + rfbClientErr("ListenAtTcpPort: listen\n"); close(sock); return -1; } @@ -349,13 +384,13 @@ AcceptTcpConnection(int listenSock) sock = accept(listenSock, (struct sockaddr *) &addr, &addrlen); if (sock < 0) { - rfbClientErr("AcceptTcpConnection: accept"); + rfbClientErr("AcceptTcpConnection: accept\n"); return -1; } if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one)) < 0) { - rfbClientErr("AcceptTcpConnection: setsockopt"); + rfbClientErr("AcceptTcpConnection: setsockopt\n"); close(sock); return -1; } @@ -371,10 +406,14 @@ AcceptTcpConnection(int listenSock) rfbBool SetNonBlocking(int sock) { +#ifndef __MINGW32__ if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) { - rfbClientErr("AcceptTcpConnection: fcntl"); + rfbClientErr("AcceptTcpConnection: fcntl\n"); return FALSE; } +#else + rfbClientErr("O_NONBLOCK on MinGW32 NOT IMPLEMENTED\n"); +#endif return TRUE; } diff --git a/libvncclient/vncviewer.c b/libvncclient/vncviewer.c index 2a11970..c97b234 100644 --- a/libvncclient/vncviewer.c +++ b/libvncclient/vncviewer.c @@ -37,9 +37,18 @@ static void DummyRect(rfbClient* client, int x, int y, int w, int h) { static char* NoPassword(rfbClient* client) { return strdup(""); } + +#ifndef __MINGW32__ #include #include +#endif + static char* ReadPassword(rfbClient* client) { +#ifdef __MINGW32__ + /* FIXME */ + rfbClientErr("ReadPassword on MinGW32 NOT IMPLEMENTED\n"); + return NoPassword(client); +#else int i; char* p=malloc(9); struct termios save,noecho; @@ -61,6 +70,7 @@ static char* ReadPassword(rfbClient* client) { } tcsetattr(fileno(stdin),TCSAFLUSH,&save); return p; +#endif } static rfbBool MallocFrameBuffer(rfbClient* client) { if(client->frameBuffer) @@ -196,7 +206,8 @@ rfbBool rfbInitClient(rfbClient* client,int* argc,char** argv) { char* colon=strchr(argv[i],':'); if(colon) { - client->serverHost=strndup(argv[i],(int)(colon-argv[i])); + client->serverHost=strdup(argv[i]); + client->serverHost[(int)(colon-argv[i])]='\0'; client->serverPort=atoi(colon+1); } else { client->serverHost=strdup(argv[i]); diff --git a/libvncserver-config.in b/libvncserver-config.in index be7ef1c..13fc4c1 100644 --- a/libvncserver-config.in +++ b/libvncserver-config.in @@ -60,7 +60,7 @@ while test $# -gt 0; do else libdirs="-L$libdir" fi - echo "$libdirs" -lvncserver @LIBS@ + echo "$libdirs" -lvncserver @LIBS@ @WSOCKLIB@ ;; --link) echo @CC@ diff --git a/libvncserver/httpd.c b/libvncserver/httpd.c index 13588b4..e169c30 100755 --- a/libvncserver/httpd.c +++ b/libvncserver/httpd.c @@ -161,6 +161,9 @@ rfbHttpCheckFds(rfbScreenInfoPtr rfbScreen) 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)) { @@ -176,6 +179,7 @@ rfbHttpCheckFds(rfbScreenInfoPtr rfbScreen) rfbScreen->httpSock = -1; return; } + flags=fcntl(rfbScreen->httpSock,F_GETFL); if(flags==-1 || fcntl(rfbScreen->httpSock,F_SETFL,flags|O_NONBLOCK)==-1) { @@ -184,6 +188,7 @@ rfbHttpCheckFds(rfbScreenInfoPtr rfbScreen) rfbScreen->httpSock=-1; return; } +#endif /*AddEnabledDevice(httpSock);*/ } diff --git a/libvncserver/main.c b/libvncserver/main.c index 97f0bc7..96aeda7 100644 --- a/libvncserver/main.c +++ b/libvncserver/main.c @@ -762,8 +762,10 @@ void rfbInitServer(rfbScreenInfoPtr screen) #endif rfbInitSockets(screen); rfbHttpInitSockets(screen); +#ifndef __MINGW32__ if(screen->ignoreSIGPIPE) signal(SIGPIPE,SIG_IGN); +#endif } #ifndef LIBVNCSERVER_HAVE_GETTIMEOFDAY diff --git a/libvncserver/sockets.c b/libvncserver/sockets.c index 5ded1c7..0937097 100755 --- a/libvncserver/sockets.c +++ b/libvncserver/sockets.c @@ -45,14 +45,6 @@ #include #endif -#ifdef WIN32 -#pragma warning (disable: 4018 4761) -#define close closesocket -#define read(sock,buf,len) recv(sock,buf,len,0) -#define EWOULDBLOCK WSAEWOULDBLOCK -#define ETIMEDOUT WSAETIMEDOUT -#define write(sock,buf,len) send(sock,buf,len,0) -#else #ifdef LIBVNCSERVER_HAVE_SYS_TIME_H #include #endif @@ -68,7 +60,6 @@ #ifdef LIBVNCSERVER_HAVE_UNISTD_H #include #endif -#endif #if defined(__linux__) && defined(NEED_TIMEVAL) struct timeval @@ -91,10 +82,14 @@ int allow_severity=LOG_INFO; int deny_severity=LOG_WARNING; #endif -/*#ifndef WIN32 -int max(int i,int j) { return(iscreen->maxFd>0 && !FD_ISSET(cl->screen->maxFd,&(cl->screen->allFds))) cl->screen->maxFd--; +#ifndef __MINGW32__ shutdown(cl->sock,SHUT_RDWR); +#endif close(cl->sock); cl->sock = -1; } @@ -414,7 +411,7 @@ rfbReadExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout) } else { #ifdef WIN32 - errno = WSAGetLastError(); + errno = WSAGetLastError(); #endif if (errno == EINTR) continue; diff --git a/rfb/rfb.h b/rfb/rfb.h index 22e2fba..16315d4 100644 --- a/rfb/rfb.h +++ b/rfb/rfb.h @@ -41,6 +41,10 @@ extern "C" #include #endif +#ifdef __MINGW32__ +#include +#endif + #ifdef LIBVNCSERVER_HAVE_LIBPTHREAD #include #if 0 /* debugging */ @@ -208,7 +212,7 @@ typedef struct _rfbScreenInfo SOCKET listenSock; int maxSock; int maxFd; - fd_set allFds; + struct fd_set allFds; rfbBool socketInitDone; SOCKET inetdSock; diff --git a/rfb/rfbproto.h b/rfb/rfbproto.h index 07d0c52..a6ff83f 100644 --- a/rfb/rfbproto.h +++ b/rfb/rfbproto.h @@ -47,7 +47,7 @@ */ -#if defined(WIN32) +#if defined(WIN32) && !defined(__MINGW32__) #define LIBVNCSERVER_WORDS_BIGENDIAN #define rfbBool int #include @@ -65,7 +65,7 @@ #endif -#if !defined(WIN32) +#if !defined(WIN32) || defined(__MINGW32__) #define max(a,b) (((a)>(b))?(a):(b)) #ifdef LIBVNCSERVER_HAVE_SYS_TIME_H #include diff --git a/test/Makefile.am b/test/Makefile.am index c2d04c4..1084cb8 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,14 +1,14 @@ DEFINES=-I.. -g -Wall +LDADD = ../libvncserver/libvncserver.a ../libvncclient/libvncclient.a @WSOCKLIB@ if HAVE_LIBPTHREAD BACKGROUND_TEST=blooptest +ENCODINGS_TEST=encodingstest endif copyrecttest_LDADD=$(LDADD) -lm -noinst_PROGRAMS=encodingstest cargstest copyrecttest $(BACKGROUND_TEST) - -LDADD = ../libvncserver/libvncserver.a ../libvncclient/libvncclient.a +noinst_PROGRAMS=$(ENCODINGS_TEST) cargstest copyrecttest $(BACKGROUND_TEST) test: encodingstest cargstest copyrecttest ./encodingstest && ./cargstest diff --git a/vncterm/Makefile.am b/vncterm/Makefile.am index 3a631ab..5d4135b 100644 --- a/vncterm/Makefile.am +++ b/vncterm/Makefile.am @@ -4,7 +4,7 @@ noinst_HEADERS=VNConsole.h vga.h CFLAGS_ADD=-I.. -LDADD=../libvncserver/libvncserver.a +LDADD=../libvncserver/libvncserver.a @WSOCKLIB@ INCLUDES=-I. if LINUX @@ -12,7 +12,13 @@ bin_PROGRAMS=LinuxVNC LinuxVNC_SOURCES=LinuxVNC.c $(CONSOLE_SRCS) endif -noinst_PROGRAMS=VNCommand example -VNCommand_SOURCES=VNCommand.c $(CONSOLE_SRCS) +if ! MINGW +VNCOMMAND=VNCommand +endif + +noinst_PROGRAMS=example $(VNCOMMAND) example_SOURCES=example.c $(CONSOLE_SRCS) +VNCommand_SOURCES=VNCommand.c $(CONSOLE_SRCS) + + diff --git a/x11vnc/Makefile.am b/x11vnc/Makefile.am index dd4cfaa..224d20f 100644 --- a/x11vnc/Makefile.am +++ b/x11vnc/Makefile.am @@ -1,5 +1,5 @@ DEFINES = -I .. -LDADD = ../libvncserver/libvncserver.a +LDADD = ../libvncserver/libvncserver.a @WSOCKLIB@ man_MANS=x11vnc.1 EXTRA_DIST=ChangeLog README $(man_MANS)