chiark / gitweb /
debian/rules: Use `git' potty wrapper.
[qmail] / qmail-valid-addresses
1 #! /usr/bin/python
2
3 import os
4 import cdb
5 from errno import *
6
7 def sort(l):
8   l = [] + l
9   l.sort()
10   return l
11 class struct (object):
12   def __init__(me, **kw):
13     me.__dict__.update(kw)
14   def __repr__(me):
15     return (type(me).__name__ +
16             '(' +
17             ', '.join(['%s = %r' % (k, me.__dict__[k])
18                        for k in me.__dict__
19                        if k[0] != '_']) +
20             ')')
21 class userentry (struct):
22   pass
23
24 os.chdir('/var/qmail')
25
26 umap = {}
27 udb = cdb.init('users/cdb')
28 for k in udb.keys():
29   if len(k) == 0 or k[0] != '!':
30     continue
31   v = udb[k].split('\0')
32   u = userentry(user = v[0], uid = int(v[1]), gid = int(v[2]), home = v[3],
33                 dash = v[4], pre = v[5])
34   if k[-1] == '\0':
35     u.name = k[1:-1]
36     u.wild = 0
37   else:
38     u.name = k[1:]
39     u.wild = 1
40   umap[u.name] = u
41 del udb
42
43 map = {}
44 def addlocal(u, p, l, forcep = False):
45   l = 'L' + l
46   p = os.path.join(u.home, p)
47   if not os.path.exists(p):
48     if forcep:
49       map[l] = '+'
50     return
51   qm = file(os.path.join(u.home, p)).readline()
52   if len(qm) > 1 and qm[0:2] == '#!':
53     map[l] = '-'
54   elif len(qm) > 1 and qm[0:2] == '#?':
55     name = u.user
56     map[l] = '?' + name
57   else:
58     map[l] = '+'
59
60 def allfiles(pre, dir):
61   for f in os.listdir(dir):
62     ff = os.path.join(dir, f)
63     if os.path.isdir(ff):
64       for sub in allfiles(f, ff):
65         yield sub
66     elif os.path.isfile(ff):
67       yield f
68     
69 def qmfiles(pre, dir):
70   for f in os.listdir(dir):
71     if not f.startswith(pre):
72       continue
73     ff = os.path.join(dir, f)
74     if os.path.isdir(ff):
75       for sub in allfiles(f, ff):
76         yield sub
77     elif os.path.isfile(ff):
78       yield f
79
80 for k in sort(umap.keys()):
81   ouid = os.geteuid()
82   u = umap[k]
83   try:
84     try:
85       os.seteuid(u.uid)
86     except OSError:
87       pass
88     qm = '.qmail' + u.dash + u.pre
89     qmlen = len(qm)
90     if u.wild:
91       try:
92         for p in qmfiles(qm, u.home):
93           ext = p[qmlen:]
94           addlocal(u, p, u.name + ext)
95       except IOError:
96         pass
97     else:
98       addlocal(u, qm, u.name, u.dash == '')
99   finally:
100     os.seteuid(ouid)
101
102 me = open('control/me').readline()
103
104 try:
105   for dom in open('control/locals'):
106     if len(dom) and dom[-1] == '\n':
107       dom = dom[:-1]
108     map['@' + dom] = ''
109 except IOError, exc:
110   if exc.errno != ENOENT:
111     raise
112   map['@' + me] = ''
113
114 try:
115   for v in open('control/virtualdomains'):
116     if len(v) and v[-1] == '\n':
117       v = v[:-1]
118     (addr, pre) = v.split(':', 2)
119     map['V' + addr] = pre
120 except IOError, exc:
121   if exc.errno != ENOENT:
122     raise
123
124 for l in sort(map.keys()):
125   print '%s:%s' % (l, map[l])