| Index: net/ftp/ftp_directory_listing_parser_ls.cc
|
| diff --git a/net/ftp/ftp_directory_listing_parser_ls.cc b/net/ftp/ftp_directory_listing_parser_ls.cc
|
| deleted file mode 100644
|
| index 2d23b6aecf5996361a0b7bb951981306b44be54d..0000000000000000000000000000000000000000
|
| --- a/net/ftp/ftp_directory_listing_parser_ls.cc
|
| +++ /dev/null
|
| @@ -1,234 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "net/ftp/ftp_directory_listing_parser_ls.h"
|
| -
|
| -#include <vector>
|
| -
|
| -#include "base/strings/string_number_conversions.h"
|
| -#include "base/strings/string_split.h"
|
| -#include "base/strings/string_util.h"
|
| -#include "base/strings/utf_string_conversions.h"
|
| -#include "base/time/time.h"
|
| -#include "net/ftp/ftp_directory_listing_parser.h"
|
| -#include "net/ftp/ftp_util.h"
|
| -
|
| -namespace {
|
| -
|
| -bool TwoColumnDateListingToTime(const base::string16& date,
|
| - const base::string16& time,
|
| - base::Time* result) {
|
| - base::Time::Exploded time_exploded = { 0 };
|
| -
|
| - // Date should be in format YYYY-MM-DD.
|
| - std::vector<base::string16> date_parts;
|
| - base::SplitString(date, '-', &date_parts);
|
| - if (date_parts.size() != 3)
|
| - return false;
|
| - if (!base::StringToInt(date_parts[0], &time_exploded.year))
|
| - return false;
|
| - if (!base::StringToInt(date_parts[1], &time_exploded.month))
|
| - return false;
|
| - if (!base::StringToInt(date_parts[2], &time_exploded.day_of_month))
|
| - return false;
|
| -
|
| - // Time should be in format HH:MM
|
| - if (time.length() != 5)
|
| - return false;
|
| -
|
| - std::vector<base::string16> time_parts;
|
| - base::SplitString(time, ':', &time_parts);
|
| - if (time_parts.size() != 2)
|
| - return false;
|
| - if (!base::StringToInt(time_parts[0], &time_exploded.hour))
|
| - return false;
|
| - if (!base::StringToInt(time_parts[1], &time_exploded.minute))
|
| - return false;
|
| - if (!time_exploded.HasValidValues())
|
| - return false;
|
| -
|
| - // We don't know the time zone of the server, so just use local time.
|
| - *result = base::Time::FromLocalExploded(time_exploded);
|
| - return true;
|
| -}
|
| -
|
| -// Returns the column index of the end of the date listing and detected
|
| -// last modification time.
|
| -bool DetectColumnOffsetSizeAndModificationTime(
|
| - const std::vector<base::string16>& columns,
|
| - const base::Time& current_time,
|
| - size_t* offset,
|
| - base::string16* size,
|
| - base::Time* modification_time) {
|
| - // The column offset can be arbitrarily large if some fields
|
| - // like owner or group name contain spaces. Try offsets from left to right
|
| - // and use the first one that matches a date listing.
|
| - //
|
| - // Here is how a listing line should look like. A star ("*") indicates
|
| - // a required field:
|
| - //
|
| - // * 1. permission listing
|
| - // 2. number of links (optional)
|
| - // * 3. owner name (may contain spaces)
|
| - // 4. group name (optional, may contain spaces)
|
| - // * 5. size in bytes
|
| - // * 6. month
|
| - // * 7. day of month
|
| - // * 8. year or time <-- column_offset will be the index of this column
|
| - // 9. file name (optional, may contain spaces)
|
| - for (size_t i = 5U; i < columns.size(); i++) {
|
| - if (net::FtpUtil::LsDateListingToTime(columns[i - 2],
|
| - columns[i - 1],
|
| - columns[i],
|
| - current_time,
|
| - modification_time)) {
|
| - *size = columns[i - 3];
|
| - *offset = i;
|
| - return true;
|
| - }
|
| - }
|
| -
|
| - // Some FTP listings have swapped the "month" and "day of month" columns
|
| - // (for example Russian listings). We try to recognize them only after making
|
| - // sure no column offset works above (this is a more strict way).
|
| - for (size_t i = 5U; i < columns.size(); i++) {
|
| - if (net::FtpUtil::LsDateListingToTime(columns[i - 1],
|
| - columns[i - 2],
|
| - columns[i],
|
| - current_time,
|
| - modification_time)) {
|
| - *size = columns[i - 3];
|
| - *offset = i;
|
| - return true;
|
| - }
|
| - }
|
| -
|
| - // Some FTP listings use a different date format.
|
| - for (size_t i = 5U; i < columns.size(); i++) {
|
| - if (TwoColumnDateListingToTime(columns[i - 1],
|
| - columns[i],
|
| - modification_time)) {
|
| - *size = columns[i - 2];
|
| - *offset = i;
|
| - return true;
|
| - }
|
| - }
|
| -
|
| - return false;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -namespace net {
|
| -
|
| -bool ParseFtpDirectoryListingLs(
|
| - const std::vector<base::string16>& lines,
|
| - const base::Time& current_time,
|
| - std::vector<FtpDirectoryListingEntry>* entries) {
|
| - // True after we have received a "total n" listing header, where n is an
|
| - // integer. Only one such header is allowed per listing.
|
| - bool received_total_line = false;
|
| -
|
| - for (size_t i = 0; i < lines.size(); i++) {
|
| - if (lines[i].empty())
|
| - continue;
|
| -
|
| - std::vector<base::string16> columns;
|
| - base::SplitString(base::CollapseWhitespace(lines[i], false), ' ', &columns);
|
| -
|
| - // Some FTP servers put a "total n" line at the beginning of the listing
|
| - // (n is an integer). Allow such a line, but only once, and only if it's
|
| - // the first non-empty line. Do not match the word exactly, because it may
|
| - // be in different languages (at least English and German have been seen
|
| - // in the field).
|
| - if (columns.size() == 2 && !received_total_line) {
|
| - received_total_line = true;
|
| -
|
| - int64 total_number;
|
| - if (!base::StringToInt64(columns[1], &total_number))
|
| - return false;
|
| - if (total_number < 0)
|
| - return false;
|
| -
|
| - continue;
|
| - }
|
| -
|
| - FtpDirectoryListingEntry entry;
|
| -
|
| - size_t column_offset;
|
| - base::string16 size;
|
| - if (!DetectColumnOffsetSizeAndModificationTime(columns,
|
| - current_time,
|
| - &column_offset,
|
| - &size,
|
| - &entry.last_modified)) {
|
| - // Some servers send a message in one of the first few lines.
|
| - // All those messages have in common is the string ".:",
|
| - // where "." means the current directory, and ":" separates it
|
| - // from the rest of the message, which may be empty.
|
| - if (lines[i].find(base::ASCIIToUTF16(".:")) != base::string16::npos)
|
| - continue;
|
| -
|
| - return false;
|
| - }
|
| -
|
| - // Do not check "validity" of the permission listing. It's quirky,
|
| - // and some servers send garbage here while other parts of the line are OK.
|
| -
|
| - if (!columns[0].empty() && columns[0][0] == 'l') {
|
| - entry.type = FtpDirectoryListingEntry::SYMLINK;
|
| - } else if (!columns[0].empty() && columns[0][0] == 'd') {
|
| - entry.type = FtpDirectoryListingEntry::DIRECTORY;
|
| - } else {
|
| - entry.type = FtpDirectoryListingEntry::FILE;
|
| - }
|
| -
|
| - if (!base::StringToInt64(size, &entry.size)) {
|
| - // Some FTP servers do not separate owning group name from file size,
|
| - // like "group1234". We still want to display the file name for that
|
| - // entry, but can't really get the size (What if the group is named
|
| - // "group1", and the size is in fact 234? We can't distinguish between
|
| - // that and "group" with size 1234). Use a dummy value for the size.
|
| - // TODO(phajdan.jr): Use a value that means "unknown" instead of 0 bytes.
|
| - entry.size = 0;
|
| - }
|
| - if (entry.size < 0) {
|
| - // Some FTP servers have bugs that cause them to display the file size
|
| - // as negative. They're most likely big files like DVD ISO images.
|
| - // We still want to display them, so just say the real file size
|
| - // is unknown.
|
| - entry.size = -1;
|
| - }
|
| - if (entry.type != FtpDirectoryListingEntry::FILE)
|
| - entry.size = -1;
|
| -
|
| - if (column_offset == columns.size() - 1) {
|
| - // If the end of the date listing is the last column, there is no file
|
| - // name. Some FTP servers send listing entries with empty names.
|
| - // It's not obvious how to display such an entry, so we ignore them.
|
| - // We don't want to make the parsing fail at this point though.
|
| - // Other entries can still be useful.
|
| - continue;
|
| - }
|
| -
|
| - entry.name = FtpUtil::GetStringPartAfterColumns(lines[i],
|
| - column_offset + 1);
|
| -
|
| - if (entry.type == FtpDirectoryListingEntry::SYMLINK) {
|
| - base::string16::size_type pos =
|
| - entry.name.rfind(base::ASCIIToUTF16(" -> "));
|
| -
|
| - // We don't require the " -> " to be present. Some FTP servers don't send
|
| - // the symlink target, possibly for security reasons.
|
| - if (pos != base::string16::npos)
|
| - entry.name = entry.name.substr(0, pos);
|
| - }
|
| -
|
| - entries->push_back(entry);
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| -} // namespace net
|
|
|