ohhdemgirls

xbiso.pl

Nov 14th, 2013
2,156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 6.44 KB | None | 0 0
  1. #!/usr/bin/perl
  2. $version='$Id: xbiso.pl,v 1.6 2004/06/30 08:56:17 codex Exp codex $ ';
  3. #
  4. ## xbiso.pl (c) codex(at)bogus.net 12/02/2004
  5. ##
  6. ## original c code by tonto rostenfaunt <[email protected]> (c) 2003
  7. ##
  8. ## i couldn't get the original to work with any of the libftp's i could find,
  9. ## so i decided to write one in perl.
  10. ##
  11. ## this is released under the GPL, as was the original c version i based
  12. ## this code on.
  13. ##
  14. $|=1;
  15. ##
  16. use POSIX 'ceil';
  17. use Getopt::Long;
  18. use Net::FTP;
  19. use Fcntl 'SEEK_SET','SEEK_CUR';
  20.  
  21. my($XMEDHEAD)="MICROSOFT*XBOX*MEDIA";
  22.  
  23. my($FILE_DIR)=0x10;
  24.  
  25. ## grab command line
  26. GetOptions("h","v","x",
  27.        "f=s" => \$xiso,
  28.        "d=s" => \$dstdir,
  29.        "t=s" => \$tmpdir,
  30.        "u=s" => \$user,
  31.        "p=s" => \$pass,
  32.        "r=s" => \$rdir,
  33.        "host=s" => \$ftphost,
  34.        "debug=s" => \$DEBUG);
  35.  
  36. $FTP=1 if($ftphost);
  37. $rdir="/f/games" if(!$rdir);
  38. $tmpdir=$ENV{PWD} if(!$tmpdir); ## suggested by matti hiljanen
  39. $ftphost="xbox" if(!$ftphost);
  40. $user="xbox" if(!$user);
  41. $pass="xbox" if(!$pass);
  42.  
  43. if($opt_v) {
  44.   print $version,"\n";
  45.   exit(0);
  46. }
  47.  
  48. if($opt_h) {
  49.   print <<EOM;
  50. $version
  51. usage: xbiso.pl [-h|-v] [-host <ftp host>] [-t <tmpdir>] -f <iso> -d <destination dir>
  52.     -h : this stuff
  53.     -v : print version information
  54.     -x : xiso compatibility (UNTESTED! but should work)
  55.     -t : temporary directory for file extraction (default: $tmpdir)
  56.     -d : destination directory (w/out full path)
  57.     -r : top level dir on remote (default: $rdir)
  58.     -f : xbox .iso image filename
  59.  -host : ftp hostname for extraction directly to xbox (default: '$ftphost')
  60.     -u : ftp username (default: '$user')
  61.     -p : ftp password (default: '$pass')
  62.  
  63. e.g.:
  64.   xbiso.pl -host xbox.mynet.net -f backup.iso -d backup
  65.   xbiso.pl -f backup.iso -d backup
  66.  
  67. EOM
  68.   exit(0);
  69. }
  70.  
  71. if(!$xiso) {
  72.   die "FATAL: you must specify an xbox iso image filename\n";
  73. }
  74.  
  75. if(!-r $xiso) {
  76.   die "FATAL: cannot read '$xiso': $!";
  77. }
  78.  
  79. die "FATAL: no destination directory given (-d dir)" if(!$dstdir);
  80.  
  81. if($FTP) {
  82.   $ftp=Net::FTP->new($ftphost) || die "FATAL: could not connect to '$ftphost': $@";
  83.   $ftp->login($user,$pass) || die "FATAL: could not login to '$ftphost', ",$ftp->message;
  84.   $ftp->cwd($rdir) || die "FATAL: could not chdir to '$rdir', ",$ftp->message;
  85.   $ftp->binary(); ## force binary mode xfers
  86. }
  87.  
  88. my($buf);
  89.  
  90. ## open iso image
  91. open(XISO,$xiso);
  92.  
  93. ## check for validity
  94. sysseek(XISO,0x10000,SEEK_SET);
  95. sysread(XISO,$buf,0x14);
  96. die "FATAL: '$xiso' doesn't appear to be an xbox iso image\n" if($buf ne $XMEDHEAD);
  97.  
  98. ## read the directory table
  99. sysread(XISO,$buf,4);
  100. my($dirtable)=unpack('V',$buf);
  101.  
  102. sysseek(XISO,systell(XISO)+0x7d4,SEEK_SET); # skip unused info
  103. sysread(XISO,$buf,0x14); # read tailend of header
  104. die "FATAL: header tail mismatch -- possible corruption?\n" if($buf ne $XMEDHEAD);
  105.  
  106. ## create top level dir
  107. if($FTP) {
  108.   $ftp->mkdir($dstdir) || print STDERR "WARNING: could not create destination dir '$dstdir', ",$ftp->message;
  109.   $ftp->cwd($dstdir) || die "FATAL: could not change to destination dir '$dstdir', ",$ftp->message;
  110. } else {
  111.   mkdir($dstdir,0755) || print "WARNING: could not create local destination directory: $!";
  112.   chdir($dstdir) || die "FATAL: could not change to local destination directory: $!";
  113. }
  114.  
  115. ## chomp through the iso
  116. ChewISO($dirtable*2048,$dirtable);
  117.  
  118. ## close the iso image
  119. print "EXTRACTION COMPLETED OK.\n";
  120.  
  121. close(XISO);
  122.  
  123. exit(0);
  124.  
  125. ## subs
  126. sub ChewISO {
  127.   my($offset,$dtable) = @_;
  128.   my($buf,$x);
  129.   sysseek(XISO,$offset,SEEK_SET);
  130.   sysread(XISO,$buf,2);
  131.   my($ltable)=unpack('v',$buf);
  132.   sysread(XISO,$buf,2);
  133.   my($rtable)=unpack('v',$buf);
  134.   sysread(XISO,$buf,4);
  135.   my($sector)=unpack('V',$buf);
  136.   sysread(XISO,$buf,4);
  137.   my($size)=unpack('V',$buf);
  138.   my($attribs,$fnamelen,$fname);
  139.   sysread(XISO,$attribs,1);
  140.   $attribs=unpack('C',$attribs);
  141.   sysread(XISO,$fnamelen,1);
  142.   $fnamelen=unpack('C',$fnamelen);
  143.   sysread(XISO,$fname,$fnamelen);
  144.  
  145.   ## xiso compatibility (UNTESTED - but should work :)
  146.     if($opt_x) {
  147.     if($rtable != 0) {
  148.       my($cpos)=systell(XISO);
  149.       sysread(XISO,$buf,32);
  150.       if($buffer=~/^\xff{6}/) {
  151.         my($foo)=($cpos-($dtable*2048));
  152.         my($block)=ceil($foo/2048);
  153.         $rtable=$block*512;
  154.       }
  155.       sysseek(XISO,$cpos,SEEK_SET);
  156.     }
  157.   }
  158.  
  159.   if($fnamelen != 0) {
  160.     if(($attribs & $FILE_DIR) != 0) {
  161.       print "Creating directory $fname ..\n" if($DEBUG);
  162.       CreateDir($fname); ## create directory and change into it
  163.       ChewISO($sector*2048,$sector);
  164.       if($FTP) {
  165.     $ftp->cdup() || die "FATAL: could not cdup() on '$ftphost', ",$ftp->message;
  166.       } else {
  167.     chdir("..");
  168.       }
  169.     } else {
  170.       print "Extracting $fname .. ";
  171.       ExtractFile($size,$fname,$sector);
  172.       print "done\n";
  173.     }
  174.     ChewISO(($dtable*2048)+($rtable*4),$dtable) if($rtable != 0);
  175.     ChewISO(($dtable*2048)+($ltable*4),$dtable) if($ltable != 0);
  176.   }
  177. }
  178.  
  179. sub ExtractFile {
  180.   my($size,$fname,$sector) = @_;
  181.   my($buffer);
  182.  
  183.   sysseek(XISO,$sector*2048,SEEK_SET);
  184.   sysread(XISO,$buffer,$size);
  185.  
  186.   if($FTP) {
  187.  
  188.     ## i'm sure this could be done w/out a temp directory
  189.     my($tmp)=TmpFile($tmpdir,"xbiso");
  190.     open(TMPFILE,">$tmp") || die "FATAL: could not open tmpfile for write: $!";
  191.     syswrite(TMPFILE,$buffer,$size);
  192.     close(TMPFILE);
  193.     $ftp->put($tmp,$fname) || die "FATAL: could not put '$fname' to '$ftphost', ",$ftp->message;
  194.     unlink($tmp);
  195.  
  196.   } else {
  197.     open(OUT,">$fname") || die "FATAL: could not open '$fname' for write: $!";
  198.     syswrite(OUT,$buffer,$size);
  199.     close(OUT);
  200.   }
  201.  
  202. }
  203.  
  204. sub CreateDir {
  205.   my($dir) = @_;
  206.   if($FTP) {
  207.     $ftp->mkdir($dir) || printf STDERR "WARNING: could not create '$dir' on host '$ftphost', ",$ftp->message;
  208.     $ftp->cwd($dir) || die "FATAL: could not chdir to '$dir' on host '$ftphost', ",$ftp->message;
  209.   } else {
  210.     mkdir($dir,0755) || printf STDERR "WARNING: failed to create directory '$dir': $!\n";
  211.     chdir($dir) || die "FATAL: could not change to directory '$dir': $!\n";
  212.   }
  213. }
  214.  
  215. sub systell {
  216.   sysseek($_[0],0,SEEK_CUR);
  217. }
  218.  
  219. ## create a temporary file
  220. sub TmpFile {
  221.     my($dir,$prefix)=@_;
  222.     my($tfile)=$prefix."_".RandChars();
  223.     $tfile=$adr."_".RandChars() while(-e "$dir/$tfile");
  224.     open(TMP,">$dir/$tfile");close(TMP);
  225.     return($dir."/".$tfile);
  226. }
  227.  
  228. sub RandChars {
  229.     my($a,$c,$i);
  230.     for($i=0;$i<10;$i++) {
  231.         if(rand(100)<50) {$a=65;} else {$a=97;}
  232.         $c .= chr(rand(26)+$a);
  233.     }
  234.     return($c);
  235. }
Advertisement
Add Comment
Please, Sign In to add comment