tools/userland-fetch
author Vladimir Marek <Vladimir.Marek@oracle.com>
Fri, 22 Feb 2013 10:11:06 +0100
branchs11-update
changeset 2506 ba463e5578fa
parent 832 d0946a4ddb78
child 3533 0b8107a40da7
child 3979 46744fa00de4
permissions -rwxr-xr-x
16195225 use _getgroupsbymember() instead of slow getgrent() calls
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
18
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
     1
#!/usr/bin/python2.6
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
     2
#
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
     3
# CDDL HEADER START
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
     4
#
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
     5
# The contents of this file are subject to the terms of the
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
     6
# Common Development and Distribution License (the "License").
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
     7
# You may not use this file except in compliance with the License.
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
     8
#
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
     9
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    10
# or http://www.opensolaris.org/os/licensing.
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    11
# See the License for the specific language governing permissions
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    12
# and limitations under the License.
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    13
#
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    14
# When distributing Covered Code, include this CDDL HEADER in each
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    15
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    16
# If applicable, add the following below this CDDL HEADER, with the
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    17
# fields enclosed by brackets "[]" replaced with your own identifying
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    18
# information: Portions Copyright [yyyy] [name of copyright owner]
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    19
#
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    20
# CDDL HEADER END
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    21
#
800
2ad056ed89ec 7163771 sha1 should not be used in userland-fetch and userland component/*/Makefile
Mike Sullivan <Mike.Sullivan@Oracle.COM>
parents: 212
diff changeset
    22
# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
18
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    23
#
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    24
#
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    25
# fetch.py - a file download utility
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    26
#
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    27
#  A simple program similiar to wget(1), but handles local file copy, ignores
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    28
#  directories, and verifies file hashes.
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    29
#
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    30
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    31
import os
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    32
import sys
42
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
    33
import shutil
832
d0946a4ddb78 PSARC/2012/198 python-jsonrpclib
Edward Pilatowicz <edward.pilatowicz@oracle.com>
parents: 800
diff changeset
    34
from urllib import splittype
d0946a4ddb78 PSARC/2012/198 python-jsonrpclib
Edward Pilatowicz <edward.pilatowicz@oracle.com>
parents: 800
diff changeset
    35
from urllib2 import urlopen
135
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
    36
import hashlib
18
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    37
136
6a7dd3a5aaf9 7027131 userland-fetch should be more verbose when printing IOError exception
Vladimir Marek <Vladimir.Marek@oracle.com>
parents: 135
diff changeset
    38
def printIOError(e, txt):
6a7dd3a5aaf9 7027131 userland-fetch should be more verbose when printing IOError exception
Vladimir Marek <Vladimir.Marek@oracle.com>
parents: 135
diff changeset
    39
	""" Function to decode and print IOError type exception """
6a7dd3a5aaf9 7027131 userland-fetch should be more verbose when printing IOError exception
Vladimir Marek <Vladimir.Marek@oracle.com>
parents: 135
diff changeset
    40
	print "I/O Error: " + txt + ": "
6a7dd3a5aaf9 7027131 userland-fetch should be more verbose when printing IOError exception
Vladimir Marek <Vladimir.Marek@oracle.com>
parents: 135
diff changeset
    41
	try:
6a7dd3a5aaf9 7027131 userland-fetch should be more verbose when printing IOError exception
Vladimir Marek <Vladimir.Marek@oracle.com>
parents: 135
diff changeset
    42
		(code, message) = e
6a7dd3a5aaf9 7027131 userland-fetch should be more verbose when printing IOError exception
Vladimir Marek <Vladimir.Marek@oracle.com>
parents: 135
diff changeset
    43
		print str(message) + " (" + str(code) + ")"
6a7dd3a5aaf9 7027131 userland-fetch should be more verbose when printing IOError exception
Vladimir Marek <Vladimir.Marek@oracle.com>
parents: 135
diff changeset
    44
	except:
6a7dd3a5aaf9 7027131 userland-fetch should be more verbose when printing IOError exception
Vladimir Marek <Vladimir.Marek@oracle.com>
parents: 135
diff changeset
    45
		print str(e)
6a7dd3a5aaf9 7027131 userland-fetch should be more verbose when printing IOError exception
Vladimir Marek <Vladimir.Marek@oracle.com>
parents: 135
diff changeset
    46
	
135
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
    47
def validate(file, hash):
58
d8024c042a00 7011369 gmake complains about fresh userland bits
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 42
diff changeset
    48
	algorithm, hashvalue = hash.split(':')
800
2ad056ed89ec 7163771 sha1 should not be used in userland-fetch and userland component/*/Makefile
Mike Sullivan <Mike.Sullivan@Oracle.COM>
parents: 212
diff changeset
    49
