]> Pileus Git - ~andy/fetchmail/blobdiff - rcfile_y.y
Spambounce patch.
[~andy/fetchmail] / rcfile_y.y
index b704c2cef8adc51b35c42836e1b1bdbb7030b65b..ea62211815961265a771b301c42aafab8796dacc 100644 (file)
 #endif /* NET_SECURITY */
 
 #include "fetchmail.h"
-
+#include "i18n.h"
+  
 /* parser reads these */
 char *rcfile;                  /* path name of rc file */
 struct query cmd_opts;         /* where to put command-line info */
 
 /* parser sets these */
-int poll_interval;             /* poll interval in seconds */
-char *logfile;                 /* log file for daemon mode */
-flag errors_to_syslog;         /* if syslog was set */
-flag use_invisible;            /* if invisible was set */
 struct query *querylist;       /* head of server list (globally visible) */
 
 int yydebug;                   /* in case we didn't generate with -- debug */
@@ -45,14 +42,10 @@ static struct query current;        /* current server record */
 static int prc_errflag;
 static struct hostdata *leadentry;
 static flag trailer;
-#if NET_SECURITY
-static struct net_security_operation request[NET_SECURITY_OPERATION_MAX];
-static int requestlen = NET_SECURITY_OPERATION_MAX;
-#endif /* NET_SECURITY */
 
-static void record_current();
-static void user_reset();
-static void reset_server(char *name, int skip);
+static void record_current(void);
+static void user_reset(void);
+static void reset_server(const char *name, int skip);
 
 /* using Bison, this arranges that yydebug messages will show actual tokens */
 extern char * yytext;
@@ -66,17 +59,22 @@ extern char * yytext;
 }
 
 %token DEFAULTS POLL SKIP VIA AKA LOCALDOMAINS PROTOCOL
-%token AUTHENTICATE TIMEOUT KPOP KERBEROS4
-%token ENVELOPE QVIRTUAL USERNAME PASSWORD FOLDER SMTPHOST MDA SMTPADDRESS
-%token PRECONNECT POSTCONNECT LIMIT
+%token PREAUTHENTICATE TIMEOUT KPOP SDPS KERBEROS4 KERBEROS5 KERBEROS SSH
+%token ENVELOPE QVIRTUAL USERNAME PASSWORD FOLDER SMTPHOST MDA BSMTP LMTP
+%token SMTPADDRESS SMTPNAME SPAMRESPONSE PRECONNECT POSTCONNECT LIMIT WARNINGS
+%token NETSEC INTERFACE MONITOR PLUGIN PLUGOUT
 %token IS HERE THERE TO MAP WILDCARD
-%token BATCHLIMIT FETCHLIMIT EXPUNGE
-%token SET LOGFILE DAEMON SYSLOG INVISIBLE NETSEC INTERFACE MONITOR
+%token BATCHLIMIT FETCHLIMIT EXPUNGE PROPERTIES
+%token SET LOGFILE DAEMON SYSLOG IDFILE INVISIBLE POSTMASTER BOUNCEMAIL 
+%token SPAMBOUNCE SHOWDOTS
 %token <proto> PROTO
 %token <sval>  STRING
 %token <number> NUMBER
-%token NO KEEP FLUSH FETCHALL REWRITE FORCECR STRIPCR PASS8BITS DROPSTATUS
-%token DNS SERVICE PORT UIDL INTERVAL
+%token NO KEEP FLUSH FETCHALL REWRITE FORCECR STRIPCR PASS8BITS 
+%token DROPSTATUS DROPDELIVERED
+%token DNS SERVICE PORT UIDL INTERVAL MIMEDECODE IDLE CHECKALIAS 
+%token SSL SSLKEY SSLCERT
+%token PRINCIPAL
 
 %%
 
@@ -91,10 +89,18 @@ statement_list      : statement
 optmap         : MAP | /* EMPTY */;
 
 /* future global options should also have the form SET <name> optmap <value> */
