Moved Postfix PostgreSQL client configuration files into the postfix directory.
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# Copyright 2007 - 2009, VEB IT
# See COPYING for distribution information.
"""This is the vmm main script."""
import gettext
from time import strftime, strptime
from VirtualMailManager import *
from VirtualMailManager.VirtualMailManager import VirtualMailManager
import VirtualMailManager.Exceptions as VMME
import VirtualMailManager.constants.EXIT as EXIT
def usage(excode=0, errMsg=None):
# TP: Please adjust translated words like the original text.
# (It's a table header.) Extract from usage text:
# Usage: vmm SUBCOMMAND OBJECT ARGS*
# short long
# subcommand object args (* = optional)
#
# da domainadd domain.tld transport*
# di domaininfo domain.tld details*
u_head = _(u"""\
Usage: %s SUBCOMMAND OBJECT ARGS*
short long
subcommand object args (* = optional)\n""")\
% __prog__
u_body = u"""\
da domainadd domain.tld transport*
di domaininfo domain.tld details*
dt domaintransport domain.tld transport force*
dd domaindelete domain.tld delalias*|deluser*|delall*
ada aliasdomainadd aliasdomain.tld domain.tld
adi aliasdomaininfo aliasdomain.tld
ads aliasdomainswitch aliasdomain.tld domain.tld
add aliasdomaindelete aliasdomain.tld
ua useradd user@domain.tld password*
ui userinfo user@domain.tld details*
un username user@domain.tld "user’s name"
up userpassword user@domain.tld password*
ut usertransport user@domain.tld transport
u0 userdisable user@domain.tld service*
u1 userenable user@domain.tld service*
ud userdelete user@domain.tld delalias*
aa aliasadd alias@domain.tld user@domain.tld
ai aliasinfo alias@domain.tld
ad aliasdelete alias@domain.tld user@domain.tld*
ra relocatedadd exaddr@domain.tld user@domain.tld
ri relocatedinfo exaddr@domain.tld
rf relocateddelete exaddr@domain.tld
gu getuser userid
ld listdomains pattern*
cf configure section*
h help
v version
"""
if excode > 0:
if errMsg is None:
w_err(excode, u_head, u_body)
else:
w_err(excode, u_head, u_body, _(u'Error: %s\n') % errMsg)
else:
w_std(u_head, u_body)
os.sys.exit(excode)
def get_vmm():
try:
vmm = VirtualMailManager()
return vmm
except (VMME.VMMException, VMME.VMMNotRootException, VMME.VMMPermException,
VMME.VMMConfigException), e:
w_err(e.code(), _(u'Error: %s\n') % e.msg())
def _getOrder():
order = ()
if vmm.cfgGetInt('misc', 'dovecotvers') > 11:
sieve_name = u'sieve'
else:
sieve_name = u'managesieve'
if argv[1] in (u'di', u'domaininfo'):
order = ((u'domainname', 0), (u'gid', 1), (u'transport', 0),
(u'domaindir', 0), (u'aliasdomains', 0), (u'accounts', 0),
(u'aliases', 0), (u'relocated', 0))
elif argv[1] in (u'ui', u'userinfo'):
if argc == 4 and argv[3] != u'aliases'\
or vmm.cfgGetBoolean('maildir', 'diskusage'):
order = ((u'address', 0), (u'name', 0), (u'uid', 1), (u'gid', 1),
(u'transport', 0), (u'maildir', 0), (u'disk usage', 0),
(u'smtp', 1), (u'pop3', 1), (u'imap', 1), (sieve_name, 1))
else:
order = ((u'address', 0), (u'name', 0), (u'uid', 1), (u'gid', 1),
(u'transport', 0), (u'maildir', 0), (u'smtp', 1),
(u'pop3', 1), (u'imap', 1), (sieve_name, 1))
elif argv[1] in (u'gu', u'getuser'):
order = ((u'uid', 1), (u'gid', 1), (u'address', 0))
return order
def _printInfo(info, title):
# TP: e.g. 'Domain information' or 'Account information'
msg = u'%s %s' % (title, _(u'information'))
w_std (u'%s\n%s' % (msg, u'-'*len(msg)))
for k,u in _getOrder():
if u:
w_std(u'\t%s: %s' % (k.upper().ljust(15, u'.'), info[k]))
else:
w_std(u'\t%s: %s' % (k.title().ljust(15, u'.'), info[k]))
print
def _printList(alist, title):
# TP: e.g. 'Available alias addresses' or 'Available accounts'
msg = u'%s %s' % (_(u'Available'), title)
w_std(u'%s\n%s' % (msg, u'-'*len(msg)))
if len(alist) > 0:
if title != _(u'alias domains'):
for val in alist:
w_std(u'\t%s' % val)
else:
for dom in alist:
if not dom.startswith('xn--'):
w_std(u'\t%s' % dom)
else:
w_std(u'\t%s (%s)' % (dom, vmm.ace2idna(dom)))
else:
w_std(_(u'\tNone'))
print
def _printAliases(alias, targets):
msg = _(u'Alias information')
w_std(u'%s\n%s' % (msg, u'-'*len(msg)))
w_std(_(u'\tMail for %s will be redirected to:') % alias)
if len(targets) > 0:
for target in targets:
w_std(u'\t * %s' % target)
else:
w_std(_(u'\tNone'))
print
def _printRelocated(addr_dest):
msg = _(u'Relocated information')
w_std(u'%s\n%s' % (msg, u'-'*len(msg)))
w_std(_(u'\tUser “%(addr)s” has moved to “%(dest)s”') % addr_dest)
print
def _formatDom(domain, main=True):
if domain.startswith('xn--'):
domain = u'%s (%s)' % (domain, vmm.ace2idna(domain))
if main:
return u'\t[+] %s' % domain
else:
return u'\t[-] %s' % domain
def _printDomList(dids, domains):
if argc < 3:
msg = _('Available domains')
else:
msg = _('Matching domains')
w_std('%s\n%s' % (msg, '-'*len(msg)))
if not len(domains):
w_std(_('\tNone'))
else:
for id in dids:
if domains[id][0] is not None:
w_std(_formatDom(domains[id][0]))
if len(domains[id]) > 1:
for alias in domains[id][1:]:
w_std(_formatDom(alias, main=False))
print
def _printAliasDomInfo(info):
msg = _('Alias domain information')
for k in ['alias', 'domain']:
if info[k].startswith('xn--'):
info[k] = "%s (%s)" % (info[k], vmm.ace2idna(info[k]))
w_std('%s\n%s' % (msg, '-'*len(msg)))
w_std(
_('\tThe alias domain %(alias)s belongs to:\n\t * %(domain)s')%info)
print
def configure():
if need_setup or len(argv) < 3:
vmm.configure()
else:
vmm.configure(argv[2])
def domain_add():
if argc < 3:
usage(EXIT.MISSING_ARGS, _(u'Missing domain name.'))
elif argc < 4:
vmm.domainAdd(argv[2].lower())
else:
vmm.domainAdd(argv[2].lower(), argv[3])
def domain_delete():
if argc < 3:
usage(EXIT.MISSING_ARGS, _(u'Missing domain name.'))
elif argc < 4:
vmm.domainDelete(argv[2].lower())
else:
vmm.domainDelete(argv[2].lower(), argv[3])
def domain_info():
if argc < 3:
usage(EXIT.MISSING_ARGS, _(u'Missing domain name.'))
try:
if argc < 4:
_printInfo(vmm.domainInfo(argv[2].lower()), _(u'Domain'))
else:
details = argv[3].lower()
infos = vmm.domainInfo(argv[2].lower(), details)
_printInfo(infos[0], _(u'Domain'))
if details == u'accounts':
_printList(infos[1], _(u'accounts'))
elif details == u'aliasdomains':
_printList(infos[1], _(u'alias domains'))
elif details == u'aliases':
_printList(infos[1], _(u'aliases'))
elif details == u'relocated':
_printList(infos[1], _(u'relocated users'))
else:
_printList(infos[1], _(u'alias domains'))
_printList(infos[2], _(u'accounts'))
_printList(infos[3], _(u'aliases'))
_printList(infos[4], _(u'relocated users'))
except VMME.VMMDomainException, e:
if e.code() is ERR.DOMAIN_ALIAS_EXISTS:
w_std(plan_a_b % {'subcommand': u'aliasdomaininfo',
'object': argv[2].lower()})
alias_domain_info()
else:
raise e
def domain_transport():
if argc < 3:
usage(EXIT.MISSING_ARGS, _(u'Missing domain name and new transport.'))
if argc < 4:
usage(EXIT.MISSING_ARGS, _(u'Missing new transport.'))
elif argc < 5:
vmm.domainTransport(argv[2].lower(), argv[3])
else:
vmm.domainTransport(argv[2].lower(), argv[3], argv[4])
def alias_domain_add():
if argc < 3:
usage(EXIT.MISSING_ARGS,
_(u'Missing alias domain name and target domain name.'))
elif argc < 4:
usage(EXIT.MISSING_ARGS, _(u'Missing target domain name.'))
else:
vmm.aliasDomainAdd(argv[2].lower(), argv[3].lower())
def alias_domain_info():
if argc < 3:
usage(EXIT.MISSING_ARGS, _(u'Missing alias domain name.'))
try:
_printAliasDomInfo(vmm.aliasDomainInfo(argv[2].lower()))
except VMME.VMMAliasDomainException, e:
if e.code() is ERR.ALIASDOMAIN_ISDOMAIN:
w_std(plan_a_b % {'subcommand': u'domaininfo',
'object': argv[2].lower()})
argv[1] = u'di' # necessary manipulation to get the order
domain_info()
else:
raise e
def alias_domain_switch():
if argc < 3:
usage(EXIT.MISSING_ARGS,
_(u'Missing alias domain name and target domain name.'))
elif argc < 4:
usage(EXIT.MISSING_ARGS, _(u'Missing target domain name.'))
else:
vmm.aliasDomainSwitch(argv[2].lower(), argv[3].lower())
def alias_domain_delete():
if argc < 3:
usage(EXIT.MISSING_ARGS, _(u'Missing alias domain name.'))
else:
vmm.aliasDomainDelete(argv[2].lower())
def user_add():
if argc < 3:
usage(EXIT.MISSING_ARGS, _(u'Missing e-mail address.'))
elif argc < 4:
password = None
else:
password = argv[3]
vmm.userAdd(argv[2].lower(), password)
def user_delete():
if argc < 3:
usage(EXIT.MISSING_ARGS, _(u'Missing e-mail address.'))
elif argc < 4:
vmm.userDelete(argv[2].lower())
else:
vmm.userDelete(argv[2].lower(), argv[3].lower())
def user_info():
if argc < 3:
usage(EXIT.MISSING_ARGS, _(u'Missing e-mail address.'))
try:
if argc < 4:
_printInfo(vmm.userInfo(argv[2].lower()), u'Account')
else:
arg3 = argv[3].lower()
info = vmm.userInfo(argv[2].lower(), arg3)
if arg3 in ['aliases', 'full']:
_printInfo(info[0], u'Account')
_printList(info[1], _(u'alias addresses'))
else:
_printInfo(info, u'Account')
except VMME.VMMAccountException, e:
if e.code() is ERR.ALIAS_EXISTS:
w_std(plan_a_b % {'subcommand': u'aliasinfo',
'object': argv[2].lower()})
alias_info()
elif e.code() is ERR.RELOCATED_EXISTS:
w_std(plan_a_b % {'subcommand': u'relocatedinfo',
'object': argv[2].lower()})
relocated_info()
else:
raise e
def user_name():
if argc < 3:
usage(EXIT.MISSING_ARGS, _(u'Missing e-mail address and user’s name.'))
if argc < 4:
usage(EXIT.MISSING_ARGS, _(u'Missing user’s name.'))
else:
vmm.userName(argv[2].lower(), argv[3])
def user_transport():
if argc < 3:
usage(EXIT.MISSING_ARGS, _(u'Missing e-mail address and transport.'))
if argc <4:
usage(EXIT.MISSING_ARGS, _(u'Missing transport.'))
else:
vmm.userTransport(argv[2].lower(), argv[3])
def user_enable():
if argc < 3:
usage(EXIT.MISSING_ARGS, _(u'Missing e-mail address.'))
elif argc < 4:
vmm.userEnable(argv[2].lower())
else:
vmm.userEnable(argv[2].lower(), argv[3].lower())
def user_disable():
if argc < 3:
usage(EXIT.MISSING_ARGS, _(u'Missing e-mail address.'))
elif argc < 4:
vmm.userDisable(argv[2].lower())
else:
vmm.userDisable(argv[2].lower(), argv[3].lower())
def user_password():
if argc < 3:
usage(EXIT.MISSING_ARGS, _(u'Missing e-mail address.'))
elif argc < 4:
password = None
else:
password = argv[3]
vmm.userPassword(argv[2].lower(), password)
def alias_add():
if argc < 3:
usage(EXIT.MISSING_ARGS, _(u'Missing alias address and destination.'))
elif argc < 4:
usage(EXIT.MISSING_ARGS, _(u'Missing destination address.'))
else:
vmm.aliasAdd(argv[2].lower(), argv[3])
def alias_info():
if argc < 3:
usage(EXIT.MISSING_ARGS, _(u'Missing alias address'))
try:
_printAliases(argv[2].lower(), vmm.aliasInfo(argv[2].lower()))
except VMME.VMMAliasException, e:
if e.code() is ERR.ACCOUNT_EXISTS:
w_std(plan_a_b % {'subcommand': u'userinfo',
'object': argv[2].lower()})
argv[1] = u'ui' # necessary manipulation to get the order
user_info()
elif e.code() is ERR.RELOCATED_EXISTS:
w_std(plan_a_b % {'subcommand': u'relocatedinfo',
'object': argv[2].lower()})
relocated_info()
else:
raise e
def alias_delete():
if argc < 3:
usage(EXIT.MISSING_ARGS, _(u'Missing alias address'))
elif argc < 4:
vmm.aliasDelete(argv[2].lower())
else:
vmm.aliasDelete(argv[2].lower(), argv[3].lower())
def relocated_add():
if argc < 3:
usage(EXIT.MISSING_ARGS,
_(u'Missing relocated address and destination.'))
elif argc < 4:
usage(EXIT.MISSING_ARGS, _(u'Missing destination address.'))
else:
vmm.relocatedAdd(argv[2].lower(), argv[3])
def relocated_info():
if argc < 3:
usage(EXIT.MISSING_ARGS, _(u'Missing relocated address'))
relocated = argv[2].lower()
try:
_printRelocated({'addr': relocated,
'dest': vmm.relocatedInfo(relocated)})
except VMME.VMMRelocatedException, e:
if e.code() is ERR.ACCOUNT_EXISTS:
w_std(plan_a_b % {'subcommand': u'userinfo', 'object': relocated})
argv[1] = u'ui' # necessary manipulation to get the order
user_info()
elif e.code() is ERR.ALIAS_EXISTS:
w_std(plan_a_b % {'subcommand': u'aliasinfo', 'object': relocated})
alias_info()
else:
raise e
def relocated_delete():
if argc < 3:
usage(EXIT.MISSING_ARGS, _(u'Missing relocated address'))
else:
vmm.relocatedDelete(argv[2].lower())
def user_byID():
if argc < 3:
usage(EXIT.MISSING_ARGS, _(u'Missing userid'))
else:
_printInfo(vmm.userByID(argv[2]), u'Account')
def domain_list():
if argc < 3:
order, doms = vmm.domainList()
else:
order, doms = vmm.domainList(argv[2].lower())
_printDomList(order, doms)
def show_warnings():
if vmm.hasWarnings():
w_std(_(u'Warnings:'))
for warning in vmm.getWarnings():
w_std( " * %s" % warning)
def show_version():
w_std('%s, %s %s (%s %s)\nPython %s %s %s\n\n%s %s' % (__prog__,
# TP: The words 'from', 'version' and 'on' are used in the version
# information:
# vmm, version 0.5.2 (from 09/09/09)
# Python 2.5.4 on FreeBSD
_(u'version'), __version__, _(u'from'),
strftime(locale.nl_langinfo(locale.D_FMT),
strptime(__date__, '%Y-%m-%d')).decode(ENCODING, 'replace'),
os.sys.version.split()[0], _(u'on'), os.uname()[0], __prog__,
_(u'is free software and comes with ABSOLUTELY NO WARRANTY.')))
#def main():
if __name__ == '__main__':
__prog__ = os.path.basename(os.sys.argv[0])
gettext.install(__prog__, '/usr/local/share/locale', unicode=1)
argv = [unicode(arg, ENCODING) for arg in os.sys.argv]
argc = len(os.sys.argv)
plan_a_b =_(u'Plan A failed ... trying Plan B: %(subcommand)s %(object)s')
if argc < 2:
usage(EXIT.MISSING_ARGS)
vmm = get_vmm()
try:
need_setup = not vmm.setupIsDone()
if argv[1] in (u'cf', u'configure') or need_setup:
configure()
elif argv[1] in (u'da', u'domainadd'):
domain_add()
elif argv[1] in (u'di', u'domaininfo'):
domain_info()
elif argv[1] in (u'dt', u'domaintransport'):
domain_transport()
elif argv[1] in (u'dd', u'domaindelete'):
domain_delete()
elif argv[1] in (u'ada', u'aliasdomainadd'):
alias_domain_add()
elif argv[1] in (u'adi', u'aliasdomaininfo'):
alias_domain_info()
elif argv[1] in (u'ads', u'aliasdomainswitch'):
alias_domain_switch()
elif argv[1] in (u'add', u'aliasdomaindelete'):
alias_domain_delete()
elif argv[1] in (u'ua', u'useradd'):
user_add()
elif argv[1] in (u'ui', u'userinfo'):
user_info()
elif argv[1] in (u'un', u'username'):
user_name()
elif argv[1] in (u'up', u'userpassword'):
user_password()
elif argv[1] in (u'ut', u'usertransport'):
user_transport()
elif argv[1] in (u'u0', u'userdisable'):
user_disable()
elif argv[1] in (u'u1', u'userenable'):
user_enable()
elif argv[1] in (u'ud', u'userdelete'):
user_delete()
elif argv[1] in (u'aa', u'aliasadd'):
alias_add()
elif argv[1] in (u'ai', u'aliasinfo'):
alias_info()
elif argv[1] in (u'ad', u'aliasdelete'):
alias_delete()
elif argv[1] in (u'ra', u'relocatedadd'):
relocated_add()
elif argv[1] in (u'ri', u'relocatedinfo'):
relocated_info()
elif argv[1] in (u'rd', u'relocateddelete'):
relocated_delete()
elif argv[1] in (u'gu', u'getuser'):
user_byID()
elif argv[1] in (u'ld', u'listdomains'):
domain_list()
elif argv[1] in (u'h', u'help'):
usage()
elif argv[1] in (u'v', u'version'):
show_version()
else:
usage(EXIT.UNKNOWN_COMMAND, _(u'Unknown subcommand: “%s”')% argv[1])
show_warnings()
except (EOFError, KeyboardInterrupt):
# TP: We have to cry, because root has killed/interrupted vmm
# with Ctrl+C or Ctrl+D.
w_err(EXIT.USER_INTERRUPT, _(u'\nOuch!\n'))
except (VMME.VMMConfigException, VMME.VMMException), e:
if e.code() != ERR.DATABASE_ERROR:
w_err(e.code(), _(u'Error: %s') % e.msg())
else:
w_err(e.code(), unicode(e.msg(), ENCODING, 'replace'))