1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
23345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Use of this source code is governed by a BSD-style license that can be
33345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// found in the LICENSE file.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/ftp/ftp_directory_listing_parser_netware.h"
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <vector>
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h"
103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_split.h"
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/string_util.h"
123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h"
13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/ftp/ftp_directory_listing_parser.h"
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/ftp/ftp_util.h"
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace {
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool LooksLikeNetwarePermissionsListing(const string16& text) {
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (text.length() != 10)
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (text[0] != '[' || text[9] != ']')
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return (text[1] == 'R' || text[1] == '-') &&
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott         (text[2] == 'W' || text[2] == '-') &&
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott         (text[3] == 'C' || text[3] == '-') &&
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott         (text[4] == 'E' || text[4] == '-') &&
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott         (text[5] == 'A' || text[5] == '-') &&
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott         (text[6] == 'F' || text[6] == '-') &&
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott         (text[7] == 'M' || text[7] == '-') &&
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott         (text[8] == 'S' || text[8] == '-');
32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net {
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ParseFtpDirectoryListingNetware(
39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const std::vector<string16>& lines,
40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const base::Time& current_time,
41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    std::vector<FtpDirectoryListingEntry>* entries) {
42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!lines.empty() && !StartsWith(lines[0], ASCIIToUTF16("total "), true))
43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (size_t i = 1U; i < lines.size(); i++) {
46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (lines[i].empty())
47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      continue;
48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    std::vector<string16> columns;
50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::SplitString(CollapseWhitespace(lines[i], false), ' ', &columns);
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (columns.size() != 8)
53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return false;
54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    FtpDirectoryListingEntry entry;
56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (columns[0].length() != 1)
58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return false;
59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (columns[0][0] == 'd') {
60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      entry.type = FtpDirectoryListingEntry::DIRECTORY;
61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else if (columns[0][0] == '-') {
62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      entry.type = FtpDirectoryListingEntry::FILE;
63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return false;
65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Note: on older Netware systems the permissions listing is in the same
68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // column as the entry type (just there is no space between them). We do not
69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // support the older format here for simplicity.
70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!LooksLikeNetwarePermissionsListing(columns[1]))
71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return false;
72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!base::StringToInt64(columns[3], &entry.size))
74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return false;
75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (entry.size < 0)
76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return false;
77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (entry.type != FtpDirectoryListingEntry::FILE)
78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      entry.size = -1;
79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Netware uses the same date listing format as Unix "ls -l".
81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!FtpUtil::LsDateListingToTime(columns[4], columns[5], columns[6],
82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                      current_time, &entry.last_modified)) {
83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return false;
84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    entry.name = columns[7];
87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    entries->push_back(entry);
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace net
95