-statement      : SET LOGFILE optmap STRING     {logfile = xstrdup($4);}
-               | SET DAEMON optmap NUMBER      {poll_interval = $4;}
-               | SET SYSLOG                    {errors_to_syslog = TRUE;}
-               | SET INVISIBLE                 {use_invisible = TRUE;}
+statement      : SET LOGFILE optmap STRING     {run.logfile = xstrdup($4);}
+               | SET IDFILE optmap STRING      {run.idfile = xstrdup($4);}
+               | SET DAEMON optmap NUMBER      {run.poll_interval = $4;}
+               | SET POSTMASTER optmap STRING  {run.postmaster = xstrdup($4);}
+               | SET BOUNCEMAIL                {run.bouncemail = TRUE;}
+               | SET NO BOUNCEMAIL             {run.bouncemail = FALSE;}
+               | SET SPAMBOUNCE                {run.spambounce = TRUE;}
+               | SET NO SPAMBOUNCE             {run.spambounce = FALSE;}
+               | SET PROPERTIES optmap STRING  {run.properties =xstrdup($4);}
+               | SET SYSLOG                    {run.use_syslog = TRUE;}
+               | SET INVISIBLE                 {run.invisible = TRUE;}
+               | SET SHOWDOTS                  {run.showdots = TRUE;}
 
 /* 
  * The way the next two productions are written depends on the fact that
@@ -107,7 +113,7 @@ statement   : SET LOGFILE optmap STRING     {logfile = xstrdup($4);}
 
 /* detect and complain about the most common user error */
                | define_server serverspecs userspecs serv_option
-                       {yyerror("server option after user options");}
+                       {yyerror(_("server option after user options"));}
                ;
 
 define_server  : POLL STRING           {reset_server($2, FALSE);}
@@ -119,12 +125,12 @@ serverspecs       : /* EMPTY */
                | serverspecs serv_option
                ;
 
-alias_list     : STRING                {save_str(&current.server.akalist,-1,$1);}
-               | alias_list STRING     {save_str(&current.server.akalist,-1,$2);}
+alias_list     : STRING                {save_str(&current.server.akalist,$1,0);}
+               | alias_list STRING     {save_str(&current.server.akalist,$2,0);}
                ;
 
-domain_list    : STRING                {save_str(&current.server.localdomains,-1,$1);}
-               | domain_list STRING    {save_str(&current.server.localdomains,-1,$2);}
+domain_list    : STRING                {save_str(&current.server.localdomains,$1,0);}
+               | domain_list STRING    {save_str(&current.server.localdomains,$2,0);}
                ;
 
 serv_option    : AKA alias_list
@@ -133,28 +139,59 @@ serv_option       : AKA alias_list
                | PROTOCOL PROTO        {current.server.protocol = $2;}
                | PROTOCOL KPOP         {
                                            current.server.protocol = P_POP3;
-                                           current.server.preauthenticate = A_KERBEROS_V4;
-#if INET6
+
+                                           if (current.server.preauthenticate == A_PASSWORD)
+#ifdef KERBEROS_V5
+                                               current.server.preauthenticate = A_KERBEROS_V5;
+#else
+                                               current.server.preauthenticate = A_KERBEROS_V4;
+#endif /* KERBEROS_V5 */
+#if INET6_ENABLE
                                            current.server.service = KPOP_PORT;
-#else /* INET6 */
+#else /* INET6_ENABLE */
                                            current.server.port = KPOP_PORT;
-#endif /* INET6 */
+#endif /* INET6_ENABLE */
+                                       }
+               | PRINCIPAL STRING      {current.server.principal = xstrdup($2);}
+               | PROTOCOL SDPS         {
+#ifdef SDPS_ENABLE
+                                           current.server.protocol = P_POP3;
+                                           current.server.sdps = TRUE;
+#else
+                                           yyerror(_("SDPS not enabled."));
+#endif /* SDPS_ENABLE */
                                        }
                | UIDL                  {current.server.uidl = FLAG_TRUE;}
                | NO UIDL               {current.server.uidl  = FLAG_FALSE;}
+               | CHECKALIAS            {current.server.checkalias = FLAG_TRUE;}
+               | NO CHECKALIAS         {current.server.checkalias  = FLAG_FALSE;}
                | SERVICE STRING        {
-#if INET6
+#if INET6_ENABLE
                                        current.server.service = $2;
-#endif /* INET6 */
+#endif /* INET6_ENABLE */
                                        }
                | PORT NUMBER           {
-#if !INET6
+#if INET6_ENABLE
+                                       int port = $2;
+                                       char buf[10];
+                                       sprintf(buf, "%d", port);
+                                       current.server.service = xstrdup(buf);
+#else
                                        current.server.port = $2;
-#endif /* !INET6 */
-                                       }
+#endif /* INET6_ENABLE */
+               }
                | INTERVAL NUMBER               {current.server.interval = $2;}
