~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/config.py

(mbp) infer default user name from /etc/mailname on unix (bug 616878)
 (Martin Pool)

Show diffs side-by-side

added added

removed removed

Lines of Context:
63
63
"""
64
64
 
65
65
import os
 
66
import string
66
67
import sys
67
68
 
68
69
from bzrlib import commands
271
272
        the concrete policy type is checked, and finally
272
273
        $EMAIL is examined.
273
274
        If no username can be found, errors.NoWhoami exception is raised.
274
 
 
275
 
        TODO: Check it's reasonably well-formed.
276
275
        """
277
276
        v = os.environ.get('BZR_EMAIL')
278
277
        if v:
279
278
            return v.decode(osutils.get_user_encoding())
280
 
 
281
279
        v = self._get_user_id()
282
280
        if v:
283
281
            return v
284
 
 
285
282
        v = os.environ.get('EMAIL')
286
283
        if v:
287
284
            return v.decode(osutils.get_user_encoding())
288
 
 
 
285
        name, email = _auto_user_id()
 
286
        if name and email:
 
287
            return '%s <%s>' % (name, email)
 
288
        elif email:
 
289
            return email
289
290
        raise errors.NoWhoami()
290
291
 
291
292
    def ensure_username(self):
1213
1214
        return os.path.expanduser('~/.cache')
1214
1215
 
1215
1216
 
 
1217
def _get_default_mail_domain():
 
1218
    """If possible, return the assumed default email domain.
 
1219
 
 
1220
    :returns: string mail domain, or None.
 
1221
    """
 
1222
    if sys.platform == 'win32':
 
1223
        # No implementation yet; patches welcome
 
1224
        return None
 
1225
    try:
 
1226
        f = open('/etc/mailname')
 
1227
    except (IOError, OSError), e:
 
1228
        return None
 
1229
    try:
 
1230
        domain = f.read().strip()
 
1231
        return domain
 
1232
    finally:
 
1233
        f.close()
 
1234
 
 
1235
 
 
1236
def _auto_user_id():
 
1237
    """Calculate automatic user identification.
 
1238
 
 
1239
    :returns: (realname, email), either of which may be None if they can't be
 
1240
    determined.
 
1241
 
 
1242
    Only used when none is set in the environment or the id file.
 
1243
 
 
1244
    This only returns an email address if we can be fairly sure the 
 
1245
    address is reasonable, ie if /etc/mailname is set on unix.
 
1246
 
 
1247
    This doesn't use the FQDN as the default domain because that may be 
 
1248
    slow, and it doesn't use the hostname alone because that's not normally 
 
1249
    a reasonable address.
 
1250
    """
 
1251
    if sys.platform == 'win32':
 
1252
        # No implementation to reliably determine Windows default mail
 
1253
        # address; please add one.
 
1254
        return None, None
 
1255
 
 
1256
    default_mail_domain = _get_default_mail_domain()
 
1257
    if not default_mail_domain:
 
1258
        return None, None
 
1259
 
 
1260
    import pwd
 
1261
    uid = os.getuid()
 
1262
    try:
 
1263
        w = pwd.getpwuid(uid)
 
1264
    except KeyError:
 
1265
        mutter('no passwd entry for uid %d?' % uid)
 
1266
        return None, None
 
1267
 
 
1268
    # we try utf-8 first, because on many variants (like Linux),
 
1269
    # /etc/passwd "should" be in utf-8, and because it's unlikely to give
 
1270
    # false positives.  (many users will have their user encoding set to
 
1271
    # latin-1, which cannot raise UnicodeError.)
 
1272
    try:
 
1273
        gecos = w.pw_gecos.decode('utf-8')
 
1274
        encoding = 'utf-8'
 
1275
    except UnicodeError:
 
1276
        try:
 
1277
            encoding = osutils.get_user_encoding()
 
1278
            gecos = w.pw_gecos.decode(encoding)
 
1279
        except UnicodeError, e:
 
1280
            mutter("cannot decode passwd entry %s" % w)
 
1281
            return None, None
 
1282
    try:
 
1283
        username = w.pw_name.decode(encoding)
 
1284
    except UnicodeError, e:
 
1285
        mutter("cannot decode passwd entry %s" % w)
 
1286
        return None, None
 
1287
 
 
1288
    comma = gecos.find(',')
 
1289
    if comma == -1:
 
1290
        realname = gecos
 
1291
    else:
 
1292
        realname = gecos[:comma]
 
1293
 
 
1294
    return realname, (username + '@' + default_mail_domain)
 
1295
 
 
1296
 
1216
1297
def parse_username(username):
1217
1298
    """Parse e-mail username and return a (name, address) tuple."""
1218
1299
    match = re.match(r'(.*?)\s*<?([\w+.-]+@[\w+.-]+)>?', username)