00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <OPENR/OPENRAPI.h>
00013 #include <OPENR/OSyslog.h>
00014 #include "FtpPI.h"
00015
00016 bool
00017 FtpPI::RequestComplete()
00018 {
00019 char* c = (char*)connection.recvData;
00020
00021 for (int i = 0; i < connection.recvSize - 1; i++) {
00022 if ((c[i] == CR) && (c[i + 1] == LF)) {
00023 c[i] = '\0';
00024 return true;
00025 }
00026 }
00027
00028 return false;
00029 }
00030
00031 bool
00032 FtpPI::CommandParser(char **cmd, char **param)
00033 {
00034 char *cur = (char *)connection.recvData;
00035 *cmd = cur;
00036
00037 while (isalpha(*cur)) {
00038 *cur = toupper(*cur);
00039 cur++;
00040 }
00041
00042 while (*cur == SP) {
00043 *cur = '\0';
00044 cur++;
00045 }
00046
00047 *param = cur;
00048 return true;
00049 }
00050
00051 bool
00052 FtpPI::RequestProcess()
00053 {
00054
00055
00056
00057 char *cmd;
00058 char *param;
00059 CommandParser(&cmd, ¶m);
00060 if (strlen(cmd) >= MAX_STRING_LENGTH) {
00061 cmd[MAX_STRING_LENGTH - 1] = '\0';
00062 }
00063
00064 if (strlen(param) >= MAX_STRING_LENGTH) {
00065 param[MAX_STRING_LENGTH - 1] = '\0';
00066 }
00067
00068 OSYSDEBUG(("FtpPI::RequestProcess() cmd %s : %s\n", cmd, param));
00069
00070
00071 if (!strcmp(cmd, "USER")) {
00072 state = FTP_LOGIN;
00073 ftpDTP.SetUser(param);
00074 Send(FTP_REPLY_NEED_PASSWD, "Password required for %s.", param);
00075 connection.recvSize = 0;
00076 Receive();
00077 } else if (!strcmp(cmd, "PASS")) {
00078 if (state == FTP_LOGIN) {
00079 OList<Passwd, MAX_LOGIN>::Iterator iter = passwd->Begin();
00080 OList<Passwd, MAX_LOGIN>::Iterator last = passwd->End();
00081 while (iter != last) {
00082 if (!strcmp((*iter).user, ftpDTP.GetUser())) {
00083 if (!strcmp((*iter).pass, param) ||
00084 !strcmp((*iter).pass, "*")) {
00085 ftpDTP.SetHome((*iter).home);
00086 state = FTP_GET_REQUEST;
00087 Send(FTP_REPLY_USER_LOGIN, "User %s logged in.",
00088 (*iter).user);
00089 connection.recvSize = 0;
00090 Receive();
00091 } else {
00092 state = FTP_NOT_LOGIN;
00093 Send(FTP_REPLY_NOT_LOGIN, "Login incorrect.");
00094 connection.recvSize = 0;
00095 Receive();
00096 }
00097 break;
00098 }
00099 ++iter;
00100 }
00101
00102 if (iter == last) {
00103 state = FTP_NOT_LOGIN;
00104 Send(FTP_REPLY_NOT_LOGIN, "Login incorrect.");
00105 connection.recvSize = 0;
00106 Receive();
00107 }
00108 } else {
00109 Send(FTP_REPLY_BAD_SEQUENCE, "Login with USER first.");
00110 connection.recvSize = 0;
00111 Receive();
00112 }
00113 } else if (!strcmp(cmd, "TYPE")) {
00114 switch(*param) {
00115 case 'I':
00116 ftpDTP.SetType(FTP_DATA_I);
00117 Send(FTP_REPLY_COMMAND_OK, "TYPE set to %s.", param);
00118 break;
00119
00120 case 'A':
00121 ftpDTP.SetType(FTP_DATA_A);
00122 Send(FTP_REPLY_COMMAND_OK, "TYPE set to %s.", param);
00123 break;
00124
00125 default:
00126 Send(FTP_REPLY_NOT_IMPLEMENT, "TYPE set to %s.", param);
00127 break;
00128 }
00129 connection.recvSize = 0;
00130 Receive();
00131 } else if (!strcmp(cmd, "PORT")) {
00132 if (state == FTP_GET_REQUEST) {
00133 if (ftpDTP.SetPort(param)) {
00134 Send(FTP_REPLY_COMMAND_OK, "PORT command successful.");
00135 connection.recvSize = 0;
00136 Receive();
00137 }
00138 } else {
00139 Send(FTP_REPLY_NOT_LOGIN, "Please login with USER and PASS.");
00140 connection.recvSize = 0;
00141 Receive();
00142 }
00143 } else if (!strcmp(cmd, "PASV")) {
00144 if (state == FTP_GET_REQUEST) {
00145 Port port = ftpDTP.SetIP(ipaddr);
00146 if (port){
00147 Send(FTP_REPLY_ENTER_PASSIVE,
00148 "Entering Passive Mode. %d,%d,%d,%d,%d,%d",
00149 (ipaddr.Address() & 0xff000000) >> 24,
00150 (ipaddr.Address() & 0x00ff0000) >> 16,
00151 (ipaddr.Address() & 0x0000ff00) >> 8,
00152 (ipaddr.Address() & 0x000000ff),
00153 (port & 0xff00) >> 8,
00154 (port & 0x00ff));
00155 connection.recvSize = 0;
00156 Receive();
00157 }else {
00158 Send(FTP_REPLY_NOT_AVAILABLE, "Passive Mode Fail.");
00159 connection.recvSize = 0;
00160 Receive();
00161 }
00162 } else {
00163 Send(FTP_REPLY_NOT_LOGIN, "Please login with USER and PASS.");
00164 connection.recvSize = 0;
00165 Receive();
00166 }
00167 } else if (!strcmp(cmd, "RETR")) {
00168 if (state == FTP_GET_REQUEST) {
00169 if (!ftpDTP.Retrieve(param)) {
00170 Send(FTP_REPLY_NO_FILE, "No such file.");
00171 connection.recvSize = 0;
00172 Receive();
00173 } else {
00174 return true;
00175 }
00176 } else {
00177 Send(FTP_REPLY_NOT_LOGIN, "Please login with USER and PASS.");
00178 connection.recvSize = 0;
00179 Receive();
00180 }
00181 } else if (!strcmp(cmd, "STOR")) {
00182 if (state == FTP_GET_REQUEST) {
00183 if (!ftpDTP.Store(param)) {
00184 Send(FTP_REPLY_NOT_TOKEN, "error.");
00185 connection.recvSize = 0;
00186 Receive();
00187 } else {
00188 return true;
00189 }
00190 } else {
00191 Send(FTP_REPLY_NOT_LOGIN, "Please login with USER and PASS.");
00192 connection.recvSize = 0;
00193 Receive();
00194 }
00195 } else if (!strcmp(cmd, "RNFR")) {
00196 if (state == FTP_GET_REQUEST) {
00197 if (ftpDTP.RenameFrom(param)) {
00198 Send(FTP_REPLY_REQUESTED_FILE,
00199 "File exists, ready for destination name");
00200 connection.recvSize = 0;
00201 Receive();
00202 return true;
00203 } else {
00204 Send(FTP_REPLY_NO_FILE, "%s : No such file or directory",
00205 param);
00206 connection.recvSize = 0;
00207 Receive();
00208 }
00209 } else {
00210 Send(FTP_REPLY_NOT_LOGIN, "Please login with USER and PASS.");
00211 connection.recvSize = 0;
00212 Receive();
00213 }
00214 } else if (!strcmp(cmd, "RNTO")) {
00215 if (state == FTP_GET_REQUEST) {
00216 char *tmp = ftpDTP.GetFilename();
00217 if (*tmp) {
00218 if (ftpDTP.RenameTo(param)) {
00219 Send(FTP_REPLY_FILE_ACTION_OK, "RNTO command successful.");
00220 connection.recvSize = 0;
00221 Receive();
00222 } else {
00223 Send(FTP_REPLY_NO_FILE, "%s : No such file or directory",
00224 param);
00225 connection.recvSize = 0;
00226 Receive();
00227 }
00228 } else {
00229 Send(FTP_REPLY_BAD_SEQUENCE, "Bad sequence of commands.");
00230 connection.recvSize = 0;
00231 Receive();
00232 }
00233 } else {
00234 Send(FTP_REPLY_NOT_LOGIN, "Please login with USER and PASS.");
00235 connection.recvSize = 0;
00236 Receive();
00237 }
00238 } else if (!strcmp(cmd, "LIST")) {
00239 if (state == FTP_GET_REQUEST) {
00240 if (!ftpDTP.List(param)) {
00241 Send(FTP_REPLY_NOT_TAKEN, "Not taken.");
00242 connection.recvSize = 0;
00243 Receive();
00244 } else {
00245 return true;
00246 }
00247 } else {
00248 Send(FTP_REPLY_NOT_LOGIN, "Please login with USER and PASS.");
00249 connection.recvSize = 0;
00250 Receive();
00251 }
00252 } else if (!strcmp(cmd, "NLST")) {
00253 if (state == FTP_GET_REQUEST) {
00254 if (!ftpDTP.List(param)) {
00255 Send(FTP_REPLY_NOT_TAKEN, "Not taken.");
00256 connection.recvSize = 0;
00257 Receive();
00258 } else {
00259 return true;
00260 }
00261 } else {
00262 Send(FTP_REPLY_NOT_LOGIN, "Please login with USER and PASS.");
00263 connection.recvSize = 0;
00264 Receive();
00265 }
00266 } else if (!strcmp(cmd, "CWD")) {
00267 if (state == FTP_GET_REQUEST) {
00268 if (ftpDTP.ChangeDir(param)) {
00269 Send(FTP_REPLY_FILE_ACTION_OK, "CWD command successful.");
00270 connection.recvSize = 0;
00271 Receive();
00272 } else {
00273 Send(FTP_REPLY_NO_FILE, "%s: No such file or directory.",
00274 param);
00275 connection.recvSize = 0;
00276 Receive();
00277 }
00278 } else {
00279 Send(FTP_REPLY_NOT_LOGIN, "Please login with USER and PASS.");
00280 connection.recvSize = 0;
00281 Receive();
00282 }
00283 } else if (!strcmp(cmd, "CDUP")) {
00284 if (state == FTP_GET_REQUEST) {
00285 if (ftpDTP.ChangeDir("../")) {
00286 Send(FTP_REPLY_FILE_ACTION_OK, "CWD command successful.");
00287 connection.recvSize = 0;
00288 Receive();
00289 } else {
00290 Send(FTP_REPLY_NO_FILE, "%s: No such file or directory.",
00291 param);
00292 connection.recvSize = 0;
00293 Receive();
00294 }
00295 } else {
00296 Send(FTP_REPLY_NOT_LOGIN, "Please login with USER and PASS.");
00297 connection.recvSize = 0;
00298 Receive();
00299 }
00300 } else if (!strcmp(cmd, "PWD")) {
00301 if (state == FTP_GET_REQUEST) {
00302 Send(FTP_REPLY_PATH_CREATED, "\"%s\" is current directory.",
00303 ftpDTP.GetDirectry());
00304 connection.recvSize = 0;
00305 Receive();
00306 } else {
00307 Send(FTP_REPLY_NOT_LOGIN, "Please login with USER and PASS.");
00308 connection.recvSize = 0;
00309 Receive();
00310 }
00311 } else if (!strcmp(cmd, "MKD")) {
00312 if (state == FTP_GET_REQUEST) {
00313 if (ftpDTP.MakeDir(param)) {
00314 Send(FTP_REPLY_PATH_CREATED, "MKD command successful.");
00315 connection.recvSize = 0;
00316 Receive();
00317 } else {
00318 Send(FTP_REPLY_NO_FILE, "MKD command Failed.");
00319 connection.recvSize = 0;
00320 Receive();
00321 }
00322 } else {
00323 Send(FTP_REPLY_NOT_LOGIN, "Please login with USER and PASS.");
00324 connection.recvSize = 0;
00325 Receive();
00326 }
00327 } else if (!strcmp(cmd, "RMD")) {
00328 if (state == FTP_GET_REQUEST) {
00329 if (ftpDTP.RemoveDir(param)) {
00330 Send(FTP_REPLY_FILE_ACTION_OK, "RMD command successful.");
00331 connection.recvSize = 0;
00332 Receive();
00333 } else {
00334 Send(FTP_REPLY_NO_FILE, "RMD command Failed.");
00335 connection.recvSize = 0;
00336 Receive();
00337 }
00338 } else {
00339 Send(FTP_REPLY_NOT_LOGIN, "Please login with USER and PASS.");
00340 connection.recvSize = 0;
00341 Receive();
00342 }
00343 } else if (!strcmp(cmd, "DELE")) {
00344 if (state == FTP_GET_REQUEST) {
00345 if (ftpDTP.Delete(param)) {
00346 Send(FTP_REPLY_FILE_ACTION_OK, "DELE command successful.");
00347 connection.recvSize = 0;
00348 Receive();
00349 } else {
00350 Send(FTP_REPLY_NO_FILE, "DELE command Failed.");
00351 connection.recvSize = 0;
00352 Receive();
00353 }
00354 } else {
00355 Send(FTP_REPLY_NOT_LOGIN, "Please login with USER and PASS.");
00356 connection.recvSize = 0;
00357 Receive();
00358 }
00359 } else if (!strcmp(cmd, "REBT")) {
00360 if (state == FTP_GET_REQUEST) {
00361 Send(FTP_REPLY_COMMAND_OK, "REBT command successful.");
00362 Close();
00363 OBootCondition bootCond(obcbBOOT_TIMER, 0, obcbttRELATIVE);
00364 OStatus result = OPENR::Shutdown(bootCond);
00365 if (result != oSUCCESS) {
00366 OSYSLOG1((osyslogWARNING, "System shutdown... failed" ));
00367 return false;
00368 }
00369 } else {
00370 Send(FTP_REPLY_NOT_LOGIN, "Please login with USER and PASS.");
00371 connection.recvSize = 0;
00372 Receive();
00373 }
00374 } else if (!strcmp(cmd, "SYST")) {
00375 sprintf((char *)connection.sendData,
00376 "%03d Aperios system type.\r\n",
00377 FTP_REPLY_SYSTEM_TYPE);
00378 TCPEndpointSendMsg sendMsg(connection.endpoint,
00379 connection.sendData,
00380 strlen((char *)connection.sendData));
00381
00382 sendMsg.continuation = continuation;
00383 sendMsg.Send(ipstackRef,
00384 myOID, Extra_Entry[entrySendContforPI],
00385 sizeof(TCPEndpointSendMsg));
00386 connection.recvSize = 0;
00387 Receive();
00388 } else if (!strcmp(cmd, "HELP")) {
00389 sprintf((char *)connection.sendData,
00390 "%03d-%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n%03d %s\r\n",
00391 FTP_REPLY_HELP_MESSAGE,
00392 "The following commands are recognized:",
00393 " USER PORT RETR MSND* ALLO* DELE SITE* XMKD* CDUP",
00394 " PASS PASV STOR MSOM* REST* CWD STAT* RMD XCUP*",
00395 " ACCT* TYPE APPE* MSAM* RNFR* XCWD* HELP XRMD* STOU*",
00396 " REIN* STRU* MLFL* MRSQ* RNTO* LIST NOOP PWD ",
00397 " QUIT MODE* MAIL* MRCP* ABOR* NLST* MKD XPWD* REBT",
00398 FTP_REPLY_HELP_MESSAGE,
00399 "(*'s => unimplemented)");
00400
00401 TCPEndpointSendMsg sendMsg(connection.endpoint,
00402 connection.sendData,
00403 strlen((char *)connection.sendData));
00404
00405 sendMsg.continuation = continuation;
00406 sendMsg.Send(ipstackRef,
00407 myOID, Extra_Entry[entrySendContforPI],
00408 sizeof(TCPEndpointSendMsg));
00409 connection.recvSize = 0;
00410 Receive();
00411 } else if (!strcmp(cmd, "NOOP")) {
00412 Send(FTP_REPLY_COMMAND_OK, "NOOP command successful.");
00413 Receive();
00414 } else if (!strcmp(cmd, "QUIT")) {
00415 Send(FTP_REPLY_SERVICE_CLOSE,
00416 "Goodbye. Thanks for using the AIBO FTP Server.");
00417 Close();
00418 } else {
00419 Send(FTP_REPLY_UNKNOWN_COMMAND,
00420 "'%s %s': command not understood.", cmd, param);
00421 connection.recvSize = 0;
00422 Receive();
00423 }
00424
00425 ftpDTP.ResetFilename();
00426 return true;
00427 }