VirtualBox

Changeset 34449 in vbox for trunk/src/VBox/Runtime/common


Ignore:
Timestamp:
Nov 29, 2010 10:46:43 AM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
68223
Message:

Implemented RTManifestReadStandard and RTManifestReadStandardEx.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/checksum/manifest2.cpp

    r34442 r34449  
    3434#include <iprt/asm.h>
    3535#include <iprt/assert.h>
     36#include <iprt/ctype.h>
    3637#include <iprt/err.h>
    3738#include <iprt/mem.h>
     39#include <iprt/param.h>
     40#include <iprt/md5.h>
     41#include <iprt/sha.h>
    3842#include <iprt/string.h>
    3943#include <iprt/vfs.h>
     
    676680
    677681
    678 #if 0
     682/**
     683 * Reads a line from a VFS I/O stream.
     684 *
     685 * @todo    Replace this with a buffered I/O stream layer.
     686 *
     687 * @returns IPRT status code.  VERR_EOF when trying to read beyond the stream
     688 *          end.
     689 * @param   hVfsIos             The I/O stream to read from.
     690 * @param   pszLine             Where to store what we've read.
     691 * @param   cbLine              The number of bytes to read.
     692 */
    679693static int rtManifestReadLine(RTVFSIOSTREAM hVfsIos, char *pszLine, size_t cbLine)
    680694{
     
    684698    while (cbLine > 1)
    685699    {
    686         int rc = RTVfsIoStrmRead(hVfsIos, pszLine, 1, true /*fBLocking*/, NULL);
     700        char ch;
     701        int rc = RTVfsIoStrmRead(hVfsIos, &ch, 1, true /*fBLocking*/, NULL);
    687702        if (RT_FAILURE(rc))
    688         {
    689             *pszLine = '\0';
    690703            return rc == VERR_EOF ? VINF_EOF : rc;
    691         }
    692     }
    693     return rc;
    694 }
    695 #endif
    696 
    697 
    698 /**
    699  * Reads in a "standard" manifest.
    700  *
    701  * This reads the format used by OVF, the distinfo in FreeBSD ports, and
    702  * others.
    703  *
    704  * @returns IPRT status code.
    705  * @param   hManifest           The handle to the manifest where to add the
    706  *                              manifest that's read in.
    707  * @param   hVfsIos             The I/O stream to read the manifest from.
    708  */
     704
     705        /* \r\n */
     706        if (ch == '\r')
     707        {
     708            if (cbLine <= 2)
     709            {
     710                pszLine[0] = ch;
     711                pszLine[1] = '\0';
     712                return VINF_BUFFER_OVERFLOW;
     713            }
     714
     715            rc = RTVfsIoStrmRead(hVfsIos, &ch, 1, true /*fBLocking*/, NULL);
     716            if (RT_SUCCESS(rc) && ch == '\n')
     717                return VINF_SUCCESS;
     718            pszLine[0] = '\r';
     719            pszLine[1] = ch;
     720            pszLine[2] = '\0';
     721            if (RT_FAILURE(rc))
     722                return rc == VERR_EOF ? VINF_EOF : rc;
     723        }
     724
     725        /* \n */
     726        if (ch == '\n')
     727            return VINF_SUCCESS;
     728
     729        /* add character. */
     730        pszLine[0] = ch;
     731        pszLine[1] = '\0';
     732
     733        /* advance */
     734        pszLine++;
     735        cbLine--;
     736    }
     737
     738    return VINF_BUFFER_OVERFLOW;
     739}
     740
     741
     742RTDECL(int) RTManifestReadStandardEx(RTMANIFEST hManifest, RTVFSIOSTREAM hVfsIos, char *pszErr, size_t cbErr)
     743{
     744    if (pszErr && cbErr)
     745        *pszErr = '\0';
     746
     747    uint32_t iLine = 0;
     748    for (;;)
     749    {
     750        /*
     751         * Read a line from the input stream.
     752         */
     753        iLine++;
     754        char szLine[RTPATH_MAX + RTSHA512_DIGEST_LEN + 32];
     755        int rc = rtManifestReadLine(hVfsIos, szLine, sizeof(szLine));
     756        if (RT_FAILURE(rc))
     757        {
     758            if (rc == VERR_EOF)
     759                return VINF_SUCCESS;
     760            RTStrPrintf(pszErr, cbErr, "Error reading line #u: %Rrc", iLine, rc);
     761            return rc;
     762        }
     763        if (rc != VINF_SUCCESS)
     764        {
     765            RTStrPrintf(pszErr, cbErr, "Line number %u is too long", iLine);
     766            return VERR_OUT_OF_RANGE;
     767        }
     768
     769        /*
     770         * Strip it and skip if empty.
     771         */
     772        char *psz = RTStrStrip(szLine);
     773        if (!*psz)
     774            continue;
     775
     776        /*
     777         * Read the attribute name.
     778         */
     779        const char * const pszAttr = psz;
     780        do
     781            psz++;
     782        while (!RT_C_IS_BLANK(*psz) && *psz);
     783        if (*psz)
     784            *psz++ = '\0';
     785
     786        /*
     787         * The entry name is enclosed in parenthesis and followed by a '='.
     788         */
     789        psz = RTStrStripL(psz);
     790        if (*psz != '(')
     791        {
     792            RTStrPrintf(pszErr, cbErr, "Expected '(' after %zu on line %u", psz - szLine, iLine);
     793            return VERR_PARSE_ERROR;
     794        }
     795        const char * const pszName = ++psz;
     796        while (*psz)
     797        {
     798            if (*psz == ')')
     799            {
     800                char *psz2 = RTStrStripL(psz + 1);
     801                if (*psz2 == '=')
     802                {
     803                    *psz = '\0';
     804                    psz = psz2;
     805                    break;
     806                }
     807            }
     808            psz++;
     809        }
     810
     811        if (*psz != '=')
     812        {
     813            RTStrPrintf(pszErr, cbErr, "Expected ')=' at %zu on line %u", psz - szLine, iLine);
     814            return VERR_PARSE_ERROR;
     815        }
     816
     817        /*
     818         * The value.
     819         */
     820        psz = RTStrStrip(psz + 1);
     821        const char * const pszValue = psz;
     822        if (!*psz)
     823        {
     824            RTStrPrintf(pszErr, cbErr, "Expected value at %zu on line %u", psz - szLine, iLine);
     825            return VERR_PARSE_ERROR;
     826        }
     827
     828        /*
     829         * Detect attribute type and sanity check the value.
     830         */
     831        uint32_t fType = RTMANIFEST_ATTR_UNKNOWN;
     832        static const struct
     833        {
     834            const char *pszAttr;
     835            uint32_t    fType;
     836            unsigned    cBits;
     837            unsigned    uBase;
     838        } s_aDecAttrs[] =
     839        {
     840            { "SIZE", RTMANIFEST_ATTR_SIZE, 64,  10}
     841        };
     842        for (unsigned i = 0; i < RT_ELEMENTS(s_aDecAttrs); i++)
     843            if (!strcmp(s_aDecAttrs[i].pszAttr, pszAttr))
     844            {
     845                fType = s_aDecAttrs[i].fType;
     846                rc = RTStrToUInt64Full(pszValue, s_aDecAttrs[i].uBase, NULL);
     847                if (rc != VINF_SUCCESS)
     848                {
     849                    RTStrPrintf(pszErr, cbErr, "Malformed value ('%s') at %zu on line %u: %Rrc", pszValue, psz - szLine, iLine, rc);
     850                    return VERR_PARSE_ERROR;
     851                }
     852                break;
     853            }
     854
     855        if (fType == RTMANIFEST_ATTR_UNKNOWN)
     856        {
     857            static const struct
     858            {
     859                const char *pszAttr;
     860                uint32_t    fType;
     861                unsigned    cchHex;
     862            } s_aHexAttrs[] =
     863            {
     864                { "MD5",        RTMANIFEST_ATTR_MD5,        RTMD5_DIGEST_LEN    },
     865                { "SHA1",       RTMANIFEST_ATTR_SHA1,       RTSHA1_DIGEST_LEN   },
     866                { "SHA256",     RTMANIFEST_ATTR_SHA256,     RTSHA256_DIGEST_LEN },
     867                { "SHA512",     RTMANIFEST_ATTR_SHA512,     RTSHA512_DIGEST_LEN }
     868            };
     869            for (unsigned i = 0; i < RT_ELEMENTS(s_aHexAttrs); i++)
     870                if (!strcmp(s_aHexAttrs[i].pszAttr, pszAttr))
     871                {
     872                    fType = s_aHexAttrs[i].fType;
     873                    for (unsigned off = 0; off < s_aHexAttrs[i].cchHex; off++)
     874                        if (!RT_C_IS_XDIGIT(pszAttr[off]))
     875                        {
     876                            RTStrPrintf(pszErr, cbErr, "Expected hex digit at %zu on line %u (value '%s', pos %u)",
     877                                        pszValue - szLine + off, iLine, pszValue, off);
     878                            return VERR_PARSE_ERROR;
     879                        }
     880                    break;
     881                }
     882        }
     883
     884        /*
     885         * Finally, add it.
     886         */
     887        rc = RTManifestEntrySetAttr(hManifest, pszName, pszAttr, pszValue, fType);
     888        if (RT_FAILURE(rc))
     889        {
     890            RTStrPrintf(pszErr, cbErr, "RTManifestEntrySetAttr(,'%s','%s', '%s', %#x) failed on line %u: %Rrc",
     891                        pszName, pszAttr, pszValue, fType, iLine, rc);
     892            return rc;
     893        }
     894    }
     895}
     896
    709897RTDECL(int) RTManifestReadStandard(RTMANIFEST hManifest, RTVFSIOSTREAM hVfsIos)
    710898{
     899    return RTManifestReadStandardEx(hManifest, hVfsIos, NULL, 0);
     900}
     901
     902
     903RTDECL(int) RTManifestWriteStandard(RTMANIFEST hManifest, RTVFSIOSTREAM hVfsIos)
     904{
    711905    return VERR_NOT_IMPLEMENTED;
    712906}
    713907
    714 
    715 /**
    716  * Writes a "standard" manifest.
    717  *
    718  * This writes the format used by OVF, the distinfo in FreeBSD ports, and
    719  * others.
    720  *
    721  * @returns IPRT status code.
    722  * @param   hManifest           The handle to the manifest where to add the
    723  *                              manifest that's read in.
    724  * @param   hVfsIos             The I/O stream to read the manifest from.
    725  */
    726 RTDECL(int) RTManifestWriteStandard(RTMANIFEST hManifest, RTVFSIOSTREAM hVfsIos)
    727 {
    728     return VERR_NOT_IMPLEMENTED;
    729 }
    730 
Note: See TracChangeset for help on using the changeset viewer.

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