Clean up and document the return values. Trying to solve a number of issues:

* The current return values have been selected pretty much without any
thought. Basically, the value 1 is used for all different kinds of
errors, except for a corner case where the server doesn't send a
RDP_PDU_DEACTIVATE in combination with a few special "reasons", where
the value 2 is used instead.

* rdesktop will currently also return with 2 if the user is closing
the rdesktop window, the same error as many other fatal errors, which
is somewhat strange.

* The main principle of my patch is to utilize more of the available
256 return codes. We are currently only using 3 values out of
256. This is bad; rdesktop should expose more information to the
caller about error conditions if it can.

Besides using the standardized exit codes for generic errors such as
EX_USAGE for command line usage errors, I've also exposed the
"extended disconnect reasons" from RDP. This allows for, for example,
to be able to distinguish between a logoff and a disconnect.



git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/rdesktop/trunk@1510 423420c4-83ab-492f-b58f-81f9feb106b5
This commit is contained in:
Peter Åstrand 2009-09-02 13:03:43 +00:00
parent 5c67800d15
commit 058ee33be3
8 changed files with 202 additions and 48 deletions

View File

@ -95,7 +95,7 @@ cache_rebuild_bmpcache_linked_list(uint8 id, sint16 * idx, int count)
{
error("Oops. %d in bitmap cache linked list, %d in ui cache...\n", c,
g_bmpcache_count[id]);
exit(1);
exit(EX_SOFTWARE);
}
}

View File

@ -36,6 +36,7 @@ AC_CHECK_HEADER(sys/filio.h, AC_DEFINE(HAVE_SYS_FILIO_H))
AC_CHECK_HEADER(sys/strtio.h, AC_DEFINE(HAVE_SYS_STRTIO_H))
AC_CHECK_HEADER(locale.h, AC_DEFINE(HAVE_LOCALE_H))
AC_CHECK_HEADER(langinfo.h, AC_DEFINE(HAVE_LANGINFO_H))
AC_CHECK_HEADER(sysexits.h, AC_DEFINE(HAVE_SYSEXITS_H))
AC_CHECK_TOOL(STRIP, strip, :)

View File

@ -408,6 +408,7 @@ enum RDP_INPUT_DEVICE
#define exDiscReasonOutOfMemory 0x0006
#define exDiscReasonServerDeniedConnection 0x0007
#define exDiscReasonServerDeniedConnectionFips 0x0008
#define exDiscReasonWindows7Disconnect 0x000b /* unofficial */
#define exDiscReasonLicenseInternal 0x0100
#define exDiscReasonLicenseNoLicenseServer 0x0101
#define exDiscReasonLicenseNoLicense 0x0102

2
disk.c
View File

