1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
%{
/*
* parser.y -- parser for the rcfile
*/
/*
* Adapted from fetchmail's rcfile_y.y by José Fonseca
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libesmtp.h>
/* parser reads these */
char *rcfile = NULL; /* path name of dot file */
/* parser sets these */
int yydebug; /* in case we didn't generate with -- debug */
extern char *host;
extern char *user;
extern char *pass;
extern enum starttls_option starttls;
extern char *certificate_passphrase;
/* using Bison, this arranges that yydebug messages will show actual tokens */
extern char * yytext;
#define YYPRINT(fp, type, val) fprintf(fp, " = \"%s\"", yytext)
%}
%union {
int number;
char *sval;
}
%token HOSTNAME USERNAME PASSWORD STARTTLS CERTIFICATE_PASSPHRASE
%token MAP
%token DISABLED ENABLED REQUIRED
%token <sval> STRING
%token <number> NUMBER
%%
rcfile : /* empty */
| statement_list
;
statement_list : statement
| statement_list statement
;
/* future global options should also have the form SET <name> optmap <value> */
statement : HOSTNAME MAP STRING { host = strdup($3); }
| USERNAME MAP STRING { user = strdup($3); }
| PASSWORD MAP STRING { pass = strdup($3); }
| STARTTLS MAP DISABLED { starttls = Starttls_DISABLED; }
| STARTTLS MAP ENABLED { starttls = Starttls_ENABLED; }
| STARTTLS MAP REQUIRED { starttls = Starttls_REQUIRED; }
| CERTIFICATE_PASSPHRASE MAP STRING { certificate_passphrase = strdup($3); }
;
%%
/* lexer interface */
extern char *rcfile;
extern int lineno;
extern char *yytext;
extern FILE *yyin;
void yyerror (const char *s)
/* report a syntax error */
{
fprintf(stderr, "%s:%d: %s at %s\n", rcfile, lineno, s,
(yytext && yytext[0]) ? yytext : "end of input");
}
#define RCFILE ".esmtprc"
void parse_rcfile (void)
{
char *home;
/* Setup the rcfile name. */
if (!(home = getenv("HOME")))
return;
if (!(rcfile = malloc(strlen(home) + sizeof(RCFILE) + 2)))
return;
strcpy(rcfile, home);
if (rcfile[strlen(rcfile) - 1] != '/')
strcat(rcfile, "/");
strcat(rcfile, RCFILE);
/* Open the configuration file and feed it to the lexer. */
if (!(yyin = fopen(rcfile, "r"))) {
if (errno != ENOENT) {
fprintf(stderr, "open: %s: %s\n", rcfile, strerror(errno));
}
}
else
{
yyparse(); /* parse entire file */
fclose(yyin); /* not checking this should be safe, file mode was r */
}
free(rcfile);
}
/* easier to do this than cope with variations in where the library lives */
int yywrap(void) { return 1; }
|