2ad056ed89ec 7163771 sha1 should not be used in userland-fetch and userland component/*/Makefile
Mike Sullivan <Mike.Sullivan@Oracle.COM>
parents: 212
diff changeset
    50
	# force migration away from sha1
2ad056ed89ec 7163771 sha1 should not be used in userland-fetch and userland component/*/Makefile
Mike Sullivan <Mike.Sullivan@Oracle.COM>
parents: 212
diff changeset
    51
	if algorithm == "sha1":
2ad056ed89ec 7163771 sha1 should not be used in userland-fetch and userland component/*/Makefile
Mike Sullivan <Mike.Sullivan@Oracle.COM>
parents: 212
diff changeset
    52
		algorithm = "sha256"
18
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    53
	try:
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    54
		m = hashlib.new(algorithm)
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    55
	except ValueError:
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    56
		return False
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    57
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    58
	while True:
137
6fb20db3eee4 7028115 userland-fetch fails to validate gd2 archive (fix bzip)
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 136
diff changeset
    59
		try:
6fb20db3eee4 7028115 userland-fetch fails to validate gd2 archive (fix bzip)
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 136
diff changeset
    60
			block = file.read()
6fb20db3eee4 7028115 userland-fetch fails to validate gd2 archive (fix bzip)
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 136
diff changeset
    61
		except IOError, err:
6fb20db3eee4 7028115 userland-fetch fails to validate gd2 archive (fix bzip)
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 136
diff changeset
    62
			print str(err),
6fb20db3eee4 7028115 userland-fetch fails to validate gd2 archive (fix bzip)
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 136
diff changeset
    63
			break
6fb20db3eee4 7028115 userland-fetch fails to validate gd2 archive (fix bzip)
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 136
diff changeset
    64
18
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    65
		m.update(block)
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    66
		if block == '':
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    67
			break
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    68
58
d8024c042a00 7011369 gmake complains about fresh userland bits
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 42
diff changeset
    69
	return "%s:%s" % (algorithm, m.hexdigest())
18
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
    70
135
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
    71
def validate_container(filename, hash):
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
    72
	try:
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
    73
		file = open(filename, 'r')
136
6a7dd3a5aaf9 7027131 userland-fetch should be more verbose when printing IOError exception
Vladimir Marek <Vladimir.Marek@oracle.com>
parents: 135
diff changeset
    74
	except IOError as e:
6a7dd3a5aaf9 7027131 userland-fetch should be more verbose when printing IOError exception
Vladimir Marek <Vladimir.Marek@oracle.com>
parents: 135
diff changeset
    75
		printIOError(e, "Can't open file " + filename)
135
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
    76
		return False
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
    77
	return validate(file, hash)
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
    78
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
    79
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
    80
def validate_payload(filename, hash):
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
    81
	import re
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
    82
	import gzip
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
    83
	import bz2
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
    84
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
    85
	expr_bz = re.compile('.+\.bz2$', re.IGNORECASE)
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
    86
	expr_gz = re.compile('.+\.gz$', re.IGNORECASE)
800
2ad056ed89ec 7163771 sha1 should not be used in userland-fetch and userland component/*/Makefile
Mike Sullivan <Mike.Sullivan@Oracle.COM>
parents: 212
diff changeset
    87
	expr_tgz = re.compile('.+\.tgz$', re.IGNORECASE)
135
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
    88
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
    89
	try:
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
    90
		if expr_bz.match(filename):
137
6fb20db3eee4 7028115 userland-fetch fails to validate gd2 archive (fix bzip)
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 136
diff changeset
    91
			file = bz2.BZ2File(filename, 'r')
135
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
    92
		elif expr_gz.match(filename):
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
    93
			file = gzip.GzipFile(filename, 'r')
800
2ad056ed89ec 7163771 sha1 should not be used in userland-fetch and userland component/*/Makefile
Mike Sullivan <Mike.Sullivan@Oracle.COM>
parents: 212
diff changeset
    94
		elif expr_tgz.match(filename):
2ad056ed89ec 7163771 sha1 should not be used in userland-fetch and userland component/*/Makefile
Mike Sullivan <Mike.Sullivan@Oracle.COM>
parents: 212
diff changeset
    95
			file = gzip.GzipFile(filename, 'r')
135
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
    96
		else:
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
    97
			return False
136
6a7dd3a5aaf9 7027131 userland-fetch should be more verbose when printing IOError exception
Vladimir Marek <Vladimir.Marek@oracle.com>
parents: 135
diff changeset
    98
	except IOError as e:
6a7dd3a5aaf9 7027131 userland-fetch should be more verbose when printing IOError exception
Vladimir Marek <Vladimir.Marek@oracle.com>
parents: 135
diff changeset
    99
		printIOError(e, "Can't open archive " + filename)
135
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
   100
		return False
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
   101
	return validate(file, hash)
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
   102
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
   103
42
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   104
def download(url, filename = None):
18
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   105
	src = None
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   106
42
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   107
	try:
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   108
		src = urlopen(url)
136
6a7dd3a5aaf9 7027131 userland-fetch should be more verbose when printing IOError exception
Vladimir Marek <Vladimir.Marek@oracle.com>
parents: 135
diff changeset
   109
	except IOError as e:
6a7dd3a5aaf9 7027131 userland-fetch should be more verbose when printing IOError exception
Vladimir Marek <Vladimir.Marek@oracle.com>
parents: 135
diff changeset
   110
		printIOError(e, "Can't open url " + url)
18
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   111
		return None
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   112
212
8a66c0c0e8dc 7041047 userland-fetch should handle http errors more gracefully
Vladimir Marek <Vladimir.Marek@oracle.com>
parents: 137
diff changeset
   113
	# 3xx, 4xx and 5xx (f|ht)tp codes designate unsuccessfull action
8a66c0c0e8dc 7041047 userland-fetch should handle http errors more gracefully
Vladimir Marek <Vladimir.Marek@oracle.com>
parents: 137
diff changeset
   114
	if 3 <= int(src.getcode()/100) <= 5:
8a66c0c0e8dc 7041047 userland-fetch should handle http errors more gracefully
Vladimir Marek <Vladimir.Marek@oracle.com>
parents: 137
diff changeset
   115
		print "Error code: " + str(src.getcode())
8a66c0c0e8dc 7041047 userland-fetch should handle http errors more gracefully
Vladimir Marek <Vladimir.Marek@oracle.com>
parents: 137
diff changeset
   116
		return None
8a66c0c0e8dc 7041047 userland-fetch should handle http errors more gracefully
Vladimir Marek <Vladimir.Marek@oracle.com>
parents: 137
diff changeset
   117
18
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   118
	if filename == None:
42
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   119
		filename = src.geturl().split('/')[-1]
18
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   120
42
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   121
	try:
18
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   122
		dst = open(filename, 'wb');
136
6a7dd3a5aaf9 7027131 userland-fetch should be more verbose when printing IOError exception
Vladimir Marek <Vladimir.Marek@oracle.com>
parents: 135
diff changeset
   123
	except IOError as e:
6a7dd3a5aaf9 7027131 userland-fetch should be more verbose when printing IOError exception
Vladimir Marek <Vladimir.Marek@oracle.com>
parents: 135
diff changeset
   124
		printIOError(e, "Can't open file " + filename + " for writing")
42
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   125
		src.close()
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   126
		return None
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   127
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   128
	while True:
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   129
		block = src.read()
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   130
		if block == '':
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   131
			break;
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   132
		dst.write(block)
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   133
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   134
	src.close()
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   135
	dst.close()
18
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   136
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   137
	# return the name of the file that we downloaded the data to.
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   138
	return filename
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   139
42
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   140
def download_paths(search, filename, url):
18
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   141
	urls = list()
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   142
42
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   143
	if filename != None:
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   144
		tmp = os.getenv('DOWNLOAD_SEARCH_PATH')
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   145
		if tmp:
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   146
			search += tmp.split(' ')
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   147
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   148
		file = os.path.basename(filename)
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   149
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   150
		urls = [ base + '/' + file for base in search ]
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   151
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   152
		# filename should always be first
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   153
		if filename in urls:
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   154
			urls.remove(filename)
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   155
		urls.insert(0, filename)
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   156
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   157
	# command line url is a fallback, so it's last
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   158
	if url != None and url not in urls:
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   159
		urls.append(url)
18
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   160
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   161
	return urls
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   162
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   163
def usage():
42
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   164
	print "Usage: %s [-f|--file (file)] [-l|--link] [-h|--hash (hash)] [-s|--search (search-dir)] --url (url)" % (sys.argv[0].split('/')[-1])
18
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   165
	sys.exit(1)
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   166
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   167
def main():
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   168
	import getopt
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   169
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   170
	# FLUSH STDOUT 
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   171
	sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   172
42
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   173
	file_arg = None
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   174
	link_arg = False
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   175
	hash_arg = None
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   176
	url_arg = None
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   177
	search_list = list()
18
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   178
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   179
	try:
42
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   180
		opts, args = getopt.getopt(sys.argv[1:], "f:h:ls:u:",
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   181
			["file=", "link", "hash=", "search=", "url="])
18
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   182
	except getopt.GetoptError, err:
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   183
		print str(err)
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   184
		usage()
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   185
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   186
	for opt, arg in opts:
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   187
		if opt in [ "-f", "--file" ]:
42
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   188
			file_arg = arg
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   189
		elif opt in [ "-l", "--link" ]:
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   190
			link_arg = True
18
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   191
		elif opt in [ "-h", "--hash" ]:
42
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   192
			hash_arg = arg
18
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   193
		elif opt in [ "-s", "--search" ]:
42
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   194
			search_list.append(arg)
18
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   195
		elif opt in [ "-u", "--url" ]:
42
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   196
			url_arg = arg
18
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   197
		else:
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   198
			assert False, "unknown option"
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   199
42
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   200
	if url_arg == None:
18
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   201
		usage()
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   202
42
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   203
	for url in download_paths(search_list, file_arg, url_arg):
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   204
		print "Source %s..." % url,
18
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   205
42
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   206
		scheme, path = splittype(url)
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   207
		name = file_arg
18
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   208
42
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   209
		if scheme in [ None, 'file' ]:
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   210
			if os.path.exists(path) == False:
58
d8024c042a00 7011369 gmake complains about fresh userland bits
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 42
diff changeset
   211
				print "not found, skipping file copy"
42
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   212
				continue
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   213
			elif name != path:
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   214
				if link_arg == False:
58
d8024c042a00 7011369 gmake complains about fresh userland bits
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 42
diff changeset
   215
					print "\n    copying..."
42
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   216
					shutil.copy2(path, name)
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   217
				else:
58
d8024c042a00 7011369 gmake complains about fresh userland bits
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 42
diff changeset
   218
					print "\n    linking..."
42
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   219
					os.symlink(path, name)
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   220
			else:
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   221
				pass
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   222
		elif scheme in [ 'http', 'https', 'ftp' ]:
58
d8024c042a00 7011369 gmake complains about fresh userland bits
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 42
diff changeset
   223
			print "\n    downloading...",
42
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   224
			name = download(url, file_arg)
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   225
			if name == None:
18
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   226
				print "failed"
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   227
				continue
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   228
58
d8024c042a00 7011369 gmake complains about fresh userland bits
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 42
diff changeset
   229
		print "\n    validating...",
d8024c042a00 7011369 gmake complains about fresh userland bits
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 42
diff changeset
   230
		if hash_arg == None:
d8024c042a00 7011369 gmake complains about fresh userland bits
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 42
diff changeset
   231
			print "skipping (no hash)"
d8024c042a00 7011369 gmake complains about fresh userland bits
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 42
diff changeset
   232
			sys.exit(0)
d8024c042a00 7011369 gmake complains about fresh userland bits
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 42
diff changeset
   233
			
135
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
   234
		realhash = validate_container(name, hash_arg)
58
d8024c042a00 7011369 gmake complains about fresh userland bits
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 42
diff changeset
   235
		if realhash == hash_arg:
42
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   236
			print "ok"
18
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   237
			sys.exit(0)
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   238
		else:
135
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
   239
			payloadhash = validate_payload(name, hash_arg)
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
   240
			if payloadhash == hash_arg:
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
   241
				print "ok"
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
   242
				sys.exit(0)
58
d8024c042a00 7011369 gmake complains about fresh userland bits
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 42
diff changeset
   243
			print "corruption detected"
d8024c042a00 7011369 gmake complains about fresh userland bits
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 42
diff changeset
   244
			print "    expected: %s" % hash_arg
d8024c042a00 7011369 gmake complains about fresh userland bits
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 42
diff changeset
   245
			print "    actual:   %s" % realhash
135
5c6feb0253fa 7028115 userland-fetch fails to validate gd2 archive
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents: 58
diff changeset
   246
			print "    payload:  %s" % payloadhash
18
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   247
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   248
		try:
42
566ce4d2ff99 fix using/downloading shared archives
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents: 34
diff changeset
   249
			os.remove(name)
18
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   250
		except OSError:
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   251
			pass
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   252
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   253
	sys.exit(1)
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   254
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   255
if __name__ == "__main__":
6da6bd662127 Add a fetch utility to do more than just download like wget does
Norm Jacobs <Norm.Jacobs@Sun.COM>
parents:
diff changeset
   256
	main()