diff options
author | ng0 <ng0@n0.is> | 2018-03-05 12:29:45 +0000 |
---|---|---|
committer | ng0 <ng0@n0.is> | 2018-03-05 12:29:45 +0000 |
commit | 0be7fa64a64245f66fa46bcbb2fe298a931a8b4d (patch) | |
tree | 31300a4e6538ca0cb907d97f81ff498f4fa849fe /contrib | |
parent | f18aadc5cbdef52ca02f55f24039f56dbee06321 (diff) | |
download | gnunet-0be7fa64a64245f66fa46bcbb2fe298a931a8b4d.tar.gz gnunet-0be7fa64a64245f66fa46bcbb2fe298a931a8b4d.zip |
contrib/gnunet-chk.py: flake8.
Diffstat (limited to 'contrib')
-rwxr-xr-x | contrib/gnunet-chk.py | 173 |
1 files changed, 90 insertions, 83 deletions
diff --git a/contrib/gnunet-chk.py b/contrib/gnunet-chk.py index e51641272..dba694c34 100755 --- a/contrib/gnunet-chk.py +++ b/contrib/gnunet-chk.py | |||
@@ -16,7 +16,7 @@ | |||
16 | # along with GNUnet; see the file COPYING. If not, write to the | 16 | # along with GNUnet; see the file COPYING. If not, write to the |
17 | # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 17 | # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
18 | # Boston, MA 02110-1301, USA. | 18 | # Boston, MA 02110-1301, USA. |
19 | # | 19 | # |
20 | # File: gnunet-chk.py | 20 | # File: gnunet-chk.py |
21 | # Brief: Computes GNUNET style Content Hash Key for a given file | 21 | # Brief: Computes GNUNET style Content Hash Key for a given file |
22 | # Author: Sree Harsha Totakura | 22 | # Author: Sree Harsha Totakura |
@@ -28,6 +28,7 @@ import getopt | |||
28 | import sys | 28 | import sys |
29 | from Crypto.Cipher import AES | 29 | from Crypto.Cipher import AES |
30 | 30 | ||
31 | |||
31 | # Defaults | 32 | # Defaults |
32 | DBLOCK_SIZE = (32 * 1024) # Data block size | 33 | DBLOCK_SIZE = (32 * 1024) # Data block size |
33 | 34 | ||
@@ -41,18 +42,18 @@ CHK_HASH_SIZE = 64 # SHA-512 hash = 512 bits = 64 bytes | |||
41 | 42 | ||
42 | CHK_QUERY_SIZE = CHK_HASH_SIZE # Again a SHA-512 hash | 43 | CHK_QUERY_SIZE = CHK_HASH_SIZE # Again a SHA-512 hash |
43 | 44 | ||
44 | GNUNET_FS_URI_PREFIX = "gnunet://fs/" # FS CHK URI prefix | 45 | GNUNET_FS_URI_PREFIX = "gnunet://fs/" # FS CHK URI prefix |
45 | 46 | ||
46 | GNUNET_FS_URI_CHK_INFIX = "chk/" # FS CHK URI infix | 47 | GNUNET_FS_URI_CHK_INFIX = "chk/" # FS CHK URI infix |
47 | 48 | ||
48 | 49 | ||
49 | def encode_data_to_string (data): | 50 | def encode_data_to_string(data): |
50 | """Returns an ASCII encoding of the given data block like | 51 | """Returns an ASCII encoding of the given data block like |
51 | GNUNET_STRINGS_data_to_string() function. | 52 | GNUNET_STRINGS_data_to_string() function. |
52 | 53 | ||
53 | data: A bytearray representing the block of data which has to be encoded | 54 | data: A bytearray representing the block of data which has to be encoded |
54 | """ | 55 | """ |
55 | echart = "0123456789ABCDEFGHIJKLMNOPQRSTUV" | 56 | echart = "0123456789ABCDEFGHIJKLMNOPQRSTUV" |
56 | assert (None != data) | 57 | assert (None != data) |
57 | assert (bytearray == type(data)) | 58 | assert (bytearray == type(data)) |
58 | size = len(data) | 59 | size = len(data) |
@@ -64,11 +65,11 @@ def encode_data_to_string (data): | |||
64 | out = "" | 65 | out = "" |
65 | while (rpos < size) or (vbit > 0): | 66 | while (rpos < size) or (vbit > 0): |
66 | if (rpos < size) and (vbit < 5): | 67 | if (rpos < size) and (vbit < 5): |
67 | bits = (bits << 8) | data[rpos] # eat 8 more bits | 68 | bits = (bits << 8) | data[rpos] # eat 8 more bits |
68 | rpos += 1 | 69 | rpos += 1 |
69 | vbit += 8 | 70 | vbit += 8 |
70 | if (vbit < 5): | 71 | if (vbit < 5): |
71 | bits <<= (5 - vbit) # zero-padding | 72 | bits <<= (5 - vbit) # zero-padding |
72 | assert (vbit == ((size * 8) % 5)) | 73 | assert (vbit == ((size * 8) % 5)) |
73 | vbit = 5 | 74 | vbit = 5 |
74 | out += echart[(bits >> (vbit - 5)) & 31] | 75 | out += echart[(bits >> (vbit - 5)) & 31] |
@@ -78,13 +79,13 @@ def encode_data_to_string (data): | |||
78 | return out; | 79 | return out; |
79 | 80 | ||
80 | 81 | ||
81 | def sha512_hash (data): | 82 | def sha512_hash(data): |
82 | """ Returns the sha512 hash of the given data. | 83 | """ Returns the sha512 hash of the given data. |
83 | 84 | ||
84 | data: string to hash | 85 | data: string to hash |
85 | """ | 86 | """ |
86 | hash_obj = sha512() | 87 | hash_obj = sha512() |
87 | hash_obj.update (data) | 88 | hash_obj.update(data) |
88 | return hash_obj.digest() | 89 | return hash_obj.digest() |
89 | 90 | ||
90 | 91 | ||
@@ -97,42 +98,44 @@ class AESKey: | |||
97 | cipher = None # The cipher object | 98 | cipher = None # The cipher object |
98 | KEY_SIZE = 32 # AES 256-bit key = 32 bytes | 99 | KEY_SIZE = 32 # AES 256-bit key = 32 bytes |
99 | IV_SIZE = AES.block_size # Initialization vector size (= AES block size) | 100 | IV_SIZE = AES.block_size # Initialization vector size (= AES block size) |
100 | 101 | ||
101 | def __init__ (self, passphrase): | 102 | def __init__(self, passphrase): |
102 | """Creates a new AES key. | 103 | """Creates a new AES key. |
103 | 104 | ||
104 | passphrase: string containing the passphrase to get the AES key and | 105 | passphrase: string containing the passphrase to get the AES key and |
105 | initialization vector | 106 | initialization vector |
106 | """ | 107 | """ |
107 | passphrase = bytearray (passphrase); | 108 | passphrase = bytearray(passphrase); |
108 | self.key = bytearray (self.KEY_SIZE) | 109 | self.key = bytearray(self.KEY_SIZE) |
109 | self.iv = bytearray (self.IV_SIZE) | 110 | self.iv = bytearray(self.IV_SIZE) |
110 | if (len (passphrase) > self.KEY_SIZE): | 111 | if (len(passphrase) > self.KEY_SIZE): |
111 | self.key = passphrase[:self.KEY_SIZE] | 112 | self.key = passphrase[:self.KEY_SIZE] |
112 | passphrase = passphrase[self.KEY_SIZE:] | 113 | passphrase = passphrase[self.KEY_SIZE:] |
113 | if (len (passphrase) > self.IV_SIZE): | 114 | if (len(passphrase) > self.IV_SIZE): |
114 | self.iv = passphrase[:self.IV_SIZE] | 115 | self.iv = passphrase[:self.IV_SIZE] |
115 | else: | 116 | else: |
116 | self.iv[0:len (passphrase)] = passphrase | 117 | self.iv[0:len(passphrase)] = passphrase |
117 | else: | 118 | else: |
118 | self.key[0:len (passphrase)] = passphrase | 119 | self.key[0:len(passphrase)] = passphrase |
119 | self.key = str (self.key) | 120 | self.key = str(self.key) |
120 | self.iv = str (self.iv) | 121 | self.iv = str(self.iv) |
121 | assert (len(self.key) == self.KEY_SIZE) | 122 | assert (len(self.key) == self.KEY_SIZE) |
122 | assert (len(self.iv) == self.IV_SIZE) | 123 | assert (len(self.iv) == self.IV_SIZE) |
123 | 124 | ||
124 | def setup_aes_cipher_ (aes_key): | 125 | |
126 | def setup_aes_cipher_(aes_key): | ||
125 | """Initializes the AES object with settings similar to those in GNUnet. | 127 | """Initializes the AES object with settings similar to those in GNUnet. |
126 | 128 | ||
127 | aes_key: the AESKey object | 129 | aes_key: the AESKey object |
128 | Returns the newly initialized AES object | 130 | Returns the newly initialized AES object |
129 | """ | 131 | """ |
130 | return AES.new (aes_key.key, AES.MODE_CFB, aes_key.iv, segment_size=128) | 132 | return AES.new(aes_key.key, AES.MODE_CFB, aes_key.iv, segment_size=128) |
133 | |||
131 | 134 | ||
132 | def aes_pad_ (data): | 135 | def aes_pad_(data): |
133 | """Adds padding to the data such that the size of the data is a multiple of | 136 | """Adds padding to the data such that the size of the data is a multiple of |
134 | 16 bytes | 137 | 16 bytes |
135 | 138 | ||
136 | data: the data string | 139 | data: the data string |
137 | Returns a tuple:(pad_len, data). pad_len denotes the number of bytes added | 140 | Returns a tuple:(pad_len, data). pad_len denotes the number of bytes added |
138 | as padding; data is the new data string with padded bytes at the end | 141 | as padding; data is the new data string with padded bytes at the end |
@@ -140,32 +143,34 @@ def aes_pad_ (data): | |||
140 | pad_len = len(data) % 16 | 143 | pad_len = len(data) % 16 |
141 | if (0 != pad_len): | 144 | if (0 != pad_len): |
142 | pad_len = 16 - pad_len | 145 | pad_len = 16 - pad_len |
143 | pad_bytes = bytearray (15) | 146 | pad_bytes = bytearray(15) |
144 | data += str(pad_bytes[:pad_len]) | 147 | data += str(pad_bytes[:pad_len]) |
145 | return (pad_len, data) | 148 | return (pad_len, data) |
146 | 149 | ||
147 | def aes_encrypt (aes_key, data): | 150 | |
151 | def aes_encrypt(aes_key, data): | ||
148 | """Encrypts the given data using AES. | 152 | """Encrypts the given data using AES. |
149 | 153 | ||
150 | aes_key: the AESKey object to use for AES encryption | 154 | aes_key: the AESKey object to use for AES encryption |
151 | data: the data string to encrypt | 155 | data: the data string to encrypt |
152 | """ | 156 | """ |
153 | (pad_len, data) = aes_pad_ (data) | 157 | (pad_len, data) = aes_pad_(data) |
154 | cipher = setup_aes_cipher_ (aes_key) | 158 | cipher = setup_aes_cipher_(aes_key) |
155 | enc_data = cipher.encrypt (data) | 159 | enc_data = cipher.encrypt(data) |
156 | if (0 != pad_len): | 160 | if (0 != pad_len): |
157 | enc_data = enc_data[:-pad_len] | 161 | enc_data = enc_data[:-pad_len] |
158 | return enc_data | 162 | return enc_data |
159 | 163 | ||
160 | def aes_decrypt (aes_key, data): | 164 | |
165 | def aes_decrypt(aes_key, data): | ||
161 | """Decrypts the given data using AES | 166 | """Decrypts the given data using AES |
162 | 167 | ||
163 | aes_key: the AESKey object to use for AES decryption | 168 | aes_key: the AESKey object to use for AES decryption |
164 | data: the data string to decrypt | 169 | data: the data string to decrypt |
165 | """ | 170 | """ |
166 | (pad_len, data) = aes_pad_ (data) | 171 | (pad_len, data) = aes_pad_(data) |
167 | cipher = setup_aes_cipher_ (aes_key) | 172 | cipher = setup_aes_cipher_(aes_key) |
168 | ptext = cipher.decrypt (data) | 173 | ptext = cipher.decrypt(data) |
169 | if (0 != pad_len): | 174 | if (0 != pad_len): |
170 | ptext = ptext[:-pad_len] | 175 | ptext = ptext[:-pad_len] |
171 | return ptext | 176 | return ptext |
@@ -187,9 +192,9 @@ class Chk: | |||
187 | self.fsize = size | 192 | self.fsize = size |
188 | 193 | ||
189 | def uri(self): | 194 | def uri(self): |
190 | sizestr = repr (self.fsize) | 195 | sizestr = repr(self.fsize) |
191 | if isinstance (self.fsize, long): | 196 | if isinstance(self.fsize, long): |
192 | sizestr = sizestr[:-1] | 197 | sizestr = sizestr[:-1] |
193 | return GNUNET_FS_URI_PREFIX + GNUNET_FS_URI_CHK_INFIX + \ | 198 | return GNUNET_FS_URI_PREFIX + GNUNET_FS_URI_CHK_INFIX + \ |
194 | encode_data_to_string(bytearray(self.key)) + "." + \ | 199 | encode_data_to_string(bytearray(self.key)) + "." + \ |
195 | encode_data_to_string(bytearray(self.query)) + "." + \ | 200 | encode_data_to_string(bytearray(self.query)) + "." + \ |
@@ -198,7 +203,7 @@ class Chk: | |||
198 | 203 | ||
199 | def compute_depth_(size): | 204 | def compute_depth_(size): |
200 | """Computes the depth of the hash tree. | 205 | """Computes the depth of the hash tree. |
201 | 206 | ||
202 | size: the size of the file whose tree's depth has to be computed | 207 | size: the size of the file whose tree's depth has to be computed |
203 | Returns the depth of the tree. Always > 0. | 208 | Returns the depth of the tree. Always > 0. |
204 | """ | 209 | """ |
@@ -211,6 +216,7 @@ def compute_depth_(size): | |||
211 | fl = fl * CHK_PER_INODE | 216 | fl = fl * CHK_PER_INODE |
212 | return depth | 217 | return depth |
213 | 218 | ||
219 | |||
214 | def compute_tree_size_(depth): | 220 | def compute_tree_size_(depth): |
215 | """Calculate how many bytes of payload a block tree of the given depth MAY | 221 | """Calculate how many bytes of payload a block tree of the given depth MAY |
216 | correspond to at most (this function ignores the fact that some blocks will | 222 | correspond to at most (this function ignores the fact that some blocks will |
@@ -226,10 +232,11 @@ def compute_tree_size_(depth): | |||
226 | rsize *= CHK_PER_INODE | 232 | rsize *= CHK_PER_INODE |
227 | return rsize | 233 | return rsize |
228 | 234 | ||
235 | |||
229 | def compute_chk_offset_(depth, end_offset): | 236 | def compute_chk_offset_(depth, end_offset): |
230 | """Compute the offset of the CHK for the current block in the IBlock | 237 | """Compute the offset of the CHK for the current block in the IBlock |
231 | above | 238 | above |
232 | 239 | ||
233 | depth: depth of the IBlock in the tree (aka overall number of tree levels | 240 | depth: depth of the IBlock in the tree (aka overall number of tree levels |
234 | minus depth); 0 == DBLOCK | 241 | minus depth); 0 == DBLOCK |
235 | end_offset: current offset in the overall file, at the *beginning* of the | 242 | end_offset: current offset in the overall file, at the *beginning* of the |
@@ -243,12 +250,13 @@ def compute_chk_offset_(depth, end_offset): | |||
243 | ret = end_offset / bds | 250 | ret = end_offset / bds |
244 | return ret % CHK_PER_INODE | 251 | return ret % CHK_PER_INODE |
245 | 252 | ||
253 | |||
246 | def compute_iblock_size_(depth, offset): | 254 | def compute_iblock_size_(depth, offset): |
247 | """Compute the size of the current IBLOCK. The encoder is triggering the | 255 | """Compute the size of the current IBLOCK. The encoder is triggering the |
248 | calculation of the size of an IBLOCK at the *end* (hence end_offset) of its | 256 | calculation of the size of an IBLOCK at the *end* (hence end_offset) of its |
249 | construction. The IBLOCK maybe a full or a partial IBLOCK, and this | 257 | construction. The IBLOCK maybe a full or a partial IBLOCK, and this |
250 | function is to calculate how long it should be. | 258 | function is to calculate how long it should be. |
251 | 259 | ||
252 | depth: depth of the IBlock in the tree, 0 would be a DBLOCK, must be > 0 | 260 | depth: depth of the IBlock in the tree, 0 would be a DBLOCK, must be > 0 |
253 | (this function is for IBLOCKs only!) | 261 | (this function is for IBLOCKs only!) |
254 | offset: current offset in the payload (!) of the overall file, must be > 0 | 262 | offset: current offset in the payload (!) of the overall file, must be > 0 |
@@ -257,7 +265,7 @@ def compute_iblock_size_(depth, offset): | |||
257 | """ | 265 | """ |
258 | assert (depth > 0) | 266 | assert (depth > 0) |
259 | assert (offset > 0) | 267 | assert (offset > 0) |
260 | bds = compute_tree_size_ (depth) | 268 | bds = compute_tree_size_(depth) |
261 | mod = offset % bds | 269 | mod = offset % bds |
262 | if mod is 0: | 270 | if mod is 0: |
263 | ret = CHK_PER_INODE | 271 | ret = CHK_PER_INODE |
@@ -278,46 +286,46 @@ def compute_rootchk(readin, size): | |||
278 | """ | 286 | """ |
279 | depth = compute_depth_(size); | 287 | depth = compute_depth_(size); |
280 | current_depth = 0 | 288 | current_depth = 0 |
281 | chks = [None] * (depth * CHK_PER_INODE) # list buffer | 289 | chks = [None] * (depth * CHK_PER_INODE) # list buffer |
282 | read_offset = 0 | 290 | read_offset = 0 |
283 | logging.debug("Begining to calculate tree hash with depth: "+ repr(depth)) | 291 | logging.debug("Begining to calculate tree hash with depth: " + repr(depth)) |
284 | while True: | 292 | while True: |
285 | if (depth == current_depth): | 293 | if (depth == current_depth): |
286 | off = CHK_PER_INODE * (depth - 1) | 294 | off = CHK_PER_INODE * (depth - 1) |
287 | assert (chks[off] is not None) | 295 | assert (chks[off] is not None) |
288 | logging.debug("Encoding done, reading CHK `"+ chks[off].query + \ | 296 | logging.debug("Encoding done, reading CHK `" + chks[off].query + \ |
289 | "' from "+ repr(off) +"\n") | 297 | "' from " + repr(off) + "\n") |
290 | uri_chk = chks[off] | 298 | uri_chk = chks[off] |
291 | assert (size == read_offset) | 299 | assert (size == read_offset) |
292 | uri_chk.setSize (size) | 300 | uri_chk.setSize(size) |
293 | return uri_chk | 301 | return uri_chk |
294 | if (0 == current_depth): | 302 | if (0 == current_depth): |
295 | pt_size = min(DBLOCK_SIZE, size - read_offset); | 303 | pt_size = min(DBLOCK_SIZE, size - read_offset); |
296 | try: | 304 | try: |
297 | pt_block = readin.read(pt_size) | 305 | pt_block = readin.read(pt_size) |
298 | except IOError: | 306 | except IOError: |
299 | logging.warning ("Error reading input file stream") | 307 | logging.warning("Error reading input file stream") |
300 | return None | 308 | return None |
301 | else: | 309 | else: |
302 | pt_elements = compute_iblock_size_(current_depth, read_offset) | 310 | pt_elements = compute_iblock_size_(current_depth, read_offset) |
303 | pt_block = "" | 311 | pt_block = "" |
304 | pt_block = \ | 312 | pt_block = \ |
305 | reduce ((lambda ba, chk: | 313 | reduce((lambda ba, chk: |
306 | ba + (chk.key + chk.query)), | 314 | ba + (chk.key + chk.query)), |
307 | chks[(current_depth - 1) * CHK_PER_INODE:][:pt_elements], | 315 | chks[(current_depth - 1) * CHK_PER_INODE:][:pt_elements], |
308 | pt_block) | 316 | pt_block) |
309 | pt_size = pt_elements * (CHK_HASH_SIZE + CHK_QUERY_SIZE) | 317 | pt_size = pt_elements * (CHK_HASH_SIZE + CHK_QUERY_SIZE) |
310 | assert (len(pt_block) == pt_size) | 318 | assert (len(pt_block) == pt_size) |
311 | assert (pt_size <= DBLOCK_SIZE) | 319 | assert (pt_size <= DBLOCK_SIZE) |
312 | off = compute_chk_offset_ (current_depth, read_offset) | 320 | off = compute_chk_offset_(current_depth, read_offset) |
313 | logging.debug ("Encoding data at offset "+ repr(read_offset) + \ | 321 | logging.debug("Encoding data at offset " + repr(read_offset) + \ |
314 | " and depth "+ repr(current_depth) +" with block " \ | 322 | " and depth " + repr(current_depth) + " with block " \ |
315 | "size "+ repr(pt_size) +" and target CHK offset "+ \ | 323 | "size " + repr(pt_size) + " and target CHK offset " + \ |
316 | repr(current_depth * CHK_PER_INODE)) | 324 | repr(current_depth * CHK_PER_INODE)) |
317 | pt_hash = sha512_hash (pt_block) | 325 | pt_hash = sha512_hash(pt_block) |
318 | pt_aes_key = AESKey (pt_hash) | 326 | pt_aes_key = AESKey(pt_hash) |
319 | pt_enc = aes_encrypt (pt_aes_key, pt_block) | 327 | pt_enc = aes_encrypt(pt_aes_key, pt_block) |
320 | pt_enc_hash = sha512_hash (pt_enc) | 328 | pt_enc_hash = sha512_hash(pt_enc) |
321 | chk = Chk(pt_hash, pt_enc_hash) | 329 | chk = Chk(pt_hash, pt_enc_hash) |
322 | chks[(current_depth * CHK_PER_INODE) + off] = chk | 330 | chks[(current_depth * CHK_PER_INODE) + off] = chk |
323 | if (0 == current_depth): | 331 | if (0 == current_depth): |
@@ -332,44 +340,43 @@ def compute_rootchk(readin, size): | |||
332 | current_depth = 0 | 340 | current_depth = 0 |
333 | 341 | ||
334 | 342 | ||
335 | def chkuri_from_path (path): | 343 | def chkuri_from_path(path): |
336 | """Returns the CHK URI of the file at the given path. | 344 | """Returns the CHK URI of the file at the given path. |
337 | 345 | ||
338 | path: the path of the file whose CHK has to be calculated | 346 | path: the path of the file whose CHK has to be calculated |
339 | """ | 347 | """ |
340 | size = os.path.getsize (path) | 348 | size = os.path.getsize(path) |
341 | readin = open (path, "rb") | 349 | readin = open(path, "rb") |
342 | chk = compute_rootchk (readin, size) | 350 | chk = compute_rootchk(readin, size) |
343 | readin.close() | 351 | readin.close() |
344 | return chk.uri() | 352 | return chk.uri() |
345 | 353 | ||
346 | def usage (): | 354 | |
355 | def usage(): | ||
347 | """Prints help about using this script.""" | 356 | """Prints help about using this script.""" |
348 | print """ | 357 | print(""" |
349 | Usage: gnunet-chk.py [options] file | 358 | Usage: gnunet-chk.py [options] file |
350 | Prints the Content Hash Key of given file in GNUNET-style URI. | 359 | Prints the Content Hash Key of given file in GNUNET-style URI. |
351 | 360 | ||
352 | Options: | 361 | Options: |
353 | -h, --help : prints this message | 362 | -h, --help : prints this message |
354 | """ | 363 | """) |
355 | 364 | ||
356 | 365 | ||
357 | if '__main__' == __name__: | 366 | if '__main__' == __name__: |
358 | try: | 367 | try: |
359 | opts, args = getopt.getopt(sys.argv[1:], | 368 | opts, args = getopt.getopt(sys.argv[1:], "h", ["help"]) |
360 | "h", | ||
361 | ["help"]) | ||
362 | except getopt.GetoptError, err: | 369 | except getopt.GetoptError, err: |
363 | print err | 370 | print(err) |
364 | print "Exception occured" | 371 | print("Exception occured") |
365 | usage() | 372 | usage() |
366 | sys.exit(2) | 373 | sys.exit(2) |
367 | for option, value in opts: | 374 | for option, value in opts: |
368 | if option in ("-h", "--help"): | 375 | if option in("-h", "--help"): |
369 | usage() | 376 | usage() |
370 | sys.exit(0) | 377 | sys.exit(0) |
371 | if len(args) != 1: | 378 | if len(args) != 1: |
372 | print "Incorrect number of arguments passed" | 379 | print("Incorrect number of arguments passed") |
373 | usage() | 380 | usage() |
374 | sys.exit(1) | 381 | sys.exit(1) |
375 | print chkuri_from_path (args[0]) | 382 | print chkuri_from_path(args[0]) |