~/.rdesktop/config patch

Jeremy Jethro <[email protected]>
Newsgroups gmane.network.rdesktop.devel
Message-ID <[email protected]>
I've written a patch that allows the use of configuration files with rdesktop much like OpenSSH supports.  Its been quite useful to me and I hope others will enjoy it.

Almost all of the configuration file parsing code was taken from OpenSSH source.

Apologies to the authors of rdesktop for uglying some really nice looking code.

Here's how to use it:

1. Patch rdesktop 1.6.0 source

$ patch -p0 < rdesktop-CONFIG.patch
patching file rdesktop-1.6.0/doc/rdesktop_config.1
patching file rdesktop-1.6.0/Makefile.in
patching file rdesktop-1.6.0/proto.h
patching file rdesktop-1.6.0/rdesktop.c
patching file rdesktop-1.6.0/readconf.c
patching file rdesktop-1.6.0/readconf.h

Now ./configure && make && make install


2. Create ~/.rdesktop/config

Example usage:

$ cat ~/.rdesktop/config
Host lydia
    Hostname 192.168.1.10
    User jjethro
    Password HaleShomaChitore
    Domain GALAXY
    Keymap de-ch
    Geometry 65%
    Title lydia-rdp
    Performance m
    Console yes
    Redirect clipboard:off

$ rdesktop lydia  &

Supported options are documented in the rdesktop_config man page provided in the attached patch.

Enjoy,

j

------------------------------------------------------------------------------
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first

_______________________________________________
rdesktop-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/rdesktop-devel
rdesktop-CONFIG.patch (text/plain, 40.4 KB)
diff -rupN rdesktop-1.6.0/doc/rdesktop_config.1 rdesktop-1.6.0-CONFIG-PATCH/doc/rdesktop_config.1
--- rdesktop-1.6.0/doc/rdesktop_config.1	1969-12-31 19:00:00.000000000 -0500
+++ rdesktop-1.6.0-CONFIG-PATCH/doc/rdesktop_config.1	2010-07-10 12:42:30.000000000 -0400
@@ -0,0 +1,199 @@
+.\"  -*- nroff -*-
+.Dd $Mdocdate: July 10 2010 $
+.Dt RDESKTOP_CONFIG 1
+.Os
+.Sh NAME
+.Nm rdesktop_config
+.Nd rdesktop client configuration file
+.Sh SYNOPSIS
+.Nm ~/.rdesktop/config
+.Sh DESCRIPTION
+.Xr rdesktop 1
+obtains configuration data from the following sources in
+the following order:
+.Pp
+.Bl -enum -offset indent -compact
+.It
+command-line options
+.It
+user's configuration file
+.Pq Pa ~/.rdesktop/config
+.El
+.Pp
+For each parameter, the first obtained value
+will be used.
+The configuration files contain sections separated by
+.Dq Host
+specifications, and that section is only applied for hosts that
+match one of the patterns given in the specification.
+The matched host name is the one given on the command line.
+.Pp
+Since the first obtained value for each parameter is used, more
+host-specific declarations should be given near the beginning of the
+file, and general defaults at the end.
+.Pp
+The configuration file has the following format:
+.Pp
+Empty lines and lines starting with
+.Ql #
+are comments.
+.Pp
+Otherwise a line is of the format
+.Dq keyword arguments .
+Configuration options may be separated by whitespace or
+optional whitespace and exactly one
+.Ql = ;
+the latter format is useful to avoid the need to quote whitespace
+when specifying configuration options.
+.Pp
+Arguments may optionally be enclosed in double quotes
+.Pq \&"
+in order to represent arguments containing spaces.
+.Pp
+The possible
+keywords and their meanings are as follows (note that
+keywords are case-insensitive and arguments are case-sensitive):
+.Bl -tag -width Ds
+.It Cm Host
+Restricts the following declarations (up to the next
+.Cm Host
+keyword) to be only for those hosts that match one of the patterns
+given after the keyword.
+If more than one pattern is provided, they should be separated by whitespace.
+A single
+.Ql *
+as a pattern can be used to provide global
+defaults for all hosts.
+The host is the
+.Ar hostname
+argument given on the command line (i.e. the name is not converted to
+a canonicalized host name before matching).
+for more information on patterns.
+.It Cm BitmapCachePersist <yes/no>
+Enable persistent bitmap caching.  
+.Dq BitmapCachePersist yes
+is equivalent to the -P command line argument. Default is 
+.Dq no .
+.It Cm ButtonSize <button size>
+Enable single application mode.  Equivalent to the -S command line argument.  Single application mode is not enabled by default.
+.It Cm ClientHostName <chostname>
+Client hostname.  Equivalent to the -n command line argument.  Without this argument rdesktop automatically obtains the hostname of the client.
+.It Cm ColourDepth <colour depth>
+Sets the colour depth for the connection (8, 15, 16, or 24).  Equivalent to the -a command line argument.  The default value is the depth of the root window.  Note: Colour must be spelled strangely.
+.It Cm Compression <yes/no>
+Enable compression of the RDP datastream.  
+.Dq Compression yes
+is equivalent to the -z command line argument.  This is not enabled by default.
+.It Cm Console <yes/no>
+Attach to the console of the server.  
+.Dq Console yes 
+is equivalent to the -0 command line argument.  Not enabled by default.
+.It Cm Directory <directory>
+The initial working directory for the user.  Often used in combination with 
+.Dq Shell .
+to set up a fixed login environment.  Equivalent to the -c command line argument.
+.It Cm Domain <domain>
+Domain for authentication.  Equivalent to the -d command line argument.
+.It Cm EmbedWindow <windowid>
+Embed rdesktop-window in another window.  The windowid is expected to be decimal or hexadecimal (prefixed by 0x).  Equivalent to the -X command line argument.
+.It Cm Encryption <yes/no>
+Enable/disable encryption.  This option is only needed (and will only work) if you have a French version of NT TSE.  
+.Dq Encryption no
+is equivalent to the -e command line argument.  Default is 
+.Dq yes .
+.It Cm ForceBitmapUpdates <yes/no>
+Force the server to send screen updates as bitmaps rather than using higher-level drawing operations.  Equivalent to the -b command line argument.  Default is 
+.Dq no .
+.It Cm FullScreen <yes/no>
+Enable fullscreen mode.  
+.Dq FullScreen yes 
+is equivalent to the -f command line argument.  Default is 
+.Dq no .
+.It Cm Geometry <geometry>
+Desktop geometry (WxH).  If geometry is the special word "workarea", the geometry will be fetched from the extended window manager hints property _NET_WORKAREA, from the root window.  The geometry can also be specified as a percentage of the whole screen, e.g. 
+.Dq 80% .
+Equivalent to the -g command line argument.
+.It Cm GrabKeyboard <yes/no>
+By default rdesktop attempts to grab all keyboard input when it is in focus (
+.Dq no
+).  
+.Dq GrabKeyboard no
+is equivalent to the -K command line argument.
+.It Cm HideDecorations <yes/no>
+Hide window manager decorations or not, by using MWM hints.  Default is 
+.Dq no  .
+.Dq HideDecorations yes
+is equivalent to the -D command line argument.
+.It Cm Hostname <hostname>
+IP address or hostname of host to connect to.
+.It Cm KeyMap <keyboard-map>
+Keyboard layout to emulate.  This requires a corresponding keymap file to be installed.  The default keyboard map depends on the current locale (LC_* and LANG environment variables).  If the current locale is unknown, the default keyboard map is en-us (a US English keyboard).  Equivalent to the  -k command line argument.
+.It Cm NumlockSync <yes/no>
+Enable or disable numlock syncronization between the Xserver and the remote RDP session.  
+.Dq NumlockSync yes
+is equivalent to the -N command line argument.  This is not enabled by default.
+.It Cm OwnColMap <yes/no>
+Use private colourmap.  This will improve colour accuracy on an 8-bit display, but rdesktop will appear in false colour when not focused.  
+.Dq OwnColMap yes 
+is equivalent to the -C command line argument.  This is not enabled by default.
+.It Cm PacketEncryption <yes/no>
+Enable or disable encryption from the client to server.  
+.Dq PacketEncryption no
+is equivalent to the -E command line argument.  Packet encryption is enabled by default.
+.It Cm Password <password>
+The password to authenticate with.  When this option is provided logins will happen automatically upon connecting.  Equivalent to the -p command line argument.
+.It Cm Performance <m/b/l>
+Changes default bandwidth performance behaviour for RDP5.  options are [m]odem [b]roadband and [l]an.  Equivalent to the -x command line argument.
+.It Cm Port <port>
+Specify RDP port.  Equivilent to providing hostname:port.
+.It Cm RDP4 <yes/no>
+Specify whether RDP4 should be used or not.
+.Dq RDP4 yes
+is equivalent to the -4 command line argument.
+.It Cm RDP5 <yes/no>
+Specify whether RDP5 should be used or not. 
+.Dq RDP5 yes
+is equivalent to the -5 command line argument.
+.It Cm Redirect <redirection string>
+See rdesktop manpage for more details.  WARNING: This option has not been thoroughly tested.  Equivalent to the -r command line argument.
+.It Cm SendMotion <yes/no>
+Specify whether to send mouse motion events or not.  
+.Dq SendMotion no
+is equivalent to the -m command line argument.
+.It Cm Shell <shell>
+Startup shell for the user.  Equivalent to the -s command line argument.  Default is Explorer.
+.It Cm Title <title>
+Sets the window title.  Equivalent to the -T command line argument.  Default is 
+.Dq rdesktop - hostname
+.It Cm UseBackingStore <yes/no>
+Use the BackingStore of the Xserver instead of the one integrated in rdesktop.  
+.Dq UseBackingStore yes
+is equivalent to the -B command line argument.
+.It Cm User <username>
+Username for authentication on the server.  Equivalent to the -u command line argument.  Default is to retrieve username from getuid().
+
+.Sh FILES
+.Bl -tag -width Ds
+.It Pa ~/.rdesktop/config
+This is the per-user configuration file.
+The format of this file is described above.
+This file is used by the rdesktop client.
+Because of the potential for abuse, this file should have strict permissions:
+read/write for the user, and not accessible by others.
+.El
+.Sh EXAMPLE
+j@vineyard ~ $ cat ~/.rdesktop/config 
+.Bl -tag -width Ds
+Host lydia
+    Hostname 192.168.1.10
+    User jjethro
+    Password HaleShomaChitore
+    Domain GALAXY
+    Keymap de-ch
+    Geometry 65%
+    Title lydia-rdp
+    Performance m
+    Redirect clipboard:off
+.El
+.Sh SEE ALSO
+.Xr rdesktop 1
diff -rupN rdesktop-1.6.0/Makefile.in rdesktop-1.6.0-CONFIG-PATCH/Makefile.in
--- rdesktop-1.6.0/Makefile.in	2007-01-09 02:24:44.000000000 -0500
+++ rdesktop-1.6.0-CONFIG-PATCH/Makefile.in	2010-07-10 12:42:30.000000000 -0400
@@ -27,7 +27,7 @@ VNCLINK     = @VNCLINK@
 SOUNDOBJ    = @SOUNDOBJ@
 SCARDOBJ    = @SCARDOBJ@
 
-RDPOBJ   = tcp.o iso.o mcs.o secure.o licence.o rdp.o orders.o bitmap.o cache.o rdp5.o channels.o rdpdr.o serial.o printer.o disk.o parallel.o printercache.o mppc.o pstcache.o lspci.o seamless.o ssl.o
+RDPOBJ   = tcp.o iso.o mcs.o secure.o licence.o rdp.o orders.o bitmap.o cache.o rdp5.o channels.o rdpdr.o serial.o printer.o disk.o parallel.o printercache.o mppc.o pstcache.o lspci.o seamless.o ssl.o readconf.o
 X11OBJ   = rdesktop.o xwin.o xkeymap.o ewmhints.o xclip.o cliprdr.o
 VNCOBJ   = vnc/rdp2vnc.o vnc/vnc.o vnc/xkeymap.o vnc/x11stubs.o
 
