src/modules/misc.py
author Bart Smaalders <Bart.Smaalders@Sun.COM>
Fri, 01 Aug 2008 23:57:44 -0700
changeset 443 5ffa5b7dac9c
parent 429 6c9cbb6e6600
child 451 74f1fe85fe2d
permissions -rw-r--r--
2589 pyc files generate lots of verify chaff 2726 pkg verify doesn't verify file or content hash by default 2680 packagemanager prototype files don't belong in the workspace
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
409
713e20963dc2 2314 shebang lines should use minimum python version
Shawn Walker <swalker@opensolaris.org>
parents: 404
diff changeset
     1
#!/usr/bin/python2.4
46
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
     2
#
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
     3
# CDDL HEADER START
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
     4
#
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
     5
# The contents of this file are subject to the terms of the
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
     6
# Common Development and Distribution License (the "License").
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
     7
# You may not use this file except in compliance with the License.
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
     8
#
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
     9
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    10
# or http://www.opensolaris.org/os/licensing.
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    11
# See the License for the specific language governing permissions
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    12
# and limitations under the License.
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    13
#
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    14
# When distributing Covered Code, include this CDDL HEADER in each
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    15
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    16
# If applicable, add the following below this CDDL HEADER, with the
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    17
# fields enclosed by brackets "[]" replaced with your own identifying
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    18
# information: Portions Copyright [yyyy] [name of copyright owner]
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    19
#
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    20
# CDDL HEADER END
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    21
#
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    22
260
a1b77322abb2 255 Symbolic HTTP response codes should be used
Shawn Walker <swalker@opensolaris.org>
parents: 181
diff changeset
    23
# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
46
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    24
# Use is subject to license terms.
119
537d69114be4 Implement bundled file downloads using filelist
johansen <johansen@sun.com>
parents: 108
diff changeset
    25
384
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
    26
import errno
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
    27
import httplib
119
537d69114be4 Implement bundled file downloads using filelist
johansen <johansen@sun.com>
parents: 108
diff changeset
    28
import os
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
    29
import platform
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
    30
import re
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
    31
import sha
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
    32
import socket
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    33
import urllib
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    34
import urllib2
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    35
import urlparse
384
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
    36
import sys
342
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
    37
import zlib
443
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    38
import time
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    39
import calendar
310
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
    40
import pkg.urlhelpers as urlhelpers
319
39b8b5c538bf 1104 want custom user-agent string
Danek Duvall <danek.duvall@sun.com>
parents: 310
diff changeset
    41
import pkg.portable as portable
39b8b5c538bf 1104 want custom user-agent string
Danek Duvall <danek.duvall@sun.com>
parents: 310
diff changeset
    42
from pkg.client.imagetypes import img_type_names, IMG_NONE
39b8b5c538bf 1104 want custom user-agent string
Danek Duvall <danek.duvall@sun.com>
parents: 310
diff changeset
    43
from pkg import VERSION
310
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
    44
443
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    45
def time_to_timestamp(t):
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    46
        """ convert seconds since epoch to %Y%m%dT%H%M%SZ format"""
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    47
        # XXX optimize?
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    48
        return time.strftime("%Y%m%dT%H%M%SZ", time.gmtime(t))
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    49
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    50
def timestamp_to_time(ts):
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    51
        """ convert %Y%m%dT%H%M%SZ format to seconds since epoch"""
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    52
        # XXX optimize?
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    53
        return calendar.timegm(time.strptime(ts, "%Y%m%dT%H%M%SZ"))
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    54
46
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    55
def hash_file_name(f):
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    56
        """Return the two-level path fragment for the given filename, which is
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    57
        assumed to be a content hash of at least 8 distinct characters."""
119
537d69114be4 Implement bundled file downloads using filelist
johansen <johansen@sun.com>
parents: 108
diff changeset
    58
        return os.path.join("%s" % f[0:2], "%s" % f[2:8], "%s" % f)
46
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    59
310
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
    60
def url_affix_trailing_slash(u):
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
    61
        if u[-1] != '/':
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
    62
                u = u + '/'
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
    63
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
    64
        return u
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
    65
319
39b8b5c538bf 1104 want custom user-agent string
Danek Duvall <danek.duvall@sun.com>
parents: 310
diff changeset
    66
