예제 #1
0
  @Override
  public Void run() {
    // let's write an info file. and delete if after extraction. this wy we have infosfiles if the
    // extraction crashes jd
    crashLog =
        new ExtractLogFileWriter(
            archive.getName(),
            archive.getFirstArchiveFile().getFilePath(),
            archive.getFactory().getID()) {
          @Override
          public void write(String string) {
            super.write(string);
            logger.info(string);
          }
        };
    try {
      fireEvent(ExtractionEvent.Type.START);
      archive.onStartExtracting();
      crashLog.write("Date: " + new Date());
      crashLog.write("Start Extracting");
      crashLog.write("Extension Setup: \r\n" + extension.getSettings().toString());

      crashLog.write("Archive Setup: \r\n" + JSonStorage.toString(archive.getSettings()));
      extractor.setCrashLog(crashLog);
      logger.info("Start unpacking of " + archive.getFirstArchiveFile().getFilePath());

      for (ArchiveFile l : archive.getArchiveFiles()) {
        if (!new File(l.getFilePath()).exists()) {
          crashLog.write("File missing: " + l.getFilePath());
          logger.info("Could not find archive file " + l.getFilePath());
          archive.addCrcError(l);
        }
      }
      if (archive.getCrcError().size() > 0) {
        fireEvent(ExtractionEvent.Type.FILE_NOT_FOUND);
        crashLog.write("Failed");
        return null;
      }

      if (gotKilled()) {
        return null;
      }
      crashLog.write("Prepare");
      if (extractor.prepare()) {
        extractToFolder = extension.getFinalExtractToFolder(archive);
        crashLog.write("Extract To: " + extractToFolder);
        if (archive.isProtected()) {
          crashLog.write("Archive is Protected");
          if (!StringUtils.isEmpty(archive.getFinalPassword())
              && !checkPassword(archive.getFinalPassword(), false)) {
            /* open archive with found pw */
            logger.info(
                "Password " + archive.getFinalPassword() + " is invalid, try to find correct one");
            archive.setFinalPassword(null);
          }
          if (StringUtils.isEmpty(archive.getFinalPassword())) {
            crashLog.write("Try to find password");
            /* pw unknown yet */
            List<String> spwList = archive.getSettings().getPasswords();
            if (spwList != null) {
              passwordList.addAll(spwList);
            }
            passwordList.addAll(archive.getFactory().getGuessedPasswordList(archive));
            passwordList.add(archive.getName());
            java.util.List<String> pwList = extractor.config.getPasswordList();
            if (pwList == null) {
              pwList = new ArrayList<String>();
            }
            passwordList.addAll(pwList);
            fireEvent(ExtractionEvent.Type.START_CRACK_PASSWORD);
            logger.info("Start password finding for " + archive);
            String correctPW = null;
            for (String password : passwordList) {
              if (password == null) {
                continue;
              }
              if (gotKilled()) {
                return null;
              }
              crashLog.write("Try Password: "******"Found password: \"" + password + "\"");
                break;
              } else {
                // try trimmed password
                String trimmed = password.trim();
                if (trimmed.length() != password.length()) {
                  password = trimmed;
                  if (checkPassword(
                      password, extension.getSettings().isPasswordFindOptimizationEnabled())) {
                    correctPW = password;
                    crashLog.write("Found password: \"" + password + "\"");
                    break;
                  }
                }
              }
            }

            if (correctPW == null) {
              fireEvent(ExtractionEvent.Type.PASSWORD_NEEDED_TO_CONTINUE);
              crashLog.write("Ask for password");
              logger.info("Found no password in passwordlist " + archive);
              if (gotKilled()) {
                return null;
              }
              if (!checkPassword(archive.getFinalPassword(), false)) {
                fireEvent(ExtractionEvent.Type.EXTRACTION_FAILED);
                logger.info("No password found for " + archive);
                crashLog.write("No password found or given");
                crashLog.write("Failed");
                return null;
              }
            }
            fireEvent(ExtractionEvent.Type.PASSWORD_FOUND);
            logger.info("Found password for " + archive + "->" + archive.getFinalPassword());
          }
          if (StringUtils.isNotEmpty(archive.getFinalPassword())) {
            extension.addPassword(archive.getFinalPassword());
          }
        }
        final DiskSpaceReservation extractReservation =
            new DiskSpaceReservation() {

              @Override
              public long getSize() {
                final long completeSize =
                    Math.max(getCompleteBytes(), archive.getContentView().getTotalSize());
                long ret = completeSize - getProcessedBytes();
                return ret;
              }

              @Override
              public File getDestination() {
                return getExtractToFolder();
              }
            };
        DISKSPACERESERVATIONRESULT reservationResult =
            DownloadWatchDog.getInstance()
                .getSession()
                .getDiskSpaceManager()
                .checkAndReserve(extractReservation, this);
        try {
          switch (reservationResult) {
            case FAILED:
              logger.info(
                  "Not enough harddisk space for unpacking archive "
                      + archive.getFirstArchiveFile().getFilePath());
              crashLog.write("Diskspace Problem: " + reservationResult);
              crashLog.write("Failed");
              fireEvent(ExtractionEvent.Type.NOT_ENOUGH_SPACE);
              return null;
            case INVALIDDESTINATION:
              logger.warning("Could use create subpath");
              crashLog.write("Could use create subpath: " + getExtractToFolder());
              crashLog.write("Failed");
              fireEvent(ExtractionEvent.Type.EXTRACTION_FAILED);
              return null;
          }
          fireEvent(ExtractionEvent.Type.OPEN_ARCHIVE_SUCCESS);
          if (!getExtractToFolder().exists()) {
            if (!FileCreationManager.getInstance().mkdir(getExtractToFolder())) {
              logger.warning("Could not create subpath");
              crashLog.write("Could not create subpath: " + getExtractToFolder());
              crashLog.write("Failed");
              fireEvent(ExtractionEvent.Type.EXTRACTION_FAILED);
              return null;
            }
          }
          logger.info("Execute unpacking of:" + archive);
          logger.info("Extract to " + getExtractToFolder());
          crashLog.write(
              "Use Password: "******"|PW Protected:"
                  + archive.isProtected()
                  + ":"
                  + archive.isPasswordRequiredToOpen());
          ScheduledExecutorService scheduler = null;
          try {
            crashLog.write("Start Extracting " + extractor);
            scheduler = DelayedRunnable.getNewScheduledExecutorService();
            timer =
                scheduler.scheduleWithFixedDelay(
                    new Runnable() {
                      public void run() {
                        fireEvent(ExtractionEvent.Type.EXTRACTING);
                      }
                    },
                    1,
                    1,
                    TimeUnit.SECONDS);
            extractor.extract(this);
          } finally {
            crashLog.write("Extractor Returned");
            if (timer != null) {
              timer.cancel(false);
            }
            if (scheduler != null) {
              scheduler.shutdown();
            }
            extractor.close();
            if (extractor.getLastAccessedArchiveFile() != null) {
              crashLog.write("Last used File: " + extractor.getLastAccessedArchiveFile());
            }
            fireEvent(ExtractionEvent.Type.EXTRACTING);
          }
        } finally {
          DownloadWatchDog.getInstance()
              .getSession()
              .getDiskSpaceManager()
              .free(extractReservation, this);
        }
        if (gotKilled()) {
          return null;
        }
        if (extractor.getException() != null) {
          exception = extractor.getException();
          logger.log(exception);
        }
        if (exception != null) {
          crashLog.write("Exception occured: \r\n" + Exceptions.getStackTrace(exception));
        }

        crashLog.write("ExitCode: " + archive.getExitCode());
        switch (archive.getExitCode()) {
          case ExtractionControllerConstants.EXIT_CODE_SUCCESS:
            logger.info("Unpacking successful for " + archive);
            archive
                .getSettings()
                .setExtractionInfo(new ExtractionInfo(getExtractToFolder(), archive));
            crashLog.write(
                "Info: \r\n"
                    + JSonStorage.serializeToJson(
                        new ExtractionInfo(getExtractToFolder(), archive)));
            crashLog.write("Successful");
            successful = true;
            fireEvent(ExtractionEvent.Type.FINISHED);
            logger.clear();
            break;
          case ExtractionControllerConstants.EXIT_CODE_INCOMPLETE_ERROR:
            logger.warning("Archive seems to be incomplete " + archive);
            crashLog.write("Incomplete Archive");
            crashLog.write("Failed");
            fireEvent(ExtractionEvent.Type.FILE_NOT_FOUND);
            break;
          case ExtractionControllerConstants.EXIT_CODE_CRC_ERROR:
            logger.warning("A CRC error occurred when unpacking " + archive);
            crashLog.write("CRC Error occured");
            crashLog.write("Failed");
            fireEvent(ExtractionEvent.Type.EXTRACTION_FAILED_CRC);
            break;
          case ExtractionControllerConstants.EXIT_CODE_USER_BREAK:
            logger.info("User interrupted unpacking of " + archive);
            crashLog.write("Interrupted by User");
            crashLog.write("Failed");
            fireEvent(ExtractionEvent.Type.EXTRACTION_FAILED);
            break;
          case ExtractionControllerConstants.EXIT_CODE_CREATE_ERROR:
            logger.warning("Could not create Outputfile for" + archive);
            crashLog.write("Could not create Outputfile");
            crashLog.write("Failed");
            fireEvent(ExtractionEvent.Type.EXTRACTION_FAILED);
            break;
          case ExtractionControllerConstants.EXIT_CODE_WRITE_ERROR:
            logger.warning("Unable to write unpacked data on harddisk for " + archive);
            this.exception = new ExtractionException("Write to disk error");
            crashLog.write("Harddisk write Error");
            crashLog.write("Failed");
            fireEvent(ExtractionEvent.Type.EXTRACTION_FAILED);
            break;
          case ExtractionControllerConstants.EXIT_CODE_FATAL_ERROR:
            logger.warning("A unknown fatal error occurred while unpacking " + archive);
            crashLog.write("Unknown Fatal Error");
            crashLog.write("Failed");
            fireEvent(ExtractionEvent.Type.EXTRACTION_FAILED);
            break;
          case ExtractionControllerConstants.EXIT_CODE_WARNING:
            logger.warning("Non fatal error(s) occurred while unpacking " + archive);
            crashLog.write("Unknown Non Fatal Error");
            crashLog.write("Failed");
            fireEvent(ExtractionEvent.Type.EXTRACTION_FAILED);
            break;
          default:
            crashLog.write("Failed...unknown reason");
            crashLog.write("Failed");
            fireEvent(ExtractionEvent.Type.EXTRACTION_FAILED);
            break;
        }
        return null;
      } else {
        crashLog.write("Failed");
        fireEvent(ExtractionEvent.Type.EXTRACTION_FAILED);
      }
    } catch (Exception e) {
      logger.log(e);
      this.exception = e;
      crashLog.write("Exception occured: \r\n" + Exceptions.getStackTrace(e));
      crashLog.write("Failed");
      fireEvent(ExtractionEvent.Type.EXTRACTION_FAILED);
    } finally {
      crashLog.close();
      if (!CFG_EXTRACTION.CFG.isWriteExtractionLogEnabled()) {
        crashLog.delete();
      }
      try {
        if (gotKilled()) {
          logger.info("ExtractionController has been killed");
          logger.clear();
        }
        try {
          extractor.close();
        } catch (final Throwable e) {
        }
        fireEvent(ExtractionEvent.Type.CLEANUP);
        archive.onCleanUp();
      } finally {
        logger.close();
      }
    }
    return null;
  }
 /**
  * saves List of FilePackages to given File as ZippedJSon
  *
  * @param packages
  * @param file
  */
 private boolean save(java.util.List<FilePackage> packages, File file) throws IOException {
   synchronized (SAVELOADLOCK) {
     List<File> availableDownloadLists = null;
     if (file == null) {
       availableDownloadLists = getAvailableDownloadLists();
       if (availableDownloadLists.size() > 0) {
         String counter =
             new Regex(availableDownloadLists.get(0).getName(), "downloadList(\\d+)\\.zip")
                 .getMatch(0);
         long count = 1;
         if (counter != null) {
           count = Long.parseLong(counter) + 1;
         }
         file = Application.getResource("cfg/downloadList" + count + ".zip");
       }
       if (file == null) file = Application.getResource("cfg/downloadList.zip");
     }
     if (packages != null && file != null) {
       if (file.exists()) {
         if (file.isDirectory()) throw new IOException("File " + file + " is a directory");
         if (file.delete() == false) throw new IOException("Could not delete file " + file);
       } else {
         if (file.getParentFile().exists() == false && file.getParentFile().mkdirs() == false)
           throw new IOException("Could not create parentFolder for file " + file);
       }
       /* prepare formatter(001,0001...) for package filenames in zipfiles */
       String format = "%02d";
       if (packages.size() >= 10) {
         format = String.format("%%0%dd", (int) Math.log10(packages.size()) + 1);
       }
       boolean deleteFile = true;
       ZipIOWriter zip = null;
       FileOutputStream fos = null;
       try {
         fos = new FileOutputStream(file);
         zip = new ZipIOWriter(new BufferedOutputStream(fos, 32767));
         int index = 0;
         for (FilePackage pkg : packages) {
           /* convert FilePackage to JSon */
           FilePackageStorable storable = new FilePackageStorable(pkg);
           String string = JSonStorage.toString(storable);
           storable = null;
           byte[] bytes = string.getBytes("UTF-8");
           string = null;
           zip.addByteArry(bytes, true, "", String.format(format, (index++)));
         }
         DownloadControllerStorable dcs = new DownloadControllerStorable();
         try {
           /*
            * set current RootPath of JDownloader, so we can update it when user moves JDownloader folder
            */
           dcs.setRootPath(JDUtilities.getJDHomeDirectoryFromEnvironment().getAbsolutePath());
         } catch (final Throwable e) {
           /* the method above can throw exceptions, eg in SVN */
           logger.log(e);
         }
         zip.addByteArry(JSonStorage.toString(dcs).getBytes("UTF-8"), true, "", "extraInfo");
         /* close ZipIOWriter */
         zip.close();
         deleteFile = false;
         try {
           int keepXOld = Math.max(JsonConfig.create(GeneralSettings.class).getKeepXOldLists(), 0);
           if (availableDownloadLists != null && availableDownloadLists.size() > keepXOld) {
             availableDownloadLists =
                 availableDownloadLists.subList(keepXOld, availableDownloadLists.size());
             for (File oldDownloadList : availableDownloadLists) {
               logger.info(
                   "Delete outdated DownloadList: "
                       + oldDownloadList
                       + " "
                       + oldDownloadList.delete());
             }
           }
         } catch (final Throwable e) {
           logger.log(e);
         }
         return true;
       } catch (final Throwable e) {
         logger.log(e);
       } finally {
         try {
           fos.close();
         } catch (final Throwable e) {
         }
         if (deleteFile && file.exists()) {
           file.delete();
         }
       }
     }
     return false;
   }
 }