@ -480,7 +480,7 @@ disk_create(uint32 device_id, uint32 accessmask, uint32 sharemode, uint32 create
{
error("Maximum number of open files (%s) reached. Increase MAX_OPEN_FILES!\n",
handle);
exit(1);
exit(EX_SOFTWARE);
}
if (dirp)

View File

@ -220,6 +220,64 @@ Use RDP version 4.
.BR "-5"
Use RDP version 5 (default).
.PP
.SH "EXIT VALUES"
.PP
.IP "\fB0\fP"
RDP session terminated normally
.IP "\fB1\fP"
Server initiated disconnect
.IP "\fB2\fP"
Server initiated logoff
.IP "\fB3\fP"
Server idle timeout reached
.IP "\fB4\fP"
Server logon timeout reached
.IP "\fB5\fP"
The session was replaced
.IP "\fB6\fP"
The server is out of memory
.IP "\fB7\fP"
The server denied the connection
.IP "\fB8\fP"
The server denied the connection for security reason
.IP "\fB16\fP"
Internal licensing error
.IP "\fB17\fP"
No license server available
.IP "\fB18\fP"
No valid license available
.IP "\fB19\fP"
Invalid licensing message
.IP "\fB20\fP"
Hardware id doesn't match software license
.IP "\fB21\fP"
Client license error
.IP "\fB22\fP"
Network error during licensing protocol
.IP "\fB23\fP"
Licensing protocol was not completed
.IP "\fB24\fP"
Incorrect client license enryption
.IP "\fB25\fP"
Can't upgrade license
.IP "\fB26\fP"
The server is not licensed to accept remote connections
.IP "\fB62\fP"
The local client window was closed
.IP "\fB63\fP"
Some other, unknown error occured
.IP "\fB64\fP"
Command line usage error
.IP "\fB69\fP"
A service or resource (such as memory) is unavailable
.IP "\fB70\fP"
An internal software error has been detected
.IP "\fB71\fP"
Operating system error
.IP "\fB76\fP"
Protocol error or unable to connect to remote host.
.PP
.SH LINKS
Main website of rdesktop
.br

View File

@ -91,6 +91,7 @@ RD_BOOL g_lspci_enabled = False;
RD_BOOL g_owncolmap = False;
RD_BOOL g_ownbackstore = True; /* We can't rely on external BackingStore */
RD_BOOL g_seamless_rdp = False;
RD_BOOL g_user_quit = False;
uint32 g_embed_wnd;
uint32 g_rdp5_performanceflags =
RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS;
@ -213,91 +214,116 @@ usage(char *program)
fprintf(stderr, " -5: use RDP version 5 (default)\n");
}
static void
print_disconnect_reason(uint16 reason)
static int
handle_disconnect_reason(RD_BOOL deactivated, uint16 reason)
{
char *text;
int retval;
switch (reason)
{
case exDiscReasonNoInfo:
text = "No information available";
if (deactivated)
retval = EX_OK;
else
retval = EXRD_UNKNOWN;
break;
case exDiscReasonAPIInitiatedDisconnect:
case exDiscReasonWindows7Disconnect:
text = "Server initiated disconnect";
retval = EXRD_API_DISCONNECT;
break;
case exDiscReasonAPIInitiatedLogoff:
text = "Server initiated logoff";
retval = EXRD_API_LOGOFF;
break;
case exDiscReasonServerIdleTimeout:
text = "Server idle timeout reached";
retval = EXRD_IDLE_TIMEOUT;
break;
case exDiscReasonServerLogonTimeout:
text = "Server logon timeout reached";
retval = EXRD_LOGON_TIMEOUT;
break;
case exDiscReasonReplacedByOtherConnection:
text = "The session was replaced";
retval = EXRD_REPLACED;
break;
case exDiscReasonOutOfMemory:
text = "The server is out of memory";
retval = EXRD_OUT_OF_MEM;
break;
case exDiscReasonServerDeniedConnection:
text = "The server denied the connection";
retval = EXRD_DENIED;
break;
case exDiscReasonServerDeniedConnectionFips:
text = "The server denied the connection for security reason";
retval = EXRD_DENIED_FIPS;
break;
case exDiscReasonLicenseInternal:
text = "Internal licensing error";
retval = EXRD_LIC_INTERNAL;
break;
case exDiscReasonLicenseNoLicenseServer:
text = "No license server available";
retval = EXRD_LIC_NOSERVER;
break;
case exDiscReasonLicenseNoLicense:
text = "No valid license available";
retval = EXRD_LIC_NOLICENSE;
break;
case exDiscReasonLicenseErrClientMsg:
text = "Invalid licensing message";
retval = EXRD_LIC_MSG;
break;
case exDiscReasonLicenseHwidDoesntMatchLicense:
text = "Hardware id doesn't match software license";
retval = EXRD_LIC_HWID;
break;
case exDiscReasonLicenseErrClientLicense:
text = "Client license error";
retval = EXRD_LIC_CLIENT;
break;
case exDiscReasonLicenseCantFinishProtocol:
text = "Network error during licensing protocol";
retval = EXRD_LIC_NET;
break;
case exDiscReasonLicenseClientEndedProtocol:
text = "Licensing protocol was not completed";
retval = EXRD_LIC_PROTO;
break;
case exDiscReasonLicenseErrClientEncryption:
text = "Incorrect client license enryption";
retval = EXRD_LIC_ENC;
break;
case exDiscReasonLicenseCantUpgradeLicense:
text = "Can't upgrade license";
retval = EXRD_LIC_UPGRADE;
break;
case exDiscReasonLicenseNoRemoteConnections:
text = "The server is not licensed to accept remote connections";
retval = EXRD_LIC_NOREMOTE;
break;
default:
@ -309,8 +335,12 @@ print_disconnect_reason(uint16 reason)
{
text = "Unknown reason";
}
retval = EXRD_UNKNOWN;
}
fprintf(stderr, "disconnect: %s.\n", text);
if (reason != exDiscReasonNoInfo)
fprintf(stderr, "disconnect: %s.\n", text);
return retval;
}
static void
@ -535,7 +565,7 @@ main(int argc, char *argv[])
if (g_width <= 0)
{
error("invalid geometry\n");
return 1;
return EX_USAGE;
}
if (*p == 'x')
@ -544,7 +574,7 @@ main(int argc, char *argv[])
if (g_height <= 0)
{
error("invalid geometry\n");
return 1;
return EX_USAGE;
}
if (*p == '%')
@ -613,7 +643,7 @@ main(int argc, char *argv[])
if (*p)
{
error("invalid button size\n");
return 1;
return EX_USAGE;
}
break;
@ -638,7 +668,7 @@ main(int argc, char *argv[])
&& g_server_depth != 32)
{
error("Invalid server colour depth.\n");
return 1;
return EX_USAGE;
}
break;
@ -789,14 +819,14 @@ main(int argc, char *argv[])
case '?':
default:
usage(argv[0]);
return 1;
return EX_USAGE;
}
}
if (argc - optind != 1)
{
usage(argv[0]);
return 1;
return EX_USAGE;
}
STRNCPY(server, argv[optind], sizeof(server));
@ -807,33 +837,33 @@ main(int argc, char *argv[])
if (g_win_button_size)
{
error("You cannot use -S and -A at the same time\n");
return 1;
return EX_USAGE;
}
g_rdp5_performanceflags &= ~RDP5_NO_FULLWINDOWDRAG;
if (geometry_option)
{
error("You cannot use -g and -A at the same time\n");
return 1;
return EX_USAGE;
}
if (g_fullscreen)
{
error("You cannot use -f and -A at the same time\n");
return 1;
return EX_USAGE;
}
if (g_hide_decorations)
{
error("You cannot use -D and -A at the same time\n");
return 1;
return EX_USAGE;
}
if (g_embed_wnd)
{
error("You cannot use -X and -A at the same time\n");
return 1;
return EX_USAGE;
}
if (!g_use_rdp5)
{
error("You cannot use -4 and -A at the same time\n");
return 1;
return EX_USAGE;
}
g_width = -100;
g_grab_keyboard = False;
@ -845,7 +875,7 @@ main(int argc, char *argv[])
if ((pw == NULL) || (pw->pw_name == NULL))
{
error("could not determine username, use -u\n");
return 1;
return EX_OSERR;
}
/* +1 for trailing \0 */
int pwlen = strlen(pw->pw_name) + 1;
@ -872,7 +902,7 @@ main(int argc, char *argv[])
if (gethostname(fullhostname, sizeof(fullhostname)) == -1)
{
error("could not determine local hostname, use -n\n");
return 1;
return EX_OSERR;
}
p = strchr(fullhostname, '.');
@ -908,11 +938,11 @@ main(int argc, char *argv[])
#ifdef RDP2VNC
rdp2vnc_connect(server, flags, domain, password, shell, directory);
return 0;
return EX_OK;
#else
if (!ui_init())
return 1;
return EX_OSERR;
#ifdef WITH_RDPSND
if (g_rdpsnd)
@ -934,11 +964,11 @@ main(int argc, char *argv[])
if (run_count == 0)
{
if (!rdp_connect(server, flags, domain, password, shell, directory))
return 1;
return EX_PROTOCOL;
}
else if (!rdp_reconnect
(server, flags, domain, password, shell, directory, g_redirect_cookie))
return 1;
return EX_PROTOCOL;
/* By setting encryption to False here, we have an encrypted login
packet but unencrypted transfer of other packets */
@ -987,28 +1017,10 @@ main(int argc, char *argv[])
cache_save_state();
ui_deinit();
if (ext_disc_reason >= 2)
print_disconnect_reason(ext_disc_reason);
if (g_user_quit)
return EXRD_WINDOW_CLOSED;
if (deactivated)
{
/* clean disconnect */
return 0;
}
else
{
if (ext_disc_reason == exDiscReasonAPIInitiatedDisconnect
|| ext_disc_reason == exDiscReasonAPIInitiatedLogoff)
{
/* not so clean disconnect, but nothing to worry about */
return 0;
}
else
{
/* return error */
return 2;
}
}
return handle_disconnect_reason(deactivated, ext_disc_reason);
#endif
if (g_redirect_username)
@ -1108,7 +1120,7 @@ xmalloc(int size)
if (mem == NULL)
{
error("xmalloc %d\n", size);
exit(1);
exit(EX_UNAVAILABLE);
}
return mem;
}
@ -1120,7 +1132,7 @@ exit_if_null(void *ptr)
if (ptr == NULL)
{
error("unexpected null pointer. Out of memory?\n");
exit(1);
exit(EX_UNAVAILABLE);
}
}
@ -1132,7 +1144,7 @@ xstrdup(const char *s)
if (mem == NULL)
{
perror("strdup");
exit(1);
exit(EX_UNAVAILABLE);
}
return mem;
}
@ -1149,7 +1161,7 @@ xrealloc(void *oldmem, size_t size)
if (mem == NULL)
{
error("xrealloc %ld\n", size);
exit(1);
exit(EX_UNAVAILABLE);
}
return mem;
}

