Changeset 34449 in vbox for trunk/src/VBox/Runtime/common
- Timestamp:
- Nov 29, 2010 10:46:43 AM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 68223
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/checksum/manifest2.cpp
r34442 r34449 34 34 #include <iprt/asm.h> 35 35 #include <iprt/assert.h> 36 #include <iprt/ctype.h> 36 37 #include <iprt/err.h> 37 38 #include <iprt/mem.h> 39 #include <iprt/param.h> 40 #include <iprt/md5.h> 41 #include <iprt/sha.h> 38 42 #include <iprt/string.h> 39 43 #include <iprt/vfs.h> … … 676 680 677 681 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 */ 679 693 static int rtManifestReadLine(RTVFSIOSTREAM hVfsIos, char *pszLine, size_t cbLine) 680 694 { … … 684 698 while (cbLine > 1) 685 699 { 686 int rc = RTVfsIoStrmRead(hVfsIos, pszLine, 1, true /*fBLocking*/, NULL); 700 char ch; 701 int rc = RTVfsIoStrmRead(hVfsIos, &ch, 1, true /*fBLocking*/, NULL); 687 702 if (RT_FAILURE(rc)) 688 {689 *pszLine = '\0';690 703 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 742 RTDECL(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 709 897 RTDECL(int) RTManifestReadStandard(RTMANIFEST hManifest, RTVFSIOSTREAM hVfsIos) 710 898 { 899 return RTManifestReadStandardEx(hManifest, hVfsIos, NULL, 0); 900 } 901 902 903 RTDECL(int) RTManifestWriteStandard(RTMANIFEST hManifest, RTVFSIOSTREAM hVfsIos) 904 { 711 905 return VERR_NOT_IMPLEMENTED; 712 906 } 713 907 714 715 /**716 * Writes a "standard" manifest.717 *718 * This writes the format used by OVF, the distinfo in FreeBSD ports, and719 * others.720 *721 * @returns IPRT status code.722 * @param hManifest The handle to the manifest where to add the723 * 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.