/* * download mail from pop server, * deliver to plan9 */ #include #include #include #include int debug; char *user = 0; char *mailto; char *secretfile = 0; int maxsize = 0; int delete = 0; char secret[260]; int passwd = 0; /* allowed to use USER/PASS mechanism? */ int bfd; char *fromaddr = "upas"; char *host; /* this should be a library routine */ int system(char *cmd) { Waitmsg *w; int pid; switch(pid = fork()){ case -1: return -1; case 0: execl("/bin/rc", "rc", "-c", cmd, 0); _exits(0); default: if((w = wait()) == nil) { werrstr("wait() fails"); return -1; } if(w->pid != pid){ werrstr("wait got unexpected pid"); return -1; } if(w->msg[0]){ werrstr("wait: %s", w->msg); return -1; } sleep(1000); return 0; } } /* * get pop3 response. * don't worry about multiline. * the commands expecting responses * should know whether or not they are multiline. */ int popresp(Biobuf *b, char *buf, int nbuf) { int rv; char *s; int n; if(debug) fprint(2, "resp..."); if((s = Brdline(b, '\n')) == 0){ fprint(2, "brdline error: %r"); exits("brdline"); } n = Blinelen(b); while(n>0 && s[n-1] == '\r' || s[n-1] == '\n') s[--n] = '\0'; if(strncmp(s, "+OK", 3) == 0) rv = 0; else rv = -1; strncpy(buf, s, nbuf); buf[nbuf-1] = '\0'; if(debug) fprint(2, "pop response '%s' rv=%d\n", buf, rv); return rv; } void xlogin(Biobuf *b, char *xuser, int passwd) { char buf[256]; char user[256], ubuf[256]; int n; char *p, *q; UserPasswd *up; if(popresp(b, buf, sizeof buf) < 0) sysfatal("bad login banner"); ubuf[0] = 0; if(xuser) snprint(ubuf, sizeof ubuf, " user=%q", xuser); /* otherwise apop */ if(!passwd && (p=strchr(buf, '<')) != 0 && (q=strchr(p+1, '>')) != 0){ *++q = '\0'; if(debug) fprint(2, "apop..."); if((n=auth_respond(p, q-p, user, sizeof user, buf, sizeof buf, auth_getkey, "proto=apop role=client server=%q%s", host, ubuf)) < 0) sysfatal("factotum failed"); if(user[0]=='\0') sysfatal("factotum did not return a user name"); buf[n] = 0; fprint(2, "APOP %s\r\n", buf); fprint(bfd, "APOP %s %s\r\n", user, buf); if(popresp(b, buf, sizeof buf) == 0) return; if(debug) fprint(2, "apop failed..."); sysfatal("cannot apop authenticate"); }else{ up = auth_getuserpasswd(auth_getkey, "proto=pass service=pop dom=%q%s", host, ubuf); if(up == nil) sysfatal("factotum failed"); if(debug) fprint(2, "user..."); fprint(bfd, "USER %s\r\n", up->user); if(popresp(b, buf, sizeof buf) < 0) sysfatal("user: %s", buf); if(debug) fprint(2, "pass..."); fprint(bfd, "PASS %s\r\n", up->passwd); if(popresp(b, buf, sizeof buf) < 0) sysfatal("secret: %s", buf); } } int getmsg(Biobuf *b, int msg) { char template[32] = "/tmp/p3g.XXXXXXXXXXX"; char buf[256]; char *s, *es, *rp, *wp; int ofd, n; fprint(2, "get msg %d...", msg); fprint(bfd, "LIST %d\r\n", msg); if(popresp(b, buf, sizeof buf) < 0) { fprint(2, "bad stat response: %r\n"); return -1; } s=buf+strlen(buf)-1; while(s>buf && *s==' ' || *s == '\t') s--; while(s>=buf && '0' <= *s && *s <= '9') s--; s++; n = atoi(s); if(maxsize && n > maxsize) { fprint(2, "msg %d too big: %d > %d\n", msg, n, maxsize); return 0; } mktemp(template); if((ofd = create(template, OWRITE, 0600)) < 0) { fprint(2, "cannot open temp file %s: %r\n", template); return -1; } fprint(bfd, "RETR %d\r\n", msg); if(popresp(b, buf, sizeof buf) < 0) { fprint(2, "bad retr response: %r\n"); return -1; } while((s = Brdline(b, '\n')) != 0) { n = Blinelen(b); if(n == 3 && strncmp(s, ".\r\n", 3) == 0) break; es = s+n; if(*s == '.') s++; for(wp=rp=s; rp=0; i--) { if(getmsg(&b, i+1) < 0) break; } else for(i=0; i= 0) { fprint(2, "error reading msgs: only read %d..%d", n, i+1); exits("readmsg"); } if(!rflag && i != n) { fprint(2, "error reading msgs: only read 1..%d\n", i); exits("readmsg"); } exits(0); }