diff --git a/src/ChangeLog b/src/ChangeLog
index c79bc8bc..9942941e 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,9 @@
+2003-11-06  Hrvoje Niksic  <hniksic@xemacs.org>
+
+	* main.c (init_switches): New function.  Convert option_data to
+	long_options and short_options, which can be fed to getopt_long.
+	(main): Execute command-line options by consulting option_data.
+
 2003-11-06  Hrvoje Niksic  <hniksic@xemacs.org>
 
 	* gen_sslfunc.c (ssl_read): Implement a more correct check for
diff --git a/src/init.c b/src/init.c
index a92b5e11..c0f260ed 100644
--- a/src/init.c
+++ b/src/init.c
@@ -559,6 +559,7 @@ static int
 setval_internal (int comind, const char *com, const char *val)
 {
   assert (0 <= comind && comind < countof (commands));
+  DEBUGP (("Setting %s (%d) to %s\n", com, comind, val));
   return ((*commands[comind].action) (com, val, commands[comind].closure));
 }
 
@@ -575,6 +576,7 @@ setval_internal (int comind, const char *com, const char *val)
 void
 setoptval (const char *com, const char *val)
 {
+  assert (val != NULL);
   if (!setval_internal (command_by_name (com), com, val))
     exit (2);
 }
diff --git a/src/main.c b/src/main.c
index 0f93690b..922d605b 100644
--- a/src/main.c
+++ b/src/main.c
@@ -49,6 +49,8 @@ so, delete this exception statement from your version.  */
 # include <locale.h>
 #endif /* HAVE_LOCALE_H */
 #endif /* HAVE_NLS */
+#include <assert.h>
+
 #include <errno.h>
 #ifndef errno
 extern int errno;
@@ -116,6 +118,233 @@ i18n_initialize (void)
 #endif /* HAVE_NLS */
 }
 
