blob: e93512a1c896c96ac29b8f7fc1ae66dece0b20ce [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
Guido van Rossum2922c6d1994-05-06 14:28:19 +000038 def read(self, length = None):
Guido van Rossumc7b68821994-04-28 09:53:33 +000039 if self.pos >= self.stop:
40 return ''
Guido van Rossum2922c6d1994-05-06 14:28:19 +000041 if length is None:
Guido van Rossumc7b68821994-04-28 09:53:33 +000042 length = self.stop - self.pos
Guido van Rossumc7b68821994-04-28 09:53:33 +000043 self.fp.seek(self.pos)
44 self.pos = self.pos + length
45 return self.fp.read(length)
46
Guido van Rossum2922c6d1994-05-06 14:28:19 +000047 def readline(self, length = None):
Guido van Rossumc7b68821994-04-28 09:53:33 +000048 if self.pos >= self.stop:
49 return ''
Guido van Rossum2922c6d1994-05-06 14:28:19 +000050 if length is None:
Guido van Rossumc7b68821994-04-28 09:53:33 +000051 length = self.stop - self.pos
Guido van Rossumc7b68821994-04-28 09:53:33 +000052 self.fp.seek(self.pos)
53 data = self.fp.readline(length)
54 if len(data) < length:
55 length = len(data)
56 self.pos = self.pos + length
57 return data
58
59 def tell(self):
60 return self.pos - self.start
61
62 def seek(self, pos):
63 self.pos = pos + self.start
64
65 def close(self):
66 pass
67
68class UnixMailbox(_Mailbox):
69 def _search_start(self):
70 while 1:
71 line = self.fp.readline()
72 if not line:
73 raise EOFError
74 if line[:5] == 'From ':
75 return
76
77 def _search_end(self):
78 while 1:
79 pos = self.fp.tell()
80 line = self.fp.readline()
81 if not line:
82 return
83 if line[:5] == 'From ':
84 self.fp.seek(pos)
85 return
86
87class MmdfMailbox(_Mailbox):
88 def _search_start(self):
89 while 1:
90 line = self.fp.readline()
91 if not line:
92 raise EOFError
93 if line[:5] == '\001\001\001\001\n':
94 return
95
96 def _search_end(self):
97 while 1:
98 pos = self.fp.tell()
99 line = self.fp.readline()
100 if not line:
101 return
102 if line == '\001\001\001\001\n':
103 self.fp.seek(pos)
104 return
105
106if __name__ == '__main__':
107 import posix
108 import time
109 import sys
110 import string
111 mbox = '/usr/mail/'+posix.environ['USER']
112 fp = open(mbox, 'r')
113 mb = UnixMailbox(fp)
114 msgs = []
115 while 1:
116 msg = mb.next()
117 if not msg:
118 break
119 msgs.append(msg)
120 if len(sys.argv) > 1:
121 num = string.atoi(sys.argv[1])
122 print 'Message %d body:'%num
123 msg = msgs[num-1]
124 msg.rewindbody()
125 sys.stdout.write(msg.fp.read())
126 sys.exit(0)
127 print 'Mailbox',mbox,'has',len(msgs),'messages:'
128 for msg in msgs:
129 f = msg.getheader('from')
130 s = msg.getheader('subject')
131 d = (msg.getheader('date'))
132 print '%20.20s %18.18s %-30.30s'%(f, d[5:], s)
133