VirtualBox

Changeset 82698 in vbox for trunk


Ignore:
Timestamp:
Jan 9, 2020 2:35:24 PM (5 years ago)
Author:
vboxsync
Message:

IPRT/FTP: More protocol handling and callback work. bugref:9437

File:
1 edited

Legend:

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

    r82687 r82698  
    4444#include <iprt/errcore.h>
    4545#include <iprt/ftp.h>
     46#include <iprt/getopt.h>
    4647#include <iprt/mem.h>
    4748#include <iprt/log.h>
     
    157158
    158159/** Function pointer declaration for a specific FTP server command handler. */
    159 typedef DECLCALLBACK(int) FNRTFTPSERVERCMD(PRTFTPSERVERCLIENT pClient);
     160typedef DECLCALLBACK(int) FNRTFTPSERVERCMD(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apcszArgs);
    160161/** Pointer to a FNRTFTPSERVERCMD(). */
    161162typedef FNRTFTPSERVERCMD *PFNRTFTPSERVERCMD;
     
    313314*********************************************************************************************************************************/
    314315
    315 static int rtFTPServerHandleABOR(PRTFTPSERVERCLIENT pClient)
    316 {
    317     RT_NOREF(pClient);
    318 
    319     /** @todo Anything to do here? */
    320     return VINF_SUCCESS;
    321 }
    322 
    323 static int rtFTPServerHandleCDUP(PRTFTPSERVERCLIENT pClient)
    324 {
    325     RT_NOREF(pClient);
    326 
    327     /** @todo Anything to do here? */
    328     return VINF_SUCCESS;
    329 }
    330 
    331 static int rtFTPServerHandleCWD(PRTFTPSERVERCLIENT pClient)
    332 {
    333     RT_NOREF(pClient);
    334 
    335     /** @todo Anything to do here? */
    336     return VINF_SUCCESS;
    337 }
    338 
    339 static int rtFTPServerHandleLIST(PRTFTPSERVERCLIENT pClient)
    340 {
    341     RT_NOREF(pClient);
    342 
    343     /** @todo Anything to do here? */
    344     return VINF_SUCCESS;
    345 }
    346 
    347 static int rtFTPServerHandleMODE(PRTFTPSERVERCLIENT pClient)
    348 {
    349     RT_NOREF(pClient);
    350 
    351     /** @todo Anything to do here? */
    352     return VINF_SUCCESS;
    353 }
    354 
    355 static int rtFTPServerHandleNOOP(PRTFTPSERVERCLIENT pClient)
    356 {
    357     RT_NOREF(pClient);
     316static int rtFTPServerHandleABOR(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apcszArgs)
     317{
     318    RT_NOREF(pClient, cArgs, apcszArgs);
     319
     320    /** @todo Anything to do here? */
     321    return VINF_SUCCESS;
     322}
     323
     324static int rtFTPServerHandleCDUP(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apcszArgs)
     325{
     326    RT_NOREF(pClient, cArgs, apcszArgs);
     327
     328    /** @todo Anything to do here? */
     329    return VINF_SUCCESS;
     330}
     331
     332static int rtFTPServerHandleCWD(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apcszArgs)
     333{
     334    AssertPtrReturn(apcszArgs, VERR_INVALID_POINTER);
     335
     336    if (cArgs != 1)
     337        return VERR_INVALID_PARAMETER;
     338
     339    RTFTPSERVER_HANDLE_CALLBACK_VA_RET(pfnOnPathSetCurrent, apcszArgs[0]);
     340
     341    return VERR_NOT_IMPLEMENTED;
     342}
     343
     344static int rtFTPServerHandleLIST(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apcszArgs)
     345{
     346    RT_NOREF(cArgs, apcszArgs);
     347
     348    void   *pvData = NULL;
     349    size_t  cbData = 0;
     350
     351    RTFTPSERVER_HANDLE_CALLBACK_VA_RET(pfnOnList, &pvData, &cbData);
     352
     353    return VERR_NOT_IMPLEMENTED;
     354}
     355
     356static int rtFTPServerHandleMODE(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apcszArgs)
     357{
     358    RT_NOREF(pClient, cArgs, apcszArgs);
     359
     360    /** @todo Anything to do here? */
     361    return VINF_SUCCESS;
     362}
     363
     364static int rtFTPServerHandleNOOP(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apcszArgs)
     365{
     366    RT_NOREF(pClient, cArgs, apcszArgs);
    358367
    359368    /* Nothing to do here. */
     
    361370}
    362371
    363 static int rtFTPServerHandlePORT(PRTFTPSERVERCLIENT pClient)
    364 {
    365     RT_NOREF(pClient);
    366 
    367     /** @todo Anything to do here? */
    368     return VINF_SUCCESS;
    369 }
    370 
    371 static int rtFTPServerHandlePWD(PRTFTPSERVERCLIENT pClient)
    372 {
     372static int rtFTPServerHandlePORT(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apcszArgs)
     373{
     374    RT_NOREF(pClient, cArgs, apcszArgs);
     375
     376    /** @todo Anything to do here? */
     377    return VINF_SUCCESS;
     378}
     379
     380static int rtFTPServerHandlePWD(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apcszArgs)
     381{
     382    RT_NOREF(cArgs, apcszArgs);
     383
    373384#if 0
    374385    char *pszReply;
     
    388399}
    389400
    390 static int rtFTPServerHandleQUIT(PRTFTPSERVERCLIENT pClient)
    391 {
    392     RT_NOREF(pClient);
    393 
    394     /** @todo Anything to do here? */
    395     return VINF_SUCCESS;
    396 }
    397 
    398 static int rtFTPServerHandleRETR(PRTFTPSERVERCLIENT pClient)
    399 {
    400     RT_NOREF(pClient);
    401 
    402     /** @todo Anything to do here? */
    403     return VINF_SUCCESS;
    404 }
    405 
    406 static int rtFTPServerHandleRGET(PRTFTPSERVERCLIENT pClient)
    407 {
    408     RT_NOREF(pClient);
    409 
    410     /** @todo Anything to do here? */
    411     return VINF_SUCCESS;
    412 }
    413 
    414 static int rtFTPServerHandleSTAT(PRTFTPSERVERCLIENT pClient)
    415 {
    416     RT_NOREF(pClient);
    417 
    418     /** @todo Anything to do here? */
    419     return VINF_SUCCESS;
    420 }
    421 
    422 static int rtFTPServerHandleSYST(PRTFTPSERVERCLIENT pClient)
    423 {
     401static int rtFTPServerHandleQUIT(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apcszArgs)
     402{
     403    RT_NOREF(pClient, cArgs, apcszArgs);
     404
     405    /** @todo Anything to do here? */
     406    return VINF_SUCCESS;
     407}
     408
     409static int rtFTPServerHandleRETR(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apcszArgs)
     410{
     411    RT_NOREF(pClient, cArgs, apcszArgs);
     412
     413    /** @todo Anything to do here? */
     414    return VINF_SUCCESS;
     415}
     416
     417static int rtFTPServerHandleRGET(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apcszArgs)
     418{
     419    RT_NOREF(pClient, cArgs, apcszArgs);
     420
     421    /** @todo Anything to do here? */
     422    return VINF_SUCCESS;
     423}
     424
     425static int rtFTPServerHandleSTAT(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apcszArgs)
     426{
     427    RT_NOREF(pClient, cArgs, apcszArgs);
     428
     429    /** @todo Anything to do here? */
     430    return VINF_SUCCESS;
     431}
     432
     433static int rtFTPServerHandleSYST(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apcszArgs)
     434{
     435    RT_NOREF(cArgs, apcszArgs);
     436
    424437    char szOSInfo[64];
    425438    int rc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, szOSInfo, sizeof(szOSInfo));
     
    430443}
    431444
    432 static int rtFTPServerHandleTYPE(PRTFTPSERVERCLIENT pClient)
    433 {
    434     RT_NOREF(pClient);
     445static int rtFTPServerHandleTYPE(PRTFTPSERVERCLIENT pClient, uint8_t cArgs, const char * const *apcszArgs)
     446{
     447    RT_NOREF(pClient, cArgs, apcszArgs);
    435448
    436449    /** @todo Anything to do here? */
     
    497510
    498511/**
     512 * Parses FTP command arguments handed in by the client.
     513 *
     514 * @returns VBox status code.
     515 * @param   pcszCmdParms        Pointer to command arguments, if any. Can be NULL if no arguments are given.
     516 * @param   pcArgs              Returns the number of parsed arguments, separated by a space (hex 0x20).
     517 * @param   ppapcszArgs         Returns the string array of parsed arguments. Needs to be free'd with rtFTPServerCmdArgsFree().
     518 */
     519static int rtFTPServerCmdArgsParse(const char *pcszCmdParms, uint8_t *pcArgs, char ***ppapcszArgs)
     520{
     521    *pcArgs      = 0;
     522    *ppapcszArgs = NULL;
     523
     524    if (!pcszCmdParms) /* No parms given? Bail out early. */
     525        return VINF_SUCCESS;
     526
     527    /** @todo Anything else to do here? */
     528    /** @todo Check if quoting is correct. */
     529
     530    int cArgs = 0;
     531    int rc = RTGetOptArgvFromString(ppapcszArgs, &cArgs, pcszCmdParms, RTGETOPTARGV_CNV_QUOTE_MS_CRT, " " /* Separators */);
     532    if (RT_SUCCESS(rc))
     533    {
     534        if (cArgs <= UINT8_MAX)
     535        {
     536            *pcArgs = (uint8_t)cArgs;
     537        }
     538        else
     539            rc = VERR_INVALID_PARAMETER;
     540    }
     541
     542    return rc;
     543}
     544
     545/**
     546 * Frees a formerly argument string array parsed by rtFTPServerCmdArgsParse().
     547 *
     548 * @param   ppapcszArgs         Argument string array to free.
     549 */
     550static void rtFTPServerCmdArgsFree(char **ppapcszArgs)
     551{
     552    RTGetOptArgvFree(ppapcszArgs);
     553}
     554
     555/**
    499556 * Main loop for processing client commands.
    500557 *
     
    527584            /* Second, determine if there is any parameters following. */
    528585            char *pszCmdParms = RTStrIStr(szCmd, " ");
    529             /* pszCmdParms can be NULL if command has not parameters. */
    530             RT_NOREF(pszCmdParms);
    531 
    532             unsigned i = 0;
    533             for (; i < RT_ELEMENTS(g_aCmdMap); i++)
     586            if (pszCmdParms)
     587                pszCmdParms++;
     588
     589            uint8_t cArgs     = 0;
     590            char  **papszArgs = NULL;
     591            rc = rtFTPServerCmdArgsParse(pszCmdParms, &cArgs, &papszArgs);
     592            if (RT_SUCCESS(rc))
    534593            {
    535                 if (!RTStrICmp(szCmd, g_aCmdMap[i].szCmd))
     594                unsigned i = 0;
     595                for (; i < RT_ELEMENTS(g_aCmdMap); i++)
    536596                {
    537                     /* Save timestamp of last command sent. */
    538                     pClient->State.tsLastCmdMs = RTTimeMilliTS();
    539 
    540                     rc = g_aCmdMap[i].pfnCmd(pClient);
     597                    if (!RTStrICmp(szCmd, g_aCmdMap[i].szCmd))
     598                    {
     599                        /* Save timestamp of last command sent. */
     600                        pClient->State.tsLastCmdMs = RTTimeMilliTS();
     601
     602                        rc = g_aCmdMap[i].pfnCmd(pClient, cArgs, papszArgs);
     603                        break;
     604                    }
     605                }
     606
     607                rtFTPServerCmdArgsFree(papszArgs);
     608
     609                if (i == RT_ELEMENTS(g_aCmdMap))
     610                {
     611                    int rc2 = rtFTPServerSendReplyRc(pClient, RTFTPSERVER_REPLY_ERROR_CMD_NOT_IMPL);
     612                    if (RT_SUCCESS(rc))
     613                        rc = rc2;
     614                }
     615
     616                if (g_aCmdMap[i].enmCmd == RTFTPSERVER_CMD_QUIT)
     617                {
     618                    RTFTPSERVER_HANDLE_CALLBACK_RET(pfnOnUserDisconnect);
    541619                    break;
    542620                }
    543621            }
    544 
    545             if (i == RT_ELEMENTS(g_aCmdMap))
     622            else
    546623            {
    547                 int rc2 = rtFTPServerSendReplyRc(pClient, RTFTPSERVER_REPLY_ERROR_CMD_NOT_IMPL);
     624                int rc2 = rtFTPServerSendReplyRc(pClient, RTFTPSERVER_REPLY_ERROR_INVALID_PARAMETERS);
    548625                if (RT_SUCCESS(rc))
    549626                    rc = rc2;
    550             }
    551 
    552             if (g_aCmdMap[i].enmCmd == RTFTPSERVER_CMD_QUIT)
    553             {
    554                 RTFTPSERVER_HANDLE_CALLBACK_RET(pfnOnUserDisconnect);
    555                 break;
    556627            }
    557628        }
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette