Changeset 50147 in vbox for trunk/src/VBox/Runtime/common/zip/tar.cpp
- Timestamp:
- Jan 21, 2014 5:46:51 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/zip/tar.cpp
r50139 r50147 5 5 6 6 /* 7 * Copyright (C) 2009-201 3Oracle Corporation7 * Copyright (C) 2009-2014 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 25 25 */ 26 26 27 //#define RT_USE_TAR_VFS_FOR_ALL_READS - make default on trunk! 27 28 28 29 /****************************************************************************** … … 39 40 #include <iprt/path.h> 40 41 #include <iprt/string.h> 42 #ifdef RT_USE_TAR_VFS_FOR_ALL_READS 43 # include <iprt/vfs.h> 44 # include <iprt/zip.h> 45 #endif /* RT_USE_TAR_VFS_FOR_ALL_READS */ 46 41 47 42 48 #include "internal/magics.h" … … 110 116 /** Whether operating in stream mode. */ 111 117 bool fStreamMode; 118 #ifndef RT_USE_TAR_VFS_FOR_ALL_READS 112 119 /** The file cache of one file. */ 113 120 PRTTARFILEINTERNAL pFileCache; 121 #else /* RT_USE_TAR_VFS_FOR_ALL_READS */ 122 /** The tar file VFS handle. */ 123 RTVFSFILE hVfsFile; 124 /** The tar file system VFS handle. */ 125 RTVFSFSSTREAM hVfsFss; 126 /** Set if hVfsFss is at the start of the stream and doesn't need rewinding. */ 127 bool fFssAtStart; 128 /** The current stream object (fStreamMode = true). */ 129 RTVFSIOSTREAM hVfsCur; 130 /** The name of the current object (fStreamMode = true). */ 131 char *pszVfsCurName; 132 #endif /* RT_USE_TAR_VFS_FOR_ALL_READS */ 114 133 } RTTARINTERNAL; 115 134 /** Pointer to a the internal data of a tar handle. */ … … 139 158 /** The link flag. */ 140 159 char linkflag; 160 #ifdef RT_USE_TAR_VFS_FOR_ALL_READS 161 /** The VFS I/O stream (only for reading atm). */ 162 RTVFSIOSTREAM hVfsIos; 163 /** The RTFSOBJATTR::fMode value for this VFS object. */ 164 RTFMODE fVfsMode; 165 /** The RTFSOBJINFO::ModificationTime value for this VFS object. */ 166 RTTIMESPEC VfsModTime; 167 #endif 141 168 } RTTARFILEINTERNAL; 142 169 /** Pointer to the internal data of a tar file. */ 143 170 typedef RTTARFILEINTERNAL *PRTTARFILEINTERNAL; 144 145 #if 0 /* not currently used */146 typedef struct RTTARFILELIST147 {148 char *pszFilename;149 RTTARFILELIST *pNext;150 } RTTARFILELIST;151 typedef RTTARFILELIST *PRTTARFILELIST;152 #endif153 171 154 172 … … 230 248 } 231 249 250 #ifndef RT_USE_TAR_VFS_FOR_ALL_READS 232 251 DECLINLINE(uint64_t) rtTarRecToSize(PRTTARRECORD pRecord) 233 252 { … … 269 288 return (uint64_t)cbSize; 270 289 } 290 #endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */ 271 291 272 292 /** … … 325 345 } 326 346 347 #ifndef RT_USE_TAR_VFS_FOR_ALL_READS 327 348 DECLINLINE(int) rtTarReadHeaderRecord(RTFILE hFile, PRTTARRECORD pRecord) 328 349 { … … 360 381 return rc; 361 382 } 383 #endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */ 362 384 363 385 DECLINLINE(int) rtTarCreateHeaderRecord(PRTTARRECORD pRecord, const char *pszSrcName, uint64_t cbSize, … … 448 470 if (!pFileInt->pszFilename) 449 471 { 472 #ifdef RT_USE_TAR_VFS_FOR_ALL_READS 473 pFileInt->hVfsIos = NIL_RTVFSIOSTREAM; 474 #endif 450 475 RTMemFree(pFileInt); 451 476 return NULL; … … 454 479 return pFileInt; 455 480 } 481 482 #ifdef RT_USE_TAR_VFS_FOR_ALL_READS 483 484 /** 485 * Creates a tar file handle for a read-only VFS stream object. 486 * 487 * @returns IPRT status code. 488 * @param pszName The file name. Automatically freed on failure. 489 * @param hVfsIos The VFS I/O stream we create the handle around. 490 * The reference is NOT consumed. 491 * @param fOpen The open flags. 492 * @param ppFile Where to return the handle. 493 */ 494 static int rtTarFileCreateHandleForReadOnly(char *pszName, RTVFSIOSTREAM hVfsIos, uint32_t fOpen, PRTTARFILEINTERNAL *ppFile) 495 { 496 int rc; 497 PRTTARFILEINTERNAL pNewFile = (PRTTARFILEINTERNAL)RTMemAllocZ(sizeof(*pNewFile)); 498 if (pNewFile) 499 { 500 RTFSOBJINFO ObjInfo; 501 rc = RTVfsIoStrmQueryInfo(hVfsIos, &ObjInfo, RTFSOBJATTRADD_UNIX); 502 if (RT_SUCCESS(rc)) 503 { 504 pNewFile->u32Magic = RTTARFILE_MAGIC; 505 pNewFile->pTar = NULL; 506 pNewFile->pszFilename = pszName; 507 pNewFile->offStart = UINT64_MAX; 508 pNewFile->cbSize = ObjInfo.cbObject; 509 pNewFile->cbSetSize = 0; 510 pNewFile->offCurrent = 0; 511 pNewFile->fOpenMode = fOpen; 512 pNewFile->linkflag = LF_NORMAL; 513 pNewFile->hVfsIos = hVfsIos; 514 pNewFile->fVfsMode = ObjInfo.Attr.fMode; 515 pNewFile->VfsModTime = ObjInfo.ModificationTime; 516 517 uint32_t cRefs = RTVfsIoStrmRetain(hVfsIos); Assert(cRefs != UINT32_MAX); NOREF(cRefs); 518 519 *ppFile = pNewFile; 520 return VINF_SUCCESS; 521 } 522 523 RTMemFree(pNewFile); 524 } 525 else 526 rc = VERR_NO_MEMORY; 527 RTStrFree(pszName); 528 return rc; 529 } 530 531 #else /* !RT_USE_TAR_VFS_FOR_ALL_READS */ 456 532 457 533 DECLINLINE(PRTTARFILEINTERNAL) rtCopyTarFileInternal(PRTTARFILEINTERNAL pInt) … … 472 548 } 473 549 550 #endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */ 551 474 552 DECLINLINE(void) rtDeleteTarFileInternal(PRTTARFILEINTERNAL pInt) 475 553 { … … 478 556 if (pInt->pszFilename) 479 557 RTStrFree(pInt->pszFilename); 558 #ifdef RT_USE_TAR_VFS_FOR_ALL_READS 559 if (pInt->hVfsIos != NIL_RTVFSIOSTREAM) 560 { 561 RTVfsIoStrmRelease(pInt->hVfsIos); 562 pInt->hVfsIos = NIL_RTVFSIOSTREAM; 563 } 564 #endif 565 480 566 pInt->u32Magic = RTTARFILE_MAGIC_DEAD; 481 567 RTMemFree(pInt); … … 483 569 } 484 570 571 #ifndef RT_USE_TAR_VFS_FOR_ALL_READS 485 572 static int rtTarExtractFileToFile(RTTARFILE hFile, const char *pszTargetName, const uint64_t cbOverallSize, uint64_t &cbOverallWritten, PFNRTPROGRESS pfnProgressCallback, void *pvUser) 486 573 { … … 564 651 return rc; 565 652 } 653 #endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */ 566 654 567 655 static int rtTarAppendFileFromFile(RTTAR hTar, const char *pszSrcName, const uint64_t cbOverallSize, uint64_t &cbOverallWritten, PFNRTPROGRESS pfnProgressCallback, void *pvUser) … … 672 760 return rc; 673 761 } 762 763 #ifndef RT_USE_TAR_VFS_FOR_ALL_READS 674 764 675 765 static int rtTarSkipData(RTFILE hFile, PRTTARRECORD pRecord) … … 727 817 } 728 818 729 #ifdef SOME_UNUSED_FUNCTION 730 static int rtTarGetFilesOverallSize(RTFILE hFile, const char * const *papszFiles, size_t cFiles, uint64_t *pcbOverallSize) 731 { 732 int rc = VINF_SUCCESS; 733 size_t cFound = 0; 734 RTTARRECORD record; 735 for (;;) 736 { 737 /* Read & verify a header record */ 738 rc = rtTarReadHeaderRecord(hFile, &record); 739 /* Check for error or EOF. */ 740 if (RT_FAILURE(rc)) 741 break; 742 743 /* We support normal files only */ 744 if ( record.h.linkflag == LF_OLDNORMAL 745 || record.h.linkflag == LF_NORMAL) 746 { 747 for (size_t i = 0; i < cFiles; ++i) 748 { 749 if (!RTStrCmp(record.h.name, papszFiles[i])) 750 { 751 /* Sum up the overall size */ 752 *pcbOverallSize += rtTarRecToSize(&record); 753 ++cFound; 754 break; 755 } 756 } 757 if ( cFound == cFiles 758 || RT_FAILURE(rc)) 759 break; 760 } 761 rc = rtTarSkipData(hFile, &record); 762 if (RT_FAILURE(rc)) 763 break; 764 } 765 if (rc == VERR_TAR_END_OF_FILE) 766 rc = VINF_SUCCESS; 767 768 /* Make sure the file pointer is at the begin of the file again. */ 769 if (RT_SUCCESS(rc)) 770 rc = RTFileSeek(hFile, 0, RTFILE_SEEK_BEGIN, 0); 771 return rc; 772 } 773 #endif /* SOME_UNUSED_FUNCTION */ 819 #endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */ 820 774 821 775 822 /****************************************************************************** … … 779 826 RTR3DECL(int) RTTarOpen(PRTTAR phTar, const char *pszTarname, uint32_t fMode, bool fStream) 780 827 { 828 AssertReturn(!fStream || !(fMode & RTFILE_O_WRITE), VERR_INVALID_PARAMETER); 829 781 830 /* 782 831 * Create a tar instance. … … 793 842 * Open the tar file. 794 843 */ 795 int rc = RTFileOpen(&pThis->hTarFile, pszTarname, fMode); 844 int rc; 845 #ifdef RT_USE_TAR_VFS_FOR_ALL_READS 846 pThis->hVfsFile = NIL_RTVFSFILE; 847 pThis->hVfsFss = NIL_RTVFSFSSTREAM; 848 pThis->fFssAtStart = false; 849 pThis->hVfsCur = NIL_RTVFSIOSTREAM; 850 pThis->pszVfsCurName = NULL; 851 852 if (!(fMode & RTFILE_O_WRITE)) 853 { 854 rc = RTVfsFileOpenNormal(pszTarname, fMode, &pThis->hVfsFile); 855 if (RT_SUCCESS(rc)) 856 { 857 RTVFSIOSTREAM hVfsIos = RTVfsFileToIoStream(pThis->hVfsFile); 858 rc = RTZipTarFsStreamFromIoStream(hVfsIos, 0 /*fFlags*/, &pThis->hVfsFss); 859 if (RT_SUCCESS(rc)) 860 pThis->fFssAtStart = true; 861 else 862 { 863 RTVfsFileRelease(pThis->hVfsFile); 864 pThis->hVfsFile = NIL_RTVFSFILE; 865 } 866 RTVfsIoStrmRelease(hVfsIos); 867 } 868 } 869 else 870 #endif 871 rc = RTFileOpen(&pThis->hTarFile, pszTarname, fMode); 796 872 if (RT_SUCCESS(rc)) 797 873 { … … 825 901 #endif 826 902 903 #ifdef RT_USE_TAR_VFS_FOR_ALL_READS 904 if (pInt->hVfsFss != NIL_RTVFSFSSTREAM) 905 { 906 uint32_t cRefs = RTVfsFsStrmRelease(pInt->hVfsFss); Assert(cRefs != UINT32_MAX); 907 pInt->hVfsFss = NIL_RTVFSFSSTREAM; 908 } 909 910 if (pInt->hVfsFile != NIL_RTVFSFILE) 911 { 912 uint32_t cRefs = RTVfsFileRelease(pInt->hVfsFile); Assert(cRefs != UINT32_MAX); 913 pInt->hVfsFile = NIL_RTVFSFILE; 914 } 915 916 if (pInt->hVfsCur != NIL_RTVFSIOSTREAM) 917 { 918 RTVfsIoStrmRelease(pInt->hVfsCur); 919 pInt->hVfsCur = NIL_RTVFSIOSTREAM; 920 } 921 922 if (pInt->pszVfsCurName) 923 { 924 RTStrFree(pInt->pszVfsCurName); 925 pInt->pszVfsCurName = NULL; 926 } 927 #endif /* RT_USE_TAR_VFS_FOR_ALL_READS */ 928 827 929 if (pInt->hTarFile != NIL_RTFILE) 930 { 828 931 rc = RTFileClose(pInt->hTarFile); 829 932 pInt->hTarFile = NIL_RTFILE; 933 } 934 935 #ifndef RT_USE_TAR_VFS_FOR_ALL_READS 830 936 /* Delete any remaining cached file headers. */ 831 937 if (pInt->pFileCache) … … 834 940 pInt->pFileCache = NULL; 835 941 } 942 #endif 836 943 837 944 pInt->u32Magic = RTTAR_MAGIC_DEAD; … … 863 970 } 864 971 865 PRTTARFILEINTERNAL pFileInt = rtCreateTarFileInternal(pInt, pszFilename, fOpen);866 if (!pFileInt)867 return VERR_NO_MEMORY;868 869 972 int rc = VINF_SUCCESS; 870 do /* break loop */ 871 { 872 if (pFileInt->fOpenMode & RTFILE_O_WRITE) 873 { 874 pInt->fFileOpenForWrite = true; 875 876 /* If we are in write mode, we also in append mode. Add an dummy 877 * header at the end of the current file. It will be filled by the 878 * close operation. */ 879 rc = RTFileSeek(pFileInt->pTar->hTarFile, 0, RTFILE_SEEK_END, &pFileInt->offStart); 973 #ifdef RT_USE_TAR_VFS_FOR_ALL_READS 974 if (!(fOpen & RTFILE_O_WRITE)) 975 { 976 /* 977 * Rewind the stream if necessary. 978 */ 979 if (!pInt->fFssAtStart) 980 { 981 if (pInt->hVfsFss != NIL_RTVFSFSSTREAM) 982 { 983 uint32_t cRefs = RTVfsFsStrmRelease(pInt->hVfsFss); Assert(cRefs != UINT32_MAX); 984 pInt->hVfsFss = NIL_RTVFSFSSTREAM; 985 } 986 987 if (pInt->hVfsFile == NIL_RTVFSFILE) 988 { 989 rc = RTVfsFileFromRTFile(pInt->hTarFile, RTFILE_O_READ, true /*fLeaveOpen*/, &pInt->hVfsFile); 990 if (RT_FAILURE(rc)) 991 return rc; 992 } 993 Assert(pInt->hVfsCur == NIL_RTVFSIOSTREAM && pInt->pszVfsCurName == NULL); 994 995 RTVFSIOSTREAM hVfsIos = RTVfsFileToIoStream(pInt->hVfsFile); 996 rc = RTZipTarFsStreamFromIoStream(hVfsIos, 0 /*fFlags*/, &pInt->hVfsFss); 997 RTVfsIoStrmRelease(hVfsIos); 880 998 if (RT_FAILURE(rc)) 999 return rc; 1000 } 1001 1002 /* 1003 * Search the file system stream. 1004 */ 1005 pInt->fFssAtStart = false; 1006 for (;;) 1007 { 1008 char *pszName; 1009 RTVFSOBJTYPE enmType; 1010 RTVFSOBJ hVfsObj; 1011 rc = RTVfsFsStrmNext(pInt->hVfsFss, &pszName, &enmType, &hVfsObj); 1012 if (rc == VERR_EOF) 1013 return VERR_FILE_NOT_FOUND; 1014 if (RT_FAILURE(rc)) 1015 return rc; 1016 1017 if (!RTStrCmp(pszName, pszFilename)) 1018 { 1019 if (enmType == RTVFSOBJTYPE_FILE || enmType == RTVFSOBJTYPE_IO_STREAM) 1020 rc = rtTarFileCreateHandleForReadOnly(pszName, RTVfsObjToIoStream(hVfsObj), fOpen, phFile); 1021 else 1022 { 1023 rc = VERR_UNEXPECTED_FS_OBJ_TYPE; 1024 RTStrFree(pszName); 1025 } 1026 RTVfsObjRelease(hVfsObj); 881 1027 break; 882 RTTARRECORD record; 883 RT_ZERO(record); 884 rc = RTFileWrite(pFileInt->pTar->hTarFile, &record, sizeof(RTTARRECORD), NULL); 885 if (RT_FAILURE(rc)) 886 break; 887 } 888 else if (pFileInt->fOpenMode & RTFILE_O_READ) 889 { 890 /* We need to be on the start of the file */ 891 rc = RTFileSeek(pFileInt->pTar->hTarFile, 0, RTFILE_SEEK_BEGIN, NULL); 892 if (RT_FAILURE(rc)) 893 break; 894 895 /* Search for the file. */ 896 rc = rtTarFindFile(pFileInt->pTar->hTarFile, pszFilename, &pFileInt->offStart, &pFileInt->cbSize); 897 if (RT_FAILURE(rc)) 898 break; 1028 } 1029 RTStrFree(pszName); 1030 RTVfsObjRelease(hVfsObj); 1031 } /* Search loop. */ 1032 } 1033 else 1034 #endif /* RT_USE_TAR_VFS_FOR_ALL_READS */ 1035 { 1036 PRTTARFILEINTERNAL pFileInt = rtCreateTarFileInternal(pInt, pszFilename, fOpen); 1037 if (!pFileInt) 1038 return VERR_NO_MEMORY; 1039 1040 do /* break loop */ 1041 { 1042 #ifndef RT_USE_TAR_VFS_FOR_ALL_READS 1043 if (pFileInt->fOpenMode & RTFILE_O_WRITE) 1044 #endif 1045 { 1046 pInt->fFileOpenForWrite = true; 1047 1048 /* If we are in write mode, we also in append mode. Add an dummy 1049 * header at the end of the current file. It will be filled by the 1050 * close operation. */ 1051 rc = RTFileSeek(pFileInt->pTar->hTarFile, 0, RTFILE_SEEK_END, &pFileInt->offStart); 1052 if (RT_FAILURE(rc)) 1053 break; 1054 RTTARRECORD record; 1055 RT_ZERO(record); 1056 rc = RTFileWrite(pFileInt->pTar->hTarFile, &record, sizeof(RTTARRECORD), NULL); 1057 if (RT_FAILURE(rc)) 1058 break; 1059 } 1060 #ifndef RT_USE_TAR_VFS_FOR_ALL_READS 1061 else 1062 { 1063 Assert(pFileInt->fOpenMode & RTFILE_O_READ); /* see first assertion */ 1064 1065 /* We need to be on the start of the file */ 1066 rc = RTFileSeek(pFileInt->pTar->hTarFile, 0, RTFILE_SEEK_BEGIN, NULL); 1067 if (RT_FAILURE(rc)) 1068 break; 1069 1070 /* Search for the file. */ 1071 rc = rtTarFindFile(pFileInt->pTar->hTarFile, pszFilename, &pFileInt->offStart, &pFileInt->cbSize); 1072 if (RT_FAILURE(rc)) 1073 break; 1074 } 1075 #endif 1076 } while (0); 1077 1078 /* Cleanup on failure */ 1079 if (RT_FAILURE(rc)) 1080 { 1081 if (pFileInt->pszFilename) 1082 RTStrFree(pFileInt->pszFilename); 1083 RTMemFree(pFileInt); 899 1084 } 900 1085 else 901 { 902 /** @todo is something missing here? */ 903 } 904 905 } while (0); 906 907 /* Cleanup on failure */ 908 if (RT_FAILURE(rc)) 909 { 910 if (pFileInt->pszFilename) 911 RTStrFree(pFileInt->pszFilename); 912 RTMemFree(pFileInt); 913 } 914 else 915 *phFile = (RTTARFILE)pFileInt; 1086 *phFile = (RTTARFILE)pFileInt; 1087 } 916 1088 917 1089 return rc; … … 929 1101 int rc = VINF_SUCCESS; 930 1102 931 /* In writemode: */1103 /* In read mode: */ 932 1104 if (pFileInt->fOpenMode & RTFILE_O_READ) 933 1105 { 1106 #ifndef RT_USE_TAR_VFS_FOR_ALL_READS 934 1107 /* In read mode, we want to make sure to stay at the aligned end of this 935 1108 * file, so the next file could be read immediately. */ … … 947 1120 rc = RTFileSeek(pFileInt->pTar->hTarFile, offNext - offCur, RTFILE_SEEK_CURRENT, NULL); 948 1121 } 1122 #endif 949 1123 } 950 1124 else if (pFileInt->fOpenMode & RTFILE_O_WRITE) … … 1001 1175 } 1002 1176 1177 #ifndef RT_USE_TAR_VFS_FOR_ALL_READS 1003 1178 RTR3DECL(int) RTTarFileSeek(RTTARFILE hFile, uint64_t offSeek, unsigned uMethod, uint64_t *poffActual) 1004 1179 { … … 1040 1215 return VINF_SUCCESS; 1041 1216 } 1042 1217 #endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */ 1218 1219 1220 #ifndef RT_USE_TAR_VFS_FOR_ALL_READS 1043 1221 RTR3DECL(uint64_t) RTTarFileTell(RTTARFILE hFile) 1044 1222 { … … 1048 1226 return pFileInt->offCurrent; 1049 1227 } 1228 #endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */ 1050 1229 1051 1230 RTR3DECL(int) RTTarFileRead(RTTARFILE hFile, void *pvBuf, size_t cbToRead, size_t *pcbRead) … … 1054 1233 RTTARFILE_VALID_RETURN(pFileInt); 1055 1234 1056 /* Todo: optimize this, by checking the current pos */1057 1235 return RTTarFileReadAt(hFile, pFileInt->offCurrent, pvBuf, cbToRead, pcbRead); 1058 1236 } … … 1062 1240 PRTTARFILEINTERNAL pFileInt = hFile; 1063 1241 RTTARFILE_VALID_RETURN(pFileInt); 1242 1243 #ifdef RT_USE_TAR_VFS_FOR_ALL_READS 1244 1245 size_t cbTmpRead = 0; 1246 int rc = RTVfsIoStrmReadAt(pFileInt->hVfsIos, off, pvBuf, cbToRead, true /*fBlocking*/, &cbTmpRead); 1247 if (RT_SUCCESS(rc)) 1248 { 1249 pFileInt->offCurrent = off + cbTmpRead; 1250 if (pcbRead) 1251 *pcbRead = cbTmpRead; 1252 if (rc == VINF_EOF) 1253 rc = pcbRead ? VINF_SUCCESS : VERR_EOF; 1254 } 1255 else if (pcbRead) 1256 *pcbRead = 0; 1257 #else 1064 1258 1065 1259 /* Check that we not read behind the end of file. If so return immediately. */ … … 1078 1272 *pcbRead = cbTmpRead; 1079 1273 1274 #endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */ 1275 1080 1276 return rc; 1081 1277 } … … 1136 1332 } 1137 1333 1334 #ifndef RT_USE_TAR_VFS_FOR_ALL_READS /* only used internally */ 1138 1335 RTR3DECL(int) RTTarFileGetMode(RTTARFILE hFile, uint32_t *pfMode) 1139 1336 { … … 1143 1340 PRTTARFILEINTERNAL pFileInt = hFile; 1144 1341 RTTARFILE_VALID_RETURN(pFileInt); 1342 1343 #ifdef RT_USE_TAR_VFS_FOR_ALL_READS 1344 if ((pFileInt->fOpenMode & RTFILE_O_WRITE) != RTFILE_O_WRITE) 1345 { 1346 Assert(pFileInt->hVfsIos != NIL_RTVFSIOSTREAM); 1347 *pfMode = pFileInt->fVfsMode; 1348 return VINF_SUCCESS; 1349 } 1350 #endif 1145 1351 1146 1352 /* Read the mode out of the header entry */ … … 1158 1364 return RTStrToUInt32Full(szMode, 8, pfMode); 1159 1365 } 1366 #endif 1160 1367 1161 1368 RTR3DECL(int) RTTarFileSetMode(RTTARFILE hFile, uint32_t fMode) … … 1179 1386 } 1180 1387 1388 #ifdef RT_UNUSED_API 1181 1389 RTR3DECL(int) RTTarFileGetTime(RTTARFILE hFile, PRTTIMESPEC pTime) 1182 1390 { 1183 1391 PRTTARFILEINTERNAL pFileInt = hFile; 1184 1392 RTTARFILE_VALID_RETURN(pFileInt); 1393 1394 # ifdef RT_USE_TAR_VFS_FOR_ALL_READS 1395 if ((pFileInt->fOpenMode & RTFILE_O_WRITE) != RTFILE_O_WRITE) 1396 { 1397 Assert(pFileInt->hVfsIos != NIL_RTVFSIOSTREAM); 1398 *pTime = pFileInt->VfsModTime; 1399 return VINF_SUCCESS; 1400 } 1401 # endif 1185 1402 1186 1403 /* Read the time out of the header entry */ … … 1205 1422 return rc; 1206 1423 } 1424 #endif /* RT_UNUSED_API */ 1207 1425 1208 1426 RTR3DECL(int) RTTarFileSetTime(RTTARFILE hFile, PRTTIMESPEC pTime) … … 1226 1444 } 1227 1445 1446 #if !defined(RT_USE_TAR_VFS_FOR_ALL_READS) && defined(RT_UNUSED_API) 1228 1447 RTR3DECL(int) RTTarFileGetOwner(RTTARFILE hFile, uint32_t *pUid, uint32_t *pGid) 1229 1448 { … … 1252 1471 return rc; 1253 1472 } 1473 #endif 1254 1474 1255 1475 RTR3DECL(int) RTTarFileSetOwner(RTTARFILE hFile, uint32_t uid, uint32_t gid) … … 1304 1524 ******************************************************************************/ 1305 1525 1526 #ifndef RT_UNUSED_API 1306 1527 RTR3DECL(int) RTTarFileExists(const char *pszTarFile, const char *pszFile) 1307 1528 { … … 1326 1547 return rc; 1327 1548 } 1549 #endif /* RT_UNUSED_API */ 1328 1550 1329 1551 RTR3DECL(int) RTTarList(const char *pszTarFile, char ***ppapszFiles, size_t *pcFiles) … … 1339 1561 if (RT_FAILURE(rc)) 1340 1562 return rc; 1563 1564 #ifdef RT_USE_TAR_VFS_FOR_ALL_READS 1565 /* 1566 * Enumerate the VFS file system stream. 1567 */ 1568 size_t cFiles = 0; 1569 size_t cFilesAllocated = 0; 1570 char **papszFiles = NULL; 1571 for (;;) 1572 { 1573 char *pszName; 1574 RTVFSOBJTYPE enmType; 1575 RTVFSOBJ hVfsObj; 1576 rc = RTVfsFsStrmNext(hTar->hVfsFss, &pszName, &enmType, &hVfsObj); 1577 if (rc == VERR_EOF) 1578 { 1579 RTTarClose(hTar); 1580 *pcFiles = cFiles; 1581 *ppapszFiles = papszFiles; 1582 return VINF_SUCCESS; 1583 } 1584 if (RT_FAILURE(rc)) 1585 break; 1586 1587 if (cFiles >= cFilesAllocated) 1588 { 1589 size_t cNew = !cFilesAllocated ? 64 : cFilesAllocated < _1M ? cFilesAllocated * 2 : cFilesAllocated + _1M; 1590 void *pvNew = RTMemRealloc(papszFiles, cNew * sizeof(char *)); 1591 if (!pvNew) 1592 { 1593 rc = VERR_NO_MEMORY; 1594 RTStrFree(pszName); 1595 RTVfsObjRelease(hVfsObj); 1596 break; 1597 } 1598 cFilesAllocated = cNew; 1599 papszFiles = (char **)pvNew; 1600 } 1601 1602 papszFiles[cFiles++] = pszName; 1603 1604 RTVfsObjRelease(hVfsObj); 1605 } /* Search loop. */ 1606 1607 /* 1608 * Failed, clean up and return. 1609 */ 1610 if (papszFiles) 1611 { 1612 while (cFiles-- > 0) 1613 RTStrFree(papszFiles[cFiles]); 1614 RTMemFree(papszFiles); 1615 } 1616 1617 #else /* !RT_USE_TAR_VFS_FOR_ALL_READS */ 1341 1618 1342 1619 /* This is done by internal methods, cause we didn't have a RTTARDIR … … 1417 1694 RTMemFree(papszFiles); 1418 1695 } 1696 #endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */ 1419 1697 1420 1698 RTTarClose(hTar); … … 1423 1701 } 1424 1702 1703 #if 0 /* broken, using wrong offset when reading. fix+test when _really_ need - use the TAR VFS wherever possible! */ 1425 1704 RTR3DECL(int) RTTarExtractFileToBuf(const char *pszTarFile, void **ppvBuf, size_t *pcbSize, const char *pszFile, 1426 1705 PFNRTPROGRESS pfnProgressCallback, void *pvUser) … … 1495 1774 return rc; 1496 1775 } 1497 1776 #endif 1777 1778 #ifndef RT_USE_TAR_VFS_FOR_ALL_READS /* Unused */ 1498 1779 RTR3DECL(int) RTTarExtractFiles(const char *pszTarFile, const char *pszOutputDir, const char * const *papszFiles, 1499 1780 size_t cFiles, PFNRTPROGRESS pfnProgressCallback, void *pvUser) … … 1548 1829 return rc; 1549 1830 } 1550 1831 #endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */ 1832 1833 #ifndef RT_USE_TAR_VFS_FOR_ALL_READS /* Unused */ 1551 1834 RTR3DECL(int) RTTarExtractAll(const char *pszTarFile, const char *pszOutputDir, PFNRTPROGRESS pfnProgressCallback, void *pvUser) 1552 1835 { … … 1568 1851 return RTTarExtractFiles(pszTarFile, pszOutputDir, papszFiles, cFiles, pfnProgressCallback, pvUser); 1569 1852 } 1853 #endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */ 1570 1854 1571 1855 RTR3DECL(int) RTTarCreate(const char *pszTarFile, const char * const *papszFiles, size_t cFiles, PFNRTPROGRESS pfnProgressCallback, void *pvUser) … … 1621 1905 RTTAR_VALID_RETURN(pInt); 1622 1906 1907 #ifdef RT_USE_TAR_VFS_FOR_ALL_READS 1908 if (!pInt->fStreamMode) 1909 return VERR_INVALID_STATE; 1910 1911 if (!pInt->pszVfsCurName) 1912 { 1913 int rc = RTTarSeekNextFile(pInt); 1914 if (RT_FAILURE(rc)) 1915 return rc; 1916 } 1917 Assert(pInt->pszVfsCurName); 1918 1919 if (ppszFilename) 1920 { 1921 *ppszFilename = RTStrDup(pInt->pszVfsCurName); 1922 if (!*ppszFilename) 1923 return VERR_NO_STR_MEMORY; 1924 } 1925 1926 return pInt->hVfsCur != NIL_RTVFSIOSTREAM ? VINF_SUCCESS : VINF_TAR_DIR_PATH; 1927 1928 #else /* !RT_USE_TAR_VFS_FOR_ALL_READS */ 1623 1929 /* Open and close the file on the current position. This makes sure the 1624 1930 * cache is filled in case we never read something before. On success it … … 1630 1936 1631 1937 return rc; 1938 #endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */ 1632 1939 } 1633 1940 … … 1637 1944 RTTAR_VALID_RETURN(pInt); 1638 1945 1639 int rc = VINF_SUCCESS;1640 1641 1946 if (!pInt->fStreamMode) 1642 1947 return VERR_INVALID_STATE; 1948 1949 #ifdef RT_USE_TAR_VFS_FOR_ALL_READS 1950 /* 1951 * Release the current object. 1952 */ 1953 if (pInt->hVfsCur != NIL_RTVFSIOSTREAM) 1954 { 1955 RTVfsIoStrmRelease(pInt->hVfsCur); 1956 pInt->hVfsCur = NIL_RTVFSIOSTREAM; 1957 } 1958 1959 if (pInt->pszVfsCurName) 1960 { 1961 RTStrFree(pInt->pszVfsCurName); 1962 pInt->pszVfsCurName = NULL; 1963 } 1964 1965 /* 1966 * Find the next file. 1967 */ 1968 for (;;) 1969 { 1970 char *pszName; 1971 RTVFSOBJTYPE enmType; 1972 RTVFSOBJ hVfsObj; 1973 int rc = RTVfsFsStrmNext(hTar->hVfsFss, &pszName, &enmType, &hVfsObj); 1974 if (rc == VERR_EOF) 1975 return VERR_TAR_END_OF_FILE; 1976 1977 if ( enmType == RTVFSOBJTYPE_FILE 1978 || enmType == RTVFSOBJTYPE_IO_STREAM 1979 || enmType == RTVFSOBJTYPE_DIR) 1980 { 1981 pInt->pszVfsCurName = pszName; 1982 if (enmType == RTVFSOBJTYPE_DIR) 1983 rc = VINF_TAR_DIR_PATH; 1984 else 1985 { 1986 pInt->hVfsCur = RTVfsObjToIoStream(hVfsObj); 1987 Assert(pInt->hVfsCur != NIL_RTVFSIOSTREAM); 1988 rc = VINF_SUCCESS; 1989 } 1990 RTVfsObjRelease(hVfsObj); 1991 return rc; 1992 } 1993 RTStrFree(pszName); 1994 RTVfsObjRelease(hVfsObj); 1995 } 1996 1997 #else /* !RT_USE_TAR_VFS_FOR_ALL_READS */ 1998 int rc = VINF_SUCCESS; 1643 1999 1644 2000 /* If there is nothing in the cache, it means we never read something. Just … … 1675 2031 /* Again check the current filename to fill the cache with the new value. */ 1676 2032 return RTTarCurrentFile(hTar, NULL); 2033 #endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */ 1677 2034 } 1678 2035 … … 1689 2046 if (!pInt->fStreamMode) 1690 2047 return VERR_INVALID_STATE; 2048 2049 #ifdef RT_USE_TAR_VFS_FOR_ALL_READS 2050 /* 2051 * Make sure there is a current file (first call w/o RTTarSeekNextFile call). 2052 */ 2053 if (pInt->hVfsCur == NIL_RTVFSIOSTREAM) 2054 { 2055 if (pInt->pszVfsCurName) 2056 return -VINF_TAR_DIR_PATH; 2057 2058 int rc = RTTarSeekNextFile(pInt); 2059 if (RT_FAILURE(rc)) 2060 return rc; 2061 2062 if (pInt->hVfsCur == NIL_RTVFSIOSTREAM) 2063 return -VINF_TAR_DIR_PATH; 2064 } 2065 Assert(pInt->pszVfsCurName); 2066 2067 /* 2068 * Return a copy of the filename if requested. 2069 */ 2070 if (ppszFilename) 2071 { 2072 *ppszFilename = RTStrDup(pInt->pszVfsCurName); 2073 if (!*ppszFilename) 2074 return VERR_NO_STR_MEMORY; 2075 } 2076 2077 /* 2078 * Create a handle for it. 2079 */ 2080 int rc = rtTarFileCreateHandleForReadOnly(RTStrDup(pInt->pszVfsCurName), pInt->hVfsCur, RTFILE_O_READ, phFile); 2081 if (RT_FAILURE(rc) && ppszFilename) 2082 { 2083 RTStrFree(*ppszFilename); 2084 *ppszFilename = NULL; 2085 } 2086 2087 #else /* !RT_USE_TAR_VFS_FOR_ALL_READS */ 1691 2088 1692 2089 int rc = VINF_SUCCESS; … … 1765 2162 *phFile = pFileInt; 1766 2163 1767 return rc; 1768 } 1769 2164 #endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */ 2165 return rc; 2166 } 2167
Note:
See TracChangeset
for help on using the changeset viewer.