#! /usr/bin/python import os import cdb from errno import * def sort(l): l = [] + l l.sort() return l class struct (object): def __init__(me, **kw): me.__dict__.update(kw) def __repr__(me): return (type(me).__name__ + '(' + ', '.join(['%s = %r' % (k, me.__dict__[k]) for k in me.__dict__ if k[0] != '_']) + ')') class userentry (struct): pass os.chdir('/var/qmail') umap = {} udb = cdb.init('users/cdb') for k in udb.keys(): if len(k) == 0 or k[0] != '!': continue v = udb[k].split('\0') u = userentry(user = v[0], uid = int(v[1]), gid = int(v[2]), home = v[3], dash = v[4], pre = v[5]) if k[-1] == '\0': u.name = k[1:-1] u.wild = 0 else: u.name = k[1:] u.wild = 1 umap[u.name] = u del udb map = {} def addlocal(u, p, l, forcep = False): l = 'L' + l p = os.path.join(u.home, p) if not os.path.exists(p): if forcep: map[l] = '+' return qm = file(os.path.join(u.home, p)).readline() if len(qm) > 1 and qm[0:2] == '#!': map[l] = '-' elif len(qm) > 1 and qm[0:2] == '#?': name = u.user map[l] = '?' + name else: map[l] = '+' def allfiles(pre, dir): for f in os.listdir(dir): ff = os.path.join(dir, f) if os.path.isdir(ff): for sub in allfiles(f, ff): yield sub elif os.path.isfile(ff): yield f def qmfiles(pre, dir): for f in os.listdir(dir): if not f.startswith(pre): continue ff = os.path.join(dir, f) if os.path.isdir(ff): for sub in allfiles(f, ff): yield sub elif os.path.isfile(ff): yield f for k in sort(umap.keys()): ouid = os.geteuid() u = umap[k] try: try: os.seteuid(u.uid) except OSError: pass qm = '.qmail' + u.dash + u.pre qmlen = len(qm) if u.wild: try: for p in qmfiles(qm, u.home): ext = p[qmlen:] addlocal(u, p, u.name + ext) except IOError: pass else: addlocal(u, qm, u.name, u.dash == '') finally: os.seteuid(ouid) me = open('control/me').readline() try: for dom in open('control/locals'): if len(dom) and dom[-1] == '\n': dom = dom[:-1] map['@' + dom] = '' except IOError, exc: if exc.errno != ENOENT: raise map['@' + me] = '' try: for v in open('control/virtualdomains'): if len(v) and v[-1] == '\n': v = v[:-1] (addr, pre) = v.split(':', 2) map['V' + addr] = pre except IOError, exc: if exc.errno != ENOENT: raise for l in sort(map.keys()): print '%s:%s' % (l, map[l])