public CommandResponse doLISTJOBS(CommandRequest request) {

    CommandResponse response = StandardCommandManager.genericResponse("RESPONSE_200_COMMAND_OK");
    ReplacerEnvironment env = new ReplacerEnvironment();
    TreeSet<Job> treeSet = new TreeSet<Job>(new JobIndexComparator());
    treeSet.addAll(getJobManager().getAllJobsFromQueue());

    for (Job job : treeSet) {
      env.add("job", job);
      env.add("count", job.getIndex());
      synchronized (job) {
        if (job.isTransferring()) {
          env.add("speed", Bytes.formatBytes(job.getSpeed()));
          env.add("progress", Bytes.formatBytes(job.getProgress()));
          try {
            env.add("total", Bytes.formatBytes(job.getFile().getSize()));
          } catch (FileNotFoundException e) {
            env.add("total", "0");
          }
          env.add("srcslave", job.getSourceSlave().getName());
          env.add("destslave", job.getDestinationSlave().getName());
          response.addComment(
              request.getSession().jprintf(_bundle, env, _keyPrefix + "listjobrunning"));
        } else {
          response.addComment(
              request.getSession().jprintf(_bundle, env, _keyPrefix + "listjobwaiting"));
        }
      }
    }
    env = new ReplacerEnvironment();
    env.add("total", treeSet.size());
    response.addComment(request.getSession().jprintf(_bundle, env, _keyPrefix + "sizeofjobs"));
    return response;
  }
Beispiel #2
0
  public CommandResponse doSITE_DELSLAVE(CommandRequest request) throws ImproperUsageException {
    Session session = request.getSession();

    CommandResponse response = StandardCommandManager.genericResponse("RESPONSE_200_COMMAND_OK");
    ReplacerEnvironment env = new ReplacerEnvironment();

    if (!request.hasArgument()) {
      throw new ImproperUsageException();
    }

    String argument = request.getArgument();
    StringTokenizer arguments = new StringTokenizer(argument);

    if (!arguments.hasMoreTokens()) {
      throw new ImproperUsageException();
    }

    String slavename = arguments.nextToken();
    env.add("slavename", slavename);

    try {
      GlobalContext.getGlobalContext().getSlaveManager().getRemoteSlave(slavename);
    } catch (ObjectNotFoundException e) {
      response.addComment(
          session.jprintf(_bundle, _keyPrefix + "delslave.notfound", env, request.getUser()));

      return response;
    }

    GlobalContext.getGlobalContext().getSlaveManager().delSlave(slavename);
    response.addComment(
        session.jprintf(_bundle, _keyPrefix + "delslave.success", env, request.getUser()));

    return response;
  }
Beispiel #3
0
 public CommandResponse doSlave(CommandRequest request) throws ImproperUsageException {
   if (!request.hasArgument()) {
     throw new ImproperUsageException();
   }
   boolean showMore = false;
   StringTokenizer arguments = new StringTokenizer(request.getArgument());
   String slaveName = arguments.nextToken();
   if (arguments.hasMoreTokens()) {
     if (arguments.nextToken().equalsIgnoreCase("more")) {
       showMore = true;
     } else {
       throw new ImproperUsageException();
     }
   }
   if (arguments.hasMoreTokens()) {
     throw new ImproperUsageException();
   }
   CommandResponse response = StandardCommandManager.genericResponse("RESPONSE_200_COMMAND_OK");
   try {
     RemoteSlave rslave =
         GlobalContext.getGlobalContext().getSlaveManager().getRemoteSlave(slaveName);
     response = addSlaveStatus(request, response, showMore, rslave);
   } catch (ObjectNotFoundException e) {
     ReplacerEnvironment env = new ReplacerEnvironment();
     env.add("slavename", slaveName);
     response.addComment(
         request
             .getSession()
             .jprintf(_bundle, _keyPrefix + "slave.notfound", env, request.getUser()));
   }
   return response;
 }
Beispiel #4
0
  private CommandResponse addSlaveStatus(
      CommandRequest request, CommandResponse response, boolean showMore, RemoteSlave rslave) {
    Session session = request.getSession();
    if (showMore) {
      response.addComment(rslave.moreInfo());
    }

    ReplacerEnvironment env = new ReplacerEnvironment();
    env.add("slavename", rslave.getName());
    try {
      env.add("slaveip", rslave.getPASVIP());
    } catch (SlaveUnavailableException e) {
      env.add("slaveip", "OFFLINE");
    }

    if (rslave.isOnline()) {
      if (!rslave.isAvailable()) {
        response.addComment(
            session.jprintf(_bundle, _keyPrefix + "slave.remerging", env, request.getUser()));
      } else {
        try {
          SlaveStatus status = rslave.getSlaveStatus();
          fillEnvWithSlaveStatus(env, status);
          env.add("status", rslave.isRemerging() ? "REMERGING" : "ONLINE");
          response.addComment(
              session.jprintf(_bundle, _keyPrefix + "slave.online", env, request.getUser()));
        } catch (SlaveUnavailableException e) {
          // should never happen since we tested slave status w/ isOnline and isAvaiable.
          throw new RuntimeException(
              "There's a bug somewhere in the code, the slave was available now it isn't.", e);
        }
      }
    } else {
      response.addComment(
          session.jprintf(_bundle, _keyPrefix + "slave.offline", env, request.getUser()));
    }
    return response;
  }
  public CommandResponse doREMOVEJOB(CommandRequest request) throws ImproperUsageException {

    if (!request.hasArgument()) {
      throw new ImproperUsageException();
    }
    class Range {
      long _low, _high;

      Range(long low, long high) {
        if (0 >= low || low > high) {
          throw new IllegalArgumentException("0 < low <= high");
        }
        _low = low;
        _high = high;
      }

      public boolean contains(long val) {
        return _low <= val && val <= _high;
      }
    }

    ArrayList<Range> rangeList = new ArrayList<Range>();
    String rangeString = request.getArgument();
    String[] ranges = rangeString.split(" ");
    for (String range : ranges) {
      if (range.indexOf("-") == -1) {
        long val = Long.parseLong(range);
        rangeList.add(new Range(val, val));
      } else {
        String[] vals = range.split("-");
        rangeList.add(new Range(Long.parseLong(vals[0]), Long.parseLong(vals[1])));
      }
    }
    TreeSet<Job> treeSet = new TreeSet<Job>(new JobIndexComparator());
    treeSet.addAll(getJobManager().getAllJobsFromQueue());
    ReplacerEnvironment env = new ReplacerEnvironment();

    CommandResponse response = StandardCommandManager.genericResponse("RESPONSE_200_COMMAND_OK");
    for (Job job : treeSet) {
      for (Range range : rangeList) {
        if (range.contains(job.getIndex())) {
          env.add("job", job);
          getJobManager().stopJob(job);
          response.addComment(
              request.getSession().jprintf(_bundle, env, _keyPrefix + "removejob.success"));
        }
      }
    }
    return response;
  }
Beispiel #6
0
  public CommandResponse doSITE_NUKES(CommandRequest request) {
    CommandResponse response = StandardCommandManager.genericResponse("RESPONSE_200_COMMAND_OK");

    ReplacerEnvironment env = new ReplacerEnvironment();

    SectionInterface section =
        GlobalContext.getGlobalContext().getSectionManager().getSection(request.getArgument());

    if (request.hasArgument() && section.getName().equalsIgnoreCase("")) {
      return new CommandResponse(501, "Invalid section!");
    }

    if (NukeBeans.getNukeBeans().getAll().isEmpty()) {
      response.addComment(
          request
              .getSession()
              .jprintf(_bundle, _keyPrefix + "nukes.empty", env, request.getUser()));
    }

    for (NukeData nd : NukeBeans.getNukeBeans().getAll()) {
      if (nd.getPath().startsWith(request.getArgument(), 1)) {
        env.add("path", nd.getPath());
        env.add("multiplier", nd.getMultiplier());
        env.add("usersnuked", nd.getNukees().size());
        env.add("size", nd.getSize());
        env.add("reason", nd.getReason());
        env.add("amount", nd.getAmount());
        env.add("nuker", nd.getUser());
        response.addComment(
            request.getSession().jprintf(_bundle, _keyPrefix + "nukes", env, request.getUser()));
      }
    }

    if (response.getComment().isEmpty()) {
      env.add("section", section.getName());
      response.addComment(
          request
              .getSession()
              .jprintf(_bundle, _keyPrefix + "nukes.empty.section", env, request.getUser()));
    }

    return response;
  }
Beispiel #7
0
  public static void fillEnvWithSlaveStatus(ReplacerEnvironment env, SlaveStatus status) {
    env.add("disktotal", Bytes.formatBytes(status.getDiskSpaceCapacity()));
    env.add("diskfree", Bytes.formatBytes(status.getDiskSpaceAvailable()));
    env.add("diskused", Bytes.formatBytes(status.getDiskSpaceUsed()));
    try {
      env.add(
          "slavesonline",
          "" + GlobalContext.getGlobalContext().getSlaveManager().getAvailableSlaves().size());
    } catch (NoAvailableSlaveException e) {
      env.add("slavesonline", "0");
    }
    env.add(
        "slavestotal", "" + GlobalContext.getGlobalContext().getSlaveManager().getSlaves().size());

    if (status.getDiskSpaceCapacity() == 0) {
      env.add("diskfreepercent", "n/a");
      env.add("diskusedpercent", "n/a");
    } else {
      env.add(
          "diskfreepercent",
          ((status.getDiskSpaceAvailable() * 100) / status.getDiskSpaceCapacity()) + "%");
      env.add(
          "diskusedpercent",
          ((status.getDiskSpaceUsed() * 100) / status.getDiskSpaceCapacity()) + "%");
    }

    env.add("xfers", "" + status.getTransfers());
    env.add("xfersdn", "" + status.getTransfersSending());
    env.add("xfersup", "" + status.getTransfersReceiving());
    env.add("xfersdown", "" + status.getTransfersSending());

    env.add("throughput", Bytes.formatBytes(status.getThroughput()) + "/s");
    env.add("throughputup", Bytes.formatBytes(status.getThroughputReceiving()) + "/s");
    env.add("throughputdown", Bytes.formatBytes(status.getThroughputSending()) + "/s");
  }
Beispiel #8
0
  /**
   * Usage: site slave slavename [set,addmask,delmask]
   *
   * @throws ImproperUsageException
   */
  public CommandResponse doSITE_SLAVE(CommandRequest request) throws ImproperUsageException {
    Session session = request.getSession();

    CommandResponse response = StandardCommandManager.genericResponse("RESPONSE_200_COMMAND_OK");
    ReplacerEnvironment env = new ReplacerEnvironment();

    if (!request.hasArgument()) {
      throw new ImproperUsageException();
    }

    String argument = request.getArgument();
    StringTokenizer arguments = new StringTokenizer(argument);

    if (!arguments.hasMoreTokens()) {
      throw new ImproperUsageException();
    }

    String slavename = arguments.nextToken();
    env.add("slavename", slavename);

    RemoteSlave rslave = null;

    try {
      rslave = GlobalContext.getGlobalContext().getSlaveManager().getRemoteSlave(slavename);
    } catch (ObjectNotFoundException e) {
      response.addComment(
          session.jprintf(_bundle, _keyPrefix + "slave.notfound", env, request.getUser()));

      return response;
    }

    if (!arguments.hasMoreTokens()) {
      if (!rslave.getMasks().isEmpty()) {
        env.add("masks", rslave.getMasks());
        response.addComment(
            session.jprintf(_bundle, _keyPrefix + "slave.masks", env, request.getUser()));
      }

      response.addComment(
          session.jprintf(_bundle, _keyPrefix + "slave.data.header", request.getUser()));

      Map<Object, Object> props = rslave.getProperties();

      for (Entry<Object, Object> entry : props.entrySet()) {
        env.add("key", entry.getKey());
        env.add("value", entry.getValue());
        response.addComment(
            session.jprintf(_bundle, _keyPrefix + "slave.data", env, request.getUser()));
      }

      return response;
    }

    String command = arguments.nextToken();

    if (command.equalsIgnoreCase("set")) {
      if (arguments.countTokens() != 2) {
        throw new ImproperUsageException();
      }

      String key = arguments.nextToken();
      String value = arguments.nextToken();
      rslave.setProperty(key, value);
      env.add("key", key);
      env.add("value", value);
      response.addComment(
          session.jprintf(_bundle, _keyPrefix + "slave.set.success", env, request.getUser()));

      return response;
    } else if (command.equalsIgnoreCase("unset")) {
      if (arguments.countTokens() != 1) {
        throw new ImproperUsageException();
      }

      String key = arguments.nextToken();
      env.add("key", key);
      String value;
      try {
        value = rslave.removeProperty(key);
      } catch (KeyNotFoundException e) {
        response.addComment(
            session.jprintf(_bundle, _keyPrefix + "slave.unset.failure", env, request.getUser()));
        return response;
      }
      env.add("value", value);
      response.addComment(
          session.jprintf(_bundle, _keyPrefix + "slave.unset.success", env, request.getUser()));
      return response;
    } else if (command.equalsIgnoreCase("addmask")) {
      if (arguments.countTokens() != 1) {
        throw new ImproperUsageException();
      }

      String mask = arguments.nextToken();
      env.add("mask", mask);
      try {
        rslave.addMask(mask);
        response.addComment(
            session.jprintf(_bundle, _keyPrefix + "slave.addmask.success", env, request.getUser()));
        return response;
      } catch (DuplicateElementException e) {
        response =
            new CommandResponse(
                501,
                session.jprintf(
                    _bundle, _keyPrefix + "slave.addmask.dupe", env, request.getUser()));
        return response;
      }
    } else if (command.equalsIgnoreCase("delmask")) {
      if (arguments.countTokens() != 1) {
        throw new ImproperUsageException();
      }

      String mask = arguments.nextToken();
      env.add("mask", mask);

      if (rslave.removeMask(mask)) {
        return new CommandResponse(
            200,
            session.jprintf(_bundle, _keyPrefix + "slave.delmask.success", env, request.getUser()));
      }
      return new CommandResponse(
          501,
          session.jprintf(_bundle, _keyPrefix + "slave.delmask.failed", env, request.getUser()));
    } else if (command.equalsIgnoreCase("shutdown")) {
      rslave.shutdown();
      return StandardCommandManager.genericResponse("RESPONSE_200_COMMAND_OK");
    }
    throw new ImproperUsageException();
  }