@@ -66,7 +66,9 @@ installbin: rdesktop
 installman: doc/rdesktop.1
 	mkdir -p $(DESTDIR)$(mandir)/man1
 	cp doc/rdesktop.1 $(DESTDIR)$(mandir)/man1
+	cp doc/rdesktop_config.1 $(DESTDIR)$(mandir)/man1
 	chmod 644 $(DESTDIR)$(mandir)/man1/rdesktop.1
+	chmod 644 $(DESTDIR)$(mandir)/man1/rdesktop_config.1
 
 .PHONY: installkeymaps
 installkeymaps:
diff -rupN rdesktop-1.6.0/proto.h rdesktop-1.6.0-CONFIG-PATCH/proto.h
--- rdesktop-1.6.0/proto.h	2008-04-02 07:13:22.000000000 -0400
+++ rdesktop-1.6.0-CONFIG-PATCH/proto.h	2010-07-10 12:42:30.000000000 -0400
@@ -133,6 +133,10 @@ int rd_read_file(int fd, void *ptr, int 
 int rd_write_file(int fd, void *ptr, int len);
 int rd_lseek_file(int fd, int offset);
 RD_BOOL rd_lock_file(int fd, int start, int len);
+int parse_geometry(char *string);
+int check_server_depth(int i);
+int set_rdp5_perfflags(char *p);
+int parse_redirect(char *string);
 /* rdp5.c */
 void rdp5_process(STREAM s);
 /* rdp.c */
diff -rupN rdesktop-1.6.0/rdesktop.c rdesktop-1.6.0-CONFIG-PATCH/rdesktop.c
--- rdesktop-1.6.0/rdesktop.c	2008-04-05 01:22:26.000000000 -0400
+++ rdesktop-1.6.0-CONFIG-PATCH/rdesktop.c	2010-07-10 12:42:30.000000000 -0400
@@ -47,6 +47,9 @@
 
 #include "ssl.h"
 
+
+#include "readconf.h"
+
 char g_title[64] = "";
 char g_username[64];
 char g_hostname[16];
@@ -101,8 +104,13 @@ char g_redirect_domain[16];
 char g_redirect_password[64];
 char g_redirect_username[64];
 char g_redirect_cookie[128];
+#ifdef WITH_RDPSND
+char *g_rdpsnd_optarg = NULL;
+#endif
+
 uint32 g_redirect_flags = 0;
 
+
 #ifdef WITH_RDPSND
 RD_BOOL g_rdpsnd = False;
 #endif
@@ -421,11 +429,13 @@ main(int argc, char *argv[])
 	char *locale = NULL;
 	int username_option = 0;
 	RD_BOOL geometry_option = False;
+	RD_BOOL rdp_compression_option = False;
+	RD_BOOL rdp4_option = False;
+	RD_BOOL rdp5_option = False;
+	RD_BOOL perf_option = False;
+        RD_BOOL redir_option = False;
 	int run_count = 0;	/* Session Directory support */
 	RD_BOOL continue_connect = True;	/* Session Directory support */
-#ifdef WITH_RDPSND
-	char *rdpsnd_optarg = NULL;
-#endif
 
 #ifdef HAVE_LOCALE_H
 	/* Set locale according to environment */
@@ -442,6 +452,10 @@ main(int argc, char *argv[])
 	g_embed_wnd = 0;
 
 	g_num_devices = 0;
+        Options options;
+
+        initialize_options(&options); 
+	
 
 #ifdef RDP2VNC
 #define VNCOPT "V:Q:"
@@ -524,46 +538,7 @@ main(int argc, char *argv[])
 			case 'g':
 				geometry_option = True;
 				g_fullscreen = False;
-				if (!strcmp(optarg, "workarea"))
-				{
-					g_width = g_height = 0;
-					break;
-				}
-
-				g_width = strtol(optarg, &p, 10);
-				if (g_width <= 0)
-				{
-					error("invalid geometry\n");
-					return 1;
-				}
-
-				if (*p == 'x')
-					g_height = strtol(p + 1, &p, 10);
-
-				if (g_height <= 0)
-				{
-					error("invalid geometry\n");
-					return 1;
-				}
-
-				if (*p == '%')
-				{
-					g_width = -g_width;
-					p++;
-				}
-
-				if (*p == '+' || *p == '-')
-				{
-					g_pos |= (*p == '-') ? 2 : 1;
-					g_xpos = strtol(p, &p, 10);
-
-				}
-				if (*p == '+' || *p == '-')
-				{
-					g_pos |= (*p == '-') ? 4 : 1;
-					g_ypos = strtol(p, NULL, 10);
-				}
-
+				parse_geometry(optarg);
 				break;
 
 			case 'f':
@@ -631,145 +606,26 @@ main(int argc, char *argv[])
 
 			case 'a':
 				g_server_depth = strtol(optarg, NULL, 10);
-				if (g_server_depth != 8 &&
-				    g_server_depth != 16 &&
-				    g_server_depth != 15 && g_server_depth != 24
-				    && g_server_depth != 32)
-				{
-					error("Invalid server colour depth.\n");
-					return 1;
-				}
+				check_server_depth(g_server_depth);
 				break;
 
 			case 'z':
 				DEBUG(("rdp compression enabled\n"));
+				rdp_compression_option = True;
 				flags |= (RDP_LOGON_COMPRESSION | RDP_LOGON_COMPRESSION2);
 				break;
 
 			case 'x':
-				if (str_startswith(optarg, "m"))	/* modem */
-				{
-					g_rdp5_performanceflags =
-						RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG |
-						RDP5_NO_MENUANIMATIONS | RDP5_NO_THEMING;
-				}
-				else if (str_startswith(optarg, "b"))	/* broadband */
-				{
-					g_rdp5_performanceflags = RDP5_NO_WALLPAPER;
-				}
-				else if (str_startswith(optarg, "l"))	/* lan */
-				{
-					g_rdp5_performanceflags = RDP5_DISABLE_NOTHING;
-				}
-				else
-				{
-					g_rdp5_performanceflags = strtol(optarg, NULL, 16);
-				}
-				break;
+			        perf_option = True;
+				g_rdp5_performanceflags = set_rdp5_perfflags(optarg);
 
 			case 'P':
 				g_bitmap_cache_persist_enable = True;
 				break;
 
 			case 'r':
-
-				if (str_startswith(optarg, "sound"))
-				{
-					optarg += 5;
-
-					if (*optarg == ':')
-					{
-						optarg++;
-						while ((p = next_arg(optarg, ',')))
-						{
-							if (str_startswith(optarg, "remote"))
-								flags |= RDP_LOGON_LEAVE_AUDIO;
-
-							if (str_startswith(optarg, "local"))
-#ifdef WITH_RDPSND
-							{
-								rdpsnd_optarg =
-									next_arg(optarg, ':');
-								g_rdpsnd = True;
-							}
-
-#else
-								warning("Not compiled with sound support\n");
-#endif
-
-							if (str_startswith(optarg, "off"))
-#ifdef WITH_RDPSND
-								g_rdpsnd = False;
-#else
-								warning("Not compiled with sound support\n");
-#endif
-
-							optarg = p;
-						}
-					}
-					else
-					{
-#ifdef WITH_RDPSND
-						g_rdpsnd = True;
-#else
-						warning("Not compiled with sound support\n");
-#endif
-					}
-				}
-				else if (str_startswith(optarg, "disk"))
-				{
-					/* -r disk:h:=/mnt/floppy */
-					disk_enum_devices(&g_num_devices, optarg + 4);
-				}
-				else if (str_startswith(optarg, "comport"))
-				{
-					serial_enum_devices(&g_num_devices, optarg + 7);
-				}
-				else if (str_startswith(optarg, "lspci"))
-				{
-					g_lspci_enabled = True;
-				}
-				else if (str_startswith(optarg, "lptport"))
-				{
-					parallel_enum_devices(&g_num_devices, optarg + 7);
-				}
-				else if (str_startswith(optarg, "printer"))
-				{
-					printer_enum_devices(&g_num_devices, optarg + 7);
-				}
-				else if (str_startswith(optarg, "clientname"))
-				{
-					g_rdpdr_clientname = xmalloc(strlen(optarg + 11) + 1);
-					strcpy(g_rdpdr_clientname, optarg + 11);
-				}
-				else if (str_startswith(optarg, "clipboard"))
-				{
-					optarg += 9;
-
-					if (*optarg == ':')
-					{
-						optarg++;
-
-						if (str_startswith(optarg, "off"))
-							g_rdpclip = False;
-						else
-							cliprdr_set_mode(optarg);
-					}
-					else
-						g_rdpclip = True;
-				}
-				else if (strncmp("scard", optarg, 5) == 0)
-				{
-#ifdef WITH_SCARD
-					scard_enum_devices(&g_num_devices, optarg + 5);
-#else
-					warning("Not compiled with smartcard support\n");
-#endif
-				}
-				else
-				{
-					warning("Unknown -r argument\n\n\tPossible arguments are: comport, disk, lptport, printer, sound, clipboard, scard\n");
-				}
+                                redir_option = True;
+			        flags |= parse_redirect(optarg);
 				break;
 
 			case '0':
@@ -778,10 +634,12 @@ main(int argc, char *argv[])
 
 			case '4':
 				g_use_rdp5 = False;
+				rdp4_option = True;
 				break;
 
 			case '5':
 				g_use_rdp5 = True;
+				rdp5_option = True;
 				break;
 
 			case 'h':
@@ -801,6 +659,125 @@ main(int argc, char *argv[])
 	STRNCPY(server, argv[optind], sizeof(server));
 	parse_server_and_port(server);
 
+        read_config_file(server, &options);
+
+
+        if (options.hostname)   
+            STRNCPY(server, options.hostname, sizeof(server));
+
+
+        if ( !username_option && options.username)  
+            STRNCPY(g_username, options.username, sizeof(g_username));
+
+        if  (g_tcp_port_rdp == TCP_PORT_RDP )
+        {
+            if ( options.port > 0 )
+                g_tcp_port_rdp = options.port;
+        }
+
+        if (!g_fullscreen && options.fullscreen )
+                g_fullscreen = True;
+
+        if ((domain[0] == 0) && options.domain ) 
+                STRNCPY(domain, options.domain, sizeof(domain));
+
+        if((shell[0] == 0) && options.shell ) 
+                STRNCPY(shell, options.shell, sizeof(shell));
+
+        if ((directory[0] == 0) && options.directory ) 
+                STRNCPY(directory, options.directory, sizeof(directory));
+
+        if ((g_hostname[0] == 0) && options.chostname ) 
+                STRNCPY(g_hostname, options.chostname, sizeof(g_hostname));
+ 
+        if (g_keymapname[0] == 0 && options.keymapname ) 
+                STRNCPY(g_keymapname, options.keymapname, sizeof(g_keymapname));
+
+        if (g_bitmap_cache && options.forcebitmapupdates) 
+                g_bitmap_cache = options.forcebitmapupdates;
+        
+        if (g_ownbackstore && options.usebackingstore) 
+                g_ownbackstore = options.usebackingstore;
+
+        if (g_encryption && options.encryption) 
+                g_encryption = options.encryption;
+
+        if (g_packet_encryption && options.packet_encryption) 
+                g_packet_encryption = options.packet_encryption;
+
+        if (g_sendmotion && options.sendmotion) 
+                g_sendmotion = options.sendmotion;
+
+        if (!g_owncolmap && options.owncolmap >= 0 ) 
+                g_owncolmap = options.owncolmap;
+
+        if (!g_hide_decorations && options.hide_decorations)
+                g_hide_decorations = options.hide_decorations;
+		
+	if (g_grab_keyboard && options.grabkeyboard >= 0 )
+	        g_grab_keyboard = options.grabkeyboard;
+		
+	if (!g_numlock_sync && options.numlocksync >= 0 )
+	        g_numlock_sync = options.numlocksync;
+		
+	if (g_embed_wnd == 0 && options.embedwnd >= 0 )
+	        g_embed_wnd = options.embedwnd;
+
+	if (g_server_depth == -1 && options.colourdepth != -2)
+	        g_server_depth = options.colourdepth;
+	
+	if (!g_bitmap_cache_persist_enable && options.bitmapcachepersist >= 0)
+	        g_bitmap_cache_persist_enable = options.bitmapcachepersist;    
+	
+	if (!g_console_session && options.console) 
+	        g_console_session = options.console;
+
+        if (!redir_option && options.redirect) 
+                flags |= parse_redirect(options.redirect);
+	
+	if ((rdp5_option && rdp4_option) || (options.rdp4 >= 0 && options.rdp5 >= 0))
+	{
+                error("Cannot specify both RDP4 and RDP5\n");
+		exit(1);
+	}
+	if (options.rdp4 == 1 && !rdp5_option)
+	        g_use_rdp5 = False;
+	if (options.rdp5 == 1 && !rdp4_option)
+	        g_use_rdp5 = True;
+	
+	
+	if (!rdp_compression_option && options.compression)
+	{ 
+	        DEBUG(("rdp compression enabled\n"));
+	        flags |= (RDP_LOGON_COMPRESSION | RDP_LOGON_COMPRESSION2);
+	}
+
+	if (!perf_option && options.performance)
+	        g_rdp5_performanceflags = set_rdp5_perfflags(options.performance);
+		
+        if ( (password[0] == 0) && options.password )
+        {
+                STRNCPY(password, options.password, sizeof(password));
+                flags |= RDP_LOGON_AUTO;
+        }
+
+        if ( !geometry_option && options.geometry )
+        {
+                g_fullscreen = False;
+                parse_geometry(options.geometry);
+        }
+	
+	if ( g_win_button_size == 0 && options.buttonsize ) 
+	{
+	        if (!strcmp(options.buttonsize, "standard"))
+		        g_win_button_size = 18;
+		else
+		        g_win_button_size = strtol(options.buttonsize, &p, 10); 
+        }
+	
+	if ( g_title[0] == 0 && options.title )
+	        STRNCPY(g_title, options.title, sizeof(g_title));
+		
 	if (g_seamless_rdp)
 	{
 		if (g_win_button_size)
@@ -838,7 +815,7 @@ main(int argc, char *argv[])
 		g_grab_keyboard = False;
 	}
 
-	if (!username_option)
+	if (!username_option && !options.username)
 	{
 		pw = getpwuid(getuid());
 		if ((pw == NULL) || (pw->pw_name == NULL))
@@ -914,7 +891,7 @@ main(int argc, char *argv[])
 #ifdef WITH_RDPSND
 	if (g_rdpsnd)
 	{
-		if (!rdpsnd_init(rdpsnd_optarg))
+		if (!rdpsnd_init(g_rdpsnd_optarg))
 		{
 			warning("Initializing sound-support failed!\n");
 		}
@@ -1625,3 +1602,184 @@ rd_lock_file(int fd, int start, int len)
 		return False;
 	return True;
 }
+
+int 
+parse_geometry(char *g)
+{
+    char *p;
+
+    if (!strcmp(g, "workarea"))
+    {
+            g_width = g_height = 0;
+            return 0;
+    }
+
+    g_width = strtol(g, &p, 10);
+    if (g_width <= 0)
+    {
+            error("invalid geometry\n");
+            return 1;
+    }
+
+    if (*p == 'x')
+            g_height = strtol(p + 1, &p, 10);
+
+    if (g_height <= 0)
+    {
+            error("invalid geometry\n");
+            return 1;
+    }
+
+    if (*p == '%')
+    {
+            g_width = -g_width;
+            p++;
+    }
+
+    if (*p == '+' || *p == '-')
+    {
+            g_pos |= (*p == '-') ? 2 : 1;
+            g_xpos = strtol(p, &p, 10);
+    }
+    if (*p == '+' || *p == '-')
+    {
+            g_pos |= (*p == '-') ? 4 : 1;
+            g_ypos = strtol(p, NULL, 10);
+    }
+
+    return 0;
+
+}
+
+int   
+check_server_depth(int i)
+{
+    if (i != 8  && i != 16 &&
+        i != 15 && i != 24 &&
+	i != 32 )
+        error("Invalid server colour depth.\n");
+    return 0;
+}
+
+
+int 
+set_rdp5_perfflags(char *p)
+{
+    if (str_startswith(p, "m"))   /* modem */ 
+        return RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS | RDP5_NO_THEMING;
+    else if (str_startswith(p, "b")) /* broadband */
+        return RDP5_NO_WALLPAPER; 
+    else if (str_startswith(p, "l")) /* lan */
+        return RDP5_DISABLE_NOTHING; 
+    else 
+        return strtol(p, NULL, 16);
+}
+
+
+int 
+parse_redirect(char *optarg)
+{
+    char *p;
+    uint32 flags = 0;
+    if (str_startswith(optarg, "sound"))
+    {
+        printf("FOUND SOUND IN PARSE DIREC\n");
+        optarg += 5;
+	
+	if (*optarg == ':')
+	{
+	    optarg++;
+	    while ((p = next_arg(optarg, ',')))
+	    {
+	            if (str_startswith(optarg, "remote"))
+		        flags |= RDP_LOGON_LEAVE_AUDIO;
+
+		    if (str_startswith(optarg, "local"))
+#ifdef WITH_RDPSND
+
+		    {
+	                g_rdpsnd_optarg = 
+			          next_arg(optarg, ':');
+		        g_rdpsnd = True;
+		    }
+
+#else
+		        warning("Not compiled with sound support\n");
+#endif
+
+                    if (str_startswith(optarg, "off"))
+#ifdef WITH_RDPSND
+		            g_rdpsnd = False;
+#else
+		            warning("Not compiled with sound support\n");
+#endif
+
+		    optarg = p;
+            }
+	}
+	else
+	{
+#ifdef WITH_RDPSND
+	    g_rdpsnd = True;
+#else
+	    warning("Not compiled with sound support\n");
+#endif
+	}
+    }
+    else if (str_startswith(optarg, "disk"))
+    {
+        /* -r disk:h:=/mnt/floppy */
+	disk_enum_devices(&g_num_devices, optarg + 4);
+    }
+    else if (str_startswith(optarg, "comport"))
+    {
+        serial_enum_devices(&g_num_devices, optarg + 7);
+    }
+    else if (str_startswith(optarg, "lspci"))
+    {
+        g_lspci_enabled = True;
+    }
+    else if (str_startswith(optarg, "lptport"))
+    {
+        parallel_enum_devices(&g_num_devices, optarg + 7);
+    }
+    else if (str_startswith(optarg, "printer"))
+    {
+        printer_enum_devices(&g_num_devices, optarg + 7);
+    }
+    else if (str_startswith(optarg, "clientname"))
+    {
+        g_rdpdr_clientname = xmalloc(strlen(optarg + 11) + 1);
+        strcpy(g_rdpdr_clientname, optarg + 11);
+    }
+    else if (str_startswith(optarg, "clipboard"))
+    {
+        optarg += 9;
+
+	if (*optarg == ':')
+	{
+	    optarg++;
+
+	    if (str_startswith(optarg, "off")) {
+	        g_rdpclip = False;
+            }
+	    else
+	        cliprdr_set_mode(optarg);
+	}
+	else
+	    g_rdpclip = True;
+    }
+    else if (strncmp("scard", optarg, 5) == 0)
+    {
+#ifdef WITH_SCARD
+        scard_enum_devices(&g_num_devices, optarg + 5);
+#else
+        warning("Not compiled with smartcard support\n");
+#endif
+    }
+    else
+    {
+        warning("Unknown redirection argument\n\n\tPossible arguments are: comport, disk, lptport, printer, sound, clipboard, scard\n");
+    }
+    return flags;
+}
diff -rupN rdesktop-1.6.0/readconf.c rdesktop-1.6.0-CONFIG-PATCH/readconf.c
--- rdesktop-1.6.0/readconf.c	1969-12-31 19:00:00.000000000 -0500
+++ rdesktop-1.6.0-CONFIG-PATCH/readconf.c	2010-07-10 12:42:30.000000000 -0400
@@ -0,0 +1,461 @@
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include "readconf.h"
+
+#define WHITESPACE " \t\r\n"
+#define QUOTE   "\""
+
+
+typedef enum {
+    oBadOption, oHostname, oUser, oHost, oPort, oDomain,
+    oPassword, oFullscreen, oShell, oDir, oCHostname, oKeymap,
+    oGeometry, oForceBitmapUpdates, oUseBackingStore, oEncryption,
+    oPacketEncryption, oSendmotion, oOwncolmap, oHideDecorations,
+    oGrabKeyboard, oButtonSize, oTitle, oNumlockSync, oEmbedWnd,
+    oColourDepth, oCompression, oPerformance, oBitmapCachePersist,
+    oConsole, oRdp4, oRdp5, oRedirect
+} OpCodes;
+
+
+
+static struct {
+        const char *name;
+        OpCodes opcode;
+} keywords[] = {
+    { "hostname", oHostname },
+    { "user", oUser },
+    { "host", oHost },
+    { "port", oPort },
+    { "domain", oDomain },
+    { "password", oPassword },
+    { "fullscreen", oFullscreen },
+    { "shell", oShell },
+    { "directory", oDir },
+    { "clienthostname", oCHostname },
+    { "keymap", oKeymap },
+    { "geometry", oGeometry },
+    { "forcebitmapupdates", oForceBitmapUpdates },
+    { "usebackingstore", oUseBackingStore },
+    { "encryption", oEncryption },
+    { "packetencryption", oPacketEncryption },
+    { "sendmotion", oSendmotion },
+    { "owncolmap", oOwncolmap },
+    { "hidedecorations", oHideDecorations },
+    { "grabkeyboard", oGrabKeyboard }, 
+    { "buttonsize", oButtonSize },
+    { "title", oTitle },
+    { "numlocksync", oNumlockSync },
+    { "embedwindow", oEmbedWnd },
+    { "colourdepth", oColourDepth },
+    { "compression", oCompression },
+    { "performance", oPerformance },
+    { "bitmapcachepersist", oBitmapCachePersist },
+    { "rdp4", oRdp4 },
+    { "rdp5", oRdp5 },
+    { "console", oConsole },
+    { "redirect", oRedirect },
+    { NULL, oBadOption }
+};
+
+
+void initialize_options(Options * options)
+{
+    memset(options, 'X', sizeof(*options));
+    options->username = NULL;
+    options->hostname = NULL;
+    options->domain = NULL; 
+    options->password = NULL;
+    options->shell = NULL;
+    options->directory = NULL;
+    options->chostname = NULL;
+    options->keymapname = NULL;
+    options->buttonsize = NULL;
+    options->title = NULL;
+    options->geometry = NULL;
+    options->performance = NULL;
+    options->redirect = NULL;
+    options->fullscreen = -1;
+    options->port = -1;
+    options->forcebitmapupdates = -1; 
+    options->usebackingstore = -1;
+    options->encryption = -1;
+    options->packet_encryption = -1;
+    options->sendmotion = -1;
+    options->owncolmap = -1;
+    options->hide_decorations = -1;
+    options->grabkeyboard = -1;
+    options->numlocksync = -1;
+    options->embedwnd = -1;
+    options->compression = -1;
+    options->bitmapcachepersist = -1;
+    options->colourdepth = -2;
+    options->console = -1;
+    options->rdp4 = -1;
+    options->rdp5 = -1;
+}
+
+
+int
+match_pattern(const char *s, const char *pattern)
+{
+        for (;;) {
+                /* If at end of pattern, accept if also at end of string. */
+                if (!*pattern)
+                        return !*s;
+
+                if (*pattern == '*') {
+                        /* Skip the asterisk. */
+                        pattern++;
+
+                        /* If at end of pattern, accept immediately. */
+                        if (!*pattern)
+                                return 1;
+
+                        /* If next character in pattern is known, optimize. */
+                        if (*pattern != '?' && *pattern != '*') {
+                                /*
+ *                               * Look instances of the next character in
+ *                               * pattern, and try to match starting from
+ *                               * those.
+ *                                                                                                                                     */
+                                for (; *s; s++)
+                                        if (*s == *pattern &&
+                                            match_pattern(s + 1, pattern + 1))
+                                                return 1;
+                                /* Failed. */
+                                return 0;
+                        }
+                        /*
+ *                       * Move ahead one character at a time and try to
+ *                       * match at each position.
+ *                                                                            */
+                        for (; *s; s++)
+                                if (match_pattern(s, pattern))
+                                        return 1;
+                        /* Failed. */
+                        return 0;
+                }
+                /*
+ *               * There must be at least one more character in the string.
+ *               * If we are at the end, fail.
+ *               */
+                if (!*s)
+                        return 0;
+
+                /* Check if the next character of the string is acceptable. */
+                if (*pattern != '?' && *pattern != *s)
+                        return 0;
+
+                /* Move to the next character, both in string and in pattern. */
+                s++;
+                pattern++;
+        }
+        /* NOTREACHED */
+}
+
+
+/* return next token in configuration line */
+char *
+strdelim(char **s)
+{
+        char *old;
+        int wspace = 0;
+
+        if (*s == NULL)
+                return NULL;
+
+        old = *s;
+
+        *s = strpbrk(*s, WHITESPACE QUOTE "=");
+        if (*s == NULL)
+                return (old);
+
+        if (*s[0] == '\"') {
+                memmove(*s, *s + 1, strlen(*s)); /* move nul too */
+                /* Find matching quote */
+                if ((*s = strpbrk(*s, QUOTE)) == NULL) {
+                        return (NULL);          /* no matching quote */
+                } else {
+                        *s[0] = '\0';
+                        return (old);
+                }
+        }
+
+        /* Allow only one '=' to be skipped */
+        if (*s[0] == '=')
+                wspace = 1;
+        *s[0] = '\0';
+
+        /* Skip any extra whitespace after first token */
+        *s += strspn(*s + 1, WHITESPACE) + 1;
+        if (*s[0] == '=' && !wspace)
+                *s += strspn(*s + 1, WHITESPACE) + 1;
+
+        return (old);
+}
+
+
+int
+read_config_file(const char *host, Options *options)
+{
+
+    FILE *f;
+    char *home, fn[256], line[1024];
+    int linenum, active;
+    int bad_options = 0;
+
+    home = getenv("HOME");
+    if (home == NULL)
+        return -1;
+
+    sprintf(fn, "%s/.rdesktop/config", home);
+
+    if ((f = fopen(fn, "r")) == NULL) {
+        printf("fopen failed in read confi file\n");
+        return 0;
+    }
+
+    active = 1; 
+    linenum = 0;
+    while (fgets(line, sizeof(line), f)) {
+        linenum++;
+        if (process_config_line(options, host, line, fn, linenum, &active) != 0)
+            bad_options++;
+    }
+    fclose(f);
+    if (bad_options > 0)
+    {
+        printf("FATAL: bad options\n");
+        exit(1);
+    }
+    return 1;
+}
+
+
+static OpCodes
+parse_token(const char *cp, const char *filename, int linenum)
+{
+        unsigned int i;
+
+        for (i = 0; keywords[i].name; i++)
+                if (strcasecmp(cp, keywords[i].name) == 0)
+                        return keywords[i].opcode;
+
+        printf("%s: line %d: Bad configuration option: %s",
+            filename, linenum, cp);
+        return oBadOption;
+}
+
+
+int process_config_line(Options *options, const char *host, char *line, 
+                        const char *filename, int linenum, int *activep)
+{
+        char *s, *keyword, *arg, *endofnumber, **charptr;
+        unsigned int len;
+        int opcode, value, *intptr;
+
+        /* Strip trailing whitespace */
+        for (len = strlen(line) -1; len > 0; len--) {
+                if (strchr(WHITESPACE, line[len]) == NULL)
+                        break;
+                line[len] = '\0';
+        }
+
+        s = line;
+         /* Get the keyword. (Each line is supposed to begin with a keyword). */
+        if ((keyword = strdelim(&s)) == NULL)
+                return 0;
+        /* Ignore leading whitespace. */
+        if (*keyword == '\0')
+                keyword = strdelim(&s);
+        if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
+                return 0;
+
+        opcode = parse_token(keyword, filename, linenum);
+
+        switch(opcode) {
+        case oBadOption:
+            printf("BAD OPTION!@#\n");
+            return -1;
+        case oHostname:
+            charptr = &options->hostname;
+            goto parse_string;
+        case oUser:
+            charptr = &options->username;
+            goto parse_string;
+        case oDomain:
+            charptr = &options->domain;
+            goto parse_string;
+        case oPassword:
+            charptr = &options->password;
+            goto parse_string;
+        case oShell:
+            charptr = &options->shell;
+            goto parse_string;
+        case oDir:
+            charptr = &options->directory;
+            goto parse_string;
+        case oCHostname:
+            charptr = &options->chostname;
+            goto parse_string; 
+        case oKeymap:
+            charptr = &options->keymapname;
+            goto parse_string;
+        case oGeometry:
+            charptr = &options->geometry;
+            goto parse_string;
+        case oForceBitmapUpdates:
+            intptr = &options->forcebitmapupdates;
+            goto parse_flag;
+        case oUseBackingStore:
+            intptr = &options->usebackingstore;
+            goto parse_flag;
+        case oFullscreen:
+            intptr = &options->fullscreen;
+            goto parse_flag;
+        case oEncryption:
+            intptr = &options->encryption;
+            goto parse_flag;
+        case oPacketEncryption:
+            intptr = &options->packet_encryption;
+            goto parse_flag;
+        case oSendmotion:
+            intptr = &options->sendmotion;
+            goto parse_flag;
+        case oOwncolmap:
+            intptr = &options->owncolmap;
+            goto parse_flag;
+        case oHideDecorations:
+            intptr = &options->hide_decorations;
+            goto parse_flag;
+	case oGrabKeyboard:
+            intptr = &options->grabkeyboard;
+	    goto parse_flag;
+	case oButtonSize:
+	    charptr = &options->buttonsize;
+	    goto parse_string;
+	case oTitle:
+            charptr = &options->title;
+	    goto parse_string;
+	case oPerformance:
+            charptr = &options->performance;
+	    goto parse_string;
+	case oNumlockSync:
+	    intptr = &options->numlocksync;
+	    goto parse_flag; 
+	case oColourDepth:
+	    intptr = &options->colourdepth;
+	    goto parse_int;
+	case oEmbedWnd:
+	    intptr = &options->embedwnd;   
+	    goto parse_int;
+	case oCompression:
+            intptr = &options->compression;
+	    goto parse_flag;
+	case oBitmapCachePersist:
+	    intptr = &options->bitmapcachepersist;
+            goto parse_flag;
+	case oConsole:
+	    intptr = &options->console;
+	    goto parse_flag;
+	case oRdp4:
+            intptr = &options->rdp4;
+	    goto parse_flag;
+	case oRdp5:
+            intptr = &options->rdp5;
+	    goto parse_flag;
+        case oRedirect:
+            charptr = &options->redirect;
+            goto parse_string;
+        case oPort:
+            intptr = &options->port;
+            goto parse_int;
+parse_int:
+                arg = strdelim(&s);
+                if (!arg || *arg == '\0') 
+                {
+                    printf("%.200s line %d: Missing argument.", filename, linenum);
+                    exit(1);
+                }
+                if (arg[0] < '0' || arg[0] > '9') 
+                {
+                    printf("%.200s line %d: Bad number.", filename, linenum);
+                    exit(1);
+                }
+
+                /* Octal, decimal, or hex format? */
+                value = strtol(arg, &endofnumber, 0);
+                if (arg == endofnumber)
+                {
+                        printf("%.200s line %d: Bad number.", filename, linenum);
+                        exit(1);
+                }
+                if (*activep && *intptr == -1) 
+                {
+                        *intptr = value;
+                }
+                break;
+
+        case oHost:
+            *activep = 0;
+            while ((arg = strdelim(&s)) != NULL && *arg != '\0')
+                  if (match_pattern(host, arg)) {
+                                *activep = 1;
+                                break;
+                        }
+                /* Avoid garbage check below, as strdelim is done. */
+                return 0;
+
+parse_string:
+                arg = strdelim(&s);
+                if (!arg || *arg == '\0')
+                {
+                        printf("%.200s line %d: Missing argument.", filename, linenum);
+                        exit(1);
+                }
+                if (*activep && *charptr == NULL )
+                { 
+                        *charptr = xstrdup(arg);
+                } 
+                
+                break;
+
+
+parse_flag:
+        arg = strdelim(&s);
+        if (!arg || *arg == '\0')
+        {
+            printf("%.200s line %d: Missing yes/no argument.", filename, linenum);
+            exit(1);
+        }
+
+        value = 0;      /* To avoid compiler warning... */
+        if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
+            value = 1;
+        else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
+            value = 0;
+        else
+        {
+            printf("%.200s line %d: Bad yes/no argument.", filename, linenum);
+            exit(1);
+        }
+        /* create options array so intptr=value may be used  */
+        if (*activep && *intptr == -1)
+            *intptr = value; 
+             break;
+
+         
+        default:
+            printf("blah blah unimplemented\n");
+        }
+
+    /* Check that there is no garbage at end of line. */
+        if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
+                printf("garbage at end of line\n");
+                exit(1);
+        }
+        return 0;
+}
diff -rupN rdesktop-1.6.0/readconf.h rdesktop-1.6.0-CONFIG-PATCH/readconf.h
--- rdesktop-1.6.0/readconf.h	1969-12-31 19:00:00.000000000 -0500
+++ rdesktop-1.6.0-CONFIG-PATCH/readconf.h	2010-07-10 12:42:30.000000000 -0400
@@ -0,0 +1,39 @@
+typedef struct {
+    char *username;
+    int port;
+    char *hostname;
+    char *domain;
+    char *password;
+    char *shell;
+    char *directory;
+    char *chostname;
+    char *keymapname;
+    char *geometry;
+    char *buttonsize;
+    char *title;
+    char *performance;
+    char *redirect;
+    int fullscreen;
+    int forcebitmapupdates;
+    int usebackingstore;
+    int encryption;
+    int packet_encryption;
+    int sendmotion;
+    int owncolmap;
+    int hide_decorations;
+    int grabkeyboard;
+    int numlocksync;
+    int embedwnd;
+    int colourdepth;
+    int compression;
+    int bitmapcachepersist;
+    int console;
+    int rdp4;
+    int rdp5;
+} Options;
+
+
+void     initialize_options(Options *);
+int      read_config_file(const char *, Options *);
+int process_config_line(Options *, const char *, char *, const char *, int, int *);
+char *xstrdup(const char *s);
signature.asc (application/pgp-signature, 189 B)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (GNU/Linux)

iD8DBQFMOMqQbz7ydCFLbp4RAmPcAJ97ueVsk43u15CQb/jAJX4tIkk3vACeLPie
Tt8EHZPradCNHy95OUym1ow=
=GLH9
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.