7 from getopt import getopt, GetoptError
8 from sys import stdin, stdout, stderr, argv, exit
9 from cStringIO import StringIO
14 print >>stderr, '%s (fatal): %s' % (prog, msg)
17 print >>stderr, '%s: %s' % (prog, msg)
21 ('Usage: %s [-d DIST] [-h HOST] [-r REMOTE] [-p PATH] GROUP <MESSAGE' %
29 if line == '' or line == '\n':
33 bad('unexpected continuation')
43 bad('failed to parse header')
44 return v[0].strip().lower(), v[1].strip()
46 remote = ('localhost', 119)
49 host = OS.popen('hostname -f').read().strip()
57 global approved, remote, host, dist, path, group
59 opts, args = getopt(argv[1:], 'a:d:h:r:p:',
60 ['approved=', 'distribution=',
61 'hostname=', 'remote=', 'path='])
65 if o in ('-a', '--approved'):
67 elif o in ('-d', '--distribution'):
69 elif o in ('-h', '--hostname'):
71 elif o in ('-r', '--remote'):
72 remote = (lambda addr, port = 119: (addr, int(port)))(*a.split(':'))
77 rx_msgid = RX.compile(r'^\<\S+@\S+\>$')
80 def __init__(me, addr):
81 me.sk = S.socket(S.AF_INET, S.SOCK_STREAM)
83 me.f = me.sk.makefile()
86 die('unable to contact server: %s %s' % (rc, msg))
92 me.f.write(stuff + '\r\n')
95 rc, msg = (lambda rc, msg = '.': (rc, msg.strip())) \
96 (*me.f.readline().split(None, 1))
97 if rc.startswith('5'):
98 die('server hated me: %s %s' % (rc, msg))
99 return rc, msg.strip()
104 hdr.write('Path: newsgate\r\n'
105 'Distribution: mail\r\n'
108 if approved: hdr.write('Approved: %s\r\n' % approved)
111 lines xref newsgroups path distribution approved received
115 for h in headers(stdin):
118 h = 'X-Newsgate-' + h
119 elif h.startswith('.'):
122 if h.endswith('\r\n'):
124 elif h.endswith('\n'):
129 if 'message-id' not in seen:
130 seen['message-id'] = ('<newsgate-%s@%s>'
131 % (OS.popen('gorp 128').read().strip(),
133 hdr.write('Message-ID: %s\r\n' % seen['message-id'])
134 if 'date' not in seen:
135 hdr.write('Date: %s\r\n'
136 % (T.strftime('%a, %d %b %Y %H:%M:%S %Z')))
137 if 'subject' not in seen:
138 hdr.write('Subject: (no subject)\r\n')
140 msgid = seen['message-id']
141 if not rx_msgid.match(msgid):
142 bad('invalid message-id %s' % msgid)
145 nntp.cmd('IHAVE %s' % msgid)
146 rc, msg = nntp.reply()
150 if i.startswith('.'):
152 if i.endswith('\r\n'):
154 elif i.endswith('\n'):
160 hdr.write('Lines: %d\r\n' % n)
162 nntp.write(hdr.getvalue())
163 nntp.write(body.getvalue())
166 rc, msg = nntp.reply()
168 ## doesn't want my article; pretend all is fine: I don't care
171 die('failed to send article: %s %s' % (rc, msg))
173 bad('server rejected article: %s %s' % (rc, msg))
174 elif not rc.startswith('2'):
175 die('unexpected response from server: %s %s' % (rc, msg))
185 # except Exception, exc:
186 # die('unhandled exception: %s, %s' % (exc.__class__.__name__,