[Message Prev][Message Next][Thread Prev][Thread Next][Message Index][Thread Index]

[PATCH] gnu-style command line options + man page



Hi,

* Long style command line options. eg. --fullscreen and --username. 
short style '-f' and '-u' can still be used and can be used interchangeably.

* Man page.  Added the new usage to the man page.

-Kervin

-- 
http://linuxquestions.org/ - Ask linux questions, give linux help.
diff -ruN rdesktop-1.1.0/Makefile rdesktop/Makefile
--- rdesktop-1.1.0/Makefile	Sat Sep 15 08:34:32 2001
+++ rdesktop/Makefile	Thu Jan 17 15:47:35 2002
@@ -16,7 +16,7 @@
 BINDIR   = $(EPREFIX)/bin
 MANDIR   = $(PREFIX)/man
 
-RDPOBJ   = rdesktop.o tcp.o iso.o mcs.o secure.o licence.o rdp.o orders.o bitmap.o cache.o xwin.o
+RDPOBJ   = rdesktop.o tcp.o iso.o mcs.o secure.o licence.o rdp.o orders.o bitmap.o cache.o xwin.o cli_parse.o
 CRYPTOBJ = crypto/rc4_enc.o crypto/rc4_skey.o crypto/md5_dgst.o crypto/sha1dgst.o crypto/bn_exp.o crypto/bn_mul.o crypto/bn_div.o crypto/bn_sqr.o crypto/bn_add.o crypto/bn_shift.o crypto/bn_asm.o crypto/bn_ctx.o crypto/bn_lib.o
 
 include Makeconf  # local configuration
