static struct query current; /* current server record */
static int prc_errflag;
+
+static void prc_register();
+static void prc_reset();
%}
%union {
char *sval;
}
-%token DEFAULTS SERVER PROTOCOL AUTHENTICATE TIMEOUT KPOP KERBEROS
-%token USERNAME PASSWORD FOLDER SMTPHOST MDA IS HERE THERE TO MAP LIMIT
+%token DEFAULTS POLL SKIP AKA LOCALDOMAINS PROTOCOL
+%token AUTHENTICATE TIMEOUT KPOP KERBEROS
+%token ENVELOPE USERNAME PASSWORD FOLDER SMTPHOST MDA PRECONNECT LIMIT
+%token IS HERE THERE TO MAP WILDCARD
+%token SET BATCHLIMIT FETCHLIMIT LOGFILE INTERFACE MONITOR
%token <proto> PROTO
%token <sval> STRING
%token <number> NUMBER
-%token <flag> KEEP FLUSH FETCHALL REWRITE PORT SKIP
+%token <flag> KEEP FLUSH FETCHALL REWRITE STRIPCR DNS PORT
/* these are actually used by the lexer */
%token FLAG_TRUE 2
| statement_list statement
;
-statement : define_server serverspecs userspecs
+/* future global options should also have the form SET <name> <value> */
+statement : SET LOGFILE MAP STRING {logfile = xstrdup($4);}
+
+/*
+ * The way the next two productions are written depends on the fact that
+ * userspecs cannot be empty. It's a kluge to deal with files that set
+ * up a load of defaults and then have poll statements following with no
+ * user options at all.
+ */
+ | define_server serverspecs {prc_register(); prc_reset();}
+ | define_server serverspecs userspecs
+ {
+ memset(¤t,'\0',sizeof(current));
+ current.stripcr = -1;
+ }
;
-define_server : SERVER STRING {strcpy(current.servername, $2);}
- | SKIP SERVER STRING {strcpy(current.servername, $3);
- current.skip=($1==FLAG_TRUE);}
- | DEFAULTS {strcpy(current.servername,"defaults");}
+define_server : POLL STRING {current.server.names = (struct idlist *)NULL;
+ save_str(¤t.server.names, -1,$2);
+ current.server.skip = FALSE;}
+ | SKIP STRING {current.server.names = (struct idlist *)NULL;
+ save_str(¤t.server.names, -1,$2);
+ current.server.skip = TRUE;}
+ | DEFAULTS {current.server.names = (struct idlist *)NULL;
+ save_str(¤t.server.names, -1,"defaults");}
;
serverspecs : /* EMPTY */
| serverspecs serv_option
;
-serv_option : PROTOCOL PROTO {current.protocol = $2;}
+alias_list : STRING {save_str(¤t.server.names,-1,$1);}
+ | alias_list STRING {save_str(¤t.server.names,-1,$2);}
+ ;
+
+domain_list : STRING {save_str(¤t.server.localdomains,-1,$1);}
+ | domain_list STRING {save_str(¤t.server.localdomains,-1,$2);}
+ ;
+
+serv_option : AKA alias_list
+ | LOCALDOMAINS domain_list
+ | PROTOCOL PROTO {current.server.protocol = $2;}
| PROTOCOL KPOP {
- current.protocol = P_POP3;
- current.authenticate = A_KERBEROS;
- current.port = KPOP_PORT;
+ current.server.protocol = P_POP3;
+ current.server.authenticate = A_KERBEROS;
+ current.server.port = KPOP_PORT;
+ }
+ | PORT NUMBER {current.server.port = $2;}
+ | AUTHENTICATE PASSWORD {current.server.authenticate = A_PASSWORD;}
+ | AUTHENTICATE KERBEROS {current.server.authenticate = A_KERBEROS;}
+ | TIMEOUT NUMBER {current.server.timeout = $2;}
+ | ENVELOPE STRING {current.server.envelope = xstrdup($2);}
+ | INTERFACE STRING {
+#ifdef linux
+ interface_parse($2, ¤t.server);
+#else
+ fprintf(stderr, "fetchmail: interface option is only supported under Linux\n");
+#endif /* linux */
}
- | PORT NUMBER {current.port = $2;}
- | SKIP {current.skip = ($1==FLAG_TRUE);}
- | AUTHENTICATE PASSWORD {current.authenticate = A_PASSWORD;}
- | AUTHENTICATE KERBEROS {current.authenticate = A_KERBEROS;}
- | TIMEOUT NUMBER {current.timeout = $2;}
+ | MONITOR STRING {
+#ifdef linux
+ current.server.monitor = xstrdup($2);
+#else
+ fprintf(stderr, "fetchmail: monitor option is only supported under Linux\n");
+#endif /* linux */
+ }
+ | DNS {current.server.no_dns = ($1==FLAG_FALSE);}
;
-/* the first and only the first user spec may omit the USERNAME part */
+/*
+ * The first and only the first user spec may omit the USERNAME part.
+ * This is a backward-compatibility kluge to allow old popclient files
+ * to keep working.
+ */
userspecs : user1opts {prc_register(); prc_reset();}
| user1opts explicits {prc_register(); prc_reset();}
| explicits
explicitdef : userdef user0opts
;
-userdef : USERNAME STRING {strcpy(current.remotename, $2);}
+userdef : USERNAME STRING {current.remotename = xstrdup($2);}
| USERNAME mapping_list HERE
- | USERNAME STRING THERE {strcpy(current.remotename, $2);}
+ | USERNAME STRING THERE {current.remotename = xstrdup($2);}
;
user0opts : /* EMPTY */
| user1opts user_option
;
+localnames : WILDCARD {current.wildcard = TRUE;}
+ | mapping_list {current.wildcard = FALSE;}
+ | mapping_list WILDCARD {current.wildcard = TRUE;}
+ ;
+
mapping_list : mapping
| mapping_list mapping
;
mapping : STRING
- {save_id_pair(¤t.localnames, $1, NULL);}
+ {save_str_pair(¤t.localnames, $1, NULL);}
| STRING MAP STRING
- {save_id_pair(¤t.localnames, $1, $3);}
+ {save_str_pair(¤t.localnames, $1, $3);}
;
-user_option : TO mapping_list HERE
- | TO mapping_list
- | IS mapping_list HERE
- | IS mapping_list
- | IS STRING THERE {strcpy(current.remotename, $2);}
- | PASSWORD STRING {strcpy(current.password, $2);}
- | FOLDER STRING {strcpy(current.mailbox, $2);}
- | SMTPHOST STRING {strcpy(current.smtphost, $2);}
- | MDA STRING {strcpy(current.mda, $2);}
+user_option : TO localnames HERE
+ | TO localnames
+ | IS localnames HERE
+ | IS localnames
+
+ | IS STRING THERE {current.remotename = xstrdup($2);}
+ | PASSWORD STRING {current.password = xstrdup($2);}
+ | FOLDER STRING {current.mailbox = xstrdup($2);}
+ | SMTPHOST STRING {current.smtphost = xstrdup($2);}
+ | MDA STRING {current.mda = xstrdup($2);}
+ | PRECONNECT STRING {current.preconnect = xstrdup($2);}
| KEEP {current.keep = ($1==FLAG_TRUE);}
| FLUSH {current.flush = ($1==FLAG_TRUE);}
| FETCHALL {current.fetchall = ($1==FLAG_TRUE);}
- | REWRITE {current.norewrite = ($1==FLAG_TRUE);}
+ | REWRITE {current.no_rewrite =($1==FLAG_FALSE);}
+ | STRIPCR {current.stripcr = ($1==FLAG_TRUE);}
| LIMIT NUMBER {current.limit = $2;}
+ | FETCHLIMIT NUMBER {current.fetchlimit = $2;}
+ | BATCHLIMIT NUMBER {current.batchlimit = $2;}
;
%%
static struct query *hosttail; /* where to add new elements */
-void yyerror (s)
+void yyerror (const char *s)
/* report a syntax error */
-const char *s; /* error string */
{
- fprintf(stderr,"%s line %d: %s at %s\n", rcfile, prc_lineno, s, yytext);
- prc_errflag++;
+ fprintf(stderr,"%s line %d: %s at %s\n", rcfile, prc_lineno, s, yytext);
+ prc_errflag++;
}
int prc_filecheck(pathname)
if (errno == ENOENT)
return(0);
else {
- perror(pathname);
+ error(0, errno, "lstat: %s", pathname);
return(PS_IOERR);
}
}
/* Open the configuration and feed it to the lexer. */
if ((yyin = fopen(pathname,"r")) == (FILE *)NULL) {
- perror(pathname);
+ error(0, errno, "open: %s", pathname);
return(PS_IOERR);
}
return(0);
}
-void prc_reset()
+static void prc_reset(void)
/* clear the global current record (server parameters) used by the parser */
{
- char savename[HOSTLEN+1];
- int saveport, saveproto, saveauth;
+ struct hostdata save;
/*
- * Purpose of this code is to initialize the new server block with
- * the command-line data, but preserve whatever server name was
- * previously set. Also preserve server options unless the
- * command-line explicitly overrides them.
+ * Purpose of this code is to initialize the new server block, but
+ * preserve whatever server name was previously set. Also
+ * preserve server options unless the command-line explicitly
+ * overrides them.
*/
- (void) strcpy(savename, current.servername);
- saveport = current.port;
- saveproto = current.protocol;
- saveauth = current.authenticate;
+ save = current.server;
memset(¤t, '\0', sizeof(current));
- (void) strcpy(current.servername, savename);
- current.protocol = saveproto;
- current.authenticate = saveauth;
+ current.server = save;
}
struct query *hostalloc(init)
return(node);
}
-void prc_register()
+static void prc_register(void)
/* register current parameters and append to the host list */
{
-#define STR_FORCE(fld, len) if (cmd_opts.fld[0]) \
- strcpy(current.fld, cmd_opts.fld)
- STR_FORCE(remotename, USERNAMELEN);
- STR_FORCE(password, PASSWORDLEN);
- STR_FORCE(mailbox, FOLDERLEN);
- STR_FORCE(smtphost, HOSTLEN);
- STR_FORCE(mda, MDALEN);
-#undef STR_FORCE
-
#define FLAG_FORCE(fld) if (cmd_opts.fld) current.fld = cmd_opts.fld
- FLAG_FORCE(protocol);
+ FLAG_FORCE(server.protocol);
+ FLAG_FORCE(server.port);
+ FLAG_FORCE(server.authenticate);
+ FLAG_FORCE(server.timeout);
+ FLAG_FORCE(server.envelope);
+ FLAG_FORCE(server.skip);
+ FLAG_FORCE(server.no_dns);
+
+#ifdef linux
+ FLAG_FORCE(server.interface);
+ FLAG_FORCE(server.monitor);
+ FLAG_FORCE(server.interface_pair);
+#endif /* linux */
+
+ FLAG_FORCE(remotename);
+ FLAG_FORCE(password);
+ FLAG_FORCE(mailbox);
+ FLAG_FORCE(smtphost);
+ FLAG_FORCE(mda);
+ FLAG_FORCE(preconnect);
+
FLAG_FORCE(keep);
FLAG_FORCE(flush);
FLAG_FORCE(fetchall);
- FLAG_FORCE(norewrite);
- FLAG_FORCE(skip);
- FLAG_FORCE(port);
- FLAG_FORCE(authenticate);
- FLAG_FORCE(timeout);
+ FLAG_FORCE(no_rewrite);
+ FLAG_FORCE(stripcr);
FLAG_FORCE(limit);
+ FLAG_FORCE(fetchlimit);
+ FLAG_FORCE(batchlimit);
+
#undef FLAG_FORCE
(void) hostalloc(¤t);
}
-void optmerge(h2, h1)
+void optmerge(struct query *h2, struct query *h1)
/* merge two options records; empty fields in h2 are filled in from h1 */
-struct query *h1;
-struct query *h2;
{
- append_uid_list(&h2->localnames, &h1->localnames);
-
-#define STR_MERGE(fld, len) if (*(h2->fld) == '\0') strcpy(h2->fld, h1->fld)
- STR_MERGE(remotename, USERNAMELEN);
- STR_MERGE(password, PASSWORDLEN);
- STR_MERGE(mailbox, FOLDERLEN);
- STR_MERGE(smtphost, HOSTLEN);
- STR_MERGE(mda, MDALEN);
-#undef STR_MERGE
+ append_str_list(&h2->server.localdomains, &h1->server.localdomains);
+ append_str_list(&h2->localnames, &h1->localnames);
#define FLAG_MERGE(fld) if (!h2->fld) h2->fld = h1->fld
- FLAG_MERGE(protocol);
+ FLAG_MERGE(server.protocol);
+ FLAG_MERGE(server.port);
+ FLAG_MERGE(server.authenticate);
+ FLAG_MERGE(server.timeout);
+ FLAG_MERGE(server.envelope);
+ FLAG_MERGE(server.skip);
+ FLAG_MERGE(server.no_dns);
+
+#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(mailbox);
+ FLAG_MERGE(smtphost);
+ FLAG_MERGE(mda);
+ FLAG_MERGE(preconnect);
+
FLAG_MERGE(keep);
FLAG_MERGE(flush);
FLAG_MERGE(fetchall);
- FLAG_MERGE(norewrite);
- FLAG_MERGE(skip);
- FLAG_MERGE(port);
- FLAG_MERGE(authenticate);
- FLAG_MERGE(timeout);
+ FLAG_MERGE(no_rewrite);
+ FLAG_MERGE(stripcr);
FLAG_MERGE(limit);
+ FLAG_MERGE(fetchlimit);
+ FLAG_MERGE(batchlimit);
#undef FLAG_MERGE
-
}
/* easier to do this than cope with variations in where the library lives */
-int yywrap() {return 1;}
+int yywrap(void) {return 1;}
/* rcfile_y.y ends here */