Changeset 86973 in vbox
- Timestamp:
- Nov 25, 2020 9:18:33 AM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 141515
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/ftp.h
r85121 r86973 54 54 55 55 /** Maximum length (in characters) a command can have (without parameters). */ 56 #define RTFTPSERVER_MAX_CMD_LEN 6456 #define RTFTPSERVER_MAX_CMD_LEN 8 57 57 58 58 /** -
trunk/src/VBox/Runtime/r3/ftp-server.cpp
r85676 r86973 326 326 327 327 /** Function pointer declaration for a specific FTP server command handler. */ 328 typedef DECLCALLBACKTYPE(int, FNRTFTPSERVERCMD,(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *ap cszArgs));328 typedef DECLCALLBACKTYPE(int, FNRTFTPSERVERCMD,(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apszArgs)); 329 329 /** Pointer to a FNRTFTPSERVERCMD(). */ 330 330 typedef FNRTFTPSERVERCMD *PFNRTFTPSERVERCMD; … … 337 337 static int rtFtpServerDataConnClose(PRTFTPSERVERDATACONN pDataConn); 338 338 static void rtFtpServerDataConnReset(PRTFTPSERVERDATACONN pDataConn); 339 static int rtFtpServerDataConnStart(PRTFTPSERVERDATACONN pDataConn, PFNRTTHREAD pfnThread, uint8_t cArgs, const char * const *ap cszArgs);339 static int rtFtpServerDataConnStart(PRTFTPSERVERDATACONN pDataConn, PFNRTTHREAD pfnThread, uint8_t cArgs, const char * const *apszArgs); 340 340 static int rtFtpServerDataConnStop(PRTFTPSERVERDATACONN pDataConn); 341 341 static void rtFtpServerDataConnDestroy(PRTFTPSERVERDATACONN pDataConn); … … 375 375 /** Command ID. */ 376 376 RTFTPSERVERCMD enmCmd; 377 /** Command represented as ASCII string. 378 * @todo r=bird: It's a waste to use 64 byte here when all supported commands 379 * are 3 or 4 chars + terminator. For (64-bit) alignment reasons, */ 377 /** Command represented as ASCII string. */ 380 378 char szCmd[RTFTPSERVER_MAX_CMD_LEN]; 381 379 /** Whether the commands needs a logged in (valid) user. */ … … 466 464 * @param pClient Client to reply to. 467 465 * @param enmReply Reply code to send. 468 * @param p cszFormatFormat string of message to send with the reply code.466 * @param pszFormat Format string of message to send with the reply code. 469 467 */ 470 468 static int rtFtpServerSendReplyRcEx(PRTFTPSERVERCLIENT pClient, RTFTPSERVER_REPLY enmReply, 471 const char *p cszFormat, ...)469 const char *pszFormat, ...) 472 470 { 473 471 char *pszMsg = NULL; 474 472 475 473 va_list args; 476 va_start(args, p cszFormat);474 va_start(args, pszFormat); 477 475 char *pszFmt = NULL; 478 const int cch = RTStrAPrintfV(&pszFmt, p cszFormat, args);476 const int cch = RTStrAPrintfV(&pszFmt, pszFormat, args); 479 477 va_end(args); 480 478 AssertReturn(cch > 0, VERR_NO_MEMORY); … … 512 510 * @returns VBox status code. 513 511 * @param pClient Client to reply to. 514 * @param p cszFormatFormat to reply.512 * @param pszFormat Format to reply. 515 513 * @param ... Format arguments. 516 514 */ 517 static int rtFtpServerSendReplyStr(PRTFTPSERVERCLIENT pClient, const char *p cszFormat, ...)515 static int rtFtpServerSendReplyStr(PRTFTPSERVERCLIENT pClient, const char *pszFormat, ...) 518 516 { 519 517 va_list args; 520 va_start(args, p cszFormat);518 va_start(args, pszFormat); 521 519 char *psz = NULL; 522 const int cch = RTStrAPrintfV(&psz, p cszFormat, args);520 const int cch = RTStrAPrintfV(&psz, pszFormat, args); 523 521 va_end(args); 524 522 AssertReturn(cch > 0, VERR_NO_MEMORY); … … 540 538 * 541 539 * @returns \c true if path is valid, or \c false if not. 542 * @param p cszPathPath to check.540 * @param pszPath Path to check. 543 541 * @param fIsAbsolute Whether the path to check is an absolute path or not. 544 542 */ 545 static bool rtFtpServerPathIsValid(const char *p cszPath, bool fIsAbsolute)546 { 547 if (!p cszPath)543 static bool rtFtpServerPathIsValid(const char *pszPath, bool fIsAbsolute) 544 { 545 if (!pszPath) 548 546 return false; 549 547 550 bool fIsValid = strlen(p cszPath)551 && RTStrIsValidEncoding(p cszPath)552 && RTStrStr(p cszPath, "..") == NULL; /** @todo Very crude for now -- improve this. */548 bool fIsValid = strlen(pszPath) 549 && RTStrIsValidEncoding(pszPath) 550 && RTStrStr(pszPath, "..") == NULL; /** @todo Very crude for now -- improve this. */ 553 551 if ( fIsValid 554 552 && fIsAbsolute) 555 553 { 556 554 RTFSOBJINFO objInfo; 557 int rc2 = RTPathQueryInfo(p cszPath, &objInfo, RTFSOBJATTRADD_NOTHING);555 int rc2 = RTPathQueryInfo(pszPath, &objInfo, RTFSOBJATTRADD_NOTHING); 558 556 if (RT_SUCCESS(rc2)) 559 557 { … … 567 565 } 568 566 569 LogFlowFunc(("p cszPath=%s -> %RTbool\n", pcszPath, fIsValid));567 LogFlowFunc(("pszPath=%s -> %RTbool\n", pszPath, fIsValid)); 570 568 return fIsValid; 571 569 } … … 576 574 * @returns VBox status code. 577 575 * @param pState Client state to set current working directory for. 578 * @param p cszPathWorking directory to set.579 */ 580 static int rtFtpSetCWD(PRTFTPSERVERCLIENTSTATE pState, const char *p cszPath)576 * @param pszPath Working directory to set. 577 */ 578 static int rtFtpSetCWD(PRTFTPSERVERCLIENTSTATE pState, const char *pszPath) 581 579 { 582 580 RTStrFree(pState->pszCWD); 583 581 584 if (!rtFtpServerPathIsValid(p cszPath, false /* fIsAbsolute */))582 if (!rtFtpServerPathIsValid(pszPath, false /* fIsAbsolute */)) 585 583 return VERR_INVALID_PARAMETER; 586 584 587 pState->pszCWD = RTStrDup(p cszPath);585 pState->pszCWD = RTStrDup(pszPath); 588 586 589 587 LogFlowFunc(("Current CWD is now '%s'\n", pState->pszCWD)); … … 599 597 * @returns VBox status code, or VERR_NOT_FOUND if user has not been found. 600 598 * @param pClient Client to look up user for. 601 * @param p cszUserUser name to look up.602 */ 603 static int rtFtpServerLookupUser(PRTFTPSERVERCLIENT pClient, const char *p cszUser)604 { 605 RTFTPSERVER_HANDLE_CALLBACK_VA_RET(pfnOnUserConnect, p cszUser);599 * @param pszUser User name to look up. 600 */ 601 static int rtFtpServerLookupUser(PRTFTPSERVERCLIENT pClient, const char *pszUser) 602 { 603 RTFTPSERVER_HANDLE_CALLBACK_VA_RET(pfnOnUserConnect, pszUser); 606 604 } 607 605 … … 611 609 * @returns VBox status code, or VERR_ACCESS_DENIED if authentication failed. 612 610 * @param pClient Client to authenticate. 613 * @param p cszUserUser name to authenticate with.614 * @param p cszPasswordPassword to authenticate with.615 */ 616 static int rtFtpServerAuthenticate(PRTFTPSERVERCLIENT pClient, const char *p cszUser, const char *pcszPassword)617 { 618 RTFTPSERVER_HANDLE_CALLBACK_VA_RET(pfnOnUserAuthenticate, p cszUser, pcszPassword);611 * @param pszUser User name to authenticate with. 612 * @param pszPassword Password to authenticate with. 613 */ 614 static int rtFtpServerAuthenticate(PRTFTPSERVERCLIENT pClient, const char *pszUser, const char *pszPassword) 615 { 616 RTFTPSERVER_HANDLE_CALLBACK_VA_RET(pfnOnUserAuthenticate, pszUser, pszPassword); 619 617 } 620 618 … … 713 711 * 714 712 * @returns VBox status code. 715 * @param p cszStrString to parse.713 * @param pszStr String to parse. 716 714 * @param pAddr Where to store the IPv4 address on success. 717 715 * @param puPort Where to store the port number on success. 718 716 */ 719 static int rtFtpParseHostAndPort(const char *p cszStr, PRTNETADDRIPV4 pAddr, uint16_t *puPort)720 { 721 AssertPtrReturn(p cszStr, VERR_INVALID_POINTER);717 static int rtFtpParseHostAndPort(const char *pszStr, PRTNETADDRIPV4 pAddr, uint16_t *puPort) 718 { 719 AssertPtrReturn(pszStr, VERR_INVALID_POINTER); 722 720 AssertPtrReturn(pAddr, VERR_INVALID_POINTER); 723 721 AssertPtrReturn(puPort, VERR_INVALID_POINTER); … … 728 726 /* Parse IP (v4). */ 729 727 /** @todo I don't think IPv6 ever will be a thing here, or will it? */ 730 rc = RTStrToUInt8Ex(p cszStr, &pszNext, 10, &pAddr->au8[0]);728 rc = RTStrToUInt8Ex(pszStr, &pszNext, 10, &pAddr->au8[0]); 731 729 if (rc != VINF_SUCCESS && rc != VWRN_TRAILING_CHARS) 732 730 return VERR_INVALID_PARAMETER; … … 774 772 * @returns Duplicated argument vector or NULL if failed or no arguments given. Needs to be free'd with rtFtpCmdArgsFree(). 775 773 * @param cArgs Number of arguments in argument vector. 776 * @param ap cszArgsPointer to argument vector to duplicate.777 */ 778 static char** rtFtpCmdArgsDup(uint8_t cArgs, const char * const *ap cszArgs)774 * @param apszArgs Pointer to argument vector to duplicate. 775 */ 776 static char** rtFtpCmdArgsDup(uint8_t cArgs, const char * const *apszArgs) 779 777 { 780 778 if (!cArgs) 781 779 return NULL; 782 780 783 char **ap cszArgsDup = (char **)RTMemAlloc(cArgs * sizeof(char *));784 if (!ap cszArgsDup)781 char **apszArgsDup = (char **)RTMemAlloc(cArgs * sizeof(char *)); 782 if (!apszArgsDup) 785 783 { 786 784 AssertFailed(); … … 793 791 for (i = 0; i < cArgs; i++) 794 792 { 795 ap cszArgsDup[i] = RTStrDup(apcszArgs[i]);796 if (!ap cszArgsDup[i])793 apszArgsDup[i] = RTStrDup(apszArgs[i]); 794 if (!apszArgsDup[i]) 797 795 rc2 = VERR_NO_MEMORY; 798 796 } … … 801 799 { 802 800 while (i--) 803 RTStrFree(ap cszArgsDup[i]);804 805 RTMemFree(ap cszArgsDup);801 RTStrFree(apszArgsDup[i]); 802 803 RTMemFree(apszArgsDup); 806 804 return NULL; 807 805 } 808 806 809 return ap cszArgsDup;807 return apszArgsDup; 810 808 } 811 809 … … 814 812 * 815 813 * @param cArgs Number of arguments in argument vector. 816 * @param pap cszArgsPointer to argument vector to free.817 */ 818 static void rtFtpCmdArgsFree(uint8_t cArgs, char **pap cszArgs)814 * @param papszArgs Pointer to argument vector to free. 815 */ 816 static void rtFtpCmdArgsFree(uint8_t cArgs, char **papszArgs) 819 817 { 820 818 while (cArgs--) 821 RTStrFree(pap cszArgs[cArgs]);822 823 RTMemFree(pap cszArgs);819 RTStrFree(papszArgs[cArgs]); 820 821 RTMemFree(papszArgs); 824 822 } 825 823 … … 1001 999 * @returns VBox status code. 1002 1000 * @param pDataConn Data connection to write to. 1003 * @param p cszFormatFormat string to send. No (terminal) termination added.1004 */ 1005 static int rtFtpServerDataConnPrintf(PRTFTPSERVERDATACONN pDataConn, const char *p cszFormat, ...)1001 * @param pszFormat Format string to send. No (terminal) termination added. 1002 */ 1003 static int rtFtpServerDataConnPrintf(PRTFTPSERVERDATACONN pDataConn, const char *pszFormat, ...) 1006 1004 { 1007 1005 va_list args; 1008 va_start(args, p cszFormat);1006 va_start(args, pszFormat); 1009 1007 char *pszFmt = NULL; 1010 const int cch = RTStrAPrintfV(&pszFmt, p cszFormat, args);1008 const int cch = RTStrAPrintfV(&pszFmt, pszFormat, args); 1011 1009 va_end(args); 1012 1010 AssertReturn(cch > 0, VERR_NO_MEMORY); … … 1057 1055 1058 1056 AssertPtr(pDataConn->papszArgs); 1059 const char *p cszFile = pDataConn->papszArgs[0];1060 AssertPtr(p cszFile);1057 const char *pszFile = pDataConn->papszArgs[0]; 1058 AssertPtr(pszFile); 1061 1059 1062 1060 void *pvHandle = NULL; /* Opaque handle known to the actual implementation. */ 1063 1061 1064 RTFTPSERVER_HANDLE_CALLBACK_VA(pfnOnFileOpen, p cszFile,1062 RTFTPSERVER_HANDLE_CALLBACK_VA(pfnOnFileOpen, pszFile, 1065 1063 RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, &pvHandle); 1066 1064 if (RT_SUCCESS(rc)) … … 1142 1140 * @param pfnThread Thread function for the data connection to use. 1143 1141 * @param cArgs Number of arguments. 1144 * @param ap cszArgsArray of arguments.1142 * @param apszArgs Array of arguments. 1145 1143 */ 1146 1144 static int rtFtpServerDataConnStart(PRTFTPSERVERDATACONN pDataConn, PFNRTTHREAD pfnThread, 1147 uint8_t cArgs, const char * const *ap cszArgs)1145 uint8_t cArgs, const char * const *apszArgs) 1148 1146 { 1149 1147 AssertPtrReturn(pDataConn, VERR_INVALID_POINTER); … … 1158 1156 if (cArgs) 1159 1157 { 1160 pDataConn->papszArgs = rtFtpCmdArgsDup(cArgs, ap cszArgs);1158 pDataConn->papszArgs = rtFtpCmdArgsDup(cArgs, apszArgs); 1161 1159 if (!pDataConn->papszArgs) 1162 1160 rc = VERR_NO_MEMORY; … … 1279 1277 *********************************************************************************************************************************/ 1280 1278 1281 static DECLCALLBACK(int) rtFtpServerHandleABOR(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *ap cszArgs)1282 { 1283 RT_NOREF(cArgs, ap cszArgs);1279 static DECLCALLBACK(int) rtFtpServerHandleABOR(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apszArgs) 1280 { 1281 RT_NOREF(cArgs, apszArgs); 1284 1282 1285 1283 int rc = rtFtpServerDataConnClose(pClient->pDataConn); … … 1295 1293 } 1296 1294 1297 static DECLCALLBACK(int) rtFtpServerHandleCDUP(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *ap cszArgs)1298 { 1299 RT_NOREF(cArgs, ap cszArgs);1295 static DECLCALLBACK(int) rtFtpServerHandleCDUP(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apszArgs) 1296 { 1297 RT_NOREF(cArgs, apszArgs); 1300 1298 1301 1299 int rc; … … 1331 1329 } 1332 1330 1333 static DECLCALLBACK(int) rtFtpServerHandleCWD(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *ap cszArgs)1331 static DECLCALLBACK(int) rtFtpServerHandleCWD(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apszArgs) 1334 1332 { 1335 1333 if (cArgs != 1) … … 1338 1336 int rc; 1339 1337 1340 const char *p cszPath = apcszArgs[0];1341 1342 if (!rtFtpServerPathIsValid(p cszPath, false /* fIsAbsolute */))1338 const char *pszPath = apszArgs[0]; 1339 1340 if (!rtFtpServerPathIsValid(pszPath, false /* fIsAbsolute */)) 1343 1341 return VERR_INVALID_PARAMETER; 1344 1342 1345 RTFTPSERVER_HANDLE_CALLBACK_VA(pfnOnPathSetCurrent, p cszPath);1343 RTFTPSERVER_HANDLE_CALLBACK_VA(pfnOnPathSetCurrent, pszPath); 1346 1344 1347 1345 if (RT_SUCCESS(rc)) 1348 rc = rtFtpSetCWD(&pClient->State, p cszPath);1346 rc = rtFtpSetCWD(&pClient->State, pszPath); 1349 1347 1350 1348 return rtFtpServerSendReplyRc(pClient, … … 1353 1351 } 1354 1352 1355 static DECLCALLBACK(int) rtFtpServerHandleFEAT(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *ap cszArgs)1356 { 1357 RT_NOREF(cArgs, ap cszArgs);1353 static DECLCALLBACK(int) rtFtpServerHandleFEAT(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apszArgs) 1354 { 1355 RT_NOREF(cArgs, apszArgs); 1358 1356 1359 1357 int rc = rtFtpServerSendReplyStr(pClient, "211-BEGIN Features:"); … … 1871 1869 } 1872 1870 1873 static DECLCALLBACK(int) rtFtpServerHandleLIST(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *ap cszArgs)1871 static DECLCALLBACK(int) rtFtpServerHandleLIST(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apszArgs) 1874 1872 { 1875 1873 /* If no argument is given, use the server's CWD as the path. */ 1876 const char *p cszPath = cArgs ? apcszArgs[0] : pClient->State.pszCWD;1877 AssertPtr(p cszPath);1874 const char *pszPath = cArgs ? apszArgs[0] : pClient->State.pszCWD; 1875 AssertPtr(pszPath); 1878 1876 1879 1877 int rc = VINF_SUCCESS; 1880 1878 1881 if (!rtFtpServerPathIsValid(p cszPath, false /* fIsAbsolute */))1879 if (!rtFtpServerPathIsValid(pszPath, false /* fIsAbsolute */)) 1882 1880 { 1883 1881 int rc2 = rtFtpServerSendReplyRc(pClient, RTFTPSERVER_REPLY_CONN_REQ_FILE_ACTION_NOT_TAKEN); … … 1886 1884 else 1887 1885 { 1888 RTFTPSERVER_HANDLE_CALLBACK_VA(pfnOnFileStat, p cszPath, NULL /* PRTFSOBJINFO */);1886 RTFTPSERVER_HANDLE_CALLBACK_VA(pfnOnFileStat, pszPath, NULL /* PRTFSOBJINFO */); 1889 1887 1890 1888 if (RT_SUCCESS(rc)) … … 1894 1892 rc = rtFtpServerDataConnCreate(pClient, &pClient->pDataConn); 1895 1893 if (RT_SUCCESS(rc)) 1896 rc = rtFtpServerDataConnStart(pClient->pDataConn, rtFtpServerDataConnListThread, cArgs, ap cszArgs);1894 rc = rtFtpServerDataConnStart(pClient->pDataConn, rtFtpServerDataConnListThread, cArgs, apszArgs); 1897 1895 1898 1896 int rc2 = rtFtpServerSendReplyRc( pClient, RT_SUCCESS(rc) … … 1917 1915 } 1918 1916 1919 static DECLCALLBACK(int) rtFtpServerHandleMODE(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *ap cszArgs)1920 { 1921 RT_NOREF(pClient, cArgs, ap cszArgs);1917 static DECLCALLBACK(int) rtFtpServerHandleMODE(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apszArgs) 1918 { 1919 RT_NOREF(pClient, cArgs, apszArgs); 1922 1920 1923 1921 /** @todo Anything to do here? */ … … 1925 1923 } 1926 1924 1927 static DECLCALLBACK(int) rtFtpServerHandleNOOP(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *ap cszArgs)1928 { 1929 RT_NOREF(cArgs, ap cszArgs);1925 static DECLCALLBACK(int) rtFtpServerHandleNOOP(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apszArgs) 1926 { 1927 RT_NOREF(cArgs, apszArgs); 1930 1928 1931 1929 /* Save timestamp of last command sent. */ … … 1935 1933 } 1936 1934 1937 static DECLCALLBACK(int) rtFtpServerHandlePASS(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *ap cszArgs)1935 static DECLCALLBACK(int) rtFtpServerHandlePASS(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apszArgs) 1938 1936 { 1939 1937 if (cArgs != 1) 1940 1938 return rtFtpServerSendReplyRc(pClient, RTFTPSERVER_REPLY_ERROR_INVALID_PARAMETERS); 1941 1939 1942 const char *p cszPassword = apcszArgs[0];1943 AssertPtrReturn(p cszPassword, VERR_INVALID_PARAMETER);1944 1945 int rc = rtFtpServerAuthenticate(pClient, pClient->State.pszUser, p cszPassword);1940 const char *pszPassword = apszArgs[0]; 1941 AssertPtrReturn(pszPassword, VERR_INVALID_PARAMETER); 1942 1943 int rc = rtFtpServerAuthenticate(pClient, pClient->State.pszUser, pszPassword); 1946 1944 if (RT_SUCCESS(rc)) 1947 1945 { … … 1960 1958 } 1961 1959 1962 static DECLCALLBACK(int) rtFtpServerHandlePORT(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *ap cszArgs)1960 static DECLCALLBACK(int) rtFtpServerHandlePORT(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apszArgs) 1963 1961 { 1964 1962 if (cArgs != 1) … … 1967 1965 RTFTPSERVER_REPLY rcClient; 1968 1966 1969 int rc = rtFtpParseHostAndPort(ap cszArgs[0], &pClient->DataConnAddr, &pClient->uDataConnPort);1967 int rc = rtFtpParseHostAndPort(apszArgs[0], &pClient->DataConnAddr, &pClient->uDataConnPort); 1970 1968 if (RT_SUCCESS(rc)) 1971 1969 rcClient = RTFTPSERVER_REPLY_OKAY; … … 1980 1978 } 1981 1979 1982 static DECLCALLBACK(int) rtFtpServerHandlePWD(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *ap cszArgs)1983 { 1984 RT_NOREF(cArgs, ap cszArgs);1980 static DECLCALLBACK(int) rtFtpServerHandlePWD(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apszArgs) 1981 { 1982 RT_NOREF(cArgs, apszArgs); 1985 1983 1986 1984 int rc; … … 1996 1994 } 1997 1995 1998 static DECLCALLBACK(int) rtFtpServerHandleOPTS(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *ap cszArgs)1999 { 2000 RT_NOREF(cArgs, ap cszArgs);1996 static DECLCALLBACK(int) rtFtpServerHandleOPTS(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apszArgs) 1997 { 1998 RT_NOREF(cArgs, apszArgs); 2001 1999 2002 2000 int rc = VINF_SUCCESS; … … 2009 2007 } 2010 2008 2011 static DECLCALLBACK(int) rtFtpServerHandleQUIT(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *ap cszArgs)2012 { 2013 RT_NOREF(cArgs, ap cszArgs);2009 static DECLCALLBACK(int) rtFtpServerHandleQUIT(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apszArgs) 2010 { 2011 RT_NOREF(cArgs, apszArgs); 2014 2012 2015 2013 int rc = VINF_SUCCESS; … … 2032 2030 } 2033 2031 2034 static DECLCALLBACK(int) rtFtpServerHandleRETR(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *ap cszArgs)2032 static DECLCALLBACK(int) rtFtpServerHandleRETR(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apszArgs) 2035 2033 { 2036 2034 if (cArgs != 1) /* File name needs to be present. */ … … 2039 2037 int rc; 2040 2038 2041 const char *p cszPath = apcszArgs[0];2042 2043 RTFTPSERVER_HANDLE_CALLBACK_VA(pfnOnFileStat, p cszPath, NULL /* PRTFSOBJINFO */);2039 const char *pszPath = apszArgs[0]; 2040 2041 RTFTPSERVER_HANDLE_CALLBACK_VA(pfnOnFileStat, pszPath, NULL /* PRTFSOBJINFO */); 2044 2042 2045 2043 if (RT_SUCCESS(rc)) … … 2051 2049 rc = rtFtpServerDataConnCreate(pClient, &pClient->pDataConn); 2052 2050 if (RT_SUCCESS(rc)) 2053 rc = rtFtpServerDataConnStart(pClient->pDataConn, rtFtpServerDataConnFileWriteThread, cArgs, ap cszArgs);2051 rc = rtFtpServerDataConnStart(pClient->pDataConn, rtFtpServerDataConnFileWriteThread, cArgs, apszArgs); 2054 2052 2055 2053 int rc2 = rtFtpServerSendReplyRc( pClient, RT_SUCCESS(rc) … … 2080 2078 } 2081 2079 2082 static DECLCALLBACK(int) rtFtpServerHandleSIZE(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *ap cszArgs)2080 static DECLCALLBACK(int) rtFtpServerHandleSIZE(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apszArgs) 2083 2081 { 2084 2082 if (cArgs != 1) … … 2087 2085 int rc; 2088 2086 2089 const char *p cszPath = apcszArgs[0];2087 const char *pszPath = apszArgs[0]; 2090 2088 uint64_t uSize = 0; 2091 2089 2092 RTFTPSERVER_HANDLE_CALLBACK_VA(pfnOnFileGetSize, p cszPath, &uSize);2090 RTFTPSERVER_HANDLE_CALLBACK_VA(pfnOnFileGetSize, pszPath, &uSize); 2093 2091 2094 2092 if (RT_SUCCESS(rc)) … … 2105 2103 } 2106 2104 2107 static DECLCALLBACK(int) rtFtpServerHandleSTAT(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *ap cszArgs)2105 static DECLCALLBACK(int) rtFtpServerHandleSTAT(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apszArgs) 2108 2106 { 2109 2107 if (cArgs != 1) … … 2115 2113 RT_ZERO(objInfo); 2116 2114 2117 const char *p cszPath = apcszArgs[0];2118 2119 RTFTPSERVER_HANDLE_CALLBACK_VA(pfnOnFileStat, p cszPath, &objInfo);2115 const char *pszPath = apszArgs[0]; 2116 2117 RTFTPSERVER_HANDLE_CALLBACK_VA(pfnOnFileStat, pszPath, &objInfo); 2120 2118 2121 2119 if (RT_SUCCESS(rc)) … … 2126 2124 { 2127 2125 char szFsPathInfo[RTPATH_MAX + 16]; 2128 const ssize_t cchPathInfo = RTStrPrintf2(szFsPathInfo, sizeof(szFsPathInfo), " %2zu %s\n", strlen(p cszPath), pcszPath);2126 const ssize_t cchPathInfo = RTStrPrintf2(szFsPathInfo, sizeof(szFsPathInfo), " %2zu %s\n", strlen(pszPath), pszPath); 2129 2127 if (cchPathInfo > 0) 2130 2128 { … … 2147 2145 } 2148 2146 2149 static DECLCALLBACK(int) rtFtpServerHandleSTRU(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *ap cszArgs)2147 static DECLCALLBACK(int) rtFtpServerHandleSTRU(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apszArgs) 2150 2148 { 2151 2149 if (cArgs != 1) 2152 2150 return VERR_INVALID_PARAMETER; 2153 2151 2154 const char *p cszType = apcszArgs[0];2152 const char *pszType = apszArgs[0]; 2155 2153 2156 2154 int rc; 2157 2155 2158 if (!RTStrICmp(p cszType, "F"))2156 if (!RTStrICmp(pszType, "F")) 2159 2157 { 2160 2158 pClient->State.enmStructType = RTFTPSERVER_STRUCT_TYPE_FILE; … … 2168 2166 } 2169 2167 2170 static DECLCALLBACK(int) rtFtpServerHandleSYST(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *ap cszArgs)2171 { 2172 RT_NOREF(cArgs, ap cszArgs);2168 static DECLCALLBACK(int) rtFtpServerHandleSYST(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apszArgs) 2169 { 2170 RT_NOREF(cArgs, apszArgs); 2173 2171 2174 2172 char szOSInfo[64]; … … 2180 2178 } 2181 2179 2182 static DECLCALLBACK(int) rtFtpServerHandleTYPE(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *ap cszArgs)2180 static DECLCALLBACK(int) rtFtpServerHandleTYPE(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apszArgs) 2183 2181 { 2184 2182 if (cArgs != 1) 2185 2183 return VERR_INVALID_PARAMETER; 2186 2184 2187 const char *p cszType = apcszArgs[0];2185 const char *pszType = apszArgs[0]; 2188 2186 2189 2187 int rc = VINF_SUCCESS; 2190 2188 2191 if (!RTStrICmp(p cszType, "A"))2189 if (!RTStrICmp(pszType, "A")) 2192 2190 { 2193 2191 pClient->State.enmDataType = RTFTPSERVER_DATA_TYPE_ASCII; 2194 2192 } 2195 else if (!RTStrICmp(p cszType, "I")) /* Image (binary). */2193 else if (!RTStrICmp(pszType, "I")) /* Image (binary). */ 2196 2194 { 2197 2195 pClient->State.enmDataType = RTFTPSERVER_DATA_TYPE_IMAGE; … … 2206 2204 } 2207 2205 2208 static DECLCALLBACK(int) rtFtpServerHandleUSER(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *ap cszArgs)2206 static DECLCALLBACK(int) rtFtpServerHandleUSER(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apszArgs) 2209 2207 { 2210 2208 if (cArgs != 1) 2211 2209 return VERR_INVALID_PARAMETER; 2212 2210 2213 const char *p cszUser = apcszArgs[0];2214 AssertPtrReturn(p cszUser, VERR_INVALID_PARAMETER);2211 const char *pszUser = apszArgs[0]; 2212 AssertPtrReturn(pszUser, VERR_INVALID_PARAMETER); 2215 2213 2216 2214 rtFtpServerClientStateReset(&pClient->State); 2217 2215 2218 int rc = rtFtpServerLookupUser(pClient, p cszUser);2216 int rc = rtFtpServerLookupUser(pClient, pszUser); 2219 2217 if (RT_SUCCESS(rc)) 2220 2218 { 2221 pClient->State.pszUser = RTStrDup(p cszUser);2219 pClient->State.pszUser = RTStrDup(pszUser); 2222 2220 AssertPtrReturn(pClient->State.pszUser, VERR_NO_MEMORY); 2223 2221 … … 2245 2243 * 2246 2244 * @returns VBox status code. 2247 * @param p cszCmdParmsPointer to command arguments, if any. Can be NULL if no arguments are given.2245 * @param pszCmdParms Pointer to command arguments, if any. Can be NULL if no arguments are given. 2248 2246 * @param pcArgs Returns the number of parsed arguments, separated by a space (hex 0x20). 2249 * @param ppap cszArgsReturns the string array of parsed arguments. Needs to be free'd with rtFtpServerCmdArgsFree().2250 */ 2251 static int rtFtpServerCmdArgsParse(const char *p cszCmdParms, uint8_t *pcArgs, char ***ppapcszArgs)2247 * @param ppapszArgs Returns the string array of parsed arguments. Needs to be free'd with rtFtpServerCmdArgsFree(). 2248 */ 2249 static int rtFtpServerCmdArgsParse(const char *pszCmdParms, uint8_t *pcArgs, char ***ppapszArgs) 2252 2250 { 2253 2251 *pcArgs = 0; 2254 *ppap cszArgs = NULL;2255 2256 if (!p cszCmdParms) /* No parms given? Bail out early. */2252 *ppapszArgs = NULL; 2253 2254 if (!pszCmdParms) /* No parms given? Bail out early. */ 2257 2255 return VINF_SUCCESS; 2258 2256 … … 2261 2259 2262 2260 int cArgs = 0; 2263 int rc = RTGetOptArgvFromString(ppap cszArgs, &cArgs, pcszCmdParms, RTGETOPTARGV_CNV_QUOTE_MS_CRT, " " /* Separators */);2261 int rc = RTGetOptArgvFromString(ppapszArgs, &cArgs, pszCmdParms, RTGETOPTARGV_CNV_QUOTE_MS_CRT, " " /* Separators */); 2264 2262 if (RT_SUCCESS(rc)) 2265 2263 { … … 2278 2276 * Frees a formerly argument string array parsed by rtFtpServerCmdArgsParse(). 2279 2277 * 2280 * @param ppap cszArgsArgument string array to free.2281 */ 2282 static void rtFtpServerCmdArgsFree(char **ppap cszArgs)2283 { 2284 RTGetOptArgvFree(ppap cszArgs);2278 * @param ppapszArgs Argument string array to free. 2279 */ 2280 static void rtFtpServerCmdArgsFree(char **ppapszArgs) 2281 { 2282 RTGetOptArgvFree(ppapszArgs); 2285 2283 } 2286 2284 … … 2290 2288 * @returns VBox status code. 2291 2289 * @param pClient Client to process commands for. 2292 * @param p cszCmdCommand string to parse and handle.2290 * @param pszCmd Command string to parse and handle. 2293 2291 * @param cbCmd Size (in bytes) of command string. 2294 2292 */ 2295 static int rtFtpServerProcessCommands(PRTFTPSERVERCLIENT pClient, char *pcszCmd, size_t cbCmd) 2296 { 2297 /** @todo r=bird: pcszCmd is a misnomer, it is _clearly_ not const as you 2298 * modify it all over the place! Please do _not_use 'c' to mean 'const', it 2299 * means 'count of'. */ 2293 static int rtFtpServerProcessCommands(PRTFTPSERVERCLIENT pClient, char *pszCmd, size_t cbCmd) 2294 { 2300 2295 /* Make sure to terminate the string in any case. */ 2301 p cszCmd[RT_MIN(RTFTPSERVER_MAX_CMD_LEN, cbCmd)] = '\0';2296 pszCmd[RT_MIN(RTFTPSERVER_MAX_CMD_LEN, cbCmd)] = '\0'; 2302 2297 2303 2298 /* A tiny bit of sanitation. */ 2304 RTStrStripL(p cszCmd);2299 RTStrStripL(pszCmd); 2305 2300 2306 2301 /* First, terminate string by finding the command end marker (telnet style). */ 2307 2302 /** @todo Not sure if this is entirely correct and/or needs tweaking; good enough for now as it seems. */ 2308 /** @todo r=bird: Why are you using the case-insensitive version here? */ 2309 char *pszCmdEnd = RTStrIStr(pcszCmd, "\r\n"); 2303 char *pszCmdEnd = RTStrStr(pszCmd, "\r\n"); 2310 2304 if (pszCmdEnd) 2311 2305 *pszCmdEnd = '\0'; … … 2318 2312 uint8_t cArgs = 0; 2319 2313 char **papszArgs = NULL; 2320 int rc = rtFtpServerCmdArgsParse(p cszCmd, &cArgs, &papszArgs);2314 int rc = rtFtpServerCmdArgsParse(pszCmd, &cArgs, &papszArgs); 2321 2315 if ( RT_SUCCESS(rc) 2322 2316 && cArgs) /* At least the actual command (without args) must be present. */ … … 2415 2409 * (even in C++ code, see init() methods in the API). 2416 2410 */ 2417 static int rtFtpServer ProcessCommands(PRTFTPSERVERCLIENT pClient)2411 static int rtFtpServerClientMain(PRTFTPSERVERCLIENT pClient) 2418 2412 { 2419 2413 int rc; … … 2527 2521 ASMAtomicIncU32(&pThis->cClients); 2528 2522 2529 rc = rtFtpServer ProcessCommands(&Client);2523 rc = rtFtpServerClientMain(&Client); 2530 2524 2531 2525 ASMAtomicDecU32(&pThis->cClients); … … 2537 2531 } 2538 2532 2539 RTR3DECL(int) RTFtpServerCreate(PRTFTPSERVER phFTPServer, const char *p cszAddress, uint16_t uPort,2533 RTR3DECL(int) RTFtpServerCreate(PRTFTPSERVER phFTPServer, const char *pszAddress, uint16_t uPort, 2540 2534 PRTFTPSERVERCALLBACKS pCallbacks, void *pvUser, size_t cbUser) 2541 2535 { 2542 2536 AssertPtrReturn(phFTPServer, VERR_INVALID_POINTER); 2543 AssertPtrReturn(p cszAddress, VERR_INVALID_POINTER);2537 AssertPtrReturn(pszAddress, VERR_INVALID_POINTER); 2544 2538 AssertReturn (uPort, VERR_INVALID_PARAMETER); 2545 2539 AssertPtrReturn(pCallbacks, VERR_INVALID_POINTER); … … 2556 2550 pThis->cbUser = cbUser; 2557 2551 2558 rc = RTTcpServerCreate(p cszAddress, uPort, RTTHREADTYPE_DEFAULT, "ftpsrv",2552 rc = RTTcpServerCreate(pszAddress, uPort, RTTHREADTYPE_DEFAULT, "ftpsrv", 2559 2553 rtFtpServerClientThread, pThis /* pvUser */, &pThis->pTCPServer); 2560 2554 if (RT_SUCCESS(rc))
Note:
See TracChangeset
for help on using the changeset viewer.