diff options
Diffstat (limited to 'sqmail-4.3.07/src/qmail-pop3d.c')
-rw-r--r-- | sqmail-4.3.07/src/qmail-pop3d.c | 314 |
1 files changed, 0 insertions, 314 deletions
diff --git a/sqmail-4.3.07/src/qmail-pop3d.c b/sqmail-4.3.07/src/qmail-pop3d.c deleted file mode 100644 index ae4b6ea..0000000 --- a/sqmail-4.3.07/src/qmail-pop3d.c +++ /dev/null @@ -1,314 +0,0 @@ -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include "commands.h" -#include "sig.h" -#include "getln.h" -#include "stralloc.h" -#include "buffer.h" -#include "alloc.h" -#include "open.h" -#include "prioq.h" -#include "scan.h" -#include "fmt.h" -#include "str.h" -#include "exit.h" -#include "maildir.h" -#include "timeout.h" -#include "qmail.h" - -#define FDIN 0 -#define FDOUT 1 -#define POP3_TIMEOUT 1200 - -int rename(const char *,const char *); // stdio.h - -void die() { _exit(0); } - -ssize_t saferead(int fd,char *buf,int len) -{ - int r; - r = timeoutread(POP3_TIMEOUT,fd,buf,len); - if (r <= 0) die(); - return r; -} - -ssize_t safewrite(int fd,char *buf,int len) -{ - int r; - r = timeoutwrite(POP3_TIMEOUT,fd,buf,len); - if (r <= 0) die(); - return r; -} - -char inbuf[BUFSIZE_LINE]; -buffer bi = BUFFER_INIT(saferead,FDIN,inbuf,sizeof(inbuf)); -char outbuf[BUFSIZE_LINE]; -buffer bo = BUFFER_INIT(safewrite,FDOUT,outbuf,sizeof(outbuf)); - -void out(char *buf,int len) -{ - buffer_put(&bo,buf,len); -} -void outs(char *s) -{ - buffer_puts(&bo,s); -} -void flush() -{ - buffer_flush(&bo); -} -void err(char *s) -{ - outs("-ERR "); - outs(s); - outs("\r\n"); - flush(); -} - -void die_nomem() { err("out of memory"); die(); } -void die_nomaildir() { err("this user has no $HOME/Maildir"); die(); } -void die_scan() { err("unable to scan $HOME/Maildir"); die(); } - -void err_syntax() { err("syntax error"); } -void err_unimpl() { err("unimplemented"); } -void err_deleted() { err("already deleted"); } -void err_nozero() { err("messages are counted from 1"); } -void err_toobig() { err("not that many messages"); } -void err_nosuch() { err("unable to open that message"); } -void err_nounlink() { err("unable to unlink all deleted messages"); } - -void okay() { outs("+OK \r\n"); flush(); } - -void printfn(char *fn) -{ - fn += 4; - out(fn,str_chr(fn,':')); -} - -char strnum[FMT_ULONG]; -stralloc line = {0}; - -void blast(buffer *bf,unsigned long limit) -{ - int match; - int inheaders = 1; - - for (;;) { - if (getln(bf,&line,&match,'\n') != 0) die(); - if (!match && !line.len) break; - if (match) --line.len; /* no way to pass this info over POP */ - if (limit) if (!inheaders) if (!--limit) break; - if (!line.len) - inheaders = 0; - else - if (line.s[0] == '.') - out(".",1); - out(line.s,line.len); - out("\r\n",2); - - if (!match) break; - } - out("\r\n.\r\n",5); - flush(); -} - -stralloc filenames = {0}; -prioq pq = {0}; - -struct message { - int flagdeleted; - unsigned long size; - char *fn; -} *m; - -int numm; -int last = 0; - -void getlist() -{ - struct prioq_elt pe; - struct stat st; - int i; - - maildir_clean(&line); - if (maildir_scan(&pq,&filenames,1,1) == -1) die_scan(); - - numm = pq.p ? pq.len : 0; - m = (struct message *) alloc(numm * sizeof(struct message)); - if (!m) die_nomem(); - - for (i = 0; i < numm; ++i) { - if (!prioq_min(&pq,&pe)) { numm = i; break; } - prioq_delmin(&pq); - m[i].fn = filenames.s + pe.id; - m[i].flagdeleted = 0; - if (stat(m[i].fn,&st) == -1) - m[i].size = 0; - else - m[i].size = st.st_size; - } -} - -void pop3_stat() -{ - int i; - unsigned long total; - - total = 0; - for (i = 0; i < numm; ++i) - if (!m[i].flagdeleted) total += m[i].size; - - outs("+OK "); - out(strnum,fmt_uint(strnum,numm)); - outs(" "); - out(strnum,fmt_ulong(strnum,total)); - outs("\r\n"); - flush(); -} - -void pop3_rset() -{ - int i; - - for (i = 0; i < numm; ++i) - m[i].flagdeleted = 0; - last = 0; - okay(); -} - -void pop3_last() -{ - outs("+OK "); - out(strnum,fmt_uint(strnum,last)); - outs("\r\n"); - flush(); -} - -void pop3_quit() -{ - int i; - - for (i = 0; i < numm; ++i) - if (m[i].flagdeleted) { - if (unlink(m[i].fn) == -1) err_nounlink(); - } else { - if (str_start(m[i].fn,"new/")) { - if (!stralloc_copys(&line,"cur/")) die_nomem(); - if (!stralloc_cats(&line,m[i].fn + 4)) die_nomem(); - if (!stralloc_cats(&line,":2,")) die_nomem(); - if (!stralloc_0(&line)) die_nomem(); - rename(m[i].fn,line.s); /* if it fails, bummer */ - } - } - okay(); - die(); -} - -int msgno(char *arg) -{ - unsigned long u; - - if (!scan_ulong(arg,&u)) { err_syntax(); return -1; } - if (!u) { err_nozero(); return -1; } - --u; - if (u >= numm) { err_toobig(); return -1; } - if (m[u].flagdeleted) { err_deleted(); return -1; } - return u; -} - -void pop3_dele(char *arg) -{ - int i; - - i = msgno(arg); - if (i == -1) return; - m[i].flagdeleted = 1; - if (i + 1 > last) last = i + 1; - okay(); -} - -void list(int i,int flaguidl) -{ - out(strnum,fmt_uint(strnum,i + 1)); - outs(" "); - if (flaguidl) printfn(m[i].fn); - else out(strnum,fmt_ulong(strnum,m[i].size)); - outs("\r\n"); -} - -void dolisting(char *arg,int flaguidl) -{ - unsigned int i; - - if (*arg) { - i = msgno(arg); - if (i == -1) return; - - outs("+OK "); - list(i,flaguidl); - } else { - okay(); - for (i = 0; i < numm; ++i) - if (!m[i].flagdeleted) list(i,flaguidl); - outs(".\r\n"); - } - flush(); -} - -void pop3_uidl(char *arg) { dolisting(arg,1); } -void pop3_list(char *arg) { dolisting(arg,0); } - -char msgbuf[BUFSIZE_MESS]; -buffer bm; - -void pop3_top(char *arg) -{ - int i; - unsigned long limit; - int fd; - - i = msgno(arg); - if (i == -1) return; - - arg += scan_ulong(arg,&limit); - while (*arg == ' ') ++arg; - if (scan_ulong(arg,&limit)) ++limit; - else limit = 0; - - fd = open_read(m[i].fn); - if (fd == -1) { err_nosuch(); return; } - okay(); - buffer_init(&bm,read,fd,msgbuf,sizeof(msgbuf)); - blast(&bm,limit); - close(fd); -} - -struct commands pop3commands[] = { - { "quit", pop3_quit, 0 } -, { "stat", pop3_stat, 0 } -, { "list", pop3_list, 0 } -, { "uidl", pop3_uidl, 0 } -, { "dele", pop3_dele, 0 } -, { "retr", pop3_top, 0 } -, { "rset", pop3_rset, 0 } -, { "last", pop3_last, 0 } -, { "top", pop3_top, 0 } -, { "noop", okay, 0 } -, { 0, err_unimpl, 0 } -} ; - -int main(int argc,char **argv) -{ - sig_alarmcatch(die); - sig_pipeignore(); - - if (!argv[1]) die_nomaildir(); - if (chdir(argv[1]) == -1) die_nomaildir(); - - getlist(); - - okay(); - commands(&bi,pop3commands); - die(); -} |