예제 #3
0
  @Override
  public ArrayList<DownloadLink> decryptIt(
      final CryptedLink param, final ProgressController progress) throws Exception {
    synchronized (LOCK) {
      PROGRESS = progress;
      final ArrayList<DownloadLink> decryptedLinks = new ArrayList<DownloadLink>();
      final String parameter = correctCryptedLink(param.toString());
      setBrowserExclusive();
      br.setFollowRedirects(true);
      br.getHeaders().put("User-Agent", UA);

      /* Handle Captcha and/or password */
      handleCaptchaAndPassword(parameter, param);
      if (!br.getURL().contains("relink.us/")) {
        try {
          validateLastChallengeResponse();
        } catch (final Throwable e) {
        }
        logger.info("Link offline: " + parameter);
        return decryptedLinks;
      }
      if (br.containsHTML("<title>404</title>")) {
        logger.info("Link offline: " + parameter);
        return decryptedLinks;
      }
      if (ALLFORM != null && ALLFORM.getRegex("password").matches()) {
        throw new DecrypterException(DecrypterException.PASSWORD);
      }
      if (ALLFORM != null && ALLFORM.getRegex("captcha").matches()) {
        throw new DecrypterException(DecrypterException.CAPTCHA);
      }

      final String page = br.toString();
      progress.setRange(0);
      final String title =
          br.getRegex("shrink\"><th>(Titel|Baslik|Title)</th><td>(.*?)</td></tr>").getMatch(1);
      FilePackage fp = null;
      if (title != null && title.trim().length() > 0) {
        fp = FilePackage.getInstance();
        fp.setName(title);
        fp.setProperty("ALLOW_MERGE", true);
      }

      /* use cnl2 button if available */
      String cnlUrl = "http://127\\.0\\.0\\.1:9666/flash/addcrypted2";
      if (br.containsHTML(cnlUrl)) {
        final Browser cnlbr = br.cloneBrowser();

        Form cnlForm = null;
        for (Form f : cnlbr.getForms()) {
          if (f.containsHTML(cnlUrl)) {
            cnlForm = f;
          }
        }
        if (cnlForm != null) {

          if (System.getProperty("jd.revision.jdownloaderrevision") != null) {
            String jk =
                cnlbr.getRegex("<input type=\"hidden\" name=\"jk\" value=\"([^\"]+)\"").getMatch(0);
            HashMap<String, String> infos = new HashMap<String, String>();
            infos.put(
                "crypted", Encoding.urlDecode(cnlForm.getInputField("crypted").getValue(), false));
            infos.put("jk", jk);
            String source = cnlForm.getInputField("source").getValue();
            if (StringUtils.isEmpty(source)) {
              source = parameter.toString();
            } else {
              source = Encoding.urlDecode(source, true);
            }
            infos.put("source", source);
            String json = JSonStorage.toString(infos);
            final DownloadLink dl =
                createDownloadlink(
                    "http://dummycnl.jdownloader.org/"
                        + HexFormatter.byteArrayToHex(json.getBytes("UTF-8")));
            if (fp != null) {
              fp.add(dl);
            }
            try {
              distribute(dl);
            } catch (final Throwable e) {
              /* does not exist in 09581 */
            }
            decryptedLinks.add(dl);
            return decryptedLinks;
          } else {
            String jk =
                cnlbr.getRegex("<input type=\"hidden\" name=\"jk\" value=\"([^\"]+)\"").getMatch(0);
            cnlForm.remove("jk");
            cnlForm.put("jk", (jk != null ? jk.replaceAll("\\+", "%2B") : "nothing"));
            try {
              cnlbr.submitForm(cnlForm);
              if (cnlbr.containsHTML("success")) {
                return decryptedLinks;
              }
              if (cnlbr.containsHTML("^failed")) {
                logger.warning(
                    "relink.us: CNL2 Postrequest was failed! Please upload now a logfile, contact our support and add this loglink to your bugreport!");
                logger.warning("relink.us: CNL2 Message: " + cnlbr.toString());
              }
            } catch (Throwable e) {
              logger.info("relink.us: ExternInterface(CNL2) is disabled!");
            }
          }
        }
      }
      if (!br.containsHTML("download.php\\?id=[a-f0-9]+") && !br.containsHTML("getFile\\(")) {
        return null;
      }
      if (!decryptContainer(page, parameter, "dlc", decryptedLinks)) {
        if (!decryptContainer(page, parameter, "ccf", decryptedLinks)) {
          decryptContainer(page, parameter, "rsdf", decryptedLinks);
        }
      }
      /* Webdecryption */
      if (decryptedLinks.isEmpty()) {
        decryptLinks(decryptedLinks, param);
        final String more_links[] =
            new Regex(
                    page,
                    Pattern.compile(
                        "<a href=\"(go\\.php\\?id=[a-zA-Z0-9]+\\&seite=\\d+)\">",
                        Pattern.CASE_INSENSITIVE))
                .getColumn(0);
        for (final String link : more_links) {
          br.getPage("http://relink.us/" + link);
          decryptLinks(decryptedLinks, param);
        }
      }
      if (decryptedLinks.isEmpty() && br.containsHTML(cnlUrl)) {
        throw new DecrypterException("CNL2 only, open this link in Browser");
      }
      try {
        validateLastChallengeResponse();
      } catch (final Throwable e) {
      }
      if (fp != null) {
        fp.addLinks(decryptedLinks);
      }
      return decryptedLinks;
    }
  }
예제 #4
0
 @Override
 public String toString() {
   return JSonStorage.toString(this);
 }