Spinning Topp Logo BlackTopp Studios
inc
ftpcommand.cpp
1 // © Copyright 2010 - 2016 BlackTopp Studios Inc.
2 /* This file is part of The Mezzanine Engine.
3 
4  The Mezzanine Engine is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  The Mezzanine Engine is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with The Mezzanine Engine. If not, see <http://www.gnu.org/licenses/>.
16 */
17 /* The original authors have included a copy of the license specified above in the
18  'Docs' folder. See 'gpl.txt'
19 */
20 /* We welcome the use of the Mezzanine engine to anyone, including companies who wish to
21  Build professional software and charge for their product.
22 
23  However there are some practical restrictions, so if your project involves
24  any of the following you should contact us and we will try to work something
25  out:
26  - DRM or Copy Protection of any kind(except Copyrights)
27  - Software Patents You Do Not Wish to Freely License
28  - Any Kind of Linking to Non-GPL licensed Works
29  - Are Currently In Violation of Another Copyright Holder's GPL License
30  - If You want to change our code and not add a few hundred MB of stuff to
31  your distribution
32 
33  These and other limitations could cause serious legal problems if you ignore
34  them, so it is best to simply contact us or the Free Software Foundation, if
35  you have any questions.
36 
37  Joseph Toppi - toppij@gmail.com
38  John Blackwood - makoenergy02@gmail.com
39 */
40 
41 #ifndef _networkftpcommand_cpp
42 #define _networkftpcommand_cpp
43 
44 #include "Network/ftpcommand.h"
45 
46 #include "stringtool.h"
47 
48 namespace Mezzanine
49 {
50  namespace Network
51  {
53  CommandType(Network::FCL_Invalid)
54  { }
55 
57  { this->Decompose(Command); }
58 
60  CommandArgs(Args),
61  CommandType(Type)
62  { }
63 
65  { }
66 
67  ///////////////////////////////////////////////////////////////////////////////
68  // Core Operations
69 
71  {
72  StringStream CommandStream;
73  CommandStream << FTPCommand::ConvertCommand(this->CommandType);
74  if( !this->CommandArgs.empty() ) {
75  CommandStream << " " << this->CommandArgs;
76  }
77  CommandStream << "\r\n";
78  return CommandStream.str();
79  }
80 
82  {
83  StringIterator CurrIt = Message.begin();
84  return this->Decompose(CurrIt,Message.end());
85  }
86 
88  {
89  this->CommandArgs.clear();
90  this->CommandType = FCL_Invalid;
91 
92  if( CurrIt != EndIt ) {
93  String Component;
94  while( CurrIt != EndIt && !this->IsEndOfLine(CurrIt) )
95  {
96  if( (*CurrIt) == ' ' ) {
97  ++CurrIt;
98  break;
99  }else{
100  Component.push_back( *CurrIt );
101  ++CurrIt;
102  }
103  }
104  this->CommandType = ConvertCommand(Component);
105  Component.clear();
106 
107  while( CurrIt != EndIt )
108  {
109  if( this->IsEndOfLine(CurrIt) ) {
110  CurrIt += 2;
111  break;
112  }else{
113  Component.push_back( *CurrIt );
114  ++CurrIt;
115  }
116  }
117  this->CommandArgs.assign(Component);
118 
119  return this->IsEndOfLine(CurrIt);
120  }
121  return false;
122  }
123 
124  ///////////////////////////////////////////////////////////////////////////////
125  // Utility
126 
128  {
129  switch( Command )
130  {
131  case FCL_ABOR: return "ABOR";
132  case FCL_ACCT: return "ACCT";
133  case FCL_ADAT: return "ADAT";
134  case FCL_ALLO: return "ALLO";
135  case FCL_APPE: return "APPE";
136  case FCL_AUTH: return "AUTH";
137  case FCL_CCC: return "CCC";
138  case FCL_CDUP: return "CDUP";
139  case FCL_CONF: return "CONF";
140  case FCL_CWD: return "CWD";
141  case FCL_DELE: return "DELE";
142  case FCL_ENC: return "ENC";
143  case FCL_EPRT: return "EPRT";
144  case FCL_EPSV: return "EPSV";
145  case FCL_FEAT: return "FEAT";
146  case FCL_HELP: return "HELP";
147  case FCL_HOST: return "HOST";
148  case FCL_LANG: return "LANG";
149  case FCL_LIST: return "LIST";
150  case FCL_LPRT: return "LPRT";
151  case FCL_LPSV: return "LPSV";
152  case FCL_MDTM: return "MDTM";
153  case FCL_MIC: return "MIC";
154  case FCL_MKD: return "MKD";
155  case FCL_MLSD: return "MLSD";
156  case FCL_MLST: return "MLST";
157  case FCL_MODE: return "MODE";
158  case FCL_NLST: return "NLST";
159  case FCL_NOOP: return "NOOP";
160  case FCL_OPTS: return "OPTS";
161  case FCL_PASS: return "PASS";
162  case FCL_PASV: return "PASV";
163  case FCL_PBSZ: return "PBSZ";
164  case FCL_PORT: return "PORT";
165  case FCL_PROT: return "PROT";
166  case FCL_PWD: return "PWD";
167  case FCL_QUIT: return "QUIT";
168  case FCL_REIN: return "REIN";
169  case FCL_REST: return "REST";
170  case FCL_RETR: return "RETR";
171  case FCL_RMD: return "RMD";
172  case FCL_RNFR: return "RNFR";
173  case FCL_RNTO: return "RNTO";
174  case FCL_SITE: return "SITE";
175  case FCL_SIZE: return "SIZE";
176  case FCL_SMNT: return "SMNT";
177  case FCL_STAT: return "STAT";
178  case FCL_STOR: return "STOR";
179  case FCL_STOU: return "STOU";
180  case FCL_STRU: return "STRU";
181  case FCL_SYST: return "SYST";
182  case FCL_TYPE: return "TYPE";
183  case FCL_USER: return "USER";
184  case FCL_XCUP: return "XCUP";
185  case FCL_XCWD: return "XCWD";
186  case FCL_XMKD: return "XMKD";
187  case FCL_XPWD: return "XPWD";
188  case FCL_XRCP: return "XRCP";
189  case FCL_XRMD: return "XRMD";
190  case FCL_XRSQ: return "XRSQ";
191  case FCL_XSEM: return "XSEM";
192  case FCL_XSEN: return "XSEN";
193  case FCL_Invalid:
194  default: return "";
195  }
196  return "";
197  }
198 
200  {
201  /// @todo This switch-case, while certainly fast, is massive and not pretty. It could be possible to generate a hash for each command and assign the hash
202  /// value to the enum and convert it directly. That could reduce the size of this method to about 5 or less lines of code at the cost of some processing
203  /// speed IF it can be verified there would be no collisions in the hashes. It should be decided later if such a thing would be worthwhile.
204  Whole ComSize = Command.size();
205  if( ComSize == 3 || ComSize == 4 ) {
206  String UpperCommand = Command;
207  StringTools::ToUpperCase(UpperCommand);
208  switch( UpperCommand[0] )
209  {
210  case 'A':
211  {
212  switch( UpperCommand[1] )
213  {
214  case 'B': return FCL_ABOR;
215  case 'C': return FCL_ACCT;
216  case 'D': return FCL_ADAT;
217  case 'L': return FCL_ALLO;
218  case 'P': return FCL_APPE;
219  case 'U': return FCL_AUTH;
220  }
221  }
222  case 'C':
223  {
224  switch( UpperCommand[1] )
225  {
226  case 'C': return FCL_CCC;
227  case 'D': return FCL_CDUP;
228  case 'O': return FCL_CONF;
229  case 'W': return FCL_CWD;
230  }
231  }
232  case 'D': return FCL_DELE;
233  case 'E':
234  {
235  switch( UpperCommand[1] )
236  {
237  case 'N': return FCL_ENC;
238  case 'P':
239  {
240  switch( UpperCommand[2] )
241  {
242  case 'R': return FCL_EPRT;
243  case 'S': return FCL_EPSV;
244  }
245  }
246  }
247  }
248  case 'F': return FCL_FEAT;
249  case 'H':
250  {
251  switch( UpperCommand[1] )
252  {
253  case 'E': return FCL_HELP;
254  case 'O': return FCL_HOST;
255  }
256  }
257  case 'L':
258  {
259  switch( UpperCommand[1] )
260  {
261  case 'A': return FCL_LANG;
262  case 'I': return FCL_LIST;
263  case 'P':
264  {
265  switch( UpperCommand[2] )
266  {
267  case 'R': return FCL_LPRT;
268  case 'S': return FCL_LPSV;
269  }
270  }
271  }
272  }
273  case 'M':
274  {
275  switch( UpperCommand[1] )
276  {
277  case 'D': return FCL_MDTM;
278  case 'I': return FCL_MIC;
279  case 'K': return FCL_MKD;
280  case 'L':
281  {
282  if( UpperCommand.size() > 3 ) {
283  switch( UpperCommand[3] )
284  {
285  case 'D': return FCL_MLSD;
286  case 'T': return FCL_MLST;
287  }
288  }
289  }
290  case 'O': return FCL_MODE;
291  }
292  }
293  case 'N':
294  {
295  switch( UpperCommand[1] )
296  {
297  case 'L': return FCL_NLST;
298  case 'O': return FCL_NOOP;
299  }
300  }
301  case 'O': return FCL_OPTS;
302  case 'P':
303  {
304  switch( UpperCommand[1] )
305  {
306  case 'A':
307  {
308  if( UpperCommand.size() > 3 ) {
309  switch( UpperCommand[3] )
310  {
311  case 'S': return FCL_PASS;
312  case 'V': return FCL_PASV;
313  }
314  }
315  }
316  case 'B': return FCL_PBSZ;
317  case 'O': return FCL_PORT;
318  case 'R': return FCL_PROT;
319  case 'W': return FCL_PWD;
320  }
321  }
322  case 'Q': return FCL_QUIT;
323  case 'R':
324  {
325  switch( UpperCommand[1] )
326  {
327  case 'E':
328  {
329  switch( UpperCommand[2] )
330  {
331  case 'I': return FCL_REIN;
332  case 'S': return FCL_REST;
333  case 'T': return FCL_RETR;
334  }
335  }
336  case 'M': return FCL_RMD;
337  case 'N':
338  {
339  switch( UpperCommand[2] )
340  {
341  case 'F': return FCL_RNFR;
342  case 'T': return FCL_RNTO;
343  }
344  }
345  }
346  }
347  case 'S':
348  {
349  switch( UpperCommand[1] )
350  {
351  case 'I':
352  {
353  switch( UpperCommand[2] )
354  {
355  case 'T': return FCL_SITE;
356  case 'Z': return FCL_SIZE;
357  }
358  }
359  case 'M': return FCL_SMNT;
360  case 'T':
361  {
362  switch( UpperCommand[2] )
363  {
364  case 'A': return FCL_STAT;
365  case 'O':
366  {
367  if( UpperCommand.size() > 3 ) {
368  switch( UpperCommand[3] )
369  {
370  case 'R': return FCL_STOR;
371  case 'U': return FCL_STOU;
372  }
373  }
374  }
375  case 'R': return FCL_STRU;
376  }
377  }
378  case 'Y': return FCL_SYST;
379  }
380  }
381  case 'T': return FCL_TYPE;
382  case 'U': return FCL_USER;
383  case 'X':
384  {
385  switch( UpperCommand[1] )
386  {
387  case 'C':
388  {
389  switch( UpperCommand[2] )
390  {
391  case 'U': return FCL_XCUP;
392  case 'W': return FCL_XCWD;
393  }
394  }
395  case 'M': return FCL_XMKD;
396  case 'P': return FCL_XPWD;
397  case 'R':
398  {
399  switch( UpperCommand[2] )
400  {
401  case 'C': return FCL_XRCP;
402  case 'M': return FCL_XRMD;
403  case 'S': return FCL_XRSQ;
404  }
405  }
406  case 'S':
407  {
408  if( UpperCommand.size() > 3 ) {
409  switch( UpperCommand[3] )
410  {
411  case 'M': return FCL_XSEM;
412  case 'N': return FCL_XSEN;
413  }
414  }
415  }// S case
416  }// Second character switch
417  }// X case
418  }// First character switch
419  }// If we have an appropriate size
420  return FCL_Invalid;
421  }
422 
424  { this->CommandType = Command; }
425 
427  { return this->CommandType; }
428 
430  { this->CommandArgs = Args; }
431 
433  { return this->CommandArgs; }
434  }//Network
435 }//Mezzanine
436 
437 #endif
Transfer Mode. Sets how the data will be transferred from the source to destination. See FTPTransferMode enum.
Status. Requests the current status of the FTP server or the current executing FTP operation on the s...
FTPCommandList CommandType
The command being issued.
Definition: ftpcommand.h:61
User Name. The user name to be used for authentication to the FTP server. In most cases the user name...
Passive. Requests the server go into passive mode for the connection. Going into passive mode tells t...
Data Type. Sets the type of data requested the file be in for downloads or the type of data that the ...
Logout. Logs out of the FTP server and closes all connections. Pending transfers are allowed to finis...
bool Boole
Generally acts a single bit, true or false.
Definition: datatypes.h:173
Data Port. Specifies the IP/Port on which to establish the data connection. Expressed in 6 comma sepa...
Rename To. The new pathname of the file being renamed. This command must be preceded by a RNFR comman...
Print Working Directory. Requests the pathname of the current directory for FTP operations.
static String ConvertCommand(const Network::FTPCommandList Command)
Converts a FTPCommandList enum value to it's text representation.
Definition: ftpcommand.cpp:127
Make Directory. Creates a new directory on the server with the name provided in the argument...
Abort. Aborts the currently active file transfer.
No Operation. This command does nothing and asks the server to do nothing but send a basic response...
Reinitialize. Sets the connection back to a starting state. User is logged out but the command connec...
const String & GetArguments() const
Gets the arguments for the command to be issued.
Definition: ftpcommand.cpp:432
Confidentiality Protected Command. Generic command for allowing the configuration of confidentiality ...
Rename From. The pathname of the file to be renamed. This simple selects the file the operation is to...
Host. Similar to HTTP Host header, allows an FTP client to provide an FTP URI Authority to specify a ...
Delete. Deletes the file specified in the argument.
Integrity Protected Command. Generic command for allowing the configuration of integrity settings on ...
Remove Directory. Deletes the directory (and all files under it) specified in the argument from the s...
Print Working Directory. Obsolete command, but can be used an an alias for PWD to provide backwards c...
Store Unique. This is the same as STOR (Store), but forces the name of the file at the destination to...
Structure Mount. Allows the user to mount a file system data structure without requiring the connecti...
std::stringstream StringStream
A Datatype used for streaming operations with strings.
Definition: datatypes.h:176
File Structure. Specifies the structure being transferred. Will almost never need to be used as the d...
Change Working Directory. Obsolete command, but can be used an an alias for CWD to provide backwards ...
Long Passive. Obsolete command. Similar to the PASV command, but permits larger addresses. Format is identical to the LPRT command.
FTPCommand()
Invalid constructor.
Definition: ftpcommand.cpp:52
Data Channel Protection Level. Sets the security to be used on the data channel. See FTPSecurityLevel...
List. Gets information on the current directory. Either files or directories other than the current o...
File Size. Gets the size of a specified file. Argument is a file and the response will contain the si...
Not an actual command. Used for error conditions.
Name List. Same as the LIST command, but only specifying names so as to make it easier to parse for m...
Extended Passive. This is similar to LPSV, but with friendlier syntax. The format is identical to the...
Options. Enables command specific options for the next command issued. Argument must be the command n...
Clear Command Channel. Clears the command stream of protected status, reverting to plain-text transmi...
Site. Executes a command that is not in the standard specific to the connected server. The argument is the command to be executed.
Change to Parent Directory. Changes the directory for file/folder operations to the parent of the cur...
void SetArguments(const String &Args)
Sets the arguments for the command to be issued.
Definition: ftpcommand.cpp:429
FTPCommandList
This enum is a listing of the commands that can be issued to an FTP server.
Protection BufferSize. Sets the maximum size (in bytes, max of 32-bit UInt) of the encoded blocks to ...
Remove Directory. Obsolete command, but can be used an an alias for RMD to provide backwards compatib...
Restart. The point where the file transfer is to begin. For files, the argument should an integer rep...
Unknown Meaning. Obsolete command, do not use. Listed here for error detection server side...
Retrieve. Downloads a file from the server, expecting a filename at the source as the argument...
Change to Parent Directory. Obsolete command, but can be used an an alias for CDUP to provide backwar...
System. Requests an identifier for the type of system the server is operating on as well as the defau...
Change Working Directory. Changes the current directory for file/folder operations.
Boole Decompose(const String &Message)
Populates the members of this class with data from a text FTP message.
Definition: ftpcommand.cpp:81
Features. Requests a listing of the available features/extensions on the server. No argument needed...
Network::FTPCommandList GetCommand() const
Gets the comment to be sent.
Definition: ftpcommand.cpp:426
Authentication/Security Data. A String of Base64 encoded data necessary to complete the authenticatio...
String::const_iterator StringIterator
Convenience typedef for String iterators.
Definition: ftpmessage.h:58
String Compose() const
Creates a completed message that can be sent across an FTP connection.
Definition: ftpcommand.cpp:70
Account. Identifies the users account. While similar sounding to the USER command, some servers differentiate the two when determining access.
Send to Terminal. Obsolete command, do not use. Listed here for error detection server side...
String CommandArgs
The arguments of the command. Not all commands require this.
Definition: ftpcommand.h:58
The bulk of the engine components go in this namspace.
Definition: actor.cpp:56
unsigned long Whole
Whole is an unsigned integer, it will be at least 32bits in size.
Definition: datatypes.h:151
Allocate. Requests the server allocate space for a file in advance. Many servers don't require this...
Append. Appends the contents of the transfer to an existing file at the destination. If the file does not exist it will be created.
~FTPCommand()
Class destructor.
Definition: ftpcommand.cpp:64
void ToUpperCase(String &Source)
Converts all lower case characters in a string to their respective upper case.
Definition: stringtool.cpp:182
Password. The users password for authentication.
Machine List Directory. Gets a machine friendly listing of all the files in the specified directory...
Authentication/Security Mechanism. Declares the desired means of protection on the FTP connection(s)...
Modification Time. Gets the time a file was last modified. Argument should be a file name...
Long Port. Obsolete command. Similar to the PORT command, but permits larger addresses. The format is comma separated bytes. Starts with an address family, then address size followed by address bytes, then port size followed by port bytes.
Make Directory. Obsolete command, but can be used an an alias for MKD to provide backwards compatibil...
Help. Another command may be specified as an argument to get details on it's implementation status on...
Boole IsEndOfLine(const StringIterator CurrIt) const
Checks to see if a parsing iterator is at a Telnet End-Of-Line.
Definition: ftpmessage.cpp:53
Store. Uploads a file to the server, expecting a filename to be given to the file at the destination ...
Privacy Protected Command. Generic command for allowing the configuration of privacy settings on the ...
Language. Requests the server change it's response message language to a different language...
Unknown Meaning. Obsolete command, do not use. Listed here for error detection server side...
std::string String
A datatype used to a series of characters.
Definition: datatypes.h:159
Send to Mail. Obsolete command, do not use. Listed here for error detection server side...
void SetCommand(const Network::FTPCommandList Command)
Sets the command to be sent.
Definition: ftpcommand.cpp:423
Machine List. Gets a machine friendly listing of information on the specified file. The format is defined in RFC 3659, section 7.2.
Extended Port. This is similar to LPRT, but with friendlier syntax. Takes a "|" delimited String star...