_client_version = "pkg/%s (%s %s; %s %s; %%s)" % \
39b8b5c538bf 1104 want custom user-agent string
Danek Duvall <danek.duvall@sun.com>
parents: 310
diff changeset
    67
    (VERSION, portable.util.get_canonical_os_name(), platform.machine(),
39b8b5c538bf 1104 want custom user-agent string
Danek Duvall <danek.duvall@sun.com>
parents: 310
diff changeset
    68
    portable.util.get_os_release(), platform.version())
39b8b5c538bf 1104 want custom user-agent string
Danek Duvall <danek.duvall@sun.com>
parents: 310
diff changeset
    69
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    70
def versioned_urlopen(base_uri, operation, versions = [], tail = None,
319
39b8b5c538bf 1104 want custom user-agent string
Danek Duvall <danek.duvall@sun.com>
parents: 310
diff changeset
    71
    data = None, headers = {}, ssl_creds = None, imgtype = IMG_NONE):
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    72
        """Open the best URI for an operation given a set of versions.
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    73
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    74
        Both the client and the server may support multiple versions of
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    75
        the protocol of a particular operation.  The client will pass
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    76
        this method an ordered array of versions it understands, along
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    77
        with the base URI and the operation it wants.  This method will
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    78
        open the URL corresponding to the best version both the client
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    79
        and the server understand, returning a tuple of the open URL and
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    80
        the version used on success, and throwing an exception if no
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    81
        matching version can be found.
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    82
        """
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    83
        # Ignore http_proxy for localhost case, by overriding
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    84
        # default proxy behaviour of urlopen().
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    85
        netloc = urlparse.urlparse(base_uri)[1]
310
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
    86
285
538afd6a9d3e 763 pkg image-create /foo , pkg image-create /tmp/foo both yield (different) tracebacks
Danek Duvall <danek.duvall@sun.com>
parents: 260
diff changeset
    87
        if not netloc:
538afd6a9d3e 763 pkg image-create /foo , pkg image-create /tmp/foo both yield (different) tracebacks
Danek Duvall <danek.duvall@sun.com>
parents: 260
diff changeset
    88
                raise ValueError, "Malformed URL: %s" % base_uri
310
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
    89
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    90
        if urllib.splitport(netloc)[0] == "localhost":
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    91
                # XXX cache this opener?
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    92
                proxy_handler = urllib2.ProxyHandler({})
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    93
                opener_dir = urllib2.build_opener(proxy_handler)
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    94
                url_opener = opener_dir.open
310
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
    95
        elif ssl_creds and ssl_creds != (None, None):
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
    96
                cert_handler = urlhelpers.HTTPSCertHandler(
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
    97
                    key_file = ssl_creds[0], cert_file = ssl_creds[1])
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
    98
                opener_dir = urllib2.build_opener(cert_handler)
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
    99
                url_opener = opener_dir.open
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   100
        else:
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   101
                url_opener = urllib2.urlopen
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   102
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   103
        for version in versions:
351
9301d4d85349 767 pkg client can't talk to repo at a path other than / on a server
johansen <johansen@sun.com>
parents: 342
diff changeset
   104
                if base_uri[-1] != '/':
9301d4d85349 767 pkg client can't talk to repo at a path other than / on a server
johansen <johansen@sun.com>
parents: 342
diff changeset
   105
                        base_uri += '/'
9301d4d85349 767 pkg client can't talk to repo at a path other than / on a server
johansen <johansen@sun.com>
parents: 342
diff changeset
   106
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   107
                if tail:
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   108
                        uri = urlparse.urljoin(base_uri, "%s/%s/%s" % \
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   109
                            (operation, version, tail))
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   110
                else:
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   111
                        uri = urlparse.urljoin(base_uri, "%s/%s" % \
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   112
                            (operation, version))
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   113
319
39b8b5c538bf 1104 want custom user-agent string
Danek Duvall <danek.duvall@sun.com>
parents: 310
diff changeset
   114
                headers["User-Agent"] = \