-               | AUTHENTICATE PASSWORD {current.server.preauthenticate = A_PASSWORD;}
-               | AUTHENTICATE KERBEROS4        {current.server.preauthenticate = A_KERBEROS_V4;}
+               | PREAUTHENTICATE PASSWORD      {current.server.preauthenticate = A_PASSWORD;}
+               | PREAUTHENTICATE KERBEROS4     {current.server.preauthenticate = A_KERBEROS_V4;}
+                | PREAUTHENTICATE KERBEROS5    {current.server.preauthenticate = A_KERBEROS_V5;}
+                | PREAUTHENTICATE KERBEROS         {
+#ifdef KERBEROS_V5
+                   current.server.preauthenticate = A_KERBEROS_V5;
+#else
+                   current.server.preauthenticate = A_KERBEROS_V4;
+#endif /* KERBEROS_V5 */
+               }
+                | PREAUTHENTICATE SSH  {current.server.preauthenticate = A_SSH;}
                | TIMEOUT NUMBER        {current.server.timeout = $2;}
 
                | ENVELOPE NUMBER STRING 
@@ -173,28 +210,35 @@ serv_option       : AKA alias_list
                | QVIRTUAL STRING       {current.server.qvirtual=xstrdup($2);}
                | NETSEC STRING         {
 #ifdef NET_SECURITY
-                                           if (net_security_strtorequest($2, request, &requestlen))
-                                               yyerror("invalid security request");
-                                           else
+                                           void *request;
+                                           int requestlen;
+
+                                           if (net_security_strtorequest($2, &request, &requestlen))
+                                               yyerror(_("invalid security request"));
+                                           else {
                                                current.server.netsec = xstrdup($2);
+                                               free(request);
+                                           }
 #else
-                                           yyerror("network-security support disabled")
+                                           yyerror(_("network-security support disabled"));
 #endif /* NET_SECURITY */
                                        }
                | INTERFACE STRING      {
-#if defined(linux) && !defined(INET6)
+#if (defined(linux) && !defined(INET6_ENABLE)) || defined(__FreeBSD__)
                                        interface_parse($2, &current.server);
-#else /* defined(linux) && !defined(INET6) */
-                                       fprintf(stderr, "fetchmail: interface option is only supported under Linux\n");
-#endif /* defined(linux) && !defined(INET6) */
+#else /* (defined(linux) && !defined(INET6_ENABLE)) || defined(__FreeBSD__) */
+                                       fprintf(stderr, _("fetchmail: interface option is only supported under Linux and FreeBSD\n"));
+#endif /* (defined(linux) && !defined(INET6_ENABLE)) || defined(__FreeBSD__) */
                                        }
                | MONITOR STRING        {
-#if defined(linux) && !defined(INET6)
+#if (defined(linux) && !defined(INET6_ENABLE)) || defined(__FreeBSD__)
                                        current.server.monitor = xstrdup($2);
-#else /* defined(linux) && !defined(INET6) */
-                                       fprintf(stderr, "fetchmail: monitor option is only supported under Linux\n");
-#endif /* defined(linux) && !defined(INET6) */
+#else /* (defined(linux) && !defined(INET6_ENABLE)) || defined(__FreeBSD__) */
+                                       fprintf(stderr, _("fetchmail: monitor option is only supported under Linux\n"));
+#endif /* (defined(linux) && !defined(INET6_ENABLE) || defined(__FreeBSD__)) */
                                        }
+               | PLUGIN STRING         { current.server.plugin = xstrdup($2); }
+               | PLUGOUT STRING        { current.server.plugout = xstrdup($2); }
                | DNS                   {current.server.dns = FLAG_TRUE;}
                | NO DNS                {current.server.dns = FLAG_FALSE;}
                | NO ENVELOPE           {current.server.envelope = STRING_DISABLED;}
@@ -239,12 +283,26 @@ mapping           : STRING
                                {save_str_pair(&current.localnames, $1, $3);}
                ;
 
-folder_list    : STRING                {save_str(&current.mailboxes,-1,$1);}
-               | folder_list STRING    {save_str(&current.mailboxes,-1,$2);}
+folder_list    : STRING                {save_str(&current.mailboxes,$1,0);}
+               | folder_list STRING    {save_str(&current.mailboxes,$2,0);}
                ;
 
-smtp_list      : STRING                {save_str(&current.smtphunt, TRUE,$1);}
-               | smtp_list STRING      {save_str(&current.smtphunt, TRUE,$2);}
+smtp_list      : STRING                {save_str(&current.smtphunt, $1,TRUE);}
+               | smtp_list STRING      {save_str(&current.smtphunt, $2,TRUE);}
+               ;
+
+num_list       : NUMBER
+                       {
+                           struct idlist *id;
+                           id=save_str(&current.antispam,STRING_DUMMY,0);
+                           id->val.status.num = $1;
+                       }
+               | num_list NUMBER
+                       {
+                           struct idlist *id;
+                           id=save_str(&current.antispam,STRING_DUMMY,0);
+                           id->val.status.num = $2;
+                       }
                ;
 
 user_option    : TO localnames HERE
@@ -252,37 +310,56 @@ user_option       : TO localnames HERE
                | IS localnames HERE
                | IS localnames
 
-               | IS STRING THERE       {current.remotename = xstrdup($2);}
-               | PASSWORD STRING       {current.password   = xstrdup($2);}
+               | IS STRING THERE       {current.remotename  = xstrdup($2);}
+               | PASSWORD STRING       {current.password    = xstrdup($2);}
                | FOLDER folder_list
                | SMTPHOST smtp_list
                | SMTPADDRESS STRING    {current.smtpaddress = xstrdup($2);}
-               | MDA STRING            {current.mda        = xstrdup($2);}
-               | PRECONNECT STRING     {current.preconnect = xstrdup($2);}
+               | SMTPNAME STRING       {current.smtpname = xstrdup($2);}
+               | SPAMRESPONSE num_list
+               | MDA STRING            {current.mda         = xstrdup($2);}
+               | BSMTP STRING          {current.bsmtp       = xstrdup($2);}
+               | LMTP                  {current.listener    = LMTP_MODE;}
+               | PRECONNECT STRING     {current.preconnect  = xstrdup($2);}
                | POSTCONNECT STRING    {current.postconnect = xstrdup($2);}
 
-               | KEEP                  {current.keep       = FLAG_TRUE;}
-               | FLUSH                 {current.flush      = FLAG_TRUE;}
-               | FETCHALL              {current.fetchall   = FLAG_TRUE;}
-               | REWRITE               {current.rewrite    = FLAG_TRUE;}
-               | FORCECR               {current.forcecr    = FLAG_TRUE;}
-               | STRIPCR               {current.stripcr    = FLAG_TRUE;}
-               | PASS8BITS             {current.pass8bits  = FLAG_TRUE;}
-               | DROPSTATUS            {current.dropstatus = FLAG_TRUE;}
-
-               | NO KEEP               {current.keep       = FLAG_FALSE;}
-               | NO FLUSH              {current.flush      = FLAG_FALSE;}
-               | NO FETCHALL           {current.fetchall   = FLAG_FALSE;}
-               | NO REWRITE            {current.rewrite    = FLAG_FALSE;}
-               | NO FORCECR            {current.forcecr    = FLAG_FALSE;}
-               | NO STRIPCR            {current.stripcr    = FLAG_FALSE;}
-               | NO PASS8BITS          {current.pass8bits  = FLAG_FALSE;}
-               | NO DROPSTATUS         {current.dropstatus = FLAG_FALSE;}
-
-               | LIMIT NUMBER          {current.limit      = NUM_VALUE($2);}
-               | FETCHLIMIT NUMBER     {current.fetchlimit = NUM_VALUE($2);}
-               | BATCHLIMIT NUMBER     {current.batchlimit = NUM_VALUE($2);}
-               | EXPUNGE NUMBER        {current.expunge    = NUM_VALUE($2);}
+               | KEEP                  {current.keep        = FLAG_TRUE;}
+               | FLUSH                 {current.flush       = FLAG_TRUE;}
+               | FETCHALL              {current.fetchall    = FLAG_TRUE;}
+               | REWRITE               {current.rewrite     = FLAG_TRUE;}
+               | FORCECR               {current.forcecr     = FLAG_TRUE;}
+               | STRIPCR               {current.stripcr     = FLAG_TRUE;}
+               | PASS8BITS             {current.pass8bits   = FLAG_TRUE;}
+               | DROPSTATUS            {current.dropstatus  = FLAG_TRUE;}
+                | DROPDELIVERED         {current.dropdelivered = FLAG_TRUE;}
+               | MIMEDECODE            {current.mimedecode  = FLAG_TRUE;}
+               | IDLE                  {current.idle        = FLAG_TRUE;}
+
+               | SSL                   {current.use_ssl = FLAG_TRUE;}
+               | SSLKEY STRING         {current.sslkey = xstrdup($2);}
+               | SSLCERT STRING        {current.sslcert = xstrdup($2);}
+
+               | NO KEEP               {current.keep        = FLAG_FALSE;}
+               | NO FLUSH              {current.flush       = FLAG_FALSE;}
+               | NO FETCHALL           {current.fetchall    = FLAG_FALSE;}
+               | NO REWRITE            {current.rewrite     = FLAG_FALSE;}
+               | NO FORCECR            {current.forcecr     = FLAG_FALSE;}
+               | NO STRIPCR            {current.stripcr     = FLAG_FALSE;}
+               | NO PASS8BITS          {current.pass8bits   = FLAG_FALSE;}
+               | NO DROPSTATUS         {current.dropstatus  = FLAG_FALSE;}
+                | NO DROPDELIVERED      {current.dropdelivered = FLAG_FALSE;}
+               | NO MIMEDECODE         {current.mimedecode  = FLAG_FALSE;}
+               | NO IDLE               {current.idle        = FLAG_FALSE;}
+
+               | NO SSL                {current.use_ssl = FLAG_FALSE;}
+
+               | LIMIT NUMBER          {current.limit       = NUM_VALUE_IN($2);}
+               | WARNINGS NUMBER       {current.warnings    = NUM_VALUE_IN($2);}
+               | FETCHLIMIT NUMBER     {current.fetchlimit  = NUM_VALUE_IN($2);}
+               | BATCHLIMIT NUMBER     {current.batchlimit  = NUM_VALUE_IN($2);}
+               | EXPUNGE NUMBER        {current.expunge     = NUM_VALUE_IN($2);}
+
+               | PROPERTIES STRING     {current.properties  = xstrdup($2);}
                ;
 %%
 
@@ -297,22 +374,26 @@ static struct query *hosttail;    /* where to add new elements */
 void yyerror (const char *s)
 /* report a syntax error */
 {
-    error_at_line( 0, 0, rcfile, prc_lineno, "%s at %s", s, 
-                  (yytext && yytext[0]) ? yytext : "end of input");
+    report_at_line(stderr, 0, rcfile, prc_lineno, _("%s at %s"), s, 
+                  (yytext && yytext[0]) ? yytext : _("end of input"));
     prc_errflag++;
 }
 
-int prc_filecheck(pathname)
+int prc_filecheck(const char *pathname, const flag securecheck)
 /* check that a configuration file is secure */
-const char *pathname;          /* pathname for the configuration file */
 {
+#ifndef __EMX__
     struct stat statbuf;
 
     errno = 0;
 
-    /* special cases useful for debugging purposes */
+    /* special case useful for debugging purposes */
     if (strcmp("/dev/null", pathname) == 0)
-       return(0);
+       return(PS_SUCCESS);
+
+    /* pass through the special name for stdin */
+    if (strcmp("-", pathname) == 0)
+       return(PS_SUCCESS);
 
     /* the run control file must have the same uid as the REAL uid of this 
        process, it must have permissions no greater than 600, and it must not 
@@ -320,30 +401,41 @@ const char *pathname;             /* pathname for the configuration file */
 
     if (lstat(pathname, &statbuf) < 0) {
        if (errno == ENOENT) 
-           return(0);
+           return(PS_SUCCESS);
        else {
-           error(0, errno, "lstat: %s", pathname);
+           report(stderr, "lstat: %s: %s\n", pathname, strerror(errno));
            return(PS_IOERR);
        }
     }
 
-    if ((statbuf.st_mode & S_IFLNK) == S_IFLNK) {
-       fprintf(stderr, "File %s must not be a symbolic link.\n", pathname);
-       return(PS_AUTHFAIL);
+    if (!securecheck)  return PS_SUCCESS;
+
+    if ((statbuf.st_mode & S_IFLNK) == S_IFLNK)
+    {
+       fprintf(stderr, _("File %s must not be a symbolic link.\n"), pathname);
+       return(PS_IOERR);
     }
 
-    if (statbuf.st_mode & ~(S_IFREG | S_IREAD | S_IWRITE)) {
-       fprintf(stderr, "File %s must have no more than -rw------ (0600) permissions.\n", 
+#ifndef __BEOS__
+    if (statbuf.st_mode & ~(S_IFREG | S_IREAD | S_IWRITE | S_IEXEC | S_IXGRP))
+    {
+       fprintf(stderr, _("File %s must have no more than -rwx--x--- (0710) permissions.\n"), 
                pathname);
-       return(PS_AUTHFAIL);
+       return(PS_IOERR);
     }
+#endif /* __BEOS__ */
 
-    if (statbuf.st_uid != getuid()) {
-       fprintf(stderr, "File %s must be owned by you.\n", pathname);
-       return(PS_AUTHFAIL);
+#ifdef HAVE_GETEUID
+    if (statbuf.st_uid != geteuid())
+#else
+    if (statbuf.st_uid != getuid())
+#endif /* HAVE_GETEUID */
+    {
+       fprintf(stderr, _("File %s must be owned by you.\n"), pathname);
+       return(PS_IOERR);
     }
-
-    return(0);
+#endif
+    return(PS_SUCCESS);
 }
 
 int prc_parse_file (const char *pathname, const flag securecheck)
@@ -355,29 +447,41 @@ int prc_parse_file (const char *pathname, const flag securecheck)
     errno = 0;
 
     /* Check that the file is secure */
-    if (securecheck && (prc_errflag = prc_filecheck(pathname)) != 0)
+    if ( (prc_errflag = prc_filecheck(pathname, securecheck)) != 0 )
        return(prc_errflag);
 
-    if (errno == ENOENT)
-       return(0);
-
-    /* Open the configuration and feed it to the lexer. */
-    if ((yyin = fopen(pathname,"r")) == (FILE *)NULL) {
-       error(0, errno, "open: %s", pathname);
+    /*
+     * Croak if the configuration directory does not exist.
+     * This probably means an NFS mount failed and we can't
+     * see a configuration file that ought to be there.
+     * Question: is this a portable check? It's not clear
+     * that all implementations of lstat() will return ENOTDIR
+     * rather than plain ENOENT in this case...
+     */
+    if (errno == ENOTDIR)
+       return(PS_IOERR);
+    else if (errno == ENOENT)
+       return(PS_SUCCESS);
+
+    /* Open the configuration file and feed it to the lexer. */
+    if (strcmp(pathname, "-") == 0)
+       yyin = stdin;
+    else if ((yyin = fopen(pathname,"r")) == (FILE *)NULL) {
+       report(stderr, "open: %s: %s\n", pathname, strerror(errno));
        return(PS_IOERR);
     }
 
     yyparse();         /* parse entire file */
 
-    fclose(yyin);
+    fclose(yyin);      /* not checking this should be safe, file mode was r */
 
     if (prc_errflag) 
        return(PS_SYNTAX);
     else
-       return(0);
+       return(PS_SUCCESS);
 }
 
-static void reset_server(char *name, int skip)
+static void reset_server(const char *name, int skip)
 /* clear the entire global record and initialize it with a new name */
 {
     trailer = FALSE;
@@ -385,6 +489,7 @@ static void reset_server(char *name, int skip)
     current.smtp_socket = -1;
     current.server.pollname = xstrdup(name);
     current.server.skip = skip;
+    current.server.principal = (char *)NULL;
 }
 
 
@@ -417,7 +522,13 @@ struct query *init;        /* pointer to block containing initial values */
     node = (struct query *) xmalloc(sizeof(struct query));
 
     /* initialize it */
-    memcpy(node, init, sizeof(struct query));
+    if (init)
+       memcpy(node, init, sizeof(struct query));
+    else
+    {
+       memset(node, '\0', sizeof(struct query));
+       node->smtp_socket = -1;
+    }
 
     /* append to end of list */
     if (hosttail != (struct query *) 0)
@@ -440,116 +551,10 @@ struct query *init;      /* pointer to block containing initial values */
 static void record_current(void)
 /* register current parameters and append to the host list */
 {
-#define FLAG_FORCE(fld) if (cmd_opts.fld) current.fld = cmd_opts.fld
-    FLAG_FORCE(server.via);
-    FLAG_FORCE(server.protocol);
-#if INET6
-    FLAG_FORCE(server.service);
-    FLAG_FORCE(server.netsec);
-#else /* INET6 */
-    FLAG_FORCE(server.port);
-#endif /* INET6 */
-    FLAG_FORCE(server.interval);
-    FLAG_FORCE(server.preauthenticate);
-    FLAG_FORCE(server.timeout);
-    FLAG_FORCE(server.envelope);
-    FLAG_FORCE(server.envskip);
-    FLAG_FORCE(server.qvirtual);
-    FLAG_FORCE(server.skip);
-    FLAG_FORCE(server.dns);
-    FLAG_FORCE(server.uidl);
-
-#ifdef linux
-    FLAG_FORCE(server.interface);
-    FLAG_FORCE(server.monitor);
-    FLAG_FORCE(server.interface_pair);
-#endif /* linux */
-
-    FLAG_FORCE(remotename);
-    FLAG_FORCE(password);
-    if (cmd_opts.mailboxes)
-       current.mailboxes = cmd_opts.mailboxes;
-    if (cmd_opts.smtphunt)
-       current.smtphunt = cmd_opts.smtphunt;
-    FLAG_FORCE(mda);
-       FLAG_FORCE(smtpaddress);
-    FLAG_FORCE(preconnect);
-    FLAG_FORCE(postconnect);
-
-    FLAG_FORCE(keep);
-    FLAG_FORCE(flush);
-    FLAG_FORCE(fetchall);
-    FLAG_FORCE(rewrite);
-    FLAG_FORCE(forcecr);
-    FLAG_FORCE(stripcr);
-    FLAG_FORCE(pass8bits);
-    FLAG_FORCE(dropstatus);
-    FLAG_FORCE(limit);
-    FLAG_FORCE(fetchlimit);
-    FLAG_FORCE(batchlimit);
-    FLAG_FORCE(expunge);
-
-#undef FLAG_FORCE
-
     (void) hostalloc(&current);
-
     trailer = TRUE;
 }
 
-void optmerge(struct query *h2, struct query *h1)
-/* merge two options records; empty fields in h2 are filled in from h1 */
-{
-    append_str_list(&h2->server.localdomains, &h1->server.localdomains);
-    append_str_list(&h2->localnames, &h1->localnames);
-    append_str_list(&h2->mailboxes, &h1->mailboxes);
-    append_str_list(&h2->smtphunt, &h1->smtphunt);
-
-#define FLAG_MERGE(fld) if (!h2->fld) h2->fld = h1->fld
-    FLAG_MERGE(server.via);
-    FLAG_MERGE(server.protocol);
-#if INET6
-    FLAG_MERGE(server.service);
-    FLAG_MERGE(server.netsec);
-#else /* INET6 */
-    FLAG_MERGE(server.port);
-#endif /* INET6 */
-    FLAG_MERGE(server.interval);
-    FLAG_MERGE(server.preauthenticate);
-    FLAG_MERGE(server.timeout);
-    FLAG_MERGE(server.envelope);
-    FLAG_MERGE(server.envskip);
-    FLAG_MERGE(server.qvirtual);
-    FLAG_MERGE(server.skip);
-    FLAG_MERGE(server.dns);
-    FLAG_MERGE(server.uidl);
-
-#ifdef linux
-    FLAG_MERGE(server.interface);
-    FLAG_MERGE(server.monitor);
-    FLAG_MERGE(server.interface_pair);
-#endif /* linux */
-
-    FLAG_MERGE(remotename);
-    FLAG_MERGE(password);
-    FLAG_MERGE(mda);
-    FLAG_MERGE(smtpaddress);
-    FLAG_MERGE(preconnect);
-
-    FLAG_MERGE(keep);
-    FLAG_MERGE(flush);
-    FLAG_MERGE(fetchall);
-    FLAG_MERGE(rewrite);
-    FLAG_MERGE(forcecr);
-    FLAG_MERGE(stripcr);
-    FLAG_MERGE(pass8bits);
-    FLAG_MERGE(dropstatus);
-    FLAG_MERGE(limit);
-    FLAG_MERGE(fetchlimit);
-    FLAG_MERGE(batchlimit);
-    FLAG_MERGE(expunge);
-#undef FLAG_MERGE
-}
-
 /* easier to do this than cope with variations in where the library lives */
 int yywrap(void) {return 1;}