# this module is an OS/2 oriented replacement for the pwd standard
# extension module.

# written by Andrew MacIntyre, April 2001.
# released into the public domain "as is", with NO WARRANTY

# note that this implementation checks whether ":" or ";" as used as 
# the field separator character.  Path conversions are are applied when
# the database uses ":" as the field separator character.

"""Replacement for pwd standard extension module, intended for use on 
OS/2 and similar systems which don't normally have an /etc/passwd file.

The standard Unix password database is an ASCII text file with 7 fields 
per record (line), separated by a colon:
  - user name (string)
  - password (encrypted string, or "*" or "")
  - user id (integer)
  - group id (integer)
  - description (usually user's name)
  - home directory (path to user's home directory)
  - shell (path to the user's login shell)

(see the section 8.1 of the Python Library Reference)

This implementation differs from the standard Unix implementation by 
allowing use of the platform's native path separator character - ';' on OS/2, 
DOS and MS-Windows - as the field separator in addition to the Unix 
standard ":".  Additionally, when ":" is the separator path conversions 
are applied to deal with any munging of the drive letter reference.

The module looks for the password database at the following locations 
(in order first to last):
  - ${ETC_PASSWD}             (or %ETC_PASSWD%)
  - ${ETC}/passwd             (or %ETC%/passwd)
  - ${PYTHONHOME}/Etc/passwd  (or %PYTHONHOME%/Etc/passwd)

Classes
-------

None

Functions
---------

getpwuid(uid) -  return the record for user-id uid as a 7-tuple

getpwnam(name) - return the record for user 'name' as a 7-tuple

getpwall() -     return a list of 7-tuples, each tuple being one record
                 (NOTE: the order is arbitrary)

Attributes
----------

passwd_file -    the path of the password database file

"""

import os

# try and find the passwd file
__passwd_path = []
if os.environ.has_key('ETC_PASSWD'):
    __passwd_path.append(os.environ['ETC_PASSWD'])
if os.environ.has_key('ETC'):
    __passwd_path.append('%s/passwd' % os.environ['ETC'])
if os.environ.has_key('PYTHONHOME'):
    __passwd_path.append('%s/Etc/passwd' % os.environ['PYTHONHOME'])

passwd_file = None
for __i in __passwd_path:
    try:
        __f = open(__i, 'r')
        __f.close()
        passwd_file = __i
        break
    except:
        pass

# path conversion handlers
def __nullpathconv(path):
    return path.replace(os.altsep, os.sep)

def __unixpathconv(path):
    # two known drive letter variations: "x;" and "$x"
    if path[0] == '$':
        conv = path[1] + ':' + path[2:]
    elif path[1] == ';':
        conv = path[0] + ':' + path[2:]
    else:
        conv = path
    return conv.replace(os.altsep, os.sep)

# decide what field separator we can try to use - Unix standard, with
# the platform's path separator as an option.  No special field conversion
# handler is required when using the platform's path separator as field 
# separator, but are required for the home directory and shell fields when 
# using the standard Unix (":") field separator.
__field_sep = {':': __unixpathconv}
if os.pathsep:
    if os.pathsep != ':':
        __field_sep[os.pathsep] = __nullpathconv

# helper routine to identify which separator character is in use
def __get_field_sep(record):
    fs = None
    for c in __field_sep.keys():
        # there should be 6 delimiter characters (for 7 fields)
        if record.count(c) == 6:
            fs = c
            break
    if fs:
        return fs
    else:
        raise KeyError, '>> passwd database fields not delimited <<'

# read the whole file, parsing each entry into tuple form
# with dictionaries to speed recall by UID or passwd name
def __read_passwd_file():
    if passwd_file:
        passwd = open(passwd_file, 'r')
    else:
        raise KeyError, '>> no password database <<'
    uidx = {}
    namx = {}
    sep = None
    while 1:
        entry = passwd.readline().strip()
        if len(entry) > 6:
            if sep == None:
                sep = __get_field_sep(entry)
            fields = entry.split(sep)
            for i in (2, 3):
                fields[i] = int(fields[i])
            for i in (5, 6):
                fields[i] = __field_sep[sep](fields[i])
            record = tuple(fields)
            if not uidx.has_key(fields[2]):
                uidx[fields[2]] = record
            if not namx.has_key(fields[0]):
                namx[fields[0]] = record
        elif len(entry) > 0:
            pass                         # skip empty or malformed records
        else:
            break
    passwd.close()
    if len(uidx) == 0:
        raise KeyError
    return (uidx, namx)

# return the passwd database entry by UID
def getpwuid(uid):
    u, n = __read_passwd_file()
    return u[uid]

# return the passwd database entry by passwd name
def getpwnam(name):
    u, n = __read_passwd_file()
    return n[name]

# return all the passwd database entries
def getpwall():
    u, n = __read_passwd_file()
    return n.values()

# test harness
if __name__ == '__main__':
    getpwall()