39b8b5c538bf 1104 want custom user-agent string
Danek Duvall <danek.duvall@sun.com>
parents: 310
diff changeset
   115
                    _client_version % img_type_names[imgtype]
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   116
                req = urllib2.Request(url = uri, headers = headers)
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   117
                if data is not None:
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   118
                        req.add_data(data)
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   119
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   120
                try:
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   121
                        c = url_opener(req)
153
05d90faecc40 Fix versioned_urlopen() to catch the right error, and catch URLError higher up.
Danek Duvall <danek.duvall@sun.com>
parents: 145
diff changeset
   122
                except urllib2.HTTPError, e:
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   123
                        if e.code != httplib.NOT_FOUND or \
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   124
                            e.msg != "Version not supported":
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   125
                                raise
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   126
                        continue
260
a1b77322abb2 255 Symbolic HTTP response codes should be used
Shawn Walker <swalker@opensolaris.org>
parents: 181
diff changeset
   127
                # XXX catch BadStatusLine and convert to INTERNAL_SERVER_ERROR?
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   128
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   129
                return c, version
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   130
        else:
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   131
                # Couldn't find a version that we liked.
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   132
                raise RuntimeError, \
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   133
                    "%s doesn't speak a known version of %s operation" % \
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   134
                    (base_uri, operation)
327
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   135
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   136
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   137
_hostname_re = re.compile("^[a-zA-Z0-9](?:[a-zA-Z0-9\-]*[a-zA-Z0-9]+\.?)*$")
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   138
_invalid_host_chars = re.compile(".*[^a-zA-Z0-9\-\.]+")
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   139
_valid_proto = ["http", "https"]
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   140
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   141
def valid_auth_prefix(prefix):
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   142
        """Verify that the authority prefix only contains valid characters."""
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   143
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   144
        # This is a workaround for the the hostname_re being slow when
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   145
        # it comes to finding invalid characters in the prefix string.
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   146
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   147
        if _invalid_host_chars.match(prefix):
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   148
                # prefix bad chars
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   149
                return False
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   150
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   151
        if _hostname_re.match(prefix):
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   152
                return True
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   153
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   154
        return False
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   155
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   156
def valid_auth_url(url):
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   157
        """Verify that the authority URL contains only valid characters."""
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   158
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   159
        # First split the URL and check if the scheme is one we support
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   160
        o = urlparse.urlsplit(url)
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   161
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   162
        if not o[0] in _valid_proto:
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   163
                return False
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   164
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   165
        # Next verify that the network location is valid
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   166
        host, port = urllib.splitport(o[1])
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   167
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   168
        if not host or _invalid_host_chars.match(host):
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   169
                return False
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   170
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   171
        if _hostname_re.match(host):
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   172
                return True
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   173
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   174
        return False
342
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   175
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   176
def gunzip_from_stream(gz, outfile):
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   177
        """Decompress a gzipped input stream into an output stream.
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   178
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   179
        The argument 'gz' is an input stream of a gzipped file (XXX make it do
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   180
        either a gzipped file or raw zlib compressed data), and 'outfile' is is
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   181
        an output stream.  gunzip_from_stream() decompresses data from 'gz' and
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   182
        writes it to 'outfile', and returns the hexadecimal SHA-1 sum of that
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   183
        data.
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   184
        """
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   185
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   186
        FHCRC = 2
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   187
        FEXTRA = 4
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   188
        FNAME = 8
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   189
        FCOMMENT = 16
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   190
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   191
        # Read the header
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   192
        magic = gz.read(2)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   193
        if magic != "\037\213":
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   194
                raise IOError, "Not a gzipped file"
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   195
        method = ord(gz.read(1))
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   196
        if method != 8:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   197
                raise IOError, "Unknown compression method"
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   198
        flag = ord(gz.read(1))
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   199
        gz.read(6) # Discard modtime, extraflag, os
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   200
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   201
        # Discard an extra field
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   202
        if flag & FEXTRA:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   203
                xlen = ord(gz.read(1))
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   204
                xlen = xlen + 256 * ord(gz.read(1))
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   205
                gz.read(xlen)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   206
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   207
        # Discard a null-terminated filename
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   208
        if flag & FNAME:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   209
                while True:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   210
                        s = gz.read(1)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   211
                        if not s or s == "\000":
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   212
                                break
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   213
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   214
        # Discard a null-terminated comment
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   215
        if flag & FCOMMENT:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   216
                while True:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   217
                        s = gz.read(1)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   218
                        if not s or s == "\000":
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   219
                                break
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   220
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   221
        # Discard a 16-bit CRC
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   222
        if flag & FHCRC:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   223
                gz.read(2)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   224
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   225
        shasum = sha.new()
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   226
        dcobj = zlib.decompressobj(-zlib.MAX_WBITS)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   227
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   228
        while True:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   229
                buf = gz.read(64 * 1024)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   230
                if buf == "":
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   231
                        ubuf = dcobj.flush()
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   232
                        shasum.update(ubuf)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   233
                        outfile.write(ubuf)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   234
                        break
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   235
                ubuf = dcobj.decompress(buf)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   236
                shasum.update(ubuf)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   237
                outfile.write(ubuf)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   238
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   239
        return shasum.hexdigest()
