diff options
Diffstat (limited to 'xrdpapi/xrdpapi.c')
-rw-r--r-- | xrdpapi/xrdpapi.c | 406 |
1 files changed, 225 insertions, 181 deletions
diff --git a/xrdpapi/xrdpapi.c b/xrdpapi/xrdpapi.c index 85a13a8e..e320ef5d 100644 --- a/xrdpapi/xrdpapi.c +++ b/xrdpapi/xrdpapi.c @@ -1,8 +1,8 @@ /** * xrdp: A Remote Desktop Protocol server. * - * Copyright (C) Thomas Goddard 2012 * Copyright (C) Jay Sorg 2012 + * Copyright (C) Laxmikant Rashinkar 2012 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,8 +17,6 @@ * limitations under the License. */ -/* do not use os_calls in here */ - #define LOG_LEVEL 1 #define LLOG(_level, _args) \ do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) @@ -29,6 +27,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <stdint.h> #include <fcntl.h> #include <errno.h> #include <sys/types.h> @@ -40,69 +39,31 @@ struct wts_obj { - int fd; - int status; - char name[8]; - char dname[128]; - int display_num; - int flags; + int fd; + int status; + char name[8]; + char dname[128]; + int display_num; + uint32_t flags; }; -/*****************************************************************************/ -static int -get_display_num_from_display(char *display_text) -{ - int index; - int mode; - int host_index; - int disp_index; - int scre_index; - char host[256]; - char disp[256]; - char scre[256]; - - index = 0; - host_index = 0; - disp_index = 0; - scre_index = 0; - mode = 0; +/* helper functions used by WTSxxx API - do not invoke directly */ +static int get_display_num_from_display(char *display_text); +static int send_init(struct wts_obj *wts); +static int can_send(int sck, int millis); +static int can_recv(int sck, int millis); - while (display_text[index] != 0) - { - if (display_text[index] == ':') - { - mode = 1; - } - else if (display_text[index] == '.') - { - mode = 2; - } - else if (mode == 0) - { - host[host_index] = display_text[index]; - host_index++; - } - else if (mode == 1) - { - disp[disp_index] = display_text[index]; - disp_index++; - } - else if (mode == 2) - { - scre[scre_index] = display_text[index]; - scre_index++; - } - - index++; - } - - host[host_index] = 0; - disp[disp_index] = 0; - scre[scre_index] = 0; - return atoi(disp); -} - -/*****************************************************************************/ +/* + * Opens a handle to the server end of a specified virtual channel - this + * call is deprecated - use WTSVirtualChannelOpenEx() instead + * + * @param hServer + * @param SessionId - current session ID; *must* be WTS_CURRENT_SERVER_HANDLE + * @param pVirtualName - virtual channel name when using SVC + * - name of endpoint listener when using DVC + * + * @return a valid pointer on success, NULL on error + ******************************************************************************/ void * WTSVirtualChannelOpen(void *hServer, unsigned int SessionId, const char *pVirtualName) @@ -115,98 +76,34 @@ WTSVirtualChannelOpen(void *hServer, unsigned int SessionId, return WTSVirtualChannelOpenEx(SessionId, pVirtualName, 0); } -/*****************************************************************************/ -static int -can_send(int sck, int millis) -{ - struct timeval time; - fd_set wfds; - int select_rv; - - FD_ZERO(&wfds); - FD_SET(sck, &wfds); - time.tv_sec = millis / 1000; - time.tv_usec = (millis * 1000) % 1000000; - select_rv = select(sck + 1, 0, &wfds, 0, &time); - - if (select_rv > 0) - { - return 1; - } - - return 0; -} - -/*****************************************************************************/ -static int -can_recv(int sck, int millis) -{ - struct timeval time; - fd_set rfds; - int select_rv; - - FD_ZERO(&rfds); - FD_SET(sck, &rfds); - time.tv_sec = millis / 1000; - time.tv_usec = (millis * 1000) % 1000000; - select_rv = select(sck + 1, &rfds, 0, 0, &time); - - if (select_rv > 0) - { - return 1; - } - - return 0; -} - -/*****************************************************************************/ -static int -send_init(struct wts_obj *wts) -{ - char initmsg[64]; - - memset(initmsg, 0, 64); - strncpy(initmsg, wts->name, 8); - initmsg[16] = (wts->flags >> 0) & 0xff; - initmsg[17] = (wts->flags >> 8) & 0xff; - initmsg[18] = (wts->flags >> 16) & 0xff; - initmsg[19] = (wts->flags >> 24) & 0xff; - LLOGLN(10, ("send_init: sending %s", initmsg)); - - if (!can_send(wts->fd, 500)) - { - return 1; - } - - if (send(wts->fd, initmsg, 64, 0) != 64) - { - return 1; - } - - LLOGLN(10, ("send_init: send ok!")); - return 0; -} - -/*****************************************************************************/ +/* + * Opens a handle to the server end of a specified virtual channel + * + * @param SessionId - current session ID; *must* be WTS_CURRENT_SERVER_HANDLE + * @param pVirtualName - virtual channel name when using SVC + * - name of endpoint listener when using DVC + * @param flags - type of channel and channel priority if DVC + * + * @return a valid pointer on success, NULL on error + ******************************************************************************/ void * -WTSVirtualChannelOpenEx(unsigned int SessionId, - const char *pVirtualName, +WTSVirtualChannelOpenEx(unsigned int SessionId, const char *pVirtualName, unsigned int flags) { - struct wts_obj *wts; - char *display_text; - struct sockaddr_un s; - int bytes; - unsigned long llong; + struct wts_obj *wts; + char *display_text; + int bytes; + unsigned long llong; + struct sockaddr_un s; if (SessionId != WTS_CURRENT_SESSION) { - LLOGLN(0, ("WTSVirtualChannelOpenEx: SessionId bad")); + LLOGLN(0, ("WTSVirtualChannelOpenEx: bad SessionId")); return 0; } - wts = (struct wts_obj *)malloc(sizeof(struct wts_obj)); - memset(wts, 0, sizeof(struct wts_obj)); + wts = (struct wts_obj *) calloc(1, sizeof(struct wts_obj)); + wts->fd = -1; wts->flags = flags; display_text = getenv("DISPLAY"); @@ -216,37 +113,40 @@ WTSVirtualChannelOpenEx(unsigned int SessionId, wts->display_num = get_display_num_from_display(display_text); } - if (wts->display_num > 0) + if (wts->display_num <= 0) { - wts->fd = socket(AF_UNIX, SOCK_STREAM, 0); - /* set non blocking */ - llong = fcntl(wts->fd, F_GETFL); - llong = llong | O_NONBLOCK; - fcntl(wts->fd, F_SETFL, llong); - /* connect to session chansrv */ - memset(&s, 0, sizeof(struct sockaddr_un)); - s.sun_family = AF_UNIX; - bytes = sizeof(s.sun_path); - snprintf(s.sun_path, bytes - 1, "/tmp/.xrdp/xrdpapi_%d", wts->display_num); - s.sun_path[bytes - 1] = 0; - bytes = sizeof(struct sockaddr_un); - - if (connect(wts->fd, (struct sockaddr *)&s, bytes) == 0) - { - LLOGLN(10, ("WTSVirtualChannelOpenEx: connected ok, name %s", pVirtualName)); - strncpy(wts->name, pVirtualName, 8); - - /* wait for connection to complete and send init */ - if (send_init(wts) == 0) - { - /* all ok */ - wts->status = 1; - } - } + LLOGLN(0, ("WTSVirtualChannelOpenEx: fatal errror; display is 0")); + free(wts); + return NULL; } - else + + /* we use unix domain socket to communicate with chansrv */ + wts->fd = socket(AF_UNIX, SOCK_STREAM, 0); + + /* set non blocking */ + llong = fcntl(wts->fd, F_GETFL); + llong = llong | O_NONBLOCK; + fcntl(wts->fd, F_SETFL, llong); + + /* connect to chansrv session */ + memset(&s, 0, sizeof(struct sockaddr_un)); + s.sun_family = AF_UNIX; + bytes = sizeof(s.sun_path); + snprintf(s.sun_path, bytes - 1, "/tmp/.xrdp/xrdpapi_%d", wts->display_num); + s.sun_path[bytes - 1] = 0; + bytes = sizeof(struct sockaddr_un); + + if (connect(wts->fd, (struct sockaddr *) &s, bytes) == 0) { - LLOGLN(0, ("WTSVirtualChannelOpenEx: display is 0")); + LLOGLN(10, ("WTSVirtualChannelOpenEx: connected ok, name %s", pVirtualName)); + strncpy(wts->name, pVirtualName, 8); + + /* wait for connection to complete and send init */ + if (send_init(wts) == 0) + { + /* all ok */ + wts->status = 1; + } } return wts; @@ -312,7 +212,7 @@ WTSVirtualChannelRead(void *hChannelHandle, unsigned int TimeOut, unsigned int *pBytesRead) { struct wts_obj *wts; - int error; + int rv; int lerrno; wts = (struct wts_obj *)hChannelHandle; @@ -329,9 +229,9 @@ WTSVirtualChannelRead(void *hChannelHandle, unsigned int TimeOut, if (can_recv(wts->fd, TimeOut)) { - error = recv(wts->fd, Buffer, BufferSize, 0); + rv = recv(wts->fd, Buffer, BufferSize, 0); - if (error == -1) + if (rv == -1) { lerrno = errno; @@ -341,16 +241,15 @@ WTSVirtualChannelRead(void *hChannelHandle, unsigned int TimeOut, *pBytesRead = 0; return 1; } - return 0; } - else if (error == 0) + else if (rv == 0) { return 0; } - else if (error > 0) + else if (rv > 0) { - *pBytesRead = error; + *pBytesRead = rv; return 1; } } @@ -419,3 +318,148 @@ WTSFreeMemory(void *pMemory) free(pMemory); } } + +/***************************************************************************** +** ** +** ** +** Helper functions used by WTSxxx API - do not invoke directly ** +** ** +** ** +*****************************************************************************/ + +/* + * check if socket is in a writable state - i.e will not block on write + * + * @param sck socket to check + * @param millis timeout value in milliseconds + * + * @return 0 if write will block + * @return 1 if write will not block + ******************************************************************************/ +static int +can_send(int sck, int millis) +{ + struct timeval time; + fd_set wfds; + int select_rv; + + /* setup for a select call */ + FD_ZERO(&wfds); + FD_SET(sck, &wfds); + time.tv_sec = millis / 1000; + time.tv_usec = (millis * 1000) % 1000000; + + /* check if it is ok to write to specified socket */ + select_rv = select(sck + 1, 0, &wfds, 0, &time); + + return (select_rv > 0) ? 1 : 0; +} + +/*****************************************************************************/ +static int +can_recv(int sck, int millis) +{ + struct timeval time; + fd_set rfds; + int select_rv; + + FD_ZERO(&rfds); + FD_SET(sck, &rfds); + time.tv_sec = millis / 1000; + time.tv_usec = (millis * 1000) % 1000000; + select_rv = select(sck + 1, &rfds, 0, 0, &time); + + if (select_rv > 0) + { + return 1; + } + + return 0; +} + +/*****************************************************************************/ +static int +send_init(struct wts_obj *wts) +{ + char initmsg[64]; + + memset(initmsg, 0, 64); + + /* insert channel name */ + strncpy(initmsg, wts->name, 8); + + /* insert open mode flags */ + initmsg[16] = (wts->flags >> 0) & 0xff; + initmsg[17] = (wts->flags >> 8) & 0xff; + initmsg[18] = (wts->flags >> 16) & 0xff; + initmsg[19] = (wts->flags >> 24) & 0xff; + + if (!can_send(wts->fd, 500)) + { + LLOGLN(10, ("send_init: send() will block!")); + return 1; + } + + if (send(wts->fd, initmsg, 64, 0) != 64) + { + LLOGLN(10, ("send_init: send() failed!")); + return 1; + } + + LLOGLN(10, ("send_init: sent ok!")); + return 0; +} + +/*****************************************************************************/ +static int +get_display_num_from_display(char *display_text) +{ + int index; + int mode; + int host_index; + int disp_index; + int scre_index; + char host[256]; + char disp[256]; + char scre[256]; + + index = 0; + host_index = 0; + disp_index = 0; + scre_index = 0; + mode = 0; + + while (display_text[index] != 0) + { + if (display_text[index] == ':') + { + mode = 1; + } + else if (display_text[index] == '.') + { + mode = 2; + } + else if (mode == 0) + { + host[host_index] = display_text[index]; + host_index++; + } + else if (mode == 1) + { + disp[disp_index] = display_text[index]; + disp_index++; + } + else if (mode == 2) + { + scre[scre_index] = display_text[index]; + scre_index++; + } + + index++; + } + + host[host_index] = 0; + disp[disp_index] = 0; + scre[scre_index] = 0; + return atoi(disp); +} |