| 1 | | /******************************************************************************* |
|---|
| 2 | | |
|---|
| 3 | | copyright: Copyright (c) 2008 (c) Lester L. Martin II. All rights reserved |
|---|
| 4 | | |
|---|
| 5 | | license: BSD style: $(LICENSE) |
|---|
| 6 | | |
|---|
| 7 | | version: Initial release: _________ 2008 |
|---|
| 8 | | |
|---|
| 9 | | author: Lester L. Martin II |
|---|
| 10 | | |
|---|
| 11 | | important: |
|---|
| 12 | | More rights and additional changes to the license can be requested |
|---|
| 13 | | at lestermartin92@gmail.com as long as my spam manager does not drop |
|---|
| 14 | | you in the spam box. |
|---|
| 15 | | All rights requested and license will be made individualy and that |
|---|
| 16 | | license and set of rights will apply only to the individual unless |
|---|
| 17 | | provided otherwise by liscense and copyright. |
|---|
| 18 | | |
|---|
| 19 | | *******************************************************************************/ |
|---|
| 20 | | |
|---|
| 21 | | module tango.io.vfs.FtpFolder; |
|---|
| 22 | | |
|---|
| 23 | | private import tango.io.vfs.model.Vfs; |
|---|
| 24 | | |
|---|
| 25 | | private import tango.io.FilePath; |
|---|
| 26 | | |
|---|
| 27 | | private import tango.io.model.IConduit; |
|---|
| 28 | | |
|---|
| 29 | | private import tango.net.ftp.FtpClient; |
|---|
| 30 | | |
|---|
| 31 | | //deals with creating null files(what I use it for) |
|---|
| 32 | | private import tango.io.FileConduit; |
|---|
| 33 | | |
|---|
| 34 | | //imports things to deal with text |
|---|
| 35 | | private import tango.text.Util; |
|---|
| 36 | | |
|---|
| 37 | | import tango.io.Console; |
|---|
| 38 | | |
|---|
| 39 | | /******************************************************************************* |
|---|
| 40 | | |
|---|
| 41 | | *******************************************************************************/ |
|---|
| 42 | | |
|---|
| 43 | | class FtpFolder : VfsFolder |
|---|
| 44 | | { |
|---|
| 45 | | char[] _name, |
|---|
| 46 | | _toString, |
|---|
| 47 | | _server, |
|---|
| 48 | | _username, |
|---|
| 49 | | _password; |
|---|
| 50 | | uint _port; |
|---|
| 51 | | package FTPConnection _ftp; |
|---|
| 52 | | bool _writableSet = false; |
|---|
| 53 | | bool _writeable; |
|---|
| 54 | | |
|---|
| 55 | | /*********************************************************************** |
|---|
| 56 | | ***********************************************************************/ |
|---|
| 57 | | |
|---|
| 58 | | package this (FtpFolder fol) |
|---|
| 59 | | { |
|---|
| 60 | | _name = fol._name.dup; |
|---|
| 61 | | _toString = fol._toString.dup; |
|---|
| 62 | | _server = fol._server.dup; |
|---|
| 63 | | _username = fol._username.dup; |
|---|
| 64 | | _password = fol._password.dup; |
|---|
| 65 | | _port = fol._port; |
|---|
| 66 | | _ftp = new FTPConnection(_toString, _username, _password, _port); |
|---|
| 67 | | writable(); |
|---|
| 68 | | } |
|---|
| 69 | | |
|---|
| 70 | | package this(VfsFolder fol) |
|---|
| 71 | | { |
|---|
| 72 | | this(cast(FtpFolder)fol); |
|---|
| 73 | | } |
|---|
| 74 | | |
|---|
| 75 | | public this(char[] server, char[] path = "", char[] username = "anonymous", char[] password = "anonymous@anonymous", uint port = 21) |
|---|
| 76 | | in |
|---|
| 77 | | { |
|---|
| 78 | | assert((server != null || server != "")); |
|---|
| 79 | | } |
|---|
| 80 | | body |
|---|
| 81 | | { |
|---|
| 82 | | _toString = server ~ path; |
|---|
| 83 | | _name = path; |
|---|
| 84 | | _server = server; |
|---|
| 85 | | _username = username; |
|---|
| 86 | | _password = password; |
|---|
| 87 | | _port = port; |
|---|
| 88 | | _ftp = new FTPConnection(_server, _username, _password, _port); |
|---|
| 89 | | if(_name != "") |
|---|
| 90 | | _ftp.cd(_name); |
|---|
| 91 | | } |
|---|
| 92 | | |
|---|
| 93 | | /*********************************************************************** |
|---|
| 94 | | |
|---|
| 95 | | Return a short name |
|---|
| 96 | | |
|---|
| 97 | | ***********************************************************************/ |
|---|
| 98 | | |
|---|
| 99 | | package void open() |
|---|
| 100 | | { |
|---|
| 101 | | _ftp.connect(_server, _username, _password, _port); |
|---|
| 102 | | } |
|---|
| 103 | | |
|---|
| 104 | | char[] name() |
|---|
| 105 | | { |
|---|
| 106 | | return _name; |
|---|
| 107 | | } |
|---|
| 108 | | |
|---|
| 109 | | /*********************************************************************** |
|---|
| 110 | | |
|---|
| 111 | | Return a long name |
|---|
| 112 | | |
|---|
| 113 | | ***********************************************************************/ |
|---|
| 114 | | |
|---|
| 115 | | char[] toString() |
|---|
| 116 | | { |
|---|
| 117 | | return _toString; |
|---|
| 118 | | } |
|---|
| 119 | | |
|---|
| 120 | | /*********************************************************************** |
|---|
| 121 | | |
|---|
| 122 | | Return a contained file representation |
|---|
| 123 | | |
|---|
| 124 | | ***********************************************************************/ |
|---|
| 125 | | |
|---|
| 126 | | VfsFile file (char[] path) |
|---|
| 127 | | { |
|---|
| 128 | | return new FtpFile(this, path); |
|---|
| 129 | | } |
|---|
| 130 | | |
|---|
| 131 | | /*********************************************************************** |
|---|
| 132 | | |
|---|
| 133 | | Return a contained folder representation |
|---|
| 134 | | |
|---|
| 135 | | ***********************************************************************/ |
|---|
| 136 | | |
|---|
| 137 | | VfsFolderEntry folder (char[] path) |
|---|
| 138 | | { |
|---|
| 139 | | return new FtpFolderEntry(this, path); |
|---|
| 140 | | } |
|---|
| 141 | | |
|---|
| 142 | | /*********************************************************************** |
|---|
| 143 | | |
|---|
| 144 | | Returns a folder set containing only this one. Statistics |
|---|
| 145 | | are inclusive of entries within this folder only |
|---|
| 146 | | |
|---|
| 147 | | ***********************************************************************/ |
|---|
| 148 | | |
|---|
| 149 | | VfsFolders self () |
|---|
| 150 | | { |
|---|
| 151 | | return new FtpFolders(this, true); |
|---|
| 152 | | } |
|---|
| 153 | | |
|---|
| 154 | | /*********************************************************************** |
|---|
| 155 | | |
|---|
| 156 | | Returns a subtree of folders. Statistics are inclusive of |
|---|
| 157 | | files within this folder and all others within the tree |
|---|
| 158 | | |
|---|
| 159 | | ***********************************************************************/ |
|---|
| 160 | | |
|---|
| 161 | | VfsFolders tree () |
|---|
| 162 | | { |
|---|
| 163 | | return new FtpFolders(this, false); |
|---|
| 164 | | } |
|---|
| 165 | | |
|---|
| 166 | | /*********************************************************************** |
|---|
| 167 | | |
|---|
| 168 | | Iterate over the set of immediate child folders. This is |
|---|
| 169 | | useful for reflecting the hierarchy |
|---|
| 170 | | |
|---|
| 171 | | ***********************************************************************/ |
|---|
| 172 | | |
|---|
| 173 | | int opApply (int delegate(inout VfsFolder) dg) |
|---|
| 174 | | { |
|---|
| 175 | | VfsFolders fol = self; |
|---|
| 176 | | int result = 0; |
|---|
| 177 | | foreach(folder; fol) |
|---|
| 178 | | { |
|---|
| 179 | | VfsFolder x = folder; |
|---|
| 180 | | if ((result = dg(x)) != 0) |
|---|
| 181 | | break; |
|---|
| 182 | | } |
|---|
| 183 | | return result; |
|---|
| 184 | | } |
|---|
| 185 | | |
|---|
| 186 | | /*********************************************************************** |
|---|
| 187 | | |
|---|
| 188 | | Clear all content from this folder and subordinates |
|---|
| 189 | | does nothing on failure |
|---|
| 190 | | |
|---|
| 191 | | ***********************************************************************/ |
|---|
| 192 | | |
|---|
| 193 | | VfsFolder clear() |
|---|
| 194 | | { |
|---|
| 195 | | if(_writeable) |
|---|
| 196 | | { |
|---|
| 197 | | _ftp.rm(name); |
|---|
| 198 | | _ftp.mkdir(name); |
|---|
| 199 | | return this; |
|---|
| 200 | | } |
|---|
| 201 | | else |
|---|
| 202 | | return new FtpFolder(this); |
|---|
| 203 | | } |
|---|
| 204 | | |
|---|
| 205 | | /*********************************************************************** |
|---|
| 206 | | |
|---|
| 207 | | Is folder writable? |
|---|
| 208 | | You should store the variable it returns. It makes a folder on the |
|---|
| 209 | | server if it works then it's writeable if not then returns false. |
|---|
| 210 | | The recommendation comes from the fact it takes up 2 ftp operations :-) |
|---|
| 211 | | |
|---|
| 212 | | ***********************************************************************/ |
|---|
| 213 | | |
|---|
| 214 | | bool writable() |
|---|
| 215 | | { |
|---|
| 216 | | if(_writableSet == true) |
|---|
| 217 | | { |
|---|
| 218 | | return _writeable; |
|---|
| 219 | | } |
|---|
| 220 | | else if(_ftp.exist(_ftp.mkdir("diw"))) |
|---|
| 221 | | { |
|---|
| 222 | | try |
|---|
| 223 | | { |
|---|
| 224 | | _ftp.rm("diw"); |
|---|
| 225 | | _writeable = true; |
|---|
| 226 | | return true; |
|---|
| 227 | | } |
|---|
| 228 | | catch(Exception) |
|---|
| 229 | | { |
|---|
| 230 | | _writeable = false; |
|---|
| 231 | | return false; |
|---|
| 232 | | } |
|---|
| 233 | | } |
|---|
| 234 | | else |
|---|
| 235 | | { |
|---|
| 236 | | return false; |
|---|
| 237 | | _writeable = false; |
|---|
| 238 | | } |
|---|
| 239 | | _writeable = false; |
|---|
| 240 | | _writableSet = true; |
|---|
| 241 | | return false; |
|---|
| 242 | | } |
|---|
| 243 | | |
|---|
| 244 | | /*********************************************************************** |
|---|
| 245 | | |
|---|
| 246 | | Close and/or synchronize changes made to this folder. Each |
|---|
| 247 | | driver should take advantage of this as appropriate, perhaps |
|---|
| 248 | | combining multiple files together, or possibly copying to a |
|---|
| 249 | | remote location |
|---|
| 250 | | This will close the ftp connection. Do not try to use the vfs folder |
|---|
| 251 | | it returns because operations to it no longer apply(throw exceptions |
|---|
| 252 | | or do nothing really)(throws exceptions if it trys to access ftp which |
|---|
| 253 | | now does not have an open connection). |
|---|
| 254 | | |
|---|
| 255 | | ***********************************************************************/ |
|---|
| 256 | | |
|---|
| 257 | | VfsFolder close (bool commit = true) |
|---|
| 258 | | { |
|---|
| 259 | | _ftp.close(); |
|---|
| 260 | | return new FtpFolder(this); |
|---|
| 261 | | } |
|---|
| 262 | | |
|---|
| 263 | | /*********************************************************************** |
|---|
| 264 | | |
|---|
| 265 | | does nothing and just returns; wastes time maybe ;-) |
|---|
| 266 | | |
|---|
| 267 | | ***********************************************************************/ |
|---|
| 268 | | |
|---|
| 269 | | void verify (VfsFolder folder, bool mounting) |
|---|
| 270 | | { |
|---|
| 271 | | return; |
|---|
| 272 | | } |
|---|
| 273 | | } |
|---|
| 274 | | |
|---|
| 275 | | /******************************************************************************* |
|---|
| 276 | | |
|---|
| 277 | | Operations upon a set of folders |
|---|
| 278 | | |
|---|
| 279 | | *******************************************************************************/ |
|---|
| 280 | | |
|---|
| 281 | | class FtpFolders : VfsFolders |
|---|
| 282 | | { |
|---|
| 283 | | FtpFolder _ftpFol; |
|---|
| 284 | | FtpFolder[] _folders, _primaryFolders; |
|---|
| 285 | | bool _flat, _foldersPopulated; |
|---|
| 286 | | |
|---|
| 287 | | package this(FtpFolder[] fols) |
|---|
| 288 | | { |
|---|
| 289 | | _primaryFolders = fols; |
|---|
| 290 | | foreach(folder; fols) |
|---|
| 291 | | { |
|---|
| 292 | | _primaryFolders ~= folder; |
|---|
| 293 | | } |
|---|
| 294 | | Cout("Doesn't work?").newline.flush; |
|---|
| 295 | | populateFolders(false); |
|---|
| 296 | | } |
|---|
| 297 | | |
|---|
| 298 | | package this(FtpFolder fol, bool flat) |
|---|
| 299 | | { |
|---|
| 300 | | _primaryFolders ~= fol; |
|---|
| 301 | | _flat = flat; |
|---|
| 302 | | populateFolders(false); |
|---|
| 303 | | } |
|---|
| 304 | | |
|---|
| 305 | | public this(char[] server, char[] path = "", char[] username = "anonymous", char[] password = "anonymous@anonymous", uint port = 21) |
|---|
| 306 | | in |
|---|
| 307 | | { |
|---|
| 308 | | assert((server != null || server != "")); |
|---|
| 309 | | } |
|---|
| 310 | | body |
|---|
| 311 | | { |
|---|
| 312 | | _primaryFolders ~= new FtpFolder(server, path, username, password, port); |
|---|
| 313 | | populateFolders(false); |
|---|
| 314 | | } |
|---|
| 315 | | /*********************************************************************** |
|---|
| 316 | | |
|---|
| 317 | | Iterate over the set of contained VfsFolder instances |
|---|
| 318 | | |
|---|
| 319 | | ***********************************************************************/ |
|---|
| 320 | | |
|---|
| 321 | | int opApply (int delegate(inout VfsFolder) dg) |
|---|
| 322 | | { |
|---|
| 323 | | if(_flat) |
|---|
| 324 | | throw new Exception("This folder contains no folders."); |
|---|
| 325 | | else |
|---|
| 326 | | { |
|---|
| 327 | | int result = 0; |
|---|
| 328 | | foreach(folder; _folders) |
|---|
| 329 | | { |
|---|
| 330 | | VfsFolder x = folder; |
|---|
| 331 | | if ((result = dg(x)) != 0) |
|---|
| | 1 | /* |
|---|
| | 2 | * Author: Lester L. Martin II |
|---|
| | 3 | * Copyright(c) Lester L. Martin II 2008 All rights reserved |
|---|
| | 4 | * Liscense: $(BSD) |
|---|
| | 5 | * |
|---|
| | 6 | */ |
|---|
| | 7 | |
|---|
| | 8 | import tango.net.ftp.FtpClient; |
|---|
| | 9 | import tango.io.vfs.model.Vfs; |
|---|
| | 10 | import tango.io.Conduit; |
|---|
| | 11 | |
|---|
| | 12 | class FtpFolderEntry: VfsFolderEntry { |
|---|
| | 13 | |
|---|
| | 14 | FTPConnection ftp_; |
|---|
| | 15 | char[] toString_, name_, username_, password_; |
|---|
| | 16 | uint port_; |
|---|
| | 17 | |
|---|
| | 18 | public this(char[] server, char[] path, char[] username = "anonymous", |
|---|
| | 19 | char[] password = "anonymous@anonymous", uint port = 21) |
|---|
| | 20 | in { |
|---|
| | 21 | assert(server != ""); |
|---|
| | 22 | } |
|---|
| | 23 | out { |
|---|
| | 24 | assert(server != ""); |
|---|
| | 25 | } |
|---|
| | 26 | body { |
|---|
| | 27 | toString_ = server; |
|---|
| | 28 | name_ = path; |
|---|
| | 29 | username_ = username; |
|---|
| | 30 | password_ = password; |
|---|
| | 31 | port_ = port; |
|---|
| | 32 | } |
|---|
| | 33 | |
|---|
| | 34 | VfsFolder open() { |
|---|
| | 35 | if(!exists()) { |
|---|
| | 36 | ftp_.close(); |
|---|
| | 37 | throw new Exception("This FTP directory is not in existence."); |
|---|
| | 38 | } else { |
|---|
| | 39 | ftp_.close(); |
|---|
| | 40 | return new FtpFolder(toString_, name_, username_, password_, port_); |
|---|
| | 41 | } |
|---|
| | 42 | } |
|---|
| | 43 | |
|---|
| | 44 | VfsFolder create() { |
|---|
| | 45 | if(exists()) { |
|---|
| | 46 | ftp_.close(); |
|---|
| | 47 | throw new Exception("This FTP Directory is already in existence."); |
|---|
| | 48 | } else { |
|---|
| | 49 | ftp_.close(); |
|---|
| | 50 | ftp_ = new FTPConnection(); |
|---|
| | 51 | ftp_.connect(toString_, username_, password_, port_); |
|---|
| | 52 | ftp_.mkdir(name_); |
|---|
| | 53 | ftp_.close(); |
|---|
| | 54 | } |
|---|
| | 55 | return new FtpFolder(toString_, name_, username_, password_, port_); |
|---|
| | 56 | } |
|---|
| | 57 | |
|---|
| | 58 | bool exists() { |
|---|
| | 59 | ftp_ = new FTPConnection(); |
|---|
| | 60 | ftp_.connect(toString_, username_, password_, port_); |
|---|
| | 61 | return ftp_.exist(name_) == 2 ? true : false; |
|---|
| | 62 | } |
|---|
| | 63 | } |
|---|
| | 64 | |
|---|
| | 65 | class FtpFolder: VfsFolder { |
|---|
| | 66 | |
|---|
| | 67 | FTPConnection ftp_; |
|---|
| | 68 | char[] toString_, name_, username_, password_; |
|---|
| | 69 | uint port_; |
|---|
| | 70 | bool writeable_, writeableSet_; |
|---|
| | 71 | |
|---|
| | 72 | public this(char[] server, char[] path, char[] username = "anonymous", |
|---|
| | 73 | char[] password = "anonymous@anonymous", uint port = 21) |
|---|
| | 74 | in { |
|---|
| | 75 | assert(server != ""); |
|---|
| | 76 | } |
|---|
| | 77 | out { |
|---|
| | 78 | assert(server != ""); |
|---|
| | 79 | } |
|---|
| | 80 | body { |
|---|
| | 81 | toString_ = server; |
|---|
| | 82 | name_ = name != "" ? path : server; |
|---|
| | 83 | username_ = username; |
|---|
| | 84 | password_ = password; |
|---|
| | 85 | port_ = port; |
|---|
| | 86 | } |
|---|
| | 87 | |
|---|
| | 88 | char[] name() { |
|---|
| | 89 | return name_; |
|---|
| | 90 | } |
|---|
| | 91 | |
|---|
| | 92 | char[] toString() { |
|---|
| | 93 | return toString_ ~ '/' ~ name_; |
|---|
| | 94 | } |
|---|
| | 95 | |
|---|
| | 96 | VfsFile file(char[] path) { |
|---|
| | 97 | return new FtpFile(toString_ ~ name_, path, username_, password_, port_); |
|---|
| | 98 | } |
|---|
| | 99 | |
|---|
| | 100 | VfsFolderEntry folder(char[] path) { |
|---|
| | 101 | return new FtpFolderEntry(toString_, name_, username_, password_, port_); |
|---|
| | 102 | } |
|---|
| | 103 | |
|---|
| | 104 | VfsFolders self() { |
|---|
| | 105 | return new VfsFolders(toString_, name_, username_, password_, port_, |
|---|
| | 106 | true); |
|---|
| | 107 | } |
|---|
| | 108 | |
|---|
| | 109 | VfsFolders tree() { |
|---|
| | 110 | return new VfsFolders(toString_, name_, username_, password_, port_, |
|---|
| | 111 | false); |
|---|
| | 112 | } |
|---|
| | 113 | |
|---|
| | 114 | int opApply(int delegate(inout VfsFolder) dg) { |
|---|
| | 115 | ftp_ = new FTPConnection(); |
|---|
| | 116 | ftp_.connect(toString_, username_, password_, port_); |
|---|
| | 117 | FtpFileInfo[] fis = ftp_.ls(name_); |
|---|
| | 118 | ftp_.close(); |
|---|
| | 119 | |
|---|
| | 120 | int result; |
|---|
| | 121 | |
|---|
| | 122 | foreach(FtpFileInfo fi; fis) { |
|---|
| | 123 | if(fi.type = FtpFileType.dir) { |
|---|
| | 124 | FtpFolder x = new FtpFolder(toString_, fi.name, username_, |
|---|
| | 125 | password_, port_); |
|---|
| | 126 | if((result = dg(x)) != 0) |
|---|
| 350 | | } |
|---|
| 351 | | if(redo) |
|---|
| 352 | | populateFolders(redo); |
|---|
| 353 | | else |
|---|
| 354 | | _foldersPopulated = true; |
|---|
| 355 | | for(int i = 0; i < _folders.length; i++) |
|---|
| 356 | | { |
|---|
| 357 | | for(int j = 0; j < _folders.length; j++) |
|---|
| 358 | | { |
|---|
| 359 | | if(_folders[i] == _folders[j]) |
|---|
| 360 | | { |
|---|
| 361 | | FtpFolder[] temp = _folders.dup; |
|---|
| 362 | | _folders[0..j] = temp[0..j].dup; |
|---|
| 363 | | _folders[j..$] = temp[j..$].dup; |
|---|
| 364 | | } |
|---|
| 365 | | } |
|---|
| 366 | | } |
|---|
| 367 | | } |
|---|
| 368 | | |
|---|
| 369 | | /*********************************************************************** |
|---|
| 370 | | |
|---|
| 371 | | Return the number of files |
|---|
| 372 | | |
|---|
| 373 | | ***********************************************************************/ |
|---|
| 374 | | |
|---|
| 375 | | uint files() |
|---|
| 376 | | { |
|---|
| 377 | | FtpFileInfo[] inf; |
|---|
| 378 | | foreach(FtpFolder fol; _folders) |
|---|
| 379 | | { |
|---|
| 380 | | inf ~= fol._ftp.ls(); |
|---|
| 381 | | } |
|---|
| 382 | | uint to_return = 0; |
|---|
| 383 | | foreach(FtpFileInfo info; inf) |
|---|
| 384 | | { |
|---|
| 385 | | if(info.type == FtpFileType.file || info.type == FtpFileType.other || info.type == FtpFileType.unknown) |
|---|
| 386 | | { |
|---|
| 387 | | to_return++; |
|---|
| 388 | | } |
|---|
| 389 | | } |
|---|
| 390 | | return to_return; |
|---|
| 391 | | } |
|---|
| 392 | | |
|---|
| 393 | | /*********************************************************************** |
|---|
| 394 | | |
|---|
| 395 | | Return the number of folders |
|---|
| 396 | | |
|---|
| 397 | | ***********************************************************************/ |
|---|
| 398 | | |
|---|
| 399 | | uint folders() |
|---|
| 400 | | { |
|---|
| 401 | | if(_flat) |
|---|
| 402 | | return 0; |
|---|
| 403 | | else |
|---|
| 404 | | { |
|---|
| 405 | | FtpFileInfo[] inf; |
|---|
| 406 | | foreach(FtpFolder fol; _folders) |
|---|
| 407 | | { |
|---|
| 408 | | inf ~= fol._ftp.ls(); |
|---|
| 409 | | } |
|---|
| 410 | | uint to_return = 0; |
|---|
| 411 | | foreach(FtpFileInfo info; inf) |
|---|
| 412 | | { |
|---|
| 413 | | if(info.type == FtpFileType.cdir || info.type == FtpFileType.dir || info.type == FtpFileType.pdir) |
|---|
| 414 | | { |
|---|
| 415 | | to_return++; |
|---|
| 416 | | } |
|---|
| 417 | | } |
|---|
| 418 | | return to_return; |
|---|
| 419 | | } |
|---|
| 420 | | } |
|---|
| 421 | | |
|---|
| 422 | | /*********************************************************************** |
|---|
| 423 | | |
|---|
| 424 | | Return the total number of entries (files + folders) |
|---|
| 425 | | |
|---|
| 426 | | ***********************************************************************/ |
|---|
| 427 | | |
|---|
| 428 | | uint entries() |
|---|
| 429 | | { |
|---|
| 430 | | return folders + files; |
|---|
| 431 | | } |
|---|
| 432 | | |
|---|
| 433 | | /*********************************************************************** |
|---|
| 434 | | |
|---|
| 435 | | Return the total size of contained files |
|---|
| 436 | | |
|---|
| 437 | | ***********************************************************************/ |
|---|
| 438 | | |
|---|
| 439 | | ulong bytes() |
|---|
| 440 | | { |
|---|
| 441 | | FtpFileInfo[] inf; |
|---|
| 442 | | foreach(FtpFolder fol; _folders) |
|---|
| 443 | | { |
|---|
| 444 | | inf ~= fol._ftp.ls(); |
|---|
| 445 | | } |
|---|
| 446 | | ulong to_return = 0; |
|---|
| 447 | | foreach(FtpFileInfo info; inf) |
|---|
| 448 | | { |
|---|
| 449 | | if(info.type == FtpFileType.file || info.type == FtpFileType.other || info.type == FtpFileType.unknown) |
|---|
| 450 | | { |
|---|
| 451 | | to_return += info.size; |
|---|
| 452 | | } |
|---|
| 453 | | } |
|---|
| 454 | | return to_return; |
|---|
| 455 | | } |
|---|
| 456 | | |
|---|
| 457 | | /*********************************************************************** |
|---|
| 458 | | |
|---|
| 459 | | Return a subset of folders matching the given pattern |
|---|
| 460 | | |
|---|
| 461 | | ***********************************************************************/ |
|---|
| 462 | | |
|---|
| 463 | | VfsFolders subset (char[] pattern) |
|---|
| 464 | | { |
|---|
| 465 | | if(_flat) |
|---|
| 466 | | return null; |
|---|
| 467 | | else |
|---|
| 468 | | { |
|---|
| 469 | | FtpFolder[] folders = null; |
|---|
| 470 | | foreach(FtpFolder folder; _folders) |
|---|
| 471 | | { |
|---|
| 472 | | if(containsPattern(folder.name, pattern) || containsPattern(folder.toString, pattern)) |
|---|
| 473 | | folders ~= folder; |
|---|
| 474 | | } |
|---|
| 475 | | return new FtpFolders(folders); |
|---|
| 476 | | } |
|---|
| 477 | | } |
|---|
| 478 | | |
|---|
| 479 | | /*********************************************************************** |
|---|
| 480 | | |
|---|
| 481 | | Return a set of files matching the given pattern |
|---|
| 482 | | |
|---|
| 483 | | ***********************************************************************/ |
|---|
| 484 | | |
|---|
| 485 | | VfsFiles catalog (char[] pattern) |
|---|
| 486 | | { |
|---|
| 487 | | VfsFiles files = new FtpFiles(this); |
|---|
| 488 | | VfsFile[] toCreateNewVfsFilesInstance; |
|---|
| 489 | | foreach(VfsFile file; files) |
|---|
| 490 | | { |
|---|
| 491 | | if(containsPattern(file.name, pattern) || containsPattern(file.toString, pattern)) |
|---|
| 492 | | toCreateNewVfsFilesInstance ~= file; |
|---|
| 493 | | } |
|---|
| 494 | | return new FtpFiles(cast(FtpFile[]) toCreateNewVfsFilesInstance); |
|---|
| 495 | | } |
|---|
| 496 | | |
|---|
| 497 | | /*********************************************************************** |
|---|
| 498 | | |
|---|
| 499 | | Return a set of files matching the given filter |
|---|
| 500 | | |
|---|
| 501 | | ***********************************************************************/ |
|---|
| 502 | | |
|---|
| 503 | | VfsFiles catalog (VfsFilter filter = null) |
|---|
| 504 | | { |
|---|
| 505 | | if(filter == null) |
|---|
| 506 | | { |
|---|
| 507 | | return catalog(""); |
|---|
| 508 | | } |
|---|
| 509 | | else |
|---|
| 510 | | { |
|---|
| 511 | | FtpFiles files = new FtpFiles(this); |
|---|
| 512 | | VfsFile[] toCreateNewVfsFilesInstance; |
|---|
| 513 | | foreach(VfsFile file; files) |
|---|
| 514 | | { |
|---|
| 515 | | FtpFile f = cast(FtpFile) file; |
|---|
| 516 | | if(filter(&f._filt)) |
|---|
| 517 | | toCreateNewVfsFilesInstance ~= file; |
|---|
| 518 | | } |
|---|
| 519 | | return new FtpFiles(cast(FtpFile[])toCreateNewVfsFilesInstance); |
|---|
| 520 | | } |
|---|
| 521 | | } |
|---|
| 522 | | } |
|---|
| 523 | | |
|---|
| 524 | | /******************************************************************************* |
|---|
| 525 | | |
|---|
| 526 | | A specific file representation |
|---|
| 527 | | |
|---|
| 528 | | *******************************************************************************/ |
|---|
| 529 | | |
|---|
| 530 | | class FtpFile : VfsFile |
|---|
| 531 | | { |
|---|
| 532 | | /*********************************************************************** |
|---|
| 533 | | |
|---|
| 534 | | Return a short name |
|---|
| 535 | | |
|---|
| 536 | | ***********************************************************************/ |
|---|
| 537 | | |
|---|
| 538 | | FtpFolder _folder; |
|---|
| 539 | | char[] _toString; |
|---|
| 540 | | char[] _name; |
|---|
| 541 | | VfsFilterInfo _filt; |
|---|
| 542 | | |
|---|
| 543 | | package this(FtpFolder fol, char[] path) |
|---|
| 544 | | { |
|---|
| 545 | | _name ='/' ~ path; |
|---|
| 546 | | _toString = fol.toString ~ path; |
|---|
| 547 | | //_folder = new FtpFolder(fol); |
|---|
| 548 | | _folder = fol; |
|---|
| 549 | | _filt.name = _name; |
|---|
| 550 | | _filt.path = _toString; |
|---|
| 551 | | _filt.folder = false; |
|---|
| 552 | | try |
|---|
| 553 | | { |
|---|
| 554 | | _filt.bytes = _folder._ftp.getFileInfo(path).size; |
|---|
| 555 | | } |
|---|
| 556 | | catch(Exception e) |
|---|
| 557 | | { |
|---|
| 558 | | _filt.bytes = 0; |
|---|
| 559 | | } |
|---|
| 560 | | } |
|---|
| 561 | | |
|---|
| 562 | | public this(VfsFolder fol, char[] path) |
|---|
| 563 | | { |
|---|
| 564 | | this(cast(FtpFolder) fol, path); |
|---|
| 565 | | } |
|---|
| 566 | | |
|---|
| 567 | | char[] name() |
|---|
| 568 | | { |
|---|
| 569 | | return _name; |
|---|
| 570 | | } |
|---|
| 571 | | |
|---|
| 572 | | /*********************************************************************** |
|---|
| 573 | | |
|---|
| 574 | | Return a long name |
|---|
| 575 | | |
|---|
| 576 | | ***********************************************************************/ |
|---|
| 577 | | |
|---|
| 578 | | char[] toString() |
|---|
| 579 | | { |
|---|
| 580 | | return _toString; |
|---|
| 581 | | } |
|---|
| 582 | | |
|---|
| 583 | | /*********************************************************************** |
|---|
| 584 | | |
|---|
| 585 | | Does this file exist? |
|---|
| 586 | | |
|---|
| 587 | | ***********************************************************************/ |
|---|
| 588 | | |
|---|
| 589 | | bool exists() |
|---|
| 590 | | { |
|---|
| 591 | | if(((_folder._ftp.exist(_name) || _folder._ftp.exist(_toString)) == 0) || ((_folder._ftp.exist(_name) || _folder._ftp.exist(_toString)) == 2)) |
|---|
| 592 | | return false; |
|---|
| 593 | | else |
|---|
| 594 | | return true; |
|---|
| 595 | | } |
|---|
| 596 | | |
|---|
| 597 | | /*********************************************************************** |
|---|
| 598 | | |
|---|
| 599 | | Return the file size |
|---|
| 600 | | |
|---|
| 601 | | ***********************************************************************/ |
|---|
| 602 | | |
|---|
| 603 | | ulong size () |
|---|
| 604 | | { |
|---|
| 605 | | return _filt.bytes; |
|---|
| 606 | | } |
|---|
| 607 | | |
|---|
| 608 | | /*********************************************************************** |
|---|
| 609 | | |
|---|
| 610 | | Create and copy the given source |
|---|
| 611 | | |
|---|
| 612 | | ***********************************************************************/ |
|---|
| 613 | | |
|---|
| 614 | | VfsFile copy (VfsFile source) |
|---|
| 615 | | { |
|---|
| 616 | | InputStream istream = source.input; |
|---|
| 617 | | this.create(); |
|---|
| 618 | | OutputStream os = this.output; |
|---|
| 619 | | void[] dest; |
|---|
| 620 | | istream.read(dest); |
|---|
| 621 | | os.write(dest); |
|---|
| 622 | | return new FtpFile(_folder, _toString); |
|---|
| 623 | | } |
|---|
| 624 | | |
|---|
| 625 | | /*********************************************************************** |
|---|
| 626 | | |
|---|
| 627 | | Create and copy the given source, and remove the source |
|---|
| 628 | | |
|---|
| 629 | | ***********************************************************************/ |
|---|
| 630 | | |
|---|
| 631 | | VfsFile move (VfsFile source) |
|---|
| 632 | | { |
|---|
| 633 | | copy(source); |
|---|
| 634 | | source.remove(); |
|---|
| 635 | | return new FtpFile(_folder, _toString); |
|---|
| 636 | | } |
|---|
| 637 | | |
|---|
| 638 | | /*********************************************************************** |
|---|
| 639 | | |
|---|
| 640 | | Create a new file instance |
|---|
| 641 | | |
|---|
| 642 | | ***********************************************************************/ |
|---|
| 643 | | |
|---|
| 644 | | VfsFile create () |
|---|
| 645 | | { |
|---|
| 646 | | _folder._ftp.del(this.toString); |
|---|
| 647 | | FileConduit.Style style; |
|---|
| 648 | | style.access = FileConduit.Access.ReadWrite; |
|---|
| 649 | | style.cache = FileConduit.Cache.None; |
|---|
| 650 | | style.open = FileConduit.Open.Create; |
|---|
| 651 | | style.share = FileConduit.Share.None; |
|---|
| 652 | | FilePath mfp = new FilePath(""); |
|---|
| 653 | | mfp.set(mfp.root ~ "//NF"); |
|---|
| 654 | | FileConduit fs = new FileConduit(mfp, style); |
|---|
| 655 | | byte[] src; |
|---|
| 656 | | src ~= cast(byte)1; |
|---|
| 657 | | src ~= cast(byte)1; |
|---|
| 658 | | fs.write(src); |
|---|
| 659 | | return create(fs); |
|---|
| 660 | | } |
|---|
| 661 | | |
|---|
| 662 | | /*********************************************************************** |
|---|
| 663 | | |
|---|
| 664 | | Create a new file instance and populate with stream |
|---|
| 665 | | |
|---|
| 666 | | ***********************************************************************/ |
|---|
| 667 | | |
|---|
| 668 | | VfsFile create (InputStream stream) |
|---|
| 669 | | { |
|---|
| 670 | | _folder._ftp.del(this.toString); |
|---|
| 671 | | _folder._ftp.put(this.toString, stream, null, FtpFormat.image); |
|---|
| 672 | | return new FtpFile(this._folder, this.toString); |
|---|
| 673 | | } |
|---|
| 674 | | |
|---|
| 675 | | /*********************************************************************** |
|---|
| 676 | | |
|---|
| 677 | | Remove this file |
|---|
| 678 | | |
|---|
| 679 | | ***********************************************************************/ |
|---|
| 680 | | |
|---|
| 681 | | VfsFile remove () |
|---|
| 682 | | { |
|---|
| 683 | | _folder._ftp.del(this.toString); |
|---|
| 684 | | return new FtpFile(this._folder, this.toString); |
|---|
| 685 | | } |
|---|
| 686 | | |
|---|
| 687 | | /*********************************************************************** |
|---|
| 688 | | |
|---|
| 689 | | Return the input stream. Don't forget to close it |
|---|
| 690 | | |
|---|
| 691 | | ***********************************************************************/ |
|---|
| 692 | | |
|---|
| 693 | | InputStream input () |
|---|
| 694 | | { |
|---|
| 695 | | InputStream istream = _folder._ftp.input; |
|---|
| 696 | | prepareInputStream(_folder._ftp, istream, FtpCommand.RETR, ["", _toString]); |
|---|
| 697 | | return istream; |
|---|
| 698 | | } |
|---|
| 699 | | |
|---|
| 700 | | /*********************************************************************** |
|---|
| 701 | | |
|---|
| 702 | | Return the output stream. Don't forget to close it |
|---|
| 703 | | |
|---|
| 704 | | ***********************************************************************/ |
|---|
| 705 | | |
|---|
| 706 | | OutputStream output () |
|---|
| 707 | | { |
|---|
| 708 | | OutputStream os = _folder._ftp.output; |
|---|
| 709 | | prepareOutputStream(_folder._ftp, os, FtpCommand.STOR, ["", _toString]); |
|---|
| 710 | | return os; |
|---|
| 711 | | } |
|---|
| 712 | | |
|---|
| 713 | | /*********************************************************************** |
|---|
| 714 | | |
|---|
| 715 | | Returns a copy of this instance; |
|---|
| 716 | | Does not copy file. |
|---|
| 717 | | |
|---|
| 718 | | ***********************************************************************/ |
|---|
| 719 | | |
|---|
| 720 | | VfsFile dup () |
|---|
| 721 | | { |
|---|
| 722 | | return new FtpFile(_folder, toString); |
|---|
| 723 | | } |
|---|
| 724 | | } |
|---|
| 725 | | |
|---|
| 726 | | /******************************************************************************* |
|---|
| 727 | | |
|---|
| 728 | | Operations upon a set of files |
|---|
| 729 | | |
|---|
| 730 | | *******************************************************************************/ |
|---|
| 731 | | |
|---|
| 732 | | class FtpFiles : VfsFiles |
|---|
| 733 | | { |
|---|
| 734 | | FtpFile[] _files; |
|---|
| 735 | | FtpFolder[] _folders; |
|---|
| 736 | | /*********************************************************************** |
|---|
| 737 | | |
|---|
| 738 | | Iterate over the set of contained VfsFile instances |
|---|
| 739 | | |
|---|
| 740 | | ***********************************************************************/ |
|---|
| 741 | | |
|---|
| 742 | | package this(FtpFolders folders) |
|---|
| 743 | | { |
|---|
| 744 | | foreach(folder; folders) |
|---|
| 745 | | { |
|---|
| 746 | | _folders ~= cast(FtpFolder)folder; |
|---|
| 747 | | } |
|---|
| 748 | | populateFiles(); |
|---|
| 749 | | } |
|---|
| 750 | | |
|---|
| 751 | | public this(char[] server, char[] path = "", char[] username = "anonymous", char[] password = "anonymous@anonymous", uint port = 21) |
|---|
| 752 | | in |
|---|
| 753 | | { |
|---|
| 754 | | assert((server != null || server != "")); |
|---|
| 755 | | } |
|---|
| 756 | | body |
|---|
| 757 | | { |
|---|
| 758 | | _folders ~= new FtpFolder(server, path, username, password, port); |
|---|
| 759 | | } |
|---|
| 760 | | |
|---|
| 761 | | private void populateFiles() |
|---|
| 762 | | { |
|---|
| 763 | | foreach(FtpFolder folder; _folders) |
|---|
| 764 | | { |
|---|
| 765 | | foreach(VfsFolder fol; folder) |
|---|
| 766 | | { |
|---|
| 767 | | FtpFolder cfol = cast(FtpFolder) fol; |
|---|
| 768 | | FtpFileInfo[] fis = cfol._ftp.ls(); |
|---|
| 769 | | foreach(FtpFileInfo fi; fis) |
|---|
| 770 | | { |
|---|
| 771 | | if(fi.type == FtpFileType.file || fi.type == FtpFileType.other || fi.type == FtpFileType.unknown) |
|---|
| 772 | | { |
|---|
| 773 | | _files ~= new FtpFile(cfol, fi.name); |
|---|
| 774 | | } |
|---|
| 775 | | } |
|---|
| 776 | | } |
|---|
| 777 | | } |
|---|
| 778 | | } |
|---|
| 779 | | |
|---|
| 780 | | package this(FtpFile[] files) |
|---|
| 781 | | { |
|---|
| 782 | | _files = files; |
|---|
| 783 | | } |
|---|
| 784 | | |
|---|
| 785 | | public this(VfsFolders folders) |
|---|
| 786 | | { |
|---|
| 787 | | this(cast(FtpFolders) folders); |
|---|
| 788 | | } |
|---|
| 789 | | |
|---|
| 790 | | public this(VfsFile[] files) |
|---|
| 791 | | { |
|---|
| 792 | | this(cast(FtpFile[]) files); |
|---|
| 793 | | } |
|---|
| 794 | | |
|---|
| 795 | | int opApply (int delegate(inout VfsFile) dg) |
|---|
| 796 | | { |
|---|
| 797 | | int result; |
|---|
| 798 | | |
|---|
| 799 | | foreach(file; _files) |
|---|
| 800 | | { |
|---|
| 801 | | VfsFile x = file; |
|---|
| 802 | | if ((result = dg(x)) != 0) |
|---|
| 803 | | break; |
|---|
| 804 | | } |
|---|
| 805 | | |
|---|
| 806 | | return result; |
|---|
| 807 | | } |
|---|
| 808 | | |
|---|
| 809 | | /*********************************************************************** |
|---|
| 810 | | |
|---|
| 811 | | Return the total number of entries |
|---|
| 812 | | |
|---|
| 813 | | ***********************************************************************/ |
|---|
| 814 | | |
|---|
| 815 | | uint files() |
|---|
| 816 | | { |
|---|
| 817 | | return _files.length; |
|---|
| 818 | | } |
|---|
| 819 | | |
|---|
| 820 | | /*********************************************************************** |
|---|
| 821 | | |
|---|
| 822 | | Return the total size of all files |
|---|
| 823 | | |
|---|
| 824 | | ***********************************************************************/ |
|---|
| 825 | | |
|---|
| 826 | | ulong bytes() |
|---|
| 827 | | { |
|---|
| 828 | | ulong to_return; |
|---|
| 829 | | foreach(file; this) |
|---|
| 830 | | { |
|---|
| 831 | | to_return += file.size; |
|---|
| 832 | | } |
|---|
| 833 | | return to_return; |
|---|
| 834 | | } |
|---|
| 835 | | } |
|---|
| 836 | | |
|---|
| 837 | | /******************************************************************************* |
|---|
| 838 | | |
|---|
| 839 | | Handler for folder operations. Needs some work ... |
|---|
| 840 | | |
|---|
| 841 | | *******************************************************************************/ |
|---|
| 842 | | |
|---|
| 843 | | class FtpFolderEntry : VfsFolderEntry |
|---|
| 844 | | { |
|---|
| 845 | | FtpFolder _folder; |
|---|
| 846 | | /*********************************************************************** |
|---|
| 847 | | |
|---|
| 848 | | Open a folder |
|---|
| 849 | | |
|---|
| 850 | | ***********************************************************************/ |
|---|
| 851 | | |
|---|
| 852 | | package this(FtpFolder fol, char[] path) |
|---|
| 853 | | { |
|---|
| 854 | | //_folder = new FtpFolder(fol); |
|---|
| 855 | | _folder = fol; |
|---|
| 856 | | } |
|---|
| 857 | | |
|---|
| 858 | | public this(VfsFolder fol) |
|---|
| 859 | | { |
|---|
| 860 | | this(cast(FtpFolder) fol, ""); |
|---|
| 861 | | } |
|---|
| 862 | | |
|---|
| 863 | | public this(char[] server, char[] path = "", char[] username = "anonymous", char[] password = "anonymous@anonymous", uint port = 21) |
|---|
| 864 | | in |
|---|
| 865 | | { |
|---|
| 866 | | assert((server != null || server != "")); |
|---|
| 867 | | } |
|---|
| 868 | | body |
|---|
| 869 | | { |
|---|
| 870 | | _folder = new FtpFolder(server, path, username, password, port); |
|---|
| 871 | | } |
|---|
| 872 | | |
|---|
| 873 | | VfsFolder open () |
|---|
| 874 | | { |
|---|
| 875 | | //return new FtpFolder(_folder); |
|---|
| 876 | | _folder.open(); |
|---|
| 877 | | return _folder; |
|---|
| 878 | | } |
|---|
| 879 | | |
|---|
| 880 | | /*********************************************************************** |
|---|
| 881 | | |
|---|
| 882 | | Create a new folder |
|---|
| 883 | | |
|---|
| 884 | | ***********************************************************************/ |
|---|
| 885 | | |
|---|
| 886 | | VfsFolder create () |
|---|
| 887 | | { |
|---|
| 888 | | _folder._ftp.mkdir(_folder.toString); |
|---|
| 889 | | return _folder; |
|---|
| 890 | | } |
|---|
| 891 | | |
|---|
| 892 | | /*********************************************************************** |
|---|
| 893 | | |
|---|
| 894 | | Test to see if a folder exists |
|---|
| 895 | | |
|---|
| 896 | | ***********************************************************************/ |
|---|
| 897 | | |
|---|
| 898 | | bool exists () |
|---|
| 899 | | { |
|---|
| 900 | | if(2 == _folder._ftp.exist(_folder.toString)) |
|---|
| 901 | | return true; |
|---|
| 902 | | else |
|---|
| 903 | | return false; |
|---|
| 904 | | } |
|---|
| 905 | | } |
|---|
| 906 | | |
|---|
| | 155 | } else { |
|---|
| | 156 | writeable_ = false; |
|---|
| | 157 | } |
|---|
| | 158 | writeableSet_ = true; |
|---|
| | 159 | ftp_.close(); |
|---|
| | 160 | return writeable_; |
|---|
| | 161 | } |
|---|
| | 162 | |
|---|
| | 163 | VfsFolder close(bool commit = true) { |
|---|
| | 164 | ftp_.close(); |
|---|
| | 165 | return new FtpFolder(toString_, name_, username_, password_, port_); |
|---|
| | 166 | } |
|---|
| | 167 | |
|---|
| | 168 | void verify(VfsFolder folder, bool mounting) { |
|---|
| | 169 | return null; |
|---|
| | 170 | } |
|---|
| | 171 | } |
|---|
| | 172 | |
|---|
| | 173 | class FtpFolders: VfsFolders { |
|---|
| | 174 | |
|---|
| | 175 | FTPConnection ftp_; |
|---|
| | 176 | char[] toString_, name_, username_, password_; |
|---|
| | 177 | uint port_; |
|---|
| | 178 | |
|---|
| | 179 | public this(char[] server, char[] path, char[] username = "anonymous", |
|---|
| | 180 | char[] password = "anonymous@anonymous", uint port = 21) |
|---|
| | 181 | in { |
|---|
| | 182 | assert(server != ""); |
|---|
| | 183 | } |
|---|
| | 184 | out { |
|---|
| | 185 | assert(server != ""); |
|---|
| | 186 | } |
|---|
| | 187 | body { |
|---|
| | 188 | toString_ = server; |
|---|
| | 189 | name_ = name != "" ? path : server; |
|---|
| | 190 | username_ = username; |
|---|
| | 191 | password_ = password; |
|---|
| | 192 | port_ = port; |
|---|
| | 193 | } |
|---|
| | 194 | |
|---|
| | 195 | int opApply(int delegate(inout VfsFolder) dg) { |
|---|
| | 196 | FtpFolder ftp = new FtpFolder(toString_, name_, username, password_, |
|---|
| | 197 | port_); |
|---|
| | 198 | ftp.opApply(dg); |
|---|
| | 199 | } |
|---|
| | 200 | |
|---|
| | 201 | uint files() { |
|---|
| | 202 | ftp_ = new FTPConnection(); |
|---|
| | 203 | ftp_.connect(toString_, username_, password_, port_); |
|---|
| | 204 | FtpFileInfo[] fis = ftp_.ls(); |
|---|
| | 205 | ftp_.close(); |
|---|
| | 206 | uint size; |
|---|
| | 207 | |
|---|
| | 208 | foreach(FtpFileInfo fi; fis) { |
|---|
| | 209 | if(fi.type == FtpFileType.unknown || fi.type == FTPFileType.file || fi.type == FtpFileType.other) |
|---|
| | 210 | size++; |
|---|
| | 211 | } |
|---|
| | 212 | |
|---|
| | 213 | return size; |
|---|
| | 214 | } |
|---|
| | 215 | |
|---|
| | 216 | uint folders() { |
|---|
| | 217 | ftp_ = new FTPConnection(); |
|---|
| | 218 | ftp_.connect(toString_, username_, password_, port_); |
|---|
| | 219 | FtpFileInfo[] fis = ftp_.ls(); |
|---|
| | 220 | ftp_.close(); |
|---|
| | 221 | uint size; |
|---|
| | 222 | |
|---|
| | 223 | foreach(FtpFileInfo fi; fis) { |
|---|
| | 224 | if(fi.type != FtpFileType.unknown || fi.type != FTPFileType.file || fi.type != FtpFileType.other) |
|---|
| | 225 | size++; |
|---|
| | 226 | } |
|---|
| | 227 | |
|---|
| | 228 | return size; |
|---|
| | 229 | } |
|---|
| | 230 | |
|---|
| | 231 | uint entries() { |
|---|
| | 232 | return files + folders; |
|---|
| | 233 | } |
|---|
| | 234 | |
|---|
| | 235 | ulong bytes() { |
|---|
| | 236 | ftp_ = new FTPConnection(); |
|---|
| | 237 | ftp_.connect(toString_, username_, password_, port_); |
|---|
| | 238 | FtpFileInfo[] fis = ftp_.ls(); |
|---|
| | 239 | ftp_.close(); |
|---|
| | 240 | uint size; |
|---|
| | 241 | |
|---|
| | 242 | foreach(FtpFileInfo fi; fis) { |
|---|
| | 243 | if(fi.type == FtpFileType.unknown || fi.type == FTPFileType.file || fi.type == FtpFileType.other) |
|---|
| | 244 | size += fi.size; |
|---|
| | 245 | } |
|---|
| | 246 | |
|---|
| | 247 | return size; |
|---|
| | 248 | } |
|---|
| | 249 | |
|---|
| | 250 | VfsFiles catalog(char[] pattern) { |
|---|
| | 251 | return null; |
|---|
| | 252 | } |
|---|
| | 253 | |
|---|
| | 254 | VfsFiles catalog(VfsFilter filter = null) { |
|---|
| | 255 | return null; |
|---|
| | 256 | } |
|---|
| | 257 | } |
|---|
| | 258 | |
|---|
| | 259 | class FtpFile: VfsFile { |
|---|
| | 260 | char[] name() { |
|---|
| | 261 | return null; |
|---|
| | 262 | } |
|---|
| | 263 | |
|---|
| | 264 | char[] toString() { |
|---|
| | 265 | return null; |
|---|
| | 266 | } |
|---|
| | 267 | |
|---|
| | 268 | bool exists() { |
|---|
| | 269 | return null; |
|---|
| | 270 | } |
|---|
| | 271 | |
|---|
| | 272 | ulong size() { |
|---|
| | 273 | return null; |
|---|
| | 274 | } |
|---|
| | 275 | |
|---|
| | 276 | VfsFile copy(VfsFile source) { |
|---|
| | 277 | return null; |
|---|
| | 278 | } |
|---|
| | 279 | |
|---|
| | 280 | VfsFile move(VfsFile source) { |
|---|
| | 281 | return null; |
|---|
| | 282 | } |
|---|
| | 283 | |
|---|
| | 284 | VfsFile create() { |
|---|
| | 285 | return null; |
|---|
| | 286 | } |
|---|
| | 287 | |
|---|
| | 288 | VfsFile create(InputStream stream) { |
|---|
| | 289 | return null; |
|---|
| | 290 | } |
|---|
| | 291 | |
|---|
| | 292 | VfsFile remove() { |
|---|
| | 293 | return null; |
|---|
| | 294 | } |
|---|
| | 295 | |
|---|
| | 296 | InputStream input() { |
|---|
| | 297 | &nb |
|---|