384
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   240
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   241
class PipeError(Exception):
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   242
        """ Pipe exception. """
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   243
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   244
        def __init__(self, args=None):
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   245
                self.args = args
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   246
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   247
def msg(*text):
429
6c9cbb6e6600 983 pkg search returns just one action per package/token-type combo
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
   248
        """ Emit a message. """
384
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   249
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   250
        try:
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   251
                print ' '.join([str(l) for l in text])
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   252
        except IOError, e:
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   253
                if e.errno == errno.EPIPE:
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   254
                        raise PipeError, e
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   255
                raise
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   256
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   257
def emsg(*text):
429
6c9cbb6e6600 983 pkg search returns just one action per package/token-type combo
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
   258
        """ Emit a message to sys.stderr. """
384
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   259
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   260
        try:
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   261
                print >> sys.stderr, ' '.join([str(l) for l in text])
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   262
        except IOError, e:
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   263
                if e.errno == errno.EPIPE:
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   264
                        raise PipeError, e
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   265
                raise
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   266
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   267
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   268
def port_available(host, port):
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   269
        """Returns True if the indicated port is available to bind to; otherwise
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   270
        returns False."""
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   271
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   272
        port = int(port)
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   273
        if host is None:
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   274
                # None is the same as INADDR_ANY, which for our purposes, should
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   275
                # be the hostname.
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   276
                host = socket.gethostname()
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   277
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   278
        try:
404
e5329e84b9a8 2331 depot command-line parsing errors cause traceback
Shawn Walker <swalker@opensolaris.org>
parents: 388
diff changeset
   279
                sock = None
e5329e84b9a8 2331 depot command-line parsing errors cause traceback
Shawn Walker <swalker@opensolaris.org>
parents: 388
diff changeset
   280
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   281
                # Get the address family of our host (to allow for IPV6, etc.).
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   282
                for entry in socket.getaddrinfo(host, port, socket.AF_UNSPEC,
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   283
                    socket.SOCK_STREAM):
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   284
                        family, socktype, proto, canonname, sockaddr = entry
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   285
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   286
                        # First try to bind to the specified port to see if we
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   287
                        # have an access problem or some other issue.
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   288
                        sock = socket.socket(family, socktype, proto)
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   289
                        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   290
                            1)
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   291
                        sock.bind((host, port))
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   292
                        sock.close()
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   293
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   294
                        # Now try to connect to the specified port to see if it
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   295
                        # is already in use.
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   296
                        sock = socket.socket(family, socktype, proto)
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   297
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   298
                        # Some systems timeout rather than refuse a connection.
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   299
                        # This avoids getting stuck on SYN_SENT for those
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   300
                        # systems (such as certain firewalls).
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   301
                        sock.settimeout(1.0)
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   302
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   303
                        sock.connect((host, port))
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   304
                        sock.close()
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   305
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   306
                        # If we successfully connected...
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   307
                        raise socket.error(errno.EBUSY,
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   308
                            'Port already in use')
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   309
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   310
        except socket.error, e:
404
e5329e84b9a8 2331 depot command-line parsing errors cause traceback
Shawn Walker <swalker@opensolaris.org>
parents: 388
diff changeset
   311
                errnum = e[0]
