| 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]) |