21#define PORT_POP3S "995"
26#define POP3_TIMEOUT 1200
30static ssize_t saferead(
int fd,
char *
buf,
int len)
52static void outs(
char *s)
60static void err(
char *s)
80static void logs(
char *s) {
if (buffer_puts(&
bl,s) == -1)
_exit(1); }
81static void logp(
char *s) { logs(
" P:"); logs(s); }
82static void logh(
char *s1,
char *s2) { logs(
" S:"); logs(s1); logs(
":"); logs(s2); }
83static void logu(
char *s) { logs(
" ?~ '"); logs(s); logs(
"'"); }
84static void logn(
char *s) {
if (buffer_puts(&
bl,s) == -1)
_exit(1);
if (buffer_flush(&
bl) == -1)
_exit(1); }
85static void logpid() {
strnum[fmt_ulong(
strnum,getpid())] = 0; logs(
"qmail-popup: pid "); logs(
strnum); logs(
" "); }
86static void log_pop(
char *s1,
char *s2,
char *s3,
char *s4,
char *s5,
char *s6)
87 { logpid(); logs(s1); logs(s2); logp(s3); logh(s4,s5), logu(s6), logn(
"\n"); }
89static void die_usage() { err(
"usage: popup hostname subprogram");
done(); }
91static void die_pipe() { err(
"unable to open pipe");
done(); }
92static void die_write() { err(
"unable to write pipe");
done(); }
93static void die_fork() { err(
"unable to fork");
done(); }
94static void die_childcrashed() { err(
"aack, child crashed"); }
95static void die_badauth() { err(
"authorization failed"); }
96static void die_tls() { err(
"TLS startup failed");
done(); }
97static void die_notls() {
98 err(
"TLS required but not negotiated");
103static void err_syntax() { err(
"syntax error"); }
104static void err_wantuser() { err(
"USER first"); }
105static void err_authoriz() { err(
"authorization first"); }
107static void okay() {
outs(
"+OK \r\n");
flush(); }
108static void pop3_quit() { okay();
done(); }
110static void poplog_init()
138static void doanddone(
char *
user,
unsigned int userlen,
char *
pass)
144 if (fd_copy(2,1) == -1) die_pipe();
146 if (pipe(pi) == -1) die_pipe();
147 if (pi[0] !=
FDAUTH) die_pipe();
148 switch (child = fork()) {
169 if (wait_pid(&wstat,child) == -1)
done();
170 if (wait_crashed(wstat)) die_childcrashed();
173 if (wait_exitcode(wstat)) {
182static void pop3_greet()
186 s += fmt_uint(s,getpid());
188 s += fmt_ulong(s,(
unsigned long)
now());
203static void pop3_user(
char *arg)
213static void pop3_pass(
char *arg)
215 if (!
seenuser) { err_wantuser();
return; }
221static void pop3_apop(
char *arg)
226 space = arg + str_chr(arg,
' ');
230 doanddone(arg,space - arg,space);
233static void pop3_capa(
char *arg)
235 outs(
"+OK capability list follows\r\n");
247static void pop3_stls(
char *arg)
250 return err(
"STLS not available");
251 outs(
"+OK starting TLS negotiation\r\n");
264 {
"user", pop3_user, 0 }
265, {
"pass", pop3_pass, 0 }
266, {
"apop", pop3_apop, 0 }
267, {
"quit", pop3_quit, 0 }
268, {
"capa", pop3_capa, 0 }
269, {
"stls", pop3_stls, 0 }
271, { 0, err_authoriz, 0 }
274int main(
int argc,
char *
const *argv)
279 sig_alarmcatch(
done);
294 pop3auth = env_get(
"POP3AUTH");
296 if (case_starts(pop3auth,
"apop"))
apop = 2;
297 if (case_starts(pop3auth,
"+apop"))
apop = 1;
int stralloc_copys(stralloc *, char const *)
ssize_t safewrite(int, char *, int)