15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/ftp/ftp_directory_listing_parser_os2.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h"
11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/strings/string_util.h"
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/ftp/ftp_directory_listing_parser.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/ftp/ftp_util.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ParseFtpDirectoryListingOS2(
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::vector<base::string16>& lines,
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<FtpDirectoryListingEntry>* entries) {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < lines.size(); i++) {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (lines[i].empty())
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::vector<base::string16> columns;
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::SplitString(base::CollapseWhitespace(lines[i], false), ' ', &columns);
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Every line of the listing consists of the following:
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   1. size in bytes (0 for directories)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   2. type (A for files, DIR for directories)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   3. date
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   4. time
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   5. filename (may be empty or contain spaces)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // For now, make sure we have 1-4, and handle 5 later.
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (columns.size() < 4)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FtpDirectoryListingEntry entry;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!base::StringToInt64(columns[0], &entry.size))
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (EqualsASCII(columns[1], "DIR")) {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (entry.size != 0)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entry.type = FtpDirectoryListingEntry::DIRECTORY;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entry.size = -1;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (EqualsASCII(columns[1], "A")) {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entry.type = FtpDirectoryListingEntry::FILE;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (entry.size < 0)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!FtpUtil::WindowsDateListingToTime(columns[2],
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           columns[3],
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           &entry.last_modified)) {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entry.name = FtpUtil::GetStringPartAfterColumns(lines[i], 4);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (entry.name.empty()) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Some FTP servers send listing entries with empty names.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // It's not obvious how to display such an entry, so ignore them.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // We don't want to make the parsing fail at this point though.
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Other entries can still be useful.
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entries->push_back(entry);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
78