expected_file_ids = None
filenames = []
- while 1:
- d = file.read(pkt_header_size)
- if not d:
- break
-
- magic, pkt_len, pkt_md5, set_id, pkt_type = struct.unpack(pkt_header_fmt, d)
-
- if docrcchecks:
- control_md5 = md5.new()
- control_md5.update(d[0x20:])
- d = file.read(pkt_len - pkt_header_size)
- control_md5.update(d)
+ # This try is here to ensure that we close the open file before
+ # returning. Since this code was (pretty much) borrowed verbatim
+ # from the cfv project, I didn't want to refactor it to make file
+ # closing more sane, so I just used a try / finally clause.
+ try:
+ while 1:
+ d = file.read(pkt_header_size)
+ if not d:
+ break
- if control_md5.digest() != pkt_md5:
- raise EnvironmentError, (errno.EINVAL, \
- "corrupt par2 file - bad packet hash")
+ magic, pkt_len, pkt_md5, set_id, pkt_type = struct.unpack(pkt_header_fmt, d)
- if pkt_type == 'PAR 2.0\0FileDesc':
- if not docrcchecks:
+ if docrcchecks:
+ control_md5 = md5.new()
+ control_md5.update(d[0x20:])
d = file.read(pkt_len - pkt_header_size)
+ control_md5.update(d)
- file_id, file_md5, file_md5_16k, file_size = \
- struct.unpack(file_pkt_fmt, d[:file_pkt_size])
+ if control_md5.digest() != pkt_md5:
+ raise EnvironmentError, (errno.EINVAL, \
+ "corrupt par2 file - bad packet hash")
- if seen_file_ids.get(file_id) is None:
- seen_file_ids[file_id] = 1
- filename = chompnulls(d[file_pkt_size:])
- filenames.append(filename)
+ if pkt_type == 'PAR 2.0\0FileDesc':
+ if not docrcchecks:
+ d = file.read(pkt_len - pkt_header_size)
- elif pkt_type == "PAR 2.0\0Main\0\0\0\0":
- if not docrcchecks:
- d = file.read(pkt_len - pkt_header_size)
+ file_id, file_md5, file_md5_16k, file_size = \
+ struct.unpack(file_pkt_fmt, d[:file_pkt_size])
+
+ if seen_file_ids.get(file_id) is None:
+ seen_file_ids[file_id] = 1
+ filename = chompnulls(d[file_pkt_size:])
+ filenames.append(filename)
- if expected_file_ids is None:
- expected_file_ids = []
- slice_size, num_files = struct.unpack(main_pkt_fmt, d[:main_pkt_size])
- num_nonrecovery = (len(d)-main_pkt_size)/16 - num_files
+ elif pkt_type == "PAR 2.0\0Main\0\0\0\0":
+ if not docrcchecks:
+ d = file.read(pkt_len - pkt_header_size)
- for i in range(main_pkt_size,main_pkt_size+(num_files+num_nonrecovery)*16,16):
- expected_file_ids.append(d[i:i+16])
+ if expected_file_ids is None:
+ expected_file_ids = []
+ slice_size, num_files = struct.unpack(main_pkt_fmt, d[:main_pkt_size])
+ num_nonrecovery = (len(d)-main_pkt_size)/16 - num_files
- else:
- if not docrcchecks:
- file.seek(pkt_len - pkt_header_size, 1)
+ for i in range(main_pkt_size,main_pkt_size+(num_files+num_nonrecovery)*16,16):
+ expected_file_ids.append(d[i:i+16])
- if expected_file_ids is None:
- raise EnvironmentError, (errno.EINVAL, \
- "corrupt or unsupported par2 file - no main packet found")
+ else:
+ if not docrcchecks:
+ file.seek(pkt_len - pkt_header_size, 1)
- for id in expected_file_ids:
- if not seen_file_ids.has_key(id):
+ if expected_file_ids is None:
raise EnvironmentError, (errno.EINVAL, \
- "corrupt or unsupported par2 file - " \
- "expected file description packet not found")
+ "corrupt or unsupported par2 file - no main packet found")
+
+ for id in expected_file_ids:
+ if not seen_file_ids.has_key(id):
+ raise EnvironmentError, (errno.EINVAL, \
+ "corrupt or unsupported par2 file - " \
+ "expected file description packet not found")
+ finally:
+ file.close ()
return filenames