+/* Definition of command-line options. */
+
+#ifdef HAVE_SSL
+# define IF_SSL(x) x
+#else
+# define IF_SSL(x) NULL
+#endif
+
+#ifdef ENABLE_DEBUG
+# define IF_DEBUG(x) x
+#else
+# define IF_DEBUG(x) NULL
+#endif
+
+struct cmdline_option {
+  const char *long_name;
+  char short_name;
+  enum {
+    OPT_VALUE,
+    OPT_BOOLEAN,
+    /* Non-standard options that have to be handled specially in
+       main().  */
+    OPT__APPEND_OUTPUT,
+    OPT__CLOBBER,
+    OPT__EXECUTE,
+    OPT__HELP,
+    OPT__NO,
+    OPT__PARENT,
+    OPT__VERSION
+  } type;
+  const char *handle_cmd;	/* for standard options */
+  int argtype;			/* for non-standard options */
+};
+
+struct cmdline_option option_data[] =
+  {
+    { "accept", 'A', OPT_VALUE, "accept", -1 },
+    { "append-output", 'a', OPT__APPEND_OUTPUT, NULL, required_argument },
+    { "background", 'b', OPT_BOOLEAN, "background", -1 },
+    { "backup-converted", 'K', OPT_BOOLEAN, "backupconverted", -1 },
+    { "backups", 0, OPT_BOOLEAN, "backups", -1 },
+    { "base", 'B', OPT_VALUE, "base", -1 },
+    { "bind-address", 0, OPT_VALUE, "bindaddress", -1 },
+    { "cache", 'C', OPT_BOOLEAN, "cache", -1 },
+    { "clobber", 0, OPT__CLOBBER, NULL, optional_argument },
+    { "connect-timeout", 0, OPT_VALUE, "connecttimeout", -1 },
+    { "continue", 'c', OPT_BOOLEAN, "continue", -1 },
+    { "convert-links", 'k', OPT_BOOLEAN, "convertlinks", -1 },
+    { "cookies", 0, OPT_BOOLEAN, "cookies", -1 },
+    { "cut-dirs", 0, OPT_VALUE, "cutdirs", -1 },
+    { IF_DEBUG ("debug"), 'd', OPT_BOOLEAN, "debug", -1 },
+    { "delete-after", 0, OPT_BOOLEAN, "deleteafter", -1 },
+    { "directories", 0, OPT_BOOLEAN, "dirstruct", -1 },
+    { "directory-prefix", 'P', OPT_VALUE, "dirprefix", -1 },
+    { "dns-cache", 0, OPT_BOOLEAN, "dnscache", -1 },
+    { "dns-timeout", 0, OPT_VALUE, "dnstimeout", -1 },
+    { "domains", 'D', OPT_VALUE, "domains", -1 },
+    { "dot-style", 0, OPT_VALUE, "dotstyle", -1 },
+    { "egd-file", 0, OPT_VALUE, "egdfile", -1 },
+    { "exclude-directories", 'X', OPT_VALUE, "excludedirectories", -1 },
+    { "exclude-domains", 0, OPT_VALUE, "excludedomains", -1 },
+    { "execute", 'e', OPT__EXECUTE, NULL, required_argument },
+    { "follow-ftp", 0, OPT_BOOLEAN, "followftp", -1 },
+    { "follow-tags", 0, OPT_VALUE, "followtags", -1 },
+    { "force-directories", 'x', OPT_BOOLEAN, "dirstruct", -1 },
+    { "force-html", 'F', OPT_BOOLEAN, "forcehtml", -1 },
+    { "glob", 'g', OPT_BOOLEAN, "glob", -1 },
+    { "header", 0, OPT_VALUE, "header", -1 },
+    { "help", 'h', OPT__HELP, NULL, no_argument },
+    { "host-directories", 0, OPT_BOOLEAN, "addhostdir", -1 },
+    { "html-extension", 'E', OPT_BOOLEAN, "htmlextension", -1 },
+    { "htmlify", 0, OPT_BOOLEAN, "htmlify", -1 },
+    { "http-keep-alive", 0, OPT_BOOLEAN, "httpkeepalive", -1 },
+    { "http-passwd", 0, OPT_VALUE, "httppasswd", -1 },
+    { "http-user", 0, OPT_VALUE, "httpuser", -1 },
+    { "ignore-length", 0, OPT_BOOLEAN, "ignorelength", -1 },
+    { "ignore-tags", 'G', OPT_VALUE, "ignoretags", -1 },
+    { "include-directories", 'I', OPT_VALUE, "includedirectories", -1 },
+    { "input-file", 'i', OPT_VALUE, "input", -1 },
+    { "keep-session-cookies", 0, OPT_BOOLEAN, "keepsessioncookies", -1 },
+    { "level", 'l', OPT_VALUE, "reclevel", -1 },
+    { "limit-rate", 0, OPT_VALUE, "limitrate", -1 },
+    { "load-cookies", 0, OPT_VALUE, "loadcookies", -1 },
+    { "mirror", 'm', OPT_BOOLEAN, NULL, -1 },
+    { "no", 'n', OPT__NO, NULL, required_argument },
+    { "no-clobber", 0, OPT_BOOLEAN, "noclobber", -1 },
+    { "no-parent", 0, OPT_BOOLEAN, "noparent", -1 },
+    { "output-document", 'O', OPT_VALUE, "outputdocument", -1 },
+    { "output-file", 'o', OPT_VALUE, "logfile", -1 },
+    { "page-requisites", 'p', OPT_BOOLEAN, "pagerequisites", -1 },
+    { "parent", 0, OPT__PARENT, NULL, optional_argument },
+    { "passive-ftp", 0, OPT_BOOLEAN, "passiveftp", -1 },
+    { "post-data", 0, OPT_VALUE, "postdata", -1 },
+    { "post-file", 0, OPT_VALUE, "postfile", -1 },
+    { "progress", 0, OPT_VALUE, "progress", -1 },
+    { "proxy", 'Y', OPT_BOOLEAN, "useproxy", -1 },
+    { "proxy-passwd", 0, OPT_VALUE, "proxypasswd", -1 },
+    { "proxy-user", 0, OPT_VALUE, "proxyuser", -1 },
+    { "quiet", 'q', OPT_BOOLEAN, "quiet", -1 },
+    { "quota", 'Q', OPT_VALUE, "quota", -1 },
+    { "random-wait", 0, OPT_BOOLEAN, "randomwait", -1 },
+    { "read-timeout", 0, OPT_VALUE, "readtimeout", -1 },
+    { "recursive", 'r', OPT_BOOLEAN, "recursive", -1 },
+    { "referer", 0, OPT_VALUE, "referer", -1 },
+    { "reject", 'R', OPT_VALUE, "reject", -1 },
+    { "relative", 'L', OPT_BOOLEAN, "relativeonly", -1 },
+    { "remove-listing", 0, OPT_BOOLEAN, "removelisting", -1 },
+    { "restrict-file-names", 0, OPT_BOOLEAN, "restrictfilenames", -1 },
+    { "retr-symlinks", 0, OPT_BOOLEAN, "retrsymlinks", -1 },
+    { "retry-connrefused", 0, OPT_BOOLEAN, "retryconnrefused", -1 },
+    { "save-cookies", 0, OPT_VALUE, "savecookies", -1 },
+    { "save-headers", 0, OPT_BOOLEAN, "saveheaders", -1 },
+    { "server-response", 'S', OPT_BOOLEAN, "serverresponse", -1 },
+    { "span-hosts", 'H', OPT_BOOLEAN, "spanhosts", -1 },
+    { "spider", 0, OPT_BOOLEAN, "spider", -1 },
+    { IF_SSL ("sslcadir"), 0, OPT_VALUE, "sslcadir", -1 },
+    { IF_SSL ("sslcafile"), 0, OPT_VALUE, "sslcafile", -1 },
+    { IF_SSL ("sslcertfile"), 0, OPT_VALUE, "sslcertfile", -1 },
+    { IF_SSL ("sslcertkey"), 0, OPT_VALUE, "sslcertkey", -1 },
+    { IF_SSL ("sslcerttype"), 0, OPT_VALUE, "sslcerttype", -1 },
+    { IF_SSL ("sslcheckcert"), 0, OPT_VALUE, "sslcheckcert", -1 },
+    { IF_SSL ("sslprotocol"), 0, OPT_VALUE, "sslprotocol", -1 },
+    { "strict-comments", 0, OPT_BOOLEAN, "strictcomments", -1 },
+    { "timeout", 'T', OPT_VALUE, "timeout", -1 },
+    { "timestamping", 'N', OPT_BOOLEAN, "timestamping", -1 },
+    { "tries", 't', OPT_VALUE, "tries", -1 },
+    { "use-proxy", 'Y', OPT_BOOLEAN, "useproxy", -1 },
+    { "user-agent", 'U', OPT_VALUE, "useragent", -1 },
+    { "verbose", 'v', OPT_BOOLEAN, "verbose", -1 },
+    { "verbose", 0, OPT_BOOLEAN, "verbose", -1 },
+    { "version", 'V', OPT__VERSION, "version", no_argument },
+    { "wait", 'w', OPT_VALUE, "wait", -1 },
+    { "waitretry", 0, OPT_VALUE, "waitretry", -1 },
+  };
+
+#undef IF_DEBUG
+#undef IF_SSL
+
+static char *
+no_prefix (const char *s)
+{
+  static char buffer[1024];
+  static char *p = buffer;
+
+  char *cp = p;
+  int size = 3 + strlen (s) + 1;  /* "no-STRING\0" */
+
+  if (p + size >= buffer + sizeof (buffer))
+    abort ();
+
+  cp[0] = 'n';
+  cp[1] = 'o';
+  cp[2] = '-';
+  strcpy (cp + 3, s);
+  p += size;
+  return cp;
+}
+
+/* The arguments that that main passes to getopt_long. */
+static struct option long_options[2 * countof (option_data) + 1];
+static char short_options[128];
+
+/* Mapping between short option chars and option_data indices. */
+static unsigned char optmap[96];
+
+/* Marker for `--no-FOO' values in long_options.  */
+#define BOOLEAN_NEG_MARKER 1024
+
+static void
+init_switches (void)
+{
+  char *p = short_options;
+  int i, o = 0;
+  for (i = 0; i < countof (option_data); i++)
+    {
+      struct cmdline_option *opt = &option_data[i];
+      struct option *longopt;
+
+      if (!opt->long_name)
+	/* The option is disabled. */
+	continue;
+
+      longopt = &long_options[o++];
+      longopt->name = opt->long_name;
+      longopt->val = i;
+      if (opt->short_name)
+	{
+	  *p++ = opt->short_name;
+	  optmap[opt->short_name - 32] = longopt - long_options;
+	}
+      switch (opt->type)
+	{
+	case OPT_VALUE:
+	  longopt->has_arg = required_argument;
+          if (opt->short_name)
+	    *p++ = ':';
+	  break;
+	case OPT_BOOLEAN:
+	  /* Don't specify optional arguments for boolean short
+	     options.  They are evil because they prevent combining of
+	     short options.  */
+	  longopt->has_arg = optional_argument;
+	  /* For Boolean options, add the "--no-FOO" variant, which is
+	     identical to "--foo", except it has opposite meaning and
+	     it doesn't allow an argument.  */
+	  longopt = &long_options[o++];
+	  longopt->name = no_prefix (opt->long_name);
+	  longopt->has_arg = no_argument;
+	  /* Mask the value so we'll be able to recognize that we're
+	     dealing with the false value.  */
+	  longopt->val = i | BOOLEAN_NEG_MARKER;
+	  break;
+	default:
+	  assert (opt->argtype != -1);
+	  longopt->has_arg = opt->argtype;
+	  if (opt->short_name)
+	    {
+	      if (longopt->has_arg == required_argument)
+		*p++ = ':';
+	      /* Don't handle optional_argument */
+	    }
+	}
+    }
+  xzero (long_options[o]);
+  *p = '\0';
+}
+
 /* Print the usage message.  */
 static void
 print_usage (void)
@@ -265,119 +494,12 @@ int
 main (int argc, char *const *argv)
 {
   char **url, **t;
-  int i, c, nurl, status, append_to_log;
-
-  static struct option long_options[] =
-  {
-    /* Options without arguments: */
-    { "background", no_argument, NULL, 'b' },
-    { "backup-converted", no_argument, NULL, 'K' },
-    { "continue", no_argument, NULL, 'c' },
-    { "convert-links", no_argument, NULL, 'k' },
-    { "debug", no_argument, NULL, 'd' },
-    { "delete-after", no_argument, NULL, 136 },
-    { "dont-remove-listing", no_argument, NULL, 149 },
-    { "follow-ftp", no_argument, NULL, 142 },
-    { "force-directories", no_argument, NULL, 'x' },
-    { "force-hier", no_argument, NULL, 'x' }, /* obsolete */
-    { "force-html", no_argument, NULL, 'F'},
-    { "help", no_argument, NULL, 'h' },
-    { "html-extension", no_argument, NULL, 'E' },
-    { "ignore-length", no_argument, NULL, 138 },
-    { "keep-session-cookies", no_argument, NULL, 181 },
-    { "mirror", no_argument, NULL, 'm' },
-    { "no-clobber", no_argument, NULL, 141 },
-    { "no-directories", no_argument, NULL, 147 },
-    { "no-host-directories", no_argument, NULL, 148 },
-    { "no-host-lookup", no_argument, NULL, 150 },
-    { "no-http-keep-alive", no_argument, NULL, 156 },
-    { "no-parent", no_argument, NULL, 133 },
-    { "non-verbose", no_argument, NULL, 146 },
-    { "passive-ftp", no_argument, NULL, 139 },
-    { "page-requisites", no_argument, NULL, 'p' },
-    { "quiet", no_argument, NULL, 'q' },
-    { "random-wait", no_argument, NULL, 165 },
-    { "recursive", no_argument, NULL, 'r' },
-    { "relative", no_argument, NULL, 'L' },
-    { "retr-symlinks", no_argument, NULL, 137 },
-    { "retry-connrefused", no_argument, NULL, 174 },
-    { "save-headers", no_argument, NULL, 's' },
-    { "server-response", no_argument, NULL, 'S' },
-    { "span-hosts", no_argument, NULL, 'H' },
-    { "spider", no_argument, NULL, 132 },
-    { "strict-comments", no_argument, NULL, 177 },
-    { "timestamping", no_argument, NULL, 'N' },
-    { "verbose", no_argument, NULL, 'v' },
-    { "version", no_argument, NULL, 'V' },
-
-    /* Options accepting an argument: */
-    { "accept", required_argument, NULL, 'A' },
-    { "append-output", required_argument, NULL, 'a' },
-    { "backups", required_argument, NULL, 151 }, /* undocumented */
-    { "base", required_argument, NULL, 'B' },
-    { "bind-address", required_argument, NULL, 155 },
-    { "cache", required_argument, NULL, 'C' },
-    { "connect-timeout", required_argument, NULL, 180 },
-    { "cookies", required_argument, NULL, 160 },
-    { "cut-dirs", required_argument, NULL, 145 },
-    { "dns-timeout", required_argument, NULL, 178 },
-    { "directory-prefix", required_argument, NULL, 'P' },
-    { "dns-cache", required_argument, NULL, 175 },
-    { "domains", required_argument, NULL, 'D' },
-    { "dot-style", required_argument, NULL, 134 },
-    { "execute", required_argument, NULL, 'e' },
-    { "exclude-directories", required_argument, NULL, 'X' },
-    { "exclude-domains", required_argument, NULL, 140 },
-    { "follow-tags", required_argument, NULL, 153 },
-    { "glob", required_argument, NULL, 'g' },
-    { "header", required_argument, NULL, 131 },
-    { "htmlify", required_argument, NULL, 135 },
-    { "http-passwd", required_argument, NULL, 130 },
-    { "http-user", required_argument, NULL, 129 },
-    { "ignore-tags", required_argument, NULL, 'G' },
-    { "include-directories", required_argument, NULL, 'I' },
-    { "input-file", required_argument, NULL, 'i' },
-    { "level", required_argument, NULL, 'l' },
-    { "limit-rate", required_argument, NULL, 164 },
-    { "load-cookies", required_argument, NULL, 161 },
-    { "no", required_argument, NULL, 'n' },
-    { "output-document", required_argument, NULL, 'O' },
-    { "output-file", required_argument, NULL, 'o' },
-    { "post-data", required_argument, NULL, 167 },
-    { "post-file", required_argument, NULL, 168 },
-    { "progress", required_argument, NULL, 163 },
-    { "proxy", required_argument, NULL, 'Y' },
-    { "proxy-passwd", required_argument, NULL, 144 },
-    { "proxy-user", required_argument, NULL, 143 },
-    { "quota", required_argument, NULL, 'Q' },
-    { "read-timeout", required_argument, NULL, 179 },
-    { "reject", required_argument, NULL, 'R' },
-    { "restrict-file-names", required_argument, NULL, 176 },
-    { "save-cookies", required_argument, NULL, 162 },
-    { "timeout", required_argument, NULL, 'T' },
-    { "tries", required_argument, NULL, 't' },
-    { "user-agent", required_argument, NULL, 'U' },
-    { "referer", required_argument, NULL, 157 },
-    { "use-proxy", required_argument, NULL, 'Y' },
-#ifdef HAVE_SSL
-    { "sslcertfile", required_argument, NULL, 158 },
-    { "sslcertkey", required_argument, NULL, 159 },
-    { "egd-file", required_argument, NULL, 166 },
-    { "sslcadir",         required_argument, NULL, 169},
-    { "sslcafile",        required_argument, NULL, 170},
-    { "sslcerttype",      required_argument, NULL, 171},
-    { "sslcheckcert",     required_argument, NULL, 172},
-    { "sslprotocol",      required_argument, NULL, 173},
-#endif /* HAVE_SSL */
-    { "wait", required_argument, NULL, 'w' },
-    { "waitretry", required_argument, NULL, 152 },
-    { 0, 0, 0, 0 }
-  };
+  int i, ret, longindex;
+  int nurl, status;
+  int append_to_log = 0;
 
   i18n_initialize ();
 
-  append_to_log = 0;
-
   /* Construct the name of the executable, without the directory part.  */
   exec_name = strrchr (argv[0], PATH_SEPARATOR);
   if (!exec_name)
@@ -389,128 +511,113 @@ main (int argc, char *const *argv)
   windows_main_junk (&argc, (char **) argv, (char **) &exec_name);
 #endif
 
-  initialize (); /* sets option defaults; reads the system wgetrc and .wgetrc */
+  /* Set option defaults; read the system wgetrc and ~/.wgetrc.  */
+  initialize ();
 
-  /* [Is the order of the option letters significant?  If not, they should be
-      alphabetized, like the long_options.  The only thing I know for sure is
-      that the options with required arguments must be followed by a ':'.
-      -- Dan Harkless <wget@harkless.org>] */
-  while ((c = getopt_long (argc, argv, "\
-hpVqvdkKsxmNWrHSLcFbEY:G:g:T:U:O:l:n:i:o:a:t:D:A:R:P:B:e:Q:X:I:w:C:",
-			   long_options, (int *)0)) != EOF)
+  init_switches ();
+  longindex = -1;
+  while ((ret = getopt_long (argc, argv,
+			     short_options, long_options, &longindex)) != -1)
     {
-      switch (c)
+      int val;
+      struct cmdline_option *opt;
+      if (ret == '?')
 	{
-	  /* Options without arguments: */
-	case 132:
-	  setoptval ("spider", "on");
+	  print_usage ();
+	  printf ("\n");
+	  printf (_("Try `%s --help' for more options.\n"), exec_name);
+	  exit (2);
+	}
+
+      /* If LONGINDEX is unchanged, it means RET is referring a short
+	 option.  Look it up in the mapping table.  */
+      if (longindex == -1)
+	longindex = optmap[ret - 32];
+      val = long_options[longindex].val;
+
+      /* Use the retrieved value to locate the option in the
+	 option_data array, and to see if we're dealing with the
+	 negated "--no-FOO" variant of the boolean option "--foo".  */
+      opt = &option_data[val & ~BOOLEAN_NEG_MARKER];
+      switch (opt->type)
+	{
+	case OPT_VALUE:
+	  setoptval (opt->handle_cmd, optarg);
 	  break;
-	case 133:
-	  setoptval ("noparent", "on");
+	case OPT_BOOLEAN:
+	  if (optarg)
+	    /* The user has specified a value -- use it. */
+	    setoptval (opt->handle_cmd, optarg);
+	  else
+	    {
+	      /* NEG is true for `--no-FOO' style boolean options. */
+	      int neg = val & BOOLEAN_NEG_MARKER;
+	      setoptval (opt->handle_cmd, neg ? "0" : "1");
+	    }
 	  break;
-	case 136:
-	  setoptval ("deleteafter", "on");
+	case OPT__APPEND_OUTPUT:
+	  setoptval ("logfile", optarg);
+	  append_to_log = 1;
 	  break;
-	case 137:
-	  setoptval ("retrsymlinks", "on");
-	  break;
-	case 138:
-	  setoptval ("ignorelength", "on");
-	  break;
-	case 139:
-	  setoptval ("passiveftp", "on");
-	  break;
-	case 141:
-	  setoptval ("noclobber", "on");
-	  break;
-	case 142:
-	  setoptval ("followftp", "on");
-	  break;
-	case 145:
-	  setoptval ("cutdirs", optarg);
-	  break;
-	case 146:
-	  setoptval ("verbose", "off");
-	  break;
-	case 147:
-	  setoptval ("dirstruct", "off");
-	  break;
-	case 148:
-	  setoptval ("addhostdir", "off");
-	  break;
-	case 149:
-	  setoptval ("removelisting", "off");
-	  break;
-	case 155:
-	  setoptval ("bindaddress", optarg);
- 	  break;
-	case 156:
-	  setoptval ("httpkeepalive", "off");
-	  break;
-	case 165:
-	  setoptval ("randomwait", "on");
-	  break;
-	case 'b':
-	  setoptval ("background", "on");
-	  break;
-	case 'c':
-	  setoptval ("continue", "on");
-	  break;
-	case 'd':
-#ifdef ENABLE_DEBUG
-	  setoptval ("debug", "on");
-#else
-	  fprintf (stderr, _("%s: debug support not compiled in.\n"),
-		   exec_name);
-#endif
-	  break;
-	case 'E':
-	  setoptval ("htmlextension", "on");
-	  break;
-	case 'F':
-	  setoptval ("forcehtml", "on");
-	  break;
-	case 'H':
-	  setoptval ("spanhosts", "on");
-	  break;
-	case 'h':
+	case OPT__HELP:
 	  print_help ();
 #ifdef WINDOWS
 	  ws_help (exec_name);
 #endif
 	  exit (0);
 	  break;
-	case 'K':
-	  setoptval ("backupconverted", "on");
+	case OPT__EXECUTE:
+	  run_command (optarg);
 	  break;
-	case 'k':
-	  setoptval ("convertlinks", "on");
-	  break;
-	case 'L':
-	  setoptval ("relativeonly", "on");
-	  break;
-	case 'm':
-	  setoptval ("mirror", "on");
-	  break;
-	case 'N':
-	  setoptval ("timestamping", "on");
-	  break;
-	case 'p':
-	  setoptval ("pagerequisites", "on");
-	  break;
-	case 'S':
-	  setoptval ("serverresponse", "on");
-	  break;
-	case 's':
-	  setoptval ("saveheaders", "on");
-	  break;
-	case 'q':
-	  setoptval ("quiet", "on");
-	  break;
-	case 'r':
-	  setoptval ("recursive", "on");
-	  break;
-	case 'V':
+	case OPT__NO:
+	  {
+	    /* We support real --no-FOO flags now, but keep these
+	       short options for convenience and backward
+	       compatibility.  */
+	    char *p;
+	    for (p = optarg; *p; p++)
+	      switch (*p)
+		{
+		case 'v':
+		  setoptval ("verbose", "0");
+		  break;
+		case 'H':
+		  setoptval ("addhostdir", "0");
+		  break;
+		case 'd':
+		  setoptval ("dirstruct", "0");
+		  break;
+		case 'c':
+		  setoptval ("noclobber", "1");
+		  break;
+		case 'p':
+		  setoptval ("noparent", "1");
+		  break;
+		default:
+		  printf (_("%s: illegal option -- `-n%c'\n"), exec_name, *p);
+		  print_usage ();
+		  printf ("\n");
+		  printf (_("Try `%s --help\' for more options.\n"), exec_name);
+		  exit (1);
+		}
+	    break;
+	  }
+	case OPT__PARENT:
+	case OPT__CLOBBER:
+	  {
+	    /* The wgetrc commands are named noparent and noclobber,
+	       so we must revert the meaning of the cmdline options
+	       before passing the value to setoptval.  */
+	    int flag = 1;
+	    if (optarg)
+	      flag = (*optarg == '1' || TOLOWER (*optarg) == 'y'
+		      || (TOLOWER (optarg[0]) == 'o'
+			  && TOLOWER (optarg[1]) == 'n'));
+	    setoptval (opt->type == OPT__PARENT ? "noparent" : "noclobber",
+		       flag ? "0" : "1");
+	    break;
+	  }
+	case OPT__VERSION:
 	  printf ("GNU Wget %s\n\n", version_string);
 	  printf ("%s", _("\
 Copyright (C) 2003 Free Software Foundation, Inc.\n"));
@@ -522,234 +629,9 @@ GNU General Public License for more details.\n"));
 	  printf (_("\nOriginally written by Hrvoje Niksic <hniksic@xemacs.org>.\n"));
 	  exit (0);
 	  break;
-	case 'v':
-	  setoptval ("verbose", "on");
-	  break;
-	case 'x':
-	  setoptval ("dirstruct", "on");
-	  break;
-	case 174:
-	  setoptval ("retryconnrefused", "on");
-	  break;
-	case 177:
-	  setoptval ("strictcomments", "on");
-	  break;
-	case 181:
-	  setoptval ("keepsessioncookies", "on");
-	  break;
-
-	  /* Options accepting an argument: */
-	case 129:
-	  setoptval ("httpuser", optarg);
-	  break;
-	case 130:
-	  setoptval ("httppasswd", optarg);
-	  break;
-	case 131:
-	  setoptval ("header", optarg);
-	  break;
-	case 134:
-	  setoptval ("dotstyle", optarg);
-	  break;
-	case 135:
-	  setoptval ("htmlify", optarg);
-	  break;
-	case 140:
-	  setoptval ("excludedomains", optarg);
-	  break;
-	case 143:
-	  setoptval ("proxyuser", optarg);
-	  break;
-	case 144:
-	  setoptval ("proxypasswd", optarg);
-	  break;
-	case 151:
-	  setoptval ("backups", optarg);
-	  break;
-	case 152:
-	  setoptval ("waitretry", optarg);
-	  break;
-	case 153:
-	  setoptval ("followtags", optarg);
-	  break;
-	case 160:
-	  setoptval ("cookies", optarg);
-	  break;
-	case 161:
-	  setoptval ("loadcookies", optarg);
-	  break;
-	case 162:
-	  setoptval ("savecookies", optarg);
-	  break;
-	case 163:
-	  setoptval ("progress", optarg);
-	  break;
-	case 164:
-	  setoptval ("limitrate", optarg);
-	  break;
-	case 157:
-	  setoptval ("referer", optarg);
-	  break;
-#ifdef HAVE_SSL
-	case 158:
-	  setoptval ("sslcertfile", optarg);
-	  break;
-	case 159:
-	  setoptval ("sslcertkey", optarg);
-	  break;
-	case 166:
-	  setoptval ("egdfile", optarg);
-	  break;
-	case 169:
-	  setoptval ("sslcadir", optarg);
-	  break;
-	case 170:
-	  setoptval ("sslcafile", optarg);
-	  break;
-	case 171:
-	  setoptval ("sslcerttype", optarg);
-	  break;
-	case 172:
-	  setoptval ("sslcheckcert", optarg);
-	  break;
-	case 173:
-	  setoptval ("sslprotocol", optarg);
-	  break;
-#endif /* HAVE_SSL */
-	case 167:
-	  setoptval ("postdata", optarg);
-	  break;
-	case 168:
-	  setoptval ("postfile", optarg);
-	  break;
-	case 175:
-	  setoptval ("dnscache", optarg);
-	  break;
-	case 176:
-	  setoptval ("restrictfilenames", optarg);
-	  break;
-	case 178:
-	  setoptval ("dnstimeout", optarg);
-	  break;
-	case 179:
-	  setoptval ("readtimeout", optarg);
-	  break;
-	case 180:
-	  setoptval ("connecttimeout", optarg);
-	  break;
-	case 'A':
-	  setoptval ("accept", optarg);
-	  break;
-	case 'a':
-	  setoptval ("logfile", optarg);
-	  append_to_log = 1;
-	  break;
-	case 'B':
-	  setoptval ("base", optarg);
-	  break;
-	case 'C':
-	  setoptval ("cache", optarg);
-	  break;
-	case 'D':
-	  setoptval ("domains", optarg);
-	  break;
-	case 'e':
-	  run_command (optarg);
-	  break;
-	case 'G':
-	  setoptval ("ignoretags", optarg);
-	  break;
-	case 'g':
-	  setoptval ("glob", optarg);
-	  break;
-	case 'I':
-	  setoptval ("includedirectories", optarg);
-	  break;
-	case 'i':
-	  setoptval ("input", optarg);
-	  break;
-	case 'l':
-	  setoptval ("reclevel", optarg);
-	  break;
-	case 'n':
-	  {
-	    /* #### What we really want here is --no-foo. */
-	    char *p;
-
-	    for (p = optarg; *p; p++)
-	      switch (*p)
-		{
-		case 'v':
-		  setoptval ("verbose", "off");
-		  break;
-		case 'H':
-		  setoptval ("addhostdir", "off");
-		  break;
-		case 'd':
-		  setoptval ("dirstruct", "off");
-		  break;
-		case 'c':
-		  setoptval ("noclobber", "on");
-		  break;
-		case 'r':
-		  setoptval ("removelisting", "off");
-		  break;
-		case 'p':
-		  setoptval ("noparent", "on");
-		  break;
-		case 'k':
-		  setoptval ("httpkeepalive", "off");
-		  break;
-		default:
-		  printf (_("%s: illegal option -- `-n%c'\n"), exec_name, *p);
-		  print_usage ();
-		  printf ("\n");
-		  printf (_("Try `%s --help\' for more options.\n"), exec_name);
-		  exit (1);
-		}
-	    break;
-	  }
-	case 'O':
-	  setoptval ("outputdocument", optarg);
-	  break;
-	case 'o':
-	  setoptval ("logfile", optarg);
-	  break;
-	case 'P':
-	  setoptval ("dirprefix", optarg);
-	  break;
-	case 'Q':
-	  setoptval ("quota", optarg);
-	  break;
-	case 'R':
-	  setoptval ("reject", optarg);
-	  break;
-	case 'T':
-	  setoptval ("timeout", optarg);
-	  break;
-	case 't':
-	  setoptval ("tries", optarg);
-	  break;
-	case 'U':
-	  setoptval ("useragent", optarg);
-	  break;
-	case 'w':
-	  setoptval ("wait", optarg);
-	  break;
-	case 'X':
-	  setoptval ("excludedirectories", optarg);
-	  break;
-	case 'Y':
-	  setoptval ("useproxy", optarg);
-	  break;
-
-	case '?':
-	  print_usage ();
-	  printf ("\n");
-	  printf (_("Try `%s --help' for more options.\n"), exec_name);
-	  exit (0);
-	  break;
 	}
+
+      longindex = -1;
     }
 
   /* All user options have now been processed, so it's now safe to do