blob: b7a5598c83b96afb9c0b4de7d66e14c1db62e06e [file] [log] [blame]
Guido van Rossumc7b68821994-04-28 09:53:33 +00001#
2# A class to hand a unix-style or mmdf-style mailboxes
3#
4# Jack Jansen, CWI, March 1994.
5#
6import rfc822
7
8class _Mailbox:
9 def __init__(self, fp):
10 self.fp = fp
11 self.seekp = 0
12
13 def seek(self, pos):
14 self.seekp = pos
15
16 def next(self):
17 while 1:
18 self.fp.seek(self.seekp)
19 try:
20 self._search_start()
21 except EOFError:
22 self.seekp = self.fp.tell()
23 return None
24 start = self.fp.tell()
25 self._search_end()
26 self.seekp = stop = self.fp.tell()
27 if start <> stop:
28 break
29 return rfc822.Message(_Subfile(self.fp, start, stop))
30
31class _Subfile:
32 def __init__(self, fp, start, stop):
33 self.fp = fp
34 self.start = start
35 self.stop = stop
36 self.pos = self.start
37
38 def read(self, *args):
39 if self.pos >= self.stop:
40 return ''
41 if args == ():
42 length = self.stop - self.pos
43 else:
44 length = args[0]
45 self.fp.seek(self.pos)
46 self.pos = self.pos + length
47 return self.fp.read(length)
48
49 def readline(self, *args):
50 if self.pos >= self.stop:
51 return ''
52 if args == ():
53 length = self.stop - self.pos
54 else:
55 length = args[0]
56 self.fp.seek(self.pos)
57 data = self.fp.readline(length)
58 if len(data) < length:
59 length = len(data)
60 self.pos = self.pos + length
61 return data
62
63 def tell(self):
64 return self.pos - self.start
65
66 def seek(self, pos):
67 self.pos = pos + self.start
68
69 def close(self):
70 pass
71
72class UnixMailbox(_Mailbox):
73 def _search_start(self):
74 while 1:
75 line = self.fp.readline()
76 if not line:
77 raise EOFError
78 if line[:5] == 'From ':
79 return
80
81 def _search_end(self):
82 while 1:
83 pos = self.fp.tell()
84 line = self.fp.readline()
85 if not line:
86 return
87 if line[:5] == 'From ':
88 self.fp.seek(pos)
89 return
90
91class MmdfMailbox(_Mailbox):
92 def _search_start(self):
93 while 1:
94 line = self.fp.readline()
95 if not line:
96 raise EOFError
97 if line[:5] == '\001\001\001\001\n':
98 return
99
100 def _search_end(self):
101 while 1:
102 pos = self.fp.tell()
103 line = self.fp.readline()
104 if not line:
105 return
106 if line == '\001\001\001\001\n':
107 self.fp.seek(pos)
108 return
109
110if __name__ == '__main__':
111 import posix
112 import time
113 import sys
114 import string
115 mbox = '/usr/mail/'+posix.environ['USER']
116 fp = open(mbox, 'r')
117 mb = UnixMailbox(fp)
118 msgs = []
119 while 1:
120 msg = mb.next()
121 if not msg:
122 break
123 msgs.append(msg)
124 if len(sys.argv) > 1:
125 num = string.atoi(sys.argv[1])
126 print 'Message %d body:'%num
127 msg = msgs[num-1]
128 msg.rewindbody()
129 sys.stdout.write(msg.fp.read())
130 sys.exit(0)
131 print 'Mailbox',mbox,'has',len(msgs),'messages:'
132 for msg in msgs:
133 f = msg.getheader('from')
134 s = msg.getheader('subject')
135 d = (msg.getheader('date'))
136 print '%20.20s %18.18s %-30.30s'%(f, d[5:], s)
137