22#define POP3_TIMEOUT 1200 
   24int rename(
const char *,
const char *); 
 
   39static ssize_t saferead(
int fd,
char *
buf,
size_t len)
 
   43  if (r == -1) 
if (errno == ETIMEDOUT) { buffer_flush(&
bo); 
_exit(0); }
 
   51static void out(
char *
buf,
int len)
 
   53  buffer_put(&
bo,
buf,len);
 
   55static void outs(
char *s)
 
   63static void err(
char *s)
 
   72static void die_nomaildir() { err(
"this user has no $HOME/Maildir"); 
done(); }
 
   73static void die_scan() { err(
"unable to scan $HOME/Maildir"); 
done(); }
 
   75static void err_syntax() { err(
"syntax error"); }
 
   76static void err_unimpl(
char *
d) { err(
"unimplemented"); }
 
   77static void err_deleted() { err(
"already deleted"); }
 
   78static void err_nozero() { err(
"messages are counted from 1"); }
 
   79static void err_toobig() { err(
"not that many messages"); }
 
   80static void err_nosuch() { err(
"unable to open that message"); }
 
   81static void err_nounlink() { err(
"unable to unlink all deleted messages"); }
 
   83static void okay(
char *
d) { 
outs(
"+OK \r\n"); 
flush(); }
 
   85static void printfn(
char *
fn)
 
   94static void blast(buffer *
bf,
unsigned long limit)
 
  101    if (!
match && !line.len) 
break;
 
  102    if (
match) --line.len; 
 
  103    if (limit) 
if (!inheaders) 
if (!--limit) 
break;
 
  107      if (line.s[0] == 
'.')
 
  109    out(line.s,line.len);
 
  143  for (i = 0; i < 
numm; ++i) {
 
  147    m[i].flagdeleted = 0;
 
  148    if (stat(
m[i].
fn,&st) == -1)
 
  151      m[i].size = st.st_size;
 
  155static void pop3_stat(
char *
d)
 
  161  for (i = 0; i < 
numm; ++i) 
 
  172static void pop3_rset(
char *
d)
 
  176  for (i = 0; i < 
numm; ++i) 
 
  182static void pop3_last(
char *
d)
 
  190static void pop3_quit(
char *
d)
 
  194  for (i = 0; i < 
numm; ++i)
 
  196      if (unlink(
m[i].
fn) == -1) err_nounlink();
 
  198      if (str_start(
m[i].
fn,
"new/")) {
 
  201        if (!stralloc_cats(&line,
":2,")) 
die_nomem();
 
  210static int msgno(
char *arg)
 
  214  if (!scan_ulong(arg,&u)) { 
err_syntax(); 
return -1; }
 
  215  if (!u) { err_nozero(); 
return -1; }
 
  217  if (u >= 
numm) { err_toobig(); 
return -1; }
 
  222static void pop3_dele(
char *arg)
 
  228  m[i].flagdeleted = 1;
 
  233static void list(
int i,
int flaguidl)
 
  237  if (flaguidl) printfn(
m[i].
fn);
 
  242static void dolisting(
char *arg,
int flaguidl)
 
  254    for (i = 0; i < 
numm; ++i)
 
  261static void pop3_uidl(
char *arg) { dolisting(arg,1); }
 
  262static void pop3_list(
char *arg) { dolisting(arg,0); }
 
  267static void pop3_top(
char *arg)
 
  276  arg += scan_ulong(arg,&limit);
 
  277  while (*arg == 
' ') ++arg;
 
  278  if (scan_ulong(arg,&limit)) ++limit; 
 
  281  fd = open_read(
m[i].
fn);
 
  282  if (
fd == -1) { err_nosuch(); 
return; }
 
  290  { 
"quit", pop3_quit, 0 }
 
  291, { 
"stat", pop3_stat, 0 }
 
  292, { 
"list", pop3_list, 0 }
 
  293, { 
"uidl", pop3_uidl, 0 }
 
  294, { 
"dele", pop3_dele, 0 }
 
  295, { 
"retr", pop3_top, 0 }
 
  296, { 
"rset", pop3_rset, 0 }
 
  297, { 
"last", pop3_last, 0 }
 
  298, { 
"top", pop3_top, 0 }
 
 
  303int main(
int argc,
char * 
const *argv)
 
  305  sig_alarmcatch((
void *)
done);
 
  308  if (!argv[1]) die_nomaildir();
 
  309  if (chdir(argv[1]) == -1) die_nomaildir();
 
 
char outbuf[BUFSIZE_MESS]
 
int commands(buffer *b, struct commands *c)
 
int stralloc_copys(stralloc *, char const *)
 
int maildir_scan(prioq *, stralloc *, int, int)
 
void maildir_clean(stralloc *)
 
struct prioq_elt *int prioq_min(prioq *, struct prioq_elt *)
 
void prioq_delmin(prioq *)
 
int rename(const char *, const char *)
 
char msgbuf[BUFSIZE_MESS]
 
struct commands pop3commands[]
 
ssize_t safewrite(int, char *, size_t)