summaryrefslogtreecommitdiff
path: root/src/qmail-pop3d.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/qmail-pop3d.c')
-rw-r--r--src/qmail-pop3d.c280
1 files changed, 175 insertions, 105 deletions
diff --git a/src/qmail-pop3d.c b/src/qmail-pop3d.c
index 2d26c16..bd46d7b 100644
--- a/src/qmail-pop3d.c
+++ b/src/qmail-pop3d.c
@@ -1,57 +1,62 @@
-#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 <sys/types.h>
+#include <unistd.h>
+
#include "alloc.h"
+#include "buffer.h"
+#include "exit.h"
+#include "fmt.h"
+#include "getln.h"
#include "open.h"
-#include "prioq.h"
#include "scan.h"
-#include "fmt.h"
+#include "sig.h"
#include "str.h"
-#include "exit.h"
-#include "maildir.h"
+#include "stralloc.h"
#include "timeout.h"
-#define FDIN 0
+#include "commands.h"
+#include "maildir.h"
+#include "prioq.h"
+
+#define FDIN 0
#define FDOUT 1
-int rename(const char *,const char *); // stdio.h
+int rename(const char *, const char *); // stdio.h
-void die() { _exit(0); }
+void die()
+{
+ _exit(0);
+}
-ssize_t saferead(int fd,char *buf,int len)
+ssize_t saferead(int fd, char *buf, int len)
{
int r;
- r = timeoutread(1200,fd,buf,len);
+ r = timeoutread(1200, fd, buf, len);
if (r <= 0) die();
return r;
}
-ssize_t safewrite(int fd,char *buf,int len)
+ssize_t safewrite(int fd, char *buf, int len)
{
int r;
- r = timeoutwrite(1200,fd,buf,len);
+ r = timeoutwrite(1200, fd, buf, len);
if (r <= 0) die();
return r;
}
char outbuf[1024];
-buffer bo = BUFFER_INIT(safewrite,FDOUT,outbuf,sizeof(outbuf));
+buffer bo = BUFFER_INIT(safewrite, FDOUT, outbuf, sizeof(outbuf));
char inbuf[128];
-buffer bi = BUFFER_INIT(saferead,FDIN,inbuf,sizeof(inbuf));
+buffer bi = BUFFER_INIT(saferead, FDIN, inbuf, sizeof(inbuf));
-void out(char *buf,int len)
+void out(char *buf, int len)
{
- buffer_put(&bo,buf,len);
+ buffer_put(&bo, buf, len);
}
void outs(char *s)
{
- buffer_puts(&bo,s);
+ buffer_puts(&bo, s);
}
void flush()
{
@@ -65,50 +70,88 @@ void err(char *s)
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 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 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 okay()
+{
+ outs("+OK \r\n");
+ flush();
+}
void printfn(char *fn)
{
fn += 4;
- out(fn,str_chr(fn,':'));
+ out(fn, str_chr(fn, ':'));
}
char strnum[FMT_ULONG];
stralloc line = {0};
-void blast(buffer *bf,unsigned long limit)
+void blast(buffer *bf, unsigned long limit)
{
int match;
int inheaders = 1;
-
+
for (;;) {
- if (getln(bf,&line,&match,'\n') != 0) die();
+ 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 (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);
-
+ 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);
+ out("\r\n.\r\n", 5);
flush();
}
@@ -129,20 +172,23 @@ void getlist()
struct prioq_elt pe;
struct stat st;
int i;
-
+
maildir_clean(&line);
- if (maildir_scan(&pq,&filenames,1,1) == -1) die_scan();
-
+ if (maildir_scan(&pq, &filenames, 1, 1) == -1) die_scan();
+
numm = pq.p ? pq.len : 0;
- m = (struct message *) alloc(numm * sizeof(struct message));
+ 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; }
+ 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)
+ if (stat(m[i].fn, &st) == -1)
m[i].size = 0;
else
m[i].size = st.st_size;
@@ -153,15 +199,15 @@ void pop3_stat()
{
int i;
unsigned long total;
-
+
total = 0;
- for (i = 0; i < numm; ++i)
+ for (i = 0; i < numm; ++i)
if (!m[i].flagdeleted) total += m[i].size;
outs("+OK ");
- out(strnum,fmt_uint(strnum,numm));
+ out(strnum, fmt_uint(strnum, numm));
outs(" ");
- out(strnum,fmt_ulong(strnum,total));
+ out(strnum, fmt_ulong(strnum, total));
outs("\r\n");
flush();
}
@@ -170,8 +216,7 @@ void pop3_rset()
{
int i;
- for (i = 0; i < numm; ++i)
- m[i].flagdeleted = 0;
+ for (i = 0; i < numm; ++i) m[i].flagdeleted = 0;
last = 0;
okay();
}
@@ -179,7 +224,7 @@ void pop3_rset()
void pop3_last()
{
outs("+OK ");
- out(strnum,fmt_uint(strnum,last));
+ out(strnum, fmt_uint(strnum, last));
outs("\r\n");
flush();
}
@@ -192,12 +237,12 @@ void pop3_quit()
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 (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 */
+ rename(m[i].fn, line.s); /* if it fails, bummer */
}
}
okay();
@@ -208,11 +253,23 @@ int msgno(char *arg)
{
unsigned long u;
- if (!scan_ulong(arg,&u)) { err_syntax(); return -1; }
- if (!u) { err_nozero(); return -1; }
+ 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; }
+ if (u >= numm) {
+ err_toobig();
+ return -1;
+ }
+ if (m[u].flagdeleted) {
+ err_deleted();
+ return -1;
+ }
return u;
}
@@ -227,16 +284,18 @@ void pop3_dele(char *arg)
okay();
}
-void list(int i,int flaguidl)
+void list(int i, int flaguidl)
{
- out(strnum,fmt_uint(strnum,i + 1));
+ out(strnum, fmt_uint(strnum, i + 1));
outs(" ");
- if (flaguidl) printfn(m[i].fn);
- else out(strnum,fmt_ulong(strnum,m[i].size));
+ if (flaguidl)
+ printfn(m[i].fn);
+ else
+ out(strnum, fmt_ulong(strnum, m[i].size));
outs("\r\n");
}
-void dolisting(char *arg,int flaguidl)
+void dolisting(char *arg, int flaguidl)
{
unsigned int i;
@@ -245,69 +304,80 @@ void dolisting(char *arg,int flaguidl)
if (i == -1) return;
outs("+OK ");
- list(i,flaguidl);
+ list(i, flaguidl);
} else {
okay();
for (i = 0; i < numm; ++i)
- if (!m[i].flagdeleted) list(i,flaguidl);
+ 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); }
+void pop3_uidl(char *arg)
+{
+ dolisting(arg, 1);
+}
+void pop3_list(char *arg)
+{
+ dolisting(arg, 0);
+}
char msgbuf[1024];
-buffer bm;
+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);
+
+ arg += scan_ulong(arg, &limit);
while (*arg == ' ') ++arg;
- if (scan_ulong(arg,&limit)) ++limit;
- else limit = 0;
-
+ if (scan_ulong(arg, &limit))
+ ++limit;
+ else
+ limit = 0;
+
fd = open_read(m[i].fn);
- if (fd == -1) { err_nosuch(); return; }
+ if (fd == -1) {
+ err_nosuch();
+ return;
+ }
okay();
- buffer_init(&bm,read,fd,msgbuf,sizeof(msgbuf));
- blast(&bm,limit);
+ 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)
+ {"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);
+ commands(&bi, pop3commands);
die();
}