4 ## This file is part of the aMule Project
6 ## Copyright (c) 2004-2008 Angel Vidal ( kry@amule.org )
7 ## Copyright (c) 2003-2008 aMule Team ( admin@amule.org / http://www.amule.org )
9 ## This program is free software; you can redistribute it and/or
10 ## modify it under the terms of the GNU General Public License
11 ## as published by the Free Software Foundation; either
12 ## version 2 of the License, or (at your option) any later version.
14 ## This program is distributed in the hope that it will be useful,
15 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ## GNU General Public License for more details.
19 ## You should have received a copy of the GNU General Public License
20 ## along with this program; if not, write to the Free Software
21 ## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 # Gimme a break, is my first perl app... (Kry)
32 print "You must specify the mldonkey config folder (usually ~/.mldonkey).\n";
33 $exit_with_help = "true";
37 print "You must specify the aMule temp folder for output.\n";
38 $exit_with_help = "true";
41 if ($exit_with_help) {
42 die "Usage: importer2.pl mldonkey_config_folder amule_temp_folder.\n";
46 my $input_folder = $ARGV[0];
48 my $output_folder = $ARGV[1];
50 open(TEST
,">" . $output_folder . "/test_file") or die "Unable to write to destination folder! Error: $!\n";
52 unlink($output_folder . "/test_file");
54 open(INFO
, $input_folder . "/files.ini") or die "Cannot open input file" . $input_folder . "/files.ini for reading: $!"; # Open the file
57 while ($line !~ /^\s*files\s*=\s*\[\s*$/) {
60 die $input_folder . "/files.ini seems not to be a mldonkey files.ini\n";
65 #We're at the start of the downloading files section.
66 # Read info for each file.
70 while ($line && ($line !~ /^.*};\].*$/)) {
71 print "Reading info for file $number\n";
73 print "End reading\n\n";
91 while (($line) && ($line !~ /^\s*}.*/) && ($done ne "true")) {
93 if ($line =~ /.*file_network\s*=\s*(.*)$/) {
94 print "Network is $1\n";
96 print "Cannot import non-ed2k part file, skipping\n";
97 while (($line) && ($line !~ /^\s*}.*/)) {
103 if ($line =~ /^\s*file_size\s*=\s*(\d+)\s*$/) {
105 print "File size: $file_size\n";
107 if ($line =~ /^\s*file_swarmer\s*=\s*\"(.*)\"\s*$/) {
109 print "Part file to import: $part_file\n";
111 if ($line =~ /^\s*file_md4\s*=\s*\"?(([A-Z]|[0-9])+)\"?\s*$/) {
113 print "File hash: $md4_hash\n";
115 if ($line =~ /^\s*file_filename\s*=\s*\"(.*)\"\s*$/) {
117 print "File name: $file_name\n";
119 if ($line =~ /^\s*file_md4s\s*=\s*\[\s*$/) {
123 my $md4_line = <INFO
>;
124 if ($md4_line =~ /^\s*\"?(([A-Z]|[0-9])+)\"?;\]?\s*$/) {
126 if ($md4_line =~ /^.*;\].*$/) {
130 print "Malformed md4 hash line $md4_line";
134 } while (!($result));
135 if ($result eq "done") {
136 print "MD4 list: @md4_list\n";
142 if ($line =~ /^\s*file_present_chunks\s*=\s*\[\s*$/) {
147 my $gaps_line = <INFO
>;
148 if ($gaps_line =~ /^\s*\((\d+),\s*(\d+)\)(;|])\s*$/) {
151 if ($gaps_line =~ /^.*\)\].*$/) {
155 print "Malformed gaps line $gaps_line";
158 } while (!($result));
160 if ($result eq "done") {
161 # Process mldonkey gaps to aMule gaps
162 print "ML Gaps list: @ml_gaps\n";
164 @gap_list = &convert_gap_format
($file_size,@ml_gaps);
166 print "aMule Gaps list: @gap_list\n";
172 if ($done ne "true") {
177 if ($done eq "true") {
178 print "File import result: false\n";
180 if ($file_name && $file_size && $md4_hash && $part_file) {
182 print "WARNING: File has no md4 hashes list, imported file will have 0 bytes downloaded\n";
185 my $first_free_number = &get_first_free_number
;
187 my $met_file = $output_folder . sprintf("/%03d.part.met",$first_free_number);
189 &create_met_file
($met_file,$file_name,$file_size,$md4_hash,@md4_list,"---",@gap_list);
191 print "File $met_file imported successfully.\n";
193 my $from = $input_folder . "/" . $part_file;
194 my $destination = $output_folder . sprintf("/%03d.part",$first_free_number);
195 copy
($from, $destination) or die "CRITICAL: File $from cannot be copied to $destination. Error: $!\n";
198 print "Not enough info to import file, sorry.\n";
204 sub create_met_file
{
206 print "Parameters: @_\n";
209 open(MET
," > $_[0]");
214 # Met file version (1 byte)
215 if ($_[2] < 4290048000) {
218 printf MET
&byte_string
(0xe0);
221 printf MET
&byte_string
(0xe2);
223 # File modification time. 0 to force aMule rehash. (4 bytes)
224 print MET
&int32_string
(0);
226 # MD4 hash (16 bytes)
227 print MET
&hash_string
($_[3]);
229 #Calculate number of MD4 hashes
230 my @md4_hashlist = ();
234 while ($_[$i] ne "---") {
235 push (@md4_hashlist,$_[$i]);
243 push(@gaps_list,$_[$i]);
247 print "Write aMule gap list: @gaps_list\n";
249 my $md4_hashsize = @md4_hashlist;
251 print "MD4 hashlist size $md4_hashsize\n";
253 #Number of MD4 hashes (2 bytes)
254 print MET
&int16_string
($md4_hashsize);
256 #Write MD4 hashes (16 bytes * number of hashes)
257 my $md4_parthash = "";
258 foreach $md4_parthash (@md4_hashlist) {
259 print MET
&hash_string
($md4_parthash);
262 #Number of tags (4 bytes)
264 my $tags_number = 2; # Fixed tags (Name + Size)
266 $tags_number = $tags_number + @gaps_list;
268 print MET
&int32_string
($tags_number);
272 print MET
&tag_string
(2,0,0x01,$_[1]); # Tagtype string, id FT_FILENAME, value
276 if ($large_file eq "yes") {
277 print MET
&tag_string
(0x0b,0,0x02,$_[2]); # Tagtype UINT64, id FT_FILESIZE, value
279 print MET
&tag_string
(3,0,0x02,$_[2]); # Tagtype UINT32, id FT_FILESIZE, value
285 if ($large_file eq "yes") {
291 while (@gaps_list[$t*2]) {
292 my $gap_start = @gaps_list[$t*2];
293 my $gap_end = @gaps_list[$t*2+1];
295 print "Gap $t start $gap_start end $gap_end\n";
297 print MET
&tag_string
($tag_type,1,sprintf("%c%d",0x09,$t),$gap_start);
298 print MET
&tag_string
($tag_type,1,sprintf("%c%d",0x0a,$t),$gap_end);
311 &byte_string
($_[0] % 256) . &byte_string
($_[0] / 256);
315 &int16_string
($_[0] % 65536) . &int16_string
($_[0] / 65536);
319 &int32_string
($_[0] % 4294967296) . &int32_string
($_[0] / 4294967296);
324 my $final_string = "";
326 $final_string = $final_string . &byte_string
(hex(substr($_[0],$i,2)));
333 # ONLY STRINGS AND UINT32/64 SUPPORTED
335 my $final_string = "";
338 $final_string = $final_string . &byte_string
($_[0]);
342 $final_string = $final_string . &int16_string
(1);
343 $final_string = $final_string . &byte_string
($_[2]);
346 $final_string = $final_string . &int16_string
(length $_[2]) . $_[2];
350 $final_string = $final_string . &int16_string
(length $_[3]) . $_[3];
354 $final_string = $final_string . &int32_string
($_[3]);
358 $final_string = $final_string . &int64_string
($_[3]);
365 sub convert_gap_format
{
366 my $total_size = $_[0];
368 my @converted_gaps = ();
373 push(@converted_gaps,0);
374 push(@converted_gaps,$_[1]);
380 push(@converted_gaps,$_[$n]);
381 push(@converted_gaps,$_[$n+1]);
385 if ($_[$n] != $total_size) {
386 push(@converted_gaps,$_[$n]);
387 push(@converted_gaps,$total_size);
393 sub get_first_free_number
{
397 while (!$result && !($n>999)) {
398 open(TEST
, " <" . $output_folder . sprintf("/%03d.part.met",$n)) or $result=$n;