Re: Patch: Document and clean up return values
Peter Åstrand <[email protected]>
| Newsgroups | gmane.network.rdesktop.devel |
|---|---|
| Message-ID | <[email protected]> |
Updated patch, which fixes a few issues: * Documents the "other" error (code 63). * Separates the return value for normal session termination and closed local window. The latter is typically a disconnect rather than a logoff. My plan is to commit this in a near future if there are no objections. Rgds, Peter On Thu, 27 Aug 2009, Peter Åstrand wrote: > > Hi. Below is a patch that cleans up and documents the rdesktop return values. > It is trying to solve a number of problem with the current implementation: > > * 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, 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. > > The patch has been tested against: > > Windows XP > Windows Server 2003 > Windows Vista > Windows 7 > > Comments? > > Best regards, --- > Peter Åstrand ThinLinc Chief Developer > Cendio AB http://www.cendio.com > Wallenbergs gata 4 > 583 30 Linköping Phone: +46-13-21 46 00 --- Peter Åstrand ThinLinc Chief Developer Cendio AB http://www.cendio.com Wallenbergs gata 4 583 30 Linköping Phone: +46-13-21 46 00 ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ rdesktop-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/rdesktop-devel
retvalues2.patch
(text/plain, 13.8 KB)
Index: configure.ac
===================================================================
--- configure.ac (revision 1509)
+++ configure.ac (arbetskopia)
@@ -36,6 +36,7 @@
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, :)
Index: doc/rdesktop.1
===================================================================
--- doc/rdesktop.1 (revision 1509)
+++ doc/rdesktop.1 (arbetskopia)
@@ -220,6 +220,64 @@
.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
Index: rdesktop.c
===================================================================
--- rdesktop.c (revision 1509)
+++ rdesktop.c (arbetskopia)
@@ -91,6 +91,7 @@
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 @@
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 @@
{
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 @@
if (g_width <= 0)
{
error("invalid geometry\n");
- return 1;
+ return EX_USAGE;
}
if (*p == 'x')
@@ -544,7 +574,7 @@
if (g_height <= 0)
{
error("invalid geometry\n");
- return 1;
+ return EX_USAGE;
}
if (*p == '%')
@@ -613,7 +643,7 @@
if (*p)
{
error("invalid button size\n");
- return 1;
+ return EX_USAGE;
}
break;
@@ -638,7 +668,7 @@
&& g_server_depth != 32)
{
error("Invalid server colour depth.\n");
- return 1;
+ return EX_USAGE;
}
break;
@@ -789,14 +819,14 @@
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 @@
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 @@
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 @@
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 @@
#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 @@
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 @@
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 @@
if (mem == NULL)
{
error("xmalloc %d\n", size);
- exit(1);
+ exit(EX_UNAVAILABLE);
}
return mem;
}
@@ -1120,7 +1132,7 @@
if (ptr == NULL)
{
error("unexpected null pointer. Out of memory?\n");
- exit(1);
+ exit(EX_UNAVAILABLE);
}
}
@@ -1132,7 +1144,7 @@
if (mem == NULL)
{
perror("strdup");
- exit(1);
+ exit(EX_UNAVAILABLE);
}
return mem;
}
@@ -1149,7 +1161,7 @@
if (mem == NULL)
{
error("xrealloc %ld\n", size);
- exit(1);
+ exit(EX_UNAVAILABLE);
}
return mem;
}
Index: rdesktop.h
===================================================================
--- rdesktop.h (revision 1509)
+++ rdesktop.h (arbetskopia)
@@ -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
Index: tcp.c
===================================================================
--- tcp.c (revision 1509)
+++ tcp.c (arbetskopia)
@@ -56,6 +56,7 @@
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 @@
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)
Index: constants.h
===================================================================
--- constants.h (revision 1509)
+++ constants.h (arbetskopia)
@@ -408,6 +408,7 @@
#define exDiscReasonOutOfMemory 0x0006
#define exDiscReasonServerDeniedConnection 0x0007
#define exDiscReasonServerDeniedConnectionFips 0x0008
+#define exDiscReasonWindows7Disconnect 0x000b /* unofficial */
#define exDiscReasonLicenseInternal 0x0100
#define exDiscReasonLicenseNoLicenseServer 0x0101
#define exDiscReasonLicenseNoLicense 0x0102
Index: disk.c
===================================================================
--- disk.c (revision 1509)
+++ disk.c (arbetskopia)
@@ -480,7 +480,7 @@
{
error("Maximum number of open files (%s) reached. Increase MAX_OPEN_FILES!\n",
handle);
- exit(1);
+ exit(EX_SOFTWARE);
}
if (dirp)
Index: cache.c
===================================================================
--- cache.c (revision 1509)
+++ cache.c (arbetskopia)
@@ -95,7 +95,7 @@
{
error("Oops. %d in bitmap cache linked list, %d in ui cache...\n", c,
g_bmpcache_count[id]);
- exit(1);
+ exit(EX_SOFTWARE);
}
}