| # | 
 | # A class to hand a unix-style or mmdf-style mailboxes | 
 | # | 
 | # Jack Jansen, CWI, March 1994. | 
 | # | 
 | import rfc822 | 
 |  | 
 | class _Mailbox: | 
 | 	def __init__(self, fp): | 
 | 		self.fp = fp | 
 | 		self.seekp = 0 | 
 |  | 
 | 	def seek(self, pos): | 
 | 		self.seekp = pos | 
 |  | 
 | 	def next(self): | 
 | 		while 1: | 
 | 			self.fp.seek(self.seekp) | 
 | 			try: | 
 | 				self._search_start() | 
 | 			except EOFError: | 
 | 				self.seekp = self.fp.tell() | 
 | 				return None | 
 | 			start = self.fp.tell() | 
 | 			self._search_end() | 
 | 			self.seekp = stop = self.fp.tell() | 
 | 			if start <> stop: | 
 | 				break | 
 | 		return rfc822.Message(_Subfile(self.fp, start, stop)) | 
 |  | 
 | class _Subfile: | 
 | 	def __init__(self, fp, start, stop): | 
 | 		self.fp = fp | 
 | 		self.start = start | 
 | 		self.stop = stop | 
 | 		self.pos = self.start | 
 |  | 
 | 	def read(self, length = None): | 
 | 		if self.pos >= self.stop: | 
 | 			return '' | 
 | 		if length is None: | 
 | 			length = self.stop - self.pos | 
 | 		self.fp.seek(self.pos) | 
 | 		self.pos = self.pos + length | 
 | 		return self.fp.read(length) | 
 |  | 
 | 	def readline(self, length = None): | 
 | 		if self.pos >= self.stop: | 
 | 			return '' | 
 | 		if length is None: | 
 | 			length = self.stop - self.pos | 
 | 		self.fp.seek(self.pos) | 
 | 		data = self.fp.readline(length) | 
 | 		if len(data) < length: | 
 | 			length = len(data) | 
 | 		self.pos = self.pos + length | 
 | 		return data | 
 |  | 
 | 	def tell(self): | 
 | 		return self.pos - self.start | 
 |  | 
 | 	def seek(self, pos): | 
 | 		self.pos = pos + self.start | 
 |  | 
 | 	def close(self): | 
 | 		pass | 
 |  | 
 | class UnixMailbox(_Mailbox): | 
 | 	def _search_start(self): | 
 | 		while 1: | 
 | 			line = self.fp.readline() | 
 | 			if not line: | 
 | 				raise EOFError | 
 | 			if line[:5] == 'From ': | 
 | 				return | 
 |  | 
 | 	def _search_end(self): | 
 | 		while 1: | 
 | 			pos = self.fp.tell() | 
 | 			line = self.fp.readline() | 
 | 			if not line: | 
 | 				return | 
 | 			if line[:5] == 'From ': | 
 | 				self.fp.seek(pos) | 
 | 				return | 
 |  | 
 | class MmdfMailbox(_Mailbox): | 
 | 	def _search_start(self): | 
 | 		while 1: | 
 | 			line = self.fp.readline() | 
 | 			if not line: | 
 | 				raise EOFError | 
 | 			if line[:5] == '\001\001\001\001\n': | 
 | 				return | 
 |  | 
 | 	def _search_end(self): | 
 | 		while 1: | 
 | 			pos = self.fp.tell() | 
 | 			line = self.fp.readline() | 
 | 			if not line: | 
 | 				return | 
 | 			if line == '\001\001\001\001\n': | 
 | 				self.fp.seek(pos) | 
 | 				return | 
 |  | 
 | if __name__ == '__main__': | 
 | 	import posix | 
 | 	import time | 
 | 	import sys | 
 | 	import string | 
 | 	mbox = '/usr/mail/'+posix.environ['USER'] | 
 | 	fp = open(mbox, 'r') | 
 | 	mb = UnixMailbox(fp) | 
 | 	msgs = [] | 
 | 	while 1: | 
 | 		msg = mb.next() | 
 | 		if not msg: | 
 | 			break | 
 | 		msgs.append(msg) | 
 | 	if len(sys.argv) > 1: | 
 | 		num = string.atoi(sys.argv[1]) | 
 | 		print 'Message %d body:'%num | 
 | 		msg = msgs[num-1] | 
 | 		msg.rewindbody() | 
 | 		sys.stdout.write(msg.fp.read()) | 
 | 		sys.exit(0) | 
 | 	print 'Mailbox',mbox,'has',len(msgs),'messages:' | 
 | 	for msg in msgs: | 
 | 		f = msg.getheader('from') | 
 | 		s = msg.getheader('subject') | 
 | 		d = (msg.getheader('date')) | 
 | 		print '%20.20s   %18.18s   %-30.30s'%(f, d[5:], s) | 
 | 		 |