diff -ruN rdesktop-1.1.0/cli_parse.c rdesktop/cli_parse.c
--- rdesktop-1.1.0/cli_parse.c	Wed Dec 31 19:00:00 1969
+++ rdesktop/cli_parse.c	Thu Jan 17 18:00:16 2002
@@ -0,0 +1,61 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "cli_parse.h"
+
+/* parse long opts, leave short opts alone  */
+/* expects to be sent argv, and argc before */
+/* being parsed by getopts()                */
+
+struct cli_opt *parse_long_opts(int *c, char **v)
+{
+	int i = 1;
+	int j = 0;
+	struct cli_opt *retval = NULL;
+	struct cli_opt **curr_opt = NULL;
+	int count = *c;
+
+	/* loop through all arguments */
+	while(i < *c)
+	{
+		/* if it begins with "--" */
+		if( strlen(v[i]) > 2 && strncmp(v[i], "--", 2) == 0 )
+		{
+			/* We have a long opt, decrement return count */
+			(*c)--;
+
+			if( retval == NULL )
+				curr_opt = &retval;
+			else curr_opt = &((*curr_opt)->next);
+
+			*curr_opt = calloc( 1, sizeof(struct cli_opt) );
+			if( *curr_opt == NULL )
+			{
+				fprintf(stderr, "ERROR: malloc failed.\n");
+				exit(1);
+			}
+			
+			(*curr_opt)->name = strdup( &v[i][2] );
+
+			/* remove that option from argv */
+			/* should I? -> free(v[i])      */
+			for(j=i;j < *c;j++)
+				v[j] = v[j+1];
+
+			/* If the next option does not begin with  a dash */
+			/* Then it is taken as a arguement for the current*/
+			/* option                                         */
+			if(i < *c && v[i][0] != '-')
+			{
+				(*c)--;
+				(*curr_opt)->value = strdup( v[i] );
+
+				for(j=i;j < *c;j++)
+					v[j] = v[j+1];
+			}
+		}
+		else i++;
+	}
+
+	return retval;
+}
diff -ruN rdesktop-1.1.0/cli_parse.h rdesktop/cli_parse.h
--- rdesktop-1.1.0/cli_parse.h	Wed Dec 31 19:00:00 1969
+++ rdesktop/cli_parse.h	Thu Jan 17 15:54:00 2002
@@ -0,0 +1,12 @@
+#ifndef CLI_PARSE_H
+#define CLI_PARSE_H
+
+struct cli_opt
+{
+	char *name;
+	char *value;
+	struct cli_opt *next;
+};
+
+struct cli_opt *parse_long_opts( int *c, char **v );
+#endif
diff -ruN rdesktop-1.1.0/rdesktop.1 rdesktop/rdesktop.1
--- rdesktop-1.1.0/rdesktop.1	Wed Dec 31 19:00:00 1969
+++ rdesktop/rdesktop.1	Thu Jan 17 22:17:07 2002
@@ -0,0 +1,91 @@
+.\" Process this file with
+.\" groff -man -Tascii rdesktop.1
+.\" Thanks to http://linuxdoc.org/HOWTO/mini/Man-Page.html
+.TH RDESKTOP 1 "JANUARY 2002" Unix "User Manuals"
+.SH NAME
+rdesktop \- A Remote Desktop Protocol client.
+.SH SYNOPSIS
+.B rdesktop [ -u
+.I username
+.B ] [ -d
+.I domain
+.B ] [ -s
+.I shell
+.B ] [ -p
+.I password
+.B ] [ -n
+.I hostname
+.B ] [ -k
+.I keylayout
+.B ] [ -g
+.I width
+.B x
+.I height
+.B ] [ -f ] [ -b ] [ -e ] [ -m ] [ -l ] [ -h ]
+.I remote-host
+.SH DESCRIPTION
+.B rdesktop
+ is an open source client for Windows NT Terminal Server and Windows 2000 Terminal Services, capable of natively speaking Remote Desktop Protocol (RDP) in order to present the user's NT desktop. Unlike Citrix ICA, no server extensions are required.
+
+rdesktop currently runs on most UNIX based platforms with the X Window System, and other ports should be fairly straightforward.
+
+rdesktop's homepage is at
+.BR http://www.rdesktop.org/ 
+ . Please visit this site for current information on rdesktop and how to help or get help on the rdesktop mailing-list.
+.SH OPTIONS
+.IP "-u username, --username username "
+Specify a 
+.I username
+for connection.
+.IP "-d domain, --domain domain"
+Specify the windows domain you intend to log into.
+.IP "-s shell, --shell shell"
+Specify shell to be used on RDP server.
+.IP "-c directory, --directory directory"
+Specify remote directory.
+.IP "-p password, --password password"
+Specify password to use for connection.
+.IP "-n hostname, --hostname hostname"
+Specify local hostname
+.IP "-k keylayout, --keylayout keylayout"
+Specify the keylayout to use.  
+.I keylayout
+is a numerical value.
+.IP "-g WxH, --geometry WxH"
+Specify the application's window dimensions.  Both the 
+.I W 
+and 
+.I H
+, that is 
+.I Width
+and 
+.I Height
+, are expected to be numerical values.
+.IP "-f, --fullscreen"
+Run application in fullscreen mode.
+.IP "-b, --bitmap-updates"
+Force bitmap updates.
+.IP "-e, --disable-encryption"
+Turn off encryption.
+.IP "-m, --disable-motion-events"
+Do not send motion events.
+.IP "-l, --disable-licence-request"
+Do not request license.
+.IP "-h or -?, --help"
+Show usage information
+.SH FILES
+.I none
+.RS
+No files used.
+.SH DIAGNOSTICS
+The following diagnostics may be issued on stderr:
+ 
+Connection reset by peer
+.RS
+The remote server has disconnected
+.SH BUGS
+Please visit the rdesktop mailing list for bug reports.
+.SH AUTHOR
+Matt Chapman <matthewc@cse.unsw.edu.au>
+.SH "SEE ALSO"
+.BR "http://www.rdesktop.org/";
diff -ruN rdesktop-1.1.0/rdesktop.c rdesktop/rdesktop.c
--- rdesktop-1.1.0/rdesktop.c	Sat Sep 15 08:34:32 2001
+++ rdesktop/rdesktop.c	Thu Jan 17 22:23:15 2002
@@ -28,6 +28,8 @@
 #include <sys/times.h>		/* times */
 #include "rdesktop.h"
 
+#include "cli_parse.h"
+
 char username[16];
 char hostname[16];
 int width;
@@ -46,19 +48,20 @@
 usage(char *program)
 {
 	printf("Usage: %s [options] server\n", program);
-	printf("   -u: user name\n");
-	printf("   -d: domain\n");
-	printf("   -s: shell\n");
-	printf("   -c: working directory\n");
-	printf("   -p: password (autologon)\n");
-	printf("   -n: client hostname\n");
-	printf("   -k: keyboard layout (hex)\n");
-	printf("   -g: desktop geometry (WxH)\n");
-	printf("   -f: full-screen mode\n");
-	printf("   -b: force bitmap updates\n");
-	printf("   -e: disable encryption (French TS)\n");
-	printf("   -m: do not send motion events\n");
-	printf("   -l: do not request licence\n\n");
+	printf("   -u or --username          : user name\n");
+	printf("   -d or --domain            : domain\n");
+	printf("   -s or --shell             : shell\n");
+	printf("   -c or --directory         : working directory\n");
+	printf("   -p or --password          : password (autologon)\n");
+	printf("   -n or --hostname          : client hostname\n");
+	printf("   -k or --keylayout         : keyboard layout (hex)\n");
+	printf("   -g or --geometry          : desktop geometry (WxH)\n");
+	printf("   -f or --fullscreen        : full-screen mode\n");
+	printf("   -b or --bitmap-updates    : force bitmap updates\n");
+	printf("   -l or --help              : Print this message\n");
+	printf("   -e or --disable-encryption          : disable encryption (French TS)\n");
+	printf("   -m or --disable-motion-events       : do not send motion events\n");
+	printf("   -l or --disable-licence-request     : do not request licence\n\n");
 }
 
 /* Client program */