View File

@ -38,9 +38,87 @@
#endif
#endif
#include <limits.h> /* PATH_MAX */
#ifdef HAVE_SYSEXITS_H
#include <sysexits.h>
#endif
#define VERSION "1.6.0"
/* standard exit codes */
#ifndef EX_OK
#define EX_OK 0
#endif
#ifndef EX_USAGE
#define EX_USAGE 64
#endif
#ifndef EX_DATAERR
#define EX_DATAERR 65
#endif
#ifndef EX_NOINPUT
#define EX_NOINPUT 66
#endif
#ifndef EX_NOUSER
#define EX_NOUSER 67
#endif
#ifndef EX_NOHOST
#define EX_NOHOST 68
#endif
#ifndef EX_UNAVAILABLE
#define EX_UNAVAILABLE 69
#endif
#ifndef EX_SOFTWARE
#define EX_SOFTWARE 70
#endif
#ifndef EX_OSERR
#define EX_OSERR 71
#endif
#ifndef EX_OSFILE
#define EX_OSFILE 72
#endif
#ifndef EX_CANTCREAT
#define EX_CANTCREAT 73
#endif
#ifndef EX_IOERR
#define EX_IOERR 74
#endif
#ifndef EX_TEMPFAIL
#define EX_TEMPFAIL 75
#endif
#ifndef EX_PROTOCOL
#define EX_PROTOCOL 76
#endif
#ifndef EX_NOPERM
#define EX_NOPERM 77
#endif
#ifndef EX_CONFIG
#define EX_CONFIG 78
#endif
/* rdesktop specific exit codes, lined up with disconnect PDU reasons */
#define EXRD_API_DISCONNECT 1
#define EXRD_API_LOGOFF 2
#define EXRD_IDLE_TIMEOUT 3
#define EXRD_LOGON_TIMEOUT 4
#define EXRD_REPLACED 5
#define EXRD_OUT_OF_MEM 6
#define EXRD_DENIED 7
#define EXRD_DENIED_FIPS 8
#define EXRD_LIC_INTERNAL 16
#define EXRD_LIC_NOSERVER 17
#define EXRD_LIC_NOLICENSE 18
#define EXRD_LIC_MSG 19
#define EXRD_LIC_HWID 20
#define EXRD_LIC_CLIENT 21
#define EXRD_LIC_NET 22
#define EXRD_LIC_PROTO 23
#define EXRD_LIC_ENC 24
#define EXRD_LIC_UPGRADE 25
#define EXRD_LIC_NOREMOTE 26
/* other exit codes */
#define EXRD_WINDOW_CLOSED 62
#define EXRD_UNKNOWN 63
#ifdef WITH_DEBUG
#define DEBUG(args) printf args;
#else

4
tcp.c
View File

@ -56,6 +56,7 @@ static int g_sock;
static struct stream g_in;
static struct stream g_out[STREAM_COUNT];
int g_tcp_port_rdp = TCP_PORT_RDP;
extern RD_BOOL g_user_quit;
/* wait till socket is ready to write or timeout */
static RD_BOOL
@ -173,8 +174,11 @@ tcp_recv(STREAM s, uint32 length)
while (length > 0)
{
if (!ui_select(g_sock))
{
/* User quit */
g_user_quit = True;
return NULL;
}
rcvd = recv(g_sock, s->end, length, 0);
if (rcvd < 0)