# HG changeset patch # User Brodie Rao # Date 2010-08-28 16:31:07 # Node ID 49463314c24f4be58a07f7ecc85c80f91815c3bc # Parent f585c9bb85c1dbb779ca68878f6d1ddcf7b23b7e mail/hgweb: support service names for ports (issue2350) This adds util.getport(port) which tries to parse port as an int, and failing that, looks it up using socket.getservbyname(). Thus, the following will work: [smtp] port = submission [web] port = http This does not apply to ports in URLs used in clone, pull, etc. diff --git a/hgext/zeroconf/__init__.py b/hgext/zeroconf/__init__.py --- a/hgext/zeroconf/__init__.py +++ b/hgext/zeroconf/__init__.py @@ -27,7 +27,7 @@ You can discover Zeroconf-enabled reposi import socket, time, os import Zeroconf -from mercurial import ui, hg, encoding +from mercurial import ui, hg, encoding, util from mercurial import extensions from mercurial.hgweb import hgweb_mod from mercurial.hgweb import hgwebdir_mod @@ -107,7 +107,7 @@ class hgwebzc(hgweb_mod.hgweb): path = self.repo.ui.config("web", "prefix", "").strip('/') desc = self.repo.ui.config("web", "description", name) publish(name, desc, path, - int(self.repo.ui.config("web", "port", 8000))) + util.getport(self.repo.ui.config("web", "port", 8000))) class hgwebdirzc(hgwebdir_mod.hgwebdir): def __init__(self, conf, baseui=None): @@ -119,7 +119,7 @@ class hgwebdirzc(hgwebdir_mod.hgwebdir): name = os.path.basename(repo) path = (prefix + repo).strip('/') desc = u.config('web', 'description', name) - publish(name, desc, path, int(u.config("web", "port", 8000))) + publish(name, desc, path, util.getport(u.config("web", "port", 8000))) # listen diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -3332,7 +3332,7 @@ def serve(ui, repo, **opts): # this way we can check if something was given in the command-line if opts.get('port'): - opts['port'] = int(opts.get('port')) + opts['port'] = util.getport(opts.get('port')) baseui = repo and repo.baseui or ui optlist = ("name templates style address port prefix ipv6" diff --git a/mercurial/hgweb/server.py b/mercurial/hgweb/server.py --- a/mercurial/hgweb/server.py +++ b/mercurial/hgweb/server.py @@ -269,7 +269,7 @@ def create_server(ui, app): import mimetypes; mimetypes.init() address = ui.config('web', 'address', '') - port = int(ui.config('web', 'port', 8000)) + port = util.getport(ui.config('web', 'port', 8000)) try: return cls(ui, app, (address, port), handler) except socket.error, inst: diff --git a/mercurial/mail.py b/mercurial/mail.py --- a/mercurial/mail.py +++ b/mercurial/mail.py @@ -37,7 +37,7 @@ def _smtp(ui): mailhost = ui.config('smtp', 'host') if not mailhost: raise util.Abort(_('no [smtp]host in hgrc - cannot send mail')) - mailport = int(ui.config('smtp', 'port', 25)) + mailport = util.getport(ui.config('smtp', 'port', 25)) ui.note(_('sending mail: smtp host %s, port %s\n') % (mailhost, mailport)) s.connect(host=mailhost, port=mailport) diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -17,7 +17,7 @@ from i18n import _ import error, osutil, encoding import errno, re, shutil, sys, tempfile, traceback import os, stat, time, calendar, textwrap, unicodedata, signal -import imp +import imp, socket # Python compatibility @@ -1414,3 +1414,19 @@ def interpolate(prefix, mapping, s, fn=N r = re.compile(r'%s(%s)' % (prefix, '|'.join(mapping.keys()))) return r.sub(lambda x: fn(mapping[x.group()[1:]]), s) +def getport(port): + """Return the port for a given network service. + + If port is an integer, it's returned as is. If it's a string, it's + looked up using socket.getservbyname(). If there's no matching + service, util.Abort is raised. + """ + try: + return int(port) + except ValueError: + pass + + try: + return socket.getservbyname(port) + except socket.error: + raise Abort(_("no port number associated with service '%s'") % port) diff --git a/tests/test-serve b/tests/test-serve --- a/tests/test-serve +++ b/tests/test-serve @@ -10,7 +10,11 @@ hgserve() echo % errors cat errors.log sleep 1 - kill `cat hg.pid` + if [ "$KILLQUIETLY" = "Y" ]; then + kill `cat hg.pid` 2>/dev/null + else + kill `cat hg.pid` + fi sleep 1 } @@ -36,6 +40,9 @@ hgserve echo % With -v and -p HGPORT2 hgserve -p "$HGPORT2" +echo '% With -v and -p http (should fail)' +KILLQUIETLY=Y hgserve -p http + echo % With --prefix foo hgserve --prefix foo diff --git a/tests/test-serve.out b/tests/test-serve.out --- a/tests/test-serve.out +++ b/tests/test-serve.out @@ -7,6 +7,10 @@ listening at http://localhost/ (bound to % With -v and -p HGPORT2 listening at http://localhost/ (bound to 127.0.0.1:HGPORT2) % errors +% With -v and -p http (should fail) +abort: cannot start server at 'localhost:80': Permission denied +abort: child process failed to start +% errors % With --prefix foo listening at http://localhost/foo/ (bound to 127.0.0.1:HGPORT1) % errors