@@ -75,6 +78,8 @@
 	char *server, *p;
 	uint32 flags;
 	int c;
+	struct cli_opt *option_list;
+	struct cli_opt *option_list_temp;
 
 	printf("rdesktop: A Remote Desktop Protocol client.\n");
 	printf("Version " VERSION ". Copyright (C) 1999-2001 Matt Chapman.\n");
@@ -83,6 +88,125 @@
 	flags = RDP_LOGON_NORMAL;
 	domain[0] = password[0] = shell[0] = directory[0] = 0;
 
+	/* call parse_long_opts() to parse gnu-style command options */
+	option_list = parse_long_opts(&argc, argv);
+	while( option_list != NULL)
+	{
+		if( strncmp( "username", option_list->name, strlen("username") ) == 0 )
+		{
+			if( option_list->value == NULL )
+			{
+				error("username must have an aguement.\n");
+				return 1;
+			}
+			STRNCPY(username, option_list->value, sizeof(username));
+		}
+		else if( strncmp( "domain", option_list->name, strlen("domain") ) == 0 )
+		{
+			if( option_list->value == NULL )
+			{
+				error("domain must have an argument.\n");
+				return 1;
+			}
+			STRNCPY(domain, option_list->value, sizeof(domain));
+		}
+		else if( strncmp( "shell", option_list->name, strlen("shell") ) == 0 )
+		{
+			if( option_list->value == NULL )
+			{
+				error("shell must have an argument.\n");
+				return 1;
+			}
+			STRNCPY(shell, option_list->value, sizeof(shell));
+		}
+		else if( strncmp( "directory", option_list->name, strlen("directory") ) == 0 )
+		{
+			if( option_list->value == NULL )
+			{
+				error("directory must have an argument.\n");
+				return 1;
+			}
+			STRNCPY(shell, option_list->value, sizeof(directory));
+		}
+		else if( strncmp( "password", option_list->name, strlen("password") ) == 0 )
+		{
+			if( option_list->value == NULL )
+			{
+				error("shell must have an argument.\n");
+				return 1;
+			}
+			STRNCPY(password, option_list->value, sizeof(password));
+			flags |= RDP_LOGON_AUTO;
+		}
+		else if( strncmp( "hostname", option_list->name, strlen("hostname") ) == 0 )
+		{
+			if( option_list->value == NULL )
+			{
+				error("hostname must have an argument.\n");
+				return 1;
+			}
+			STRNCPY(hostname, option_list->value, sizeof(hostname));
+		}
+		else if( strncmp( "keylayout", option_list->name, strlen("keylayout") ) == 0 )
+		{
+			if( option_list->value == NULL )
+			{
+				error("keylayout must have an argument.\n");
+				return 1;
+			}
+
+			keylayout = strtol(option_list->value, NULL, 16);
+			if (keylayout == 0)
+			{
+				error("invalid keyboard layout\n");
+				return 1;
+			}
+		}
+		else if( strncmp( "geometry", option_list->name, strlen("geometry") ) == 0 )
+		{
+			if( option_list->value == NULL )
+			{
+				error("geometry must have an argument.\n");
+				return 1;
+			}
+
+			width = strtol(option_list->value, &p, 10);
+			if (*p == 'x')
+				height = strtol(p+1, NULL, 10);
+
+			if ((width == 0) || (height == 0))
+			{
+				error("invalid geometry\n");
+				return 1;
+			}
+		}
+		else if( strncmp( "fullscreen", option_list->name, strlen("fullscreen") ) == 0 )
+			fullscreen = True;
+		else if( strncmp( "bitmap-updates", option_list->name, strlen("bitmap-updates") ) == 0 )
+			orders = False;
+		else if( strncmp( "disable-encryption", option_list->name, strlen("disable-encryption") ) == 0 )
+				encryption = False;
+		else if( strncmp( "disable-motion-events", option_list->name, strlen("disable-motion-events") ) == 0 )
+				sendmotion = False;
+		else if( strncmp( "disable-licence-request", option_list->name, strlen("disable-licence-request") ) == 0 )
+				licence = False;
+		else if( strncmp( "help", option_list->name, strlen("help") ) == 0 )
+		{
+				usage(argv[0]);
+				return 1;
+		}
+		else
+		{
+			error("'%s' is an unregonized option.\n", option_list->name);
+			return 1;
+		}
+
+		option_list_temp = option_list;
+		option_list = option_list->next;
+		free( option_list_temp );
+	}
+
+	/* Any option set by a long option can be overridded by a short */
 	while ((c = getopt(argc, argv, "u:d:s:c:p:n:k:g:fbemlh?")) != -1)
 	{
 		switch (c)