# Copyright (c) 2009, Andrew McNabb
# Copyright (c) 2003-2008, Brent N. Chun

import fcntl
import string
import sys

HOST_FORMAT = 'Host format is [user[:passwd]@]host[:port] [user]'


def read_host_files(paths, default_user=None, default_port=None):
    """Reads the given host files.

    Returns a list of (host, port, user) triples.
    """
    hosts = []
    if paths:
        for path in paths:
            hosts.extend(read_host_file(path))
    return hosts


def read_host_file(path, default_user=None, default_port=None):
    """Reads the given host file.

    Lines are of the form: host[:port] [login].
    Returns a list of (host, port, user) triples.
    """
    lines = []
    f = open(path)
    for line in f:
        lines.append(line.strip())
    f.close()

    hosts = []
    for line in lines:
        # Skip blank lines or lines starting with #
        line = line.strip()
        if not line or line.startswith('#'):
            continue
        host, port, user, passwd = parse_host_entry(line, default_user, default_port)
        if host:
            hosts.append((host, port, user, passwd))
    return hosts


# TODO: deprecate the second host field and standardize on the
# [user@]host[:port] format.
def parse_host_entry(line, default_user, default_port):
    """Parses a single host entry.

    This may take either the of the form [user@]host[:port] or
    host[:port][ user].

    Returns a (host, port, user) triple.
    """
    fields = line.split()
    if len(fields) > 2:
        sys.stderr.write('Bad line: "%s". Format should be'
                ' [user[:passwd]@]host[:port] [user]\n' % line)
        return None, None, None
    host_field = fields[0]
    host, port, user, passwd = parse_host(host_field, default_port=default_port)
    if len(fields) == 2:
        if user is None:
            user = fields[1]
        else:
            sys.stderr.write('User specified twice in line: "%s"\n' % line)
            return None, None, None
    if user is None:
        user = default_user
    return host, port, user, passwd


def parse_host_string(host_string, default_user=None, default_port=None):
    """Parses a whitespace-delimited string of "[user@]host[:port]" entries.

    Returns a list of (host, port, user) triples.
    """
    hosts = []
    entries = host_string.split()
    for entry in entries:
        hosts.append(parse_host(entry, default_user, default_port))
    return hosts


def parse_host(host, default_user=None, default_port=None):
    """Parses host entries of the form "[user[:passwd]@]host[:port]".

    Returns a (host, port, user) triple.
    """
    # TODO: when we stop supporting Python 2.4, switch to using str.partition.
    user = default_user
    port = default_port
    if '@' in host:
        user, host = host.split('@', 1)
    if ':' in host:
        host, port = host.rsplit(':', 1)
    # add by <a href="mailto:liuguangzhao@users.sf.net">liuguangzhao@users.sf.net</a>   [user[:passwd]@]host[:port]
    passwd = None
    if ':' in user:
        user, passwd = user.split(':')
    return (host, port, user, passwd)


def set_cloexec(filelike):
    """Sets the underlying filedescriptor to automatically close on exec.

    If set_cloexec is called for all open files, then subprocess.Popen does
    not require the close_fds option.
    """
    fcntl.fcntl(filelike.fileno(), fcntl.FD_CLOEXEC, 1)

@@ -311,32 +311,40 @@
 host, port, user
+, passwd
 ) triples.%0A    %22
@@ -330,32 +330,32 @@
 asswd) triples.%0A
-
     %22%22%22%0A    host
@@ -1430,32 +1430,40 @@
 host, port, user
+, passwd
 ) triple.%0A    %22%22
@@ -1656,32 +1656,38 @@
 turn None, None,
+ None,
  None%0A    host_f
@@ -1863,16 +1863,91 @@
 elds%5B1%5D%0A
+            if ':' in user:%0A                user, passwd = user.split(':')%0A
         
@@ -2050,32 +2050,38 @@
 turn None, None,
+ None,
  None%0A    if use
@@ -3087,24 +3087,81 @@
 sswd = None%0A
+    if user is None:%0A        passwd = None%0A    else:%0A    
     if ':' i
@@ -3160,32 +3160,36 @@
 if ':' in user:%0A
+    
         user, pa
@@ -3205,24 +3205,27 @@
 er.split(':'
+, 1
 )%0A    return

update patched pssh new 2.2 to 9.2.2 version