e5329e84b9a8 2331 depot command-line parsing errors cause traceback
Shawn Walker <swalker@opensolaris.org>
parents: 388
diff changeset
   312
                try:
e5329e84b9a8 2331 depot command-line parsing errors cause traceback
Shawn Walker <swalker@opensolaris.org>
parents: 388
diff changeset
   313
                        msg = e[1]
e5329e84b9a8 2331 depot command-line parsing errors cause traceback
Shawn Walker <swalker@opensolaris.org>
parents: 388
diff changeset
   314
                except IndexError:
e5329e84b9a8 2331 depot command-line parsing errors cause traceback
Shawn Walker <swalker@opensolaris.org>
parents: 388
diff changeset
   315
                        msg = e[0]
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   316
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   317
                if sock:
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   318
                        sock.close()
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   319
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   320
                if errnum == errno.ECONNREFUSED:
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   321
                        # If we could not connect to the port, we know it isn't
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   322
                        # in use.
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   323
                        return True, None
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   324
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   325
                return False, msg
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   326
388
5a08791fb814 2188 Client must fail gracefully when network timeout occurs
johansen <johansen@sun.com>
parents: 386
diff changeset
   327
5a08791fb814 2188 Client must fail gracefully when network timeout occurs
johansen <johansen@sun.com>
parents: 386
diff changeset
   328
# Set the maximum number of timeouts before we giveup.  This can
5a08791fb814 2188 Client must fail gracefully when network timeout occurs
johansen <johansen@sun.com>
parents: 386
diff changeset
   329
# be adjusted by setting the environment variable PKG_TIMEOUT_MAX
5a08791fb814 2188 Client must fail gracefully when network timeout occurs
johansen <johansen@sun.com>
parents: 386
diff changeset
   330
MAX_TIMEOUT_COUNT = 4
5a08791fb814 2188 Client must fail gracefully when network timeout occurs
johansen <johansen@sun.com>
parents: 386
diff changeset
   331
5a08791fb814 2188 Client must fail gracefully when network timeout occurs
johansen <johansen@sun.com>
parents: 386
diff changeset
   332
class TransferTimedOutException(Exception):
5a08791fb814 2188 Client must fail gracefully when network timeout occurs
johansen <johansen@sun.com>
parents: 386
diff changeset
   333
        def __init__(self, args = None):
5a08791fb814 2188 Client must fail gracefully when network timeout occurs
johansen <johansen@sun.com>
parents: 386
diff changeset
   334
                self.args = args
429
6c9cbb6e6600 983 pkg search returns just one action per package/token-type combo
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
   335
6c9cbb6e6600 983 pkg search returns just one action per package/token-type combo
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
   336
6c9cbb6e6600 983 pkg search returns just one action per package/token-type combo
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
   337
# Default maximum memory useage during indexing
6c9cbb6e6600 983 pkg search returns just one action per package/token-type combo
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
   338
# This is a soft cap since memory usage is estimated.
6c9cbb6e6600 983 pkg search returns just one action per package/token-type combo
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
   339
try:
6c9cbb6e6600 983 pkg search returns just one action per package/token-type combo
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
   340
        phys_pages = os.sysconf("SC_PHYS_PAGES")
6c9cbb6e6600 983 pkg search returns just one action per package/token-type combo
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
   341
        page_size = os.sysconf("SC_PAGE_SIZE")
6c9cbb6e6600 983 pkg search returns just one action per package/token-type combo
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
   342
        SERVER_DEFAULT_MEM_USE_KB = (phys_pages / 1024.0) * page_size / 3
6c9cbb6e6600 983 pkg search returns just one action per package/token-type combo
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
   343
        CLIENT_DEFAULT_MEM_USE_KB = SERVER_DEFAULT_MEM_USE_KB / 2.0
6c9cbb6e6600 983 pkg search returns just one action per package/token-type combo
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
   344
6c9cbb6e6600 983 pkg search returns just one action per package/token-type combo
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
   345
except:
6c9cbb6e6600 983 pkg search returns just one action per package/token-type combo
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
   346
        CLIENT_DEFAULT_MEM_USE_KB = 100
6c9cbb6e6600 983 pkg search returns just one action per package/token-type combo
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
   347
        SERVER_DEFAULT_MEM_USE_KB = 500