Beispiel #9
0
  /**
   * USAGE: site nuke <directory> <multiplier> <message> Nuke a directory
   *
   * <p>ex. site nuke shit 2 CRAP
   *
   * <p>This will nuke the directory 'shit' and remove x2 credits with the comment 'CRAP'.
   *
   * <p>NOTE: You can enclose the directory in braces if you have spaces in the name ex. site NUKE
   * {My directory name} 1 because_i_dont_like_it
   *
   * <p>Q) What does the multiplier in 'site nuke' do? A) Multiplier is a penalty measure. If it is
   * 0, the user doesn't lose any credits for the stuff being nuked. If it is 1, user only loses the
   * amount of credits he gained by uploading the files (which is calculated by multiplying total
   * size of file by his/her ratio). If multiplier is more than 1, the user loses the credits he/she
   * gained by uploading, PLUS some extra credits. The formula is this: size * ratio + size *
   * (multiplier - 1). This way, multiplier of 2 causes user to lose size * ratio + size * 1, so the
   * additional penalty in this case is the size of nuked files. If the multiplier is 3, user loses
   * size * ratio + size * 2, etc.
   *
   * @throws ImproperUsageException
   */
  public CommandResponse doSITE_NUKE(CommandRequest request) throws ImproperUsageException {
    if (!request.hasArgument()) {
      throw new ImproperUsageException();
    }

    StringTokenizer st = new StringTokenizer(request.getArgument());

    if (!st.hasMoreTokens()) {
      throw new ImproperUsageException();
    }

    Session session = request.getSession();

    int multiplier;

    DirectoryHandle currentDir = request.getCurrentDirectory();
    String nukeDirName = st.nextToken();

    User requestUser = session.getUserNull(request.getUser());

    String nukeDirPath = VirtualFileSystem.fixPath(nukeDirName);

    if (!(nukeDirPath.startsWith(VirtualFileSystem.separator))) {
      // Not a full path, let's make it one
      if (request.getCurrentDirectory().isRoot()) {
        boolean searchIndex =
            request.getProperties().getProperty("search", "true").equalsIgnoreCase("true");
        if (searchIndex) {
          // Get dirs from index system
          ArrayList<DirectoryHandle> dirsToNuke;
          try {
            dirsToNuke = NukeUtils.findNukeDirs(currentDir, requestUser, nukeDirPath);
          } catch (FileNotFoundException e) {
            logger.warn(e);
            return new CommandResponse(550, e.getMessage());
          }

          ReplacerEnvironment env = new ReplacerEnvironment();

          if (dirsToNuke.isEmpty()) {
            env.add("searchstr", nukeDirPath);
            return new CommandResponse(
                550, session.jprintf(_bundle, _keyPrefix + "nuke.search.empty", env, requestUser));
          } else if (dirsToNuke.size() == 1) {
            nukeDirPath = dirsToNuke.get(0).getPath();
          } else {
            CommandResponse response = new CommandResponse(200);

            for (DirectoryHandle nukeDir : dirsToNuke) {
              try {
                env.add("name", nukeDir.getName());
                env.add("path", nukeDir.getPath());
                env.add("owner", nukeDir.getUsername());
                env.add("group", nukeDir.getGroup());
                env.add("size", Bytes.formatBytes(nukeDir.getSize()));
                response.addComment(
                    session.jprintf(_bundle, _keyPrefix + "nuke.search.item", env, requestUser));
              } catch (FileNotFoundException e) {
                logger.warn(
                    "Dir deleted after index search?, skip and continue: " + nukeDir.getPath());
              }
            }

            response.addComment(
                session.jprintf(_bundle, _keyPrefix + "nuke.search.end", env, requestUser));

            // Return matching dirs and let user decide what to nuke
            return response;
          }
        } else {
          nukeDirPath = VirtualFileSystem.separator + nukeDirPath;
        }
      } else {
        nukeDirPath =
            request.getCurrentDirectory().getPath() + VirtualFileSystem.separator + nukeDirPath;
      }
    }

    DirectoryHandle nukeDir;

    try {
      nukeDir = request.getCurrentDirectory().getDirectory(nukeDirPath, requestUser);
    } catch (FileNotFoundException e) {
      return StandardCommandManager.genericResponse("RESPONSE_550_REQUESTED_ACTION_NOT_TAKEN");
    } catch (ObjectNotValidException e) {
      return new CommandResponse(550, nukeDirPath + " is not a directory");
    }

    nukeDirName = nukeDir.getName();

    if (!st.hasMoreTokens()) {
      throw new ImproperUsageException();
    }

    try {
      multiplier = Integer.parseInt(st.nextToken());
    } catch (NumberFormatException ex) {
      logger.warn(ex, ex);
      return new CommandResponse(501, "Invalid multiplier: " + ex.getMessage());
    }

    String reason = "";

    if (st.hasMoreTokens()) {
      reason = st.nextToken("").trim();
    }

    NukeData nd;
    try {
      nd = NukeUtils.nuke(nukeDir, multiplier, reason, requestUser);
    } catch (NukeException e) {
      return new CommandResponse(500, "Nuke failed: " + e.getMessage());
    }

    CommandResponse response = new CommandResponse(200, "Nuke succeeded");

    GlobalContext.getEventService().publishAsync(new NukeEvent(requestUser, "NUKE", nd));

    ReplacerEnvironment env = new ReplacerEnvironment();

    String section = GlobalContext.getGlobalContext().getSectionManager().lookup(nukeDir).getName();
    env.add("section", section);
    env.add("dir", nukeDirName);
    env.add("path", nukeDirPath);
    env.add("relpath", nukeDirPath.replaceAll("/.*?" + section + "/", ""));
    env.add("multiplier", multiplier);
    env.add("nukedamount", Bytes.formatBytes(nd.getAmount()));
    env.add("reason", reason);
    env.add("size", Bytes.formatBytes(nd.getSize()));

    if (session instanceof BaseFtpConnection) {
      response.addComment(session.jprintf(_bundle, _keyPrefix + "nuke", env, requestUser));
      for (NukedUser nukeeObj : NukeBeans.getNukeeList(nd)) {
        ReplacerEnvironment nukeeenv = new ReplacerEnvironment();
        User nukee;
        try {
          nukee =
              GlobalContext.getGlobalContext()
                  .getUserManager()
                  .getUserByName(nukeeObj.getUsername());
        } catch (NoSuchUserException e1) {
          // Unable to get user, does not exist.. skip announce for this user
          continue;
        } catch (UserFileException e1) {
          // Error in user file.. skip announce for this user
          continue;
        }

        long debt =
            NukeUtils.calculateNukedAmount(
                nukeeObj.getAmount(),
                nukee.getKeyedMap().getObjectFloat(UserManagement.RATIO),
                multiplier);
        nukeeenv.add("nukedamount", Bytes.formatBytes(debt));
        response.addComment(session.jprintf(_bundle, _keyPrefix + "nuke.nukees", nukeeenv, nukee));
      }
    }

    return response;
  }
Beispiel #10
0
  /**
   * USAGE: site unnuke <directory> <message> Unnuke a directory.
   *
   * <p>ex. site unnuke shit NOT CRAP
   *
   * <p>This will unnuke the directory 'shit' with the comment 'NOT CRAP'.
   *
   * <p>NOTE: You can enclose the directory in braces if you have spaces in the name ex. site unnuke
   * {My directory name} justcause
   *
   * <p>You need to configure glftpd to keep nuked files if you want to unnuke. See the section
   * about glftpd.conf.
   *
   * @throws ImproperUsageException
   */
  public CommandResponse doSITE_UNNUKE(CommandRequest request) throws ImproperUsageException {
    if (!request.hasArgument()) {
      throw new ImproperUsageException();
    }

    StringTokenizer st = new StringTokenizer(request.getArgument());

    Session session = request.getSession();

    DirectoryHandle currentDir = request.getCurrentDirectory();
    User user = session.getUserNull(request.getUser());
    String toName = st.nextToken();
    String toDir;
    String nukeName;

    if (!toName.startsWith(VirtualFileSystem.separator)) {
      // Not a full path, let's make it one and append [NUKED]- if needed.
      if (toName.startsWith("[NUKED]-")) {
        nukeName = toName;
        toName = toName.substring(8);
      } else {
        nukeName = "[NUKED]-" + toName;
      }
      if (request.getCurrentDirectory().isRoot()) {
        boolean searchIndex =
            request.getProperties().getProperty("search", "true").equalsIgnoreCase("true");
        if (searchIndex) {
          // Get dirs from index system
          ArrayList<DirectoryHandle> dirsToUnNuke;
          try {
            dirsToUnNuke = NukeUtils.findNukeDirs(currentDir, user, nukeName);
          } catch (FileNotFoundException e) {
            logger.warn(e);
            return new CommandResponse(550, e.getMessage());
          }

          ReplacerEnvironment env = new ReplacerEnvironment();

          if (dirsToUnNuke.isEmpty()) {
            env.add("searchstr", nukeName);
            return new CommandResponse(
                550, session.jprintf(_bundle, _keyPrefix + "unnuke.search.empty", env, user));
          } else if (dirsToUnNuke.size() == 1) {
            toDir = dirsToUnNuke.get(0).getParent().getPath() + VirtualFileSystem.separator;
          } else {
            CommandResponse response = new CommandResponse(200);

            for (DirectoryHandle nukeDir : dirsToUnNuke) {
              try {
                env.add("name", nukeDir.getName());
                env.add("path", nukeDir.getPath());
                env.add("owner", nukeDir.getUsername());
                env.add("group", nukeDir.getGroup());
                env.add("size", Bytes.formatBytes(nukeDir.getSize()));
                response.addComment(
                    session.jprintf(_bundle, _keyPrefix + "unnuke.search.item", env, user));
              } catch (FileNotFoundException e) {
                logger.warn(
                    "Dir deleted after index search?, skip and continue: " + nukeDir.getPath());
              }
            }

            response.addComment(
                session.jprintf(_bundle, _keyPrefix + "unnuke.search.end", env, user));

            // Return matching dirs and let user decide what to unnuke
            return response;
          }
        } else {
          toDir = VirtualFileSystem.separator;
        }
      } else {
        toDir = currentDir.getPath() + VirtualFileSystem.separator;
      }
    } else {
      // Full path to Nuked dir provided, append [NUKED]- if needed.
      toDir = VirtualFileSystem.fixPath(toName);
      toName = toDir.substring(toDir.lastIndexOf(VirtualFileSystem.separator) + 1);
      toDir = toDir.substring(0, toDir.lastIndexOf(VirtualFileSystem.separator) + 1);
      if (toName.startsWith("[NUKED]-")) {
        nukeName = toName;
        toName = toName.substring(8);
      } else {
        nukeName = "[NUKED]-" + toName;
      }
    }

    String reason;

    if (st.hasMoreTokens()) {
      reason = st.nextToken("").trim();
    } else {
      reason = "";
    }

    DirectoryHandle nukeDir;

    try {
      nukeDir = currentDir.getDirectory(toDir + nukeName, user);
    } catch (FileNotFoundException e) {
      // Maybe dir was deleted/wiped, lets remove it from nukelog.
      try {
        NukeBeans.getNukeBeans().remove(toDir + toName);
      } catch (ObjectNotFoundException ex) {
        return new CommandResponse(
            500, toDir + nukeName + " doesnt exist and no nukelog for this path was found.");
      }
      return new CommandResponse(
          200, toDir + nukeName + " doesnt exist, removed nuke from nukelog.");
    } catch (ObjectNotValidException e) {
      return new CommandResponse(550, toDir + nukeName + " is not a directory");
    }

    NukeData nd;
    try {
      nd = NukeUtils.unnuke(nukeDir, reason);
    } catch (NukeException e) {
      return new CommandResponse(500, "Unnuke failed: " + e.getMessage());
    }

    CommandResponse response = new CommandResponse(200, "Unnuke succeeded");

    NukeEvent nukeEvent = new NukeEvent(session.getUserNull(request.getUser()), "UNNUKE", nd);
    GlobalContext.getEventService().publishAsync(nukeEvent);

    ReplacerEnvironment env = new ReplacerEnvironment();

    String section = GlobalContext.getGlobalContext().getSectionManager().lookup(nukeDir).getName();
    env.add("section", section);
    env.add("dir", nukeDir.getName());
    env.add("path", nukeDir.getPath());
    env.add("relpath", nukeDir.getPath().replaceAll("/" + section + "/", ""));
    env.add("multiplier", nd.getMultiplier());
    env.add("nukedamount", Bytes.formatBytes(nd.getAmount()));
    env.add("reason", reason);
    env.add("size", Bytes.formatBytes(nd.getSize()));

    if (session instanceof BaseFtpConnection) {
      response.addComment(session.jprintf(_bundle, _keyPrefix + "unnuke", env, user));
      for (NukedUser nukeeObj : NukeBeans.getNukeeList(nd)) {
        ReplacerEnvironment nukeeenv = new ReplacerEnvironment();
        User nukee;
        try {
          nukee =
              GlobalContext.getGlobalContext()
                  .getUserManager()
                  .getUserByName(nukeeObj.getUsername());
        } catch (NoSuchUserException e1) {
          // Unable to get user, does not exist.. skip announce for this user
          continue;
        } catch (UserFileException e1) {
          // Error in user file.. skip announce for this user
          continue;
        }

        long debt =
            NukeUtils.calculateNukedAmount(
                nukeeObj.getAmount(),
                nukee.getKeyedMap().getObjectFloat(UserManagement.RATIO),
                nd.getMultiplier());
        nukeeenv.add("nukedamount", Bytes.formatBytes(debt));
        response.addComment(
            session.jprintf(_bundle, _keyPrefix + "unnuke.nukees", nukeeenv, nukee));
      }
    }

    return response;
  }
  /**
   * USAGE: <file><priority>[destslave ...]
   *
   * @param conn
   * @return
   * @throws ImproperUsageException
   * @throws ReplyException
   * @throws FileNotFoundException
   */
  public CommandResponse doADDJOB(CommandRequest request) throws ImproperUsageException {

    if (!request.hasArgument()) {
      throw new ImproperUsageException();
    }

    CommandResponse response = StandardCommandManager.genericResponse("RESPONSE_200_COMMAND_OK");

    StringTokenizer st = new StringTokenizer(request.getArgument());
    User user = request.getSession().getUserNull(request.getUser());
    FileHandle lrf;

    try {
      try {
        lrf = request.getCurrentDirectory().getFile(st.nextToken(), user);
      } catch (ObjectNotValidException e) {
        throw new ImproperUsageException("addjob does not handle directories or links");
      }
    } catch (FileNotFoundException e) {
      return new CommandResponse(500, "File does not exist");
    }

    int priority;

    try {
      priority = Integer.parseInt(st.nextToken());
    } catch (Exception e) {
      throw new ImproperUsageException();
    }

    int timesToMirror;

    try {
      timesToMirror = Integer.parseInt(st.nextToken());
    } catch (NumberFormatException e) {
      throw new ImproperUsageException();
    }

    HashSet<String> destSlaves = new HashSet<String>();

    while (st.hasMoreTokens()) {
      String slaveName = st.nextToken();

      try {
        GlobalContext.getGlobalContext().getSlaveManager().getRemoteSlave(slaveName);
      } catch (ObjectNotFoundException e1) {
        response.addComment(slaveName + "was not found, cannot add to destination slave list");

        continue;
      }

      destSlaves.add(slaveName);
    }

    if (destSlaves.size() == 0) {
      throw new ImproperUsageException();
    }

    Job job = new Job(lrf, destSlaves, priority, timesToMirror);
    getJobManager().addJobToQueue(job);

    ReplacerEnvironment env = new ReplacerEnvironment();
    env.add("job", job);
    response.addComment(request.getSession().jprintf(_bundle, env, _keyPrefix + "addjob.success"));

    return response;
  }