unstick r82781

Revision 82781

Date:
2020/01/16 12:49:33
Author:
vboxsync
Revision Log:
IPRT/FTP: Implemented FEAT and OPTS commands, along with some more protocol tweaking in order to make connecting w/ Nautilus work. bugref:9646
Files:

Legend:

 
Added
 
Removed
 
Modified
  • trunk/src/VBox/Runtime/generic/ftp-server.cpp

     
    132 132 RTFTPSERVER_CMD_PORT,
    133 133 /** Gets the current working directory. */
    134 134 RTFTPSERVER_CMD_PWD,
    135 /** Get options. Needed in conjunction with the FEAT command. */
    136 RTFTPSERVER_CMD_OPTS,
    135 137 /** Terminates the session (connection). */
    136 138 RTFTPSERVER_CMD_QUIT,
    137 139 /** Retrieves a specific file. */
     
    299 301 static FNRTFTPSERVERCMD rtFtpServerHandlePASS;
    300 302 static FNRTFTPSERVERCMD rtFtpServerHandlePORT;
    301 303 static FNRTFTPSERVERCMD rtFtpServerHandlePWD;
    304 static FNRTFTPSERVERCMD rtFtpServerHandleOPTS;
    302 305 static FNRTFTPSERVERCMD rtFtpServerHandleQUIT;
    303 306 static FNRTFTPSERVERCMD rtFtpServerHandleRETR;
    304 307 static FNRTFTPSERVERCMD rtFtpServerHandleSIZE;
     
    333 336 { RTFTPSERVER_CMD_ABOR, "ABOR", true, rtFtpServerHandleABOR },
    334 337 { RTFTPSERVER_CMD_CDUP, "CDUP", true, rtFtpServerHandleCDUP },
    335 338 { RTFTPSERVER_CMD_CWD, "CWD", true, rtFtpServerHandleCWD },
    336 { RTFTPSERVER_CMD_FEAT, "FEAT", true, rtFtpServerHandleFEAT },
    339 { RTFTPSERVER_CMD_FEAT, "FEAT", false, rtFtpServerHandleFEAT },
    337 340 { RTFTPSERVER_CMD_LIST, "LIST", true, rtFtpServerHandleLIST },
    338 341 { RTFTPSERVER_CMD_MODE, "MODE", true, rtFtpServerHandleMODE },
    339 342 { RTFTPSERVER_CMD_NOOP, "NOOP", true, rtFtpServerHandleNOOP },
    340 343 { RTFTPSERVER_CMD_PASS, "PASS", false, rtFtpServerHandlePASS },
    341 344 { RTFTPSERVER_CMD_PORT, "PORT", true, rtFtpServerHandlePORT },
    342 345 { RTFTPSERVER_CMD_PWD, "PWD", true, rtFtpServerHandlePWD },
    346 { RTFTPSERVER_CMD_OPTS, "OPTS", false, rtFtpServerHandleOPTS },
    343 347 { RTFTPSERVER_CMD_QUIT, "QUIT", false, rtFtpServerHandleQUIT },
    344 348 { RTFTPSERVER_CMD_RETR, "RETR", true, rtFtpServerHandleRETR },
    345 349 { RTFTPSERVER_CMD_SIZE, "SIZE", true, rtFtpServerHandleSIZE },
     
    351 355 { RTFTPSERVER_CMD_LAST, "", false, NULL }
    352 356 };
    353 357
    354 /** Feature string which represents all commands we support in addition to RFC 959.
    358 /** Feature string which represents all commands we support in addition to RFC 959 (see RFC 2398).
    355 359 * Must match the command table above.
    356 360 *
    357 * Don't forget the terminating ";" at each feature. */
    361 * Don't forget the beginning space (" ") at each feature. */
    358 362 #define RTFTPSERVER_FEATURES_STRING \
    359 "SIZE;" /* Supports reporting file sizes. */
    363 " SIZE\r\n" \
    364 " UTF8"
    360 365
    361 366
    362 367 /*********************************************************************************************************************************
     
    379 384
    380 385 LogFlowFunc(("Sending reply code %RU32\n", enmReply));
    381 386
    382 return RTTcpWrite(pClient->hSocket, szReply, strlen(szReply) + 1);
    387 return RTTcpWrite(pClient->hSocket, szReply, strlen(szReply));
    383 388 }
    384 389
    385 390 /**
     
    422 427
    423 428 RTStrFree(pszFmt);
    424 429
    425 rc = RTTcpWrite(pClient->hSocket, pszMsg, strlen(pszMsg) + 1 /* Include termination */);
    430 rc = RTTcpWrite(pClient->hSocket, pszMsg, strlen(pszMsg));
    426 431
    427 432 RTStrFree(pszMsg);
    428 433
     
    449 454 int rc = RTStrAAppend(&psz, "\r\n");
    450 455 AssertRCReturn(rc, rc);
    451 456
    452 rc = RTTcpWrite(pClient->hSocket, psz, strlen(psz) + 1 /* Include termination */);
    457 LogFlowFunc(("Sending reply '%s'\n", psz));
    453 458
    459 rc = RTTcpWrite(pClient->hSocket, psz, strlen(psz));
    460
    454 461 RTStrFree(psz);
    455 462
    456 463 return rc;
     
    1054 1061 {
    1055 1062 RT_NOREF(cArgs, apcszArgs);
    1056 1063
    1057 int rc = rtFtpServerSendReplyRc(pClient, RTFTPSERVER_REPLY_SYSTEM_STATUS); /* Features begin */
    1064 int rc = rtFtpServerSendReplyStr(pClient, "211-BEGIN Features:");
    1058 1065 if (RT_SUCCESS(rc))
    1059 1066 {
    1060 1067 rc = rtFtpServerSendReplyStr(pClient, RTFTPSERVER_FEATURES_STRING);
    1061 1068 if (RT_SUCCESS(rc))
    1062 rc = rtFtpServerSendReplyRc(pClient, RTFTPSERVER_REPLY_SYSTEM_STATUS); /* Features end */
    1069 rc = rtFtpServerSendReplyStr(pClient, "211 END Features");
    1063 1070 }
    1064 1071
    1065 1072 return rc;
     
    1245 1252 return rc;
    1246 1253 }
    1247 1254
    1255 static int rtFtpServerHandleOPTS(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apcszArgs)
    1256 {
    1257 RT_NOREF(cArgs, apcszArgs);
    1258
    1259 int rc = VINF_SUCCESS;
    1260
    1261 int rc2 = rtFtpServerSendReplyRc(pClient, RTFTPSERVER_REPLY_OKAY);
    1262 if (RT_SUCCESS(rc))
    1263 rc = rc2;
    1264
    1265 return rc;
    1266 }
    1267
    1248 1268 static int rtFtpServerHandleQUIT(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apcszArgs)
    1249 1269 {
    1250 1270 RT_NOREF(cArgs, apcszArgs);
     
    1393 1413 char szOSInfo[64];
    1394 1414 int rc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, szOSInfo, sizeof(szOSInfo));
    1395 1415 if (RT_SUCCESS(rc))
    1396 rc = rtFtpServerSendReplyStr(pClient, szOSInfo);
    1416 rc = rtFtpServerSendReplyStr(pClient, "215 %s", szOSInfo);
    1397 1417
    1398 1418 return rc;
    1399 1419 }