[PATCH] No extern declarations of optarg & co if getopt.h is available

Corinna Vinschen vinschen at redhat.com
Thu Sep 11 04:59:47 EST 2003


Hi,

I have a problem with the extern declarations of optarg, optind, etc.

We're currently moving getopt from being a statically linked function
to a dynamically linked function as part of the Cygwin DLL.  On Windows,
this requires to generate special symbols (__imp__optarg, etc.), which
is done by marking the exported variables in the corresponding header. 
Instead of

  extern char *optarg;

getopt.h now contains

  extern char __declspec(dllimport) *optarg;

I'm sorry, but that's not my invention.

Now the problem.  ssh.c, sshd.c and a lot of other files do explicitely
declare the opt* variables at the beginning of main(), even when a
getopt.h file is available.  The problem with this is, that this
explicit extern declaration overrides the declaration from getopt.h.
So instead of linking against the correct __imp__optarg symbol, the
linker tries to linked against the normal _optarg.

This could be easily circumvented by either not declaring the variables
at all in these main() funcs, or by surrounding the declarations with

  #ifndef HAVE_GETOPT_H
      extern char *optarg;
      ...
  #endif

The patch is attached.

Thanks,
Corinna

Index: scp.c
===================================================================
RCS file: /cvs/openssh_cvs/scp.c,v
retrieving revision 1.118
diff -p -u -r1.118 scp.c
--- scp.c	21 Aug 2003 23:34:41 -0000	1.118
+++ scp.c	10 Sep 2003 18:59:00 -0000
@@ -219,8 +219,10 @@ main(int argc, char **argv)
 	int ch, fflag, tflag, status;
 	double speed;
 	char *targ, *endp;
+#ifndef HAVE_GETOPT_H
 	extern char *optarg;
 	extern int optind;
+#endif
 
 	__progname = ssh_get_progname(argv[0]);
 
Index: sftp.c
===================================================================
RCS file: /cvs/openssh_cvs/sftp.c,v
retrieving revision 1.38
diff -p -u -r1.38 sftp.c
--- sftp.c	21 Aug 2003 23:34:41 -0000	1.38
+++ sftp.c	10 Sep 2003 18:59:00 -0000
@@ -129,8 +129,10 @@ main(int argc, char **argv)
 	char *ssh_program = _PATH_SSH_PROGRAM, *sftp_direct = NULL;
 	LogLevel ll = SYSLOG_LEVEL_INFO;
 	arglist args;
+#ifndef HAVE_GETOPT_H
 	extern int optind;
 	extern char *optarg;
+#endif
 
 	__progname = ssh_get_progname(argv[0]);
 	args.list = NULL;
Index: ssh-add.c
===================================================================
RCS file: /cvs/openssh_cvs/ssh-add.c,v
retrieving revision 1.74
diff -p -u -r1.74 ssh-add.c
--- ssh-add.c	21 Aug 2003 23:34:41 -0000	1.74
+++ ssh-add.c	10 Sep 2003 18:59:00 -0000
@@ -313,8 +313,10 @@ usage(void)
 int
 main(int argc, char **argv)
 {
+#ifndef HAVE_GETOPT_H
 	extern char *optarg;
 	extern int optind;
+#endif
 	AuthenticationConnection *ac = NULL;
 	char *sc_reader_id = NULL;
 	int i, ch, deleting = 0, ret = 0;
Index: ssh-agent.c
===================================================================
RCS file: /cvs/openssh_cvs/ssh-agent.c,v
retrieving revision 1.122
diff -p -u -r1.122 ssh-agent.c
--- ssh-agent.c	21 Aug 2003 23:34:41 -0000	1.122
+++ ssh-agent.c	10 Sep 2003 18:59:01 -0000
@@ -1013,8 +1013,10 @@ main(int ac, char **av)
 #ifdef HAVE_CYGWIN
 	int prev_mask;
 #endif
+#ifndef HAVE_GETOPT_H
 	extern int optind;
 	extern char *optarg;
+#endif
 	pid_t pid;
 	char pidstrbuf[1 + 3 * sizeof pid];
 
Index: ssh-keygen.c
===================================================================
RCS file: /cvs/openssh_cvs/ssh-keygen.c,v
retrieving revision 1.111
diff -p -u -r1.111 ssh-keygen.c
--- ssh-keygen.c	8 Sep 2003 23:11:33 -0000	1.111
+++ ssh-keygen.c	10 Sep 2003 18:59:01 -0000
@@ -806,8 +806,10 @@ main(int ac, char **av)
 	BIGNUM *start = NULL;
 	FILE *f;
 
+#ifndef HAVE_GETOPT_H
 	extern int optind;
 	extern char *optarg;
+#endif
 
 	__progname = ssh_get_progname(av[0]);
 
Index: ssh-keyscan.c
===================================================================
RCS file: /cvs/openssh_cvs/ssh-keyscan.c,v
retrieving revision 1.56
diff -p -u -r1.56 ssh-keyscan.c
--- ssh-keyscan.c	21 Aug 2003 23:34:41 -0000	1.56
+++ ssh-keyscan.c	10 Sep 2003 18:59:01 -0000
@@ -694,8 +694,10 @@ main(int argc, char **argv)
 	int opt, fopt_count = 0;
 	char *tname;
 
+#ifndef HAVE_GETOPT_H
 	extern int optind;
 	extern char *optarg;
+#endif
 
 	__progname = ssh_get_progname(argv[0]);
 	init_rng();
Index: ssh-rand-helper.c
===================================================================
RCS file: /cvs/openssh_cvs/ssh-rand-helper.c,v
retrieving revision 1.13
diff -p -u -r1.13 ssh-rand-helper.c
--- ssh-rand-helper.c	21 Aug 2003 23:34:41 -0000	1.13
+++ ssh-rand-helper.c	10 Sep 2003 18:59:01 -0000
@@ -766,7 +766,9 @@ main(int argc, char **argv)
 {
 	unsigned char *buf;
 	int ret, ch, debug_level, output_hex, bytes;
+#ifndef HAVE_GETOPT_H
 	extern char *optarg;
+#endif
 	LogLevel ll;
 
 	__progname = ssh_get_progname(argv[0]);
Index: ssh.c
===================================================================
RCS file: /cvs/openssh_cvs/ssh.c,v
retrieving revision 1.181
diff -p -u -r1.181 ssh.c
--- ssh.c	2 Sep 2003 12:58:22 -0000	1.181
+++ ssh.c	10 Sep 2003 18:59:02 -0000
@@ -208,8 +208,10 @@ main(int ac, char **av)
 	struct stat st;
 	struct passwd *pw;
 	int dummy;
+#ifndef HAVE_GETOPT_H
 	extern int optind, optreset;
 	extern char *optarg;
+#endif
 
 	__progname = ssh_get_progname(av[0]);
 	init_rng();
Index: sshd.c
===================================================================
RCS file: /cvs/openssh_cvs/sshd.c,v
retrieving revision 1.260
diff -p -u -r1.260 sshd.c
--- sshd.c	2 Sep 2003 12:51:17 -0000	1.260
+++ sshd.c	10 Sep 2003 18:59:02 -0000
@@ -797,8 +797,10 @@ usage(void)
 int
 main(int ac, char **av)
 {
+#ifndef HAVE_GETOPT_H
 	extern char *optarg;
 	extern int optind;
+#endif
 	int opt, sock_in = 0, sock_out = 0, newsock, j, i, fdsetsz, on = 1;
 	pid_t pid;
 	socklen_t fromlen;

-- 
Corinna Vinschen
Cygwin Developer
Red Hat, Inc.




More information about the openssh-unix-dev mailing list