Plan 9 from Bell Labs’s /usr/web/sources/contrib/boyd/sys/src/cmd/pop.bundle

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


# To unbundle, run this file
echo pop.b
sed 's/.//' >pop.b <<'//GO.SYSIN DD pop.b'
-# (C) Copyright Boyd Roberts, Bruce Ellis, November 1998
-
-implement Pop;
-
-include	"sys.m";
-include	"bufio.m";
-include	"string.m";
-include	"pop.m";
-
-sys:	Sys;
-bufio:	Bufio;
-str:	String;
-
-Iobuf:	import bufio;
-
-stderr:	ref Sys->FD;
-rx, tx:	ref Iobuf;
-
-debug:	con 0;
-
-init(): string
-{
-	sys = load Sys Sys->PATH;
-	if (sys == nil)
-		return "load $Sys failed";
-	stderr = sys->fildes(2);
-	bufio = load Bufio Bufio->PATH;
-	if (bufio == nil)
-		return sys->sprint("could not load %s: %r", Bufio->PATH);
-	str = load String String->PATH;
-	if (str == nil)
-		return sys->sprint("could not load %s: %r", String->PATH);
-	return nil;
-}
-
-fetch(user, host, password, dir: string, del: int): (string, big)
-{
-	dest := sys->sprint("tcp!%s!%d", host, Pop->POP3);
-	(ok, C) := sys->dial(dest, nil);
-	if (ok < 0)
-		return (sys->sprint("dial '%s' failed: %r", dest), big 0);
-
-	rx = bufio->fopen(C.dfd, Sys->OREAD);
-	if (rx == nil)
-		return (sys->sprint("bufio read open '%s' failed: %r", dest), big 0);
-	tx = bufio->fopen(C.dfd, Sys->OWRITE);
-	if (tx == nil)
-		return (sys->sprint("bufio write open '%s' failed: %r", dest), big 0);
-
-	(e, s) := reply(0);
-	case e {
-	ERR =>
-		return(s, big 0);
-	OK =>
-		if (debug)
-			sys->print("%s\n", s);
-	}
-	
-	(e, s) = request(CMD_USER, user);
-	case e {
-	ERR =>
-		return(s, big 0);
-	OK =>
-		if (debug)
-			sys->print("%s\n", s);
-	}
-
-	(e, s) = request(CMD_PASS, password);
-	case e {
-	ERR =>
-		return(s, big 0);
-	OK =>
-		if (debug)
-			sys->print("%s\n", s);
-	}
-
-	(e, s) = request(CMD_STAT, nil);
-	case e {
-	ERR =>
-		return(s, big 0);
-	OK =>
-		if (debug)
-			sys->print("%s\n", s);
-	}
-
-	messages := big 0;
-	size := big 0;
-	(n, l) := sys->tokenize(s, " ");
-	case n {
-	1 =>
-		sys->print("%d message%s for '%s@%s', maildrop size unknown.\n", int messages, plural(messages), user, host);
-		messages = big hd l;
-
-	2 =>
-		messages = big hd l;
-		size = big hd tl l;
-
-	* =>
-		return (sys->sprint("unknown number of messages for '%s@%s'.\n", user, host), big 0);
-	}
-
-	fetched: list of string;
-	err := "";
-getem:
-	for (i := big 1; i <= messages; i++) {
-		(e, s) = request(CMD_RETR, string i);
-		case e {
-		ERR =>
-			return(s, big 0);
-		OK =>
-			if (debug)
-				sys->print("%s\n", s);
-		}
-		f := filename(dir, string i);
-		fd := sys->create(f, Sys->OWRITE, 0);
-		if (fd == nil) {
-			err = sys->sprint("could not create '%s'", f);
-			break;
-		}
-
-		for (;;) {
-			(e, s) = reply(1);
-			case e {
-			ERR =>
-				err = s;
-				break getem;
-			DATA =>
-				if (debug)
-					sys->print("%s\n", s);
-				if (sys->fprint(fd, "%s\n", s) < 0) {
-					err = sys->sprint("could not write '%s': %r", f);
-					sys->remove(f);
-					break getem;
-				}
-
-			END =>
-				s = readable(f, fd);
-				if (s != nil)
-					sys->fprint(stderr, "warning: %s\n", s);
-				fd = nil;
-				fetched = string i :: fetched;
-				continue getem;
-			}
-		}
-	}
-
-	messages = big 0;
-
-	if (del)
-	{
-		while (fetched != nil)
-		{
-			s = hd fetched;
-			fetched = tl fetched;
-	
-			(e, s) = request(CMD_DELE, s);
-			case e {
-			ERR =>
-				sys->remove(filename(dir, s));
-			OK =>
-				messages++;
-			}
-		}
-	}
-
-	(e, s) = request(CMD_QUIT, nil);
-	if (e != OK && err == nil) {
-		if (messages != big 0)
-			err = sys->sprint("%bd message%s: ", messages, plural(messages));
-		err = sys->sprint("%swarning: %s", err, s);
-	}
-
-	return (err, messages);
-}
-
-reply(data: int): (int, string)
-{
-	r := rx.gets('\n');
-	if (r == nil)
-		return (ERR, sys->sprint("pop server read failed: %r"));
-	(n, l) := sys->tokenize(r, "\r\n");
-	if (n != 1) {
-		if (n == 0 && data)
-			return (DATA, nil);
-		return (ERR, "reply missing CRLF");
-	}
-	line := hd l;
-	if (debug)
-		sys->print("<-- %s\n", line);
-
-	if (data) {
-		if (line == REP_TCHAR)
-			return (END, nil);
-		return (DATA, line);
-	}
-
-	(cmd, rest) := str->splitl(line, " ");
-	rest = rest[1:];
-	case cmd {
-	REP_OK =>
-		return (OK, rest);
-	REP_ERR =>
-		return (ERR, rest);
-	* =>
-		return (ERR, "protocol error");
-	}
-}
-
-request(cmd, arg: string): (int, string)
-{
-	s := cmd;
-	if (arg != nil)
-		s += " " + arg;
-	if (debug)
-		sys->print("--> %s\n", s);
-	if (tx.puts(s + "\r\n") < 0 || tx.flush() < 0)
-		return (ERR, sys->sprint("pop server write failed: %r"));
-	return reply(0);
-}
-
-plural(n: big): string
-{
-	if (n == big 1)
-		return nil;
-
-	return "s";
-}
-
-readable(f: string, fd: ref Sys->FD): string
-{
-	(ok, d) := sys->fstat(fd);
-	if (ok < 0)
-		return sys->sprint("could not fstat '%s': %r", f);
-
-	d.mode |= 8r600;
-	if (sys->wstat(f, d) < 0)
-		return sys->sprint("could not wstat '%s': %r", f);
-
-	return nil;
-}
-
-filename(dir, file: string): string
-{
-	return dir + "/" + file;
-}
//GO.SYSIN DD pop.b
echo pop.m
sed 's/.//' >pop.m <<'//GO.SYSIN DD pop.m'
-# (C) Copyright Boyd Roberts, Bruce Ellis, November 1998
-
-Pop: module
-{
-	PATH:		con "pop.dis";
-	POP3:		con 110;
-	OK:		con 0;
-	END:		con 1;
-	DATA:		con 2;
-	ERR:		con -1;
-
-	CMD_DELE:	con "DELE";
-	CMD_LAST:	con "LAST";
-	CMD_NOOP:	con "NOOP";
-	CMD_PASS:	con "PASS";
-	CMD_QUIT:	con "QUIT";
-	CMD_RETR:	con "RETR";
-	CMD_RSET:	con "RSET";
-	CMD_STAT:	con "STAT";
-	CMD_USER:	con "USER";
-
-	REP_OK:		con "+OK";
-	REP_ERR:	con "-ERR";
-	REP_TCHAR:	con ".";
-
-	init:		fn(): string;
-	fetch:		fn(user, host, password, dir: string, del: int): (string, big);
-	plural:		fn(n: big): string;
-};
//GO.SYSIN DD pop.m
echo test.b
sed 's/.//' >test.b <<'//GO.SYSIN DD test.b'
-# (C) Copyright Boyd Roberts, Bruce Ellis, November 1998
-
-implement Test;
-
-include	"sys.m";
-include	"draw.m";
-include	"pop.m";
-
-sys:	Sys;
-pop:	Pop;
-
-stderr:	ref Sys->FD;
-
-Test: module
-{
-	init:	fn(nil: ref Draw->Context, nil: list of string);
-};
-
-init(nil: ref Draw->Context, nil: list of string)
-{
-	sys = load Sys Sys->PATH;
-	stderr = sys->fildes(2);
-	pop = load Pop Pop->PATH;
-	if (pop == nil)
-		exits(sys->sprint("could not load %s: %r\n", Pop->PATH));
-	s := pop->init();
-	if (s != nil)
-		exits(s);
-	n: big;
-	(s, n) = pop->fetch("user", "host", "password", ".", 0);
-	if (s != nil)
-		exits(s);
-	if (n != big 0)
-		sys->print("%bd message%s\n", n, pop->plural(n));
-}
-
-exits(s: string)
-{
-	sys->raise("fail: " + s);
-}
//GO.SYSIN DD test.b

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.