diff --git a/src/apps/packageinstaller/PackageInfo.cpp b/src/apps/packageinstaller/PackageInfo.cpp index a8d6bf8da5..dfdb836527 100644 --- a/src/apps/packageinstaller/PackageInfo.cpp +++ b/src/apps/packageinstaller/PackageInfo.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Haiku, Inc. + * Copyright (c) 2007-2009, Haiku, Inc. * Distributed under the terms of the MIT license. * * Author: @@ -67,23 +67,22 @@ PackageInfo::~PackageInfo() pkg_profile *iter = 0; while (1) { iter = static_cast(fProfiles.RemoveItem((long int)0)); - if (iter) - delete iter; - else + if (iter == NULL) break; + + delete iter; } - PkgItem *file = 0; - while (1) { - file = static_cast(fFiles.RemoveItem((long int)0)); - if (file) - delete file; - else + PackageItem *file = 0; + while (true) { + file = static_cast(fFiles.RemoveItem((long int)0)); + if (file == NULL) break; + + delete file; } - if (fPackageFile) - delete fPackageFile; + delete fPackageFile; } @@ -116,7 +115,7 @@ PackageInfo::Parse() off_t actualSize = 0; fPackageFile->GetSize(&actualSize); uint64 fileSize = 0; - + const char padding[7] = { 0, 0, 0, 0, 0, 0, 0 }; system_info sysinfo; @@ -124,9 +123,9 @@ PackageInfo::Parse() uint64 infoOffset = 0, groupsOffset = 0; uint64 length = 0; - + // Parse the file header - while (1) { + while (true) { bytesRead = fPackageFile->Read(buffer, 7); if (bytesRead != 7) { fStatus = B_ERROR; @@ -134,36 +133,30 @@ PackageInfo::Parse() } if (!memcmp(buffer, "PhIn", 5)) { - } - else if (!memcmp(buffer, "FVer", 5)) { + } else if (!memcmp(buffer, "FVer", 5)) { // Not used right now fPackageFile->Seek(4, SEEK_CUR); parser_debug("FVer\n"); - } - else if (!memcmp(buffer, "AFla", 5)) { + } else if (!memcmp(buffer, "AFla", 5)) { // Not used right now TODO: Check what this tag is for fPackageFile->Seek(8, SEEK_CUR); parser_debug("AFla\n"); - } - else if (!memcmp(buffer, "FSiz", 5)) { + } else if (!memcmp(buffer, "FSiz", 5)) { fPackageFile->Read(&fileSize, 8); swap_data(B_UINT64_TYPE, &fileSize, sizeof(uint64), B_SWAP_BENDIAN_TO_HOST); parser_debug("FSiz %llu\n", fileSize); - } - else if (!memcmp(buffer, "COff", 5)) { + } else if (!memcmp(buffer, "COff", 5)) { fPackageFile->Read(&infoOffset, 8); swap_data(B_UINT64_TYPE, &infoOffset, sizeof(uint64), B_SWAP_BENDIAN_TO_HOST); parser_debug("COff %llu\n", infoOffset); - } - else if (!memcmp(buffer, "AOff", 5)) { + } else if (!memcmp(buffer, "AOff", 5)) { fPackageFile->Read(&groupsOffset, 8); swap_data(B_UINT64_TYPE, &groupsOffset, sizeof(uint64), B_SWAP_BENDIAN_TO_HOST); parser_debug("AOff %llu\n", groupsOffset); - } - else if (!memcmp(buffer, padding, 7)) { + } else if (!memcmp(buffer, padding, 7)) { // This means the end of this section - we should move to the // groups section. if (groupsOffset) { @@ -171,8 +164,7 @@ PackageInfo::Parse() } parser_debug("End!\n"); break; - } - else { + } else { fStatus = B_ERROR; return fStatus; } @@ -183,7 +175,7 @@ PackageInfo::Parse() fStatus = B_ERROR; return fStatus; } - + // Section header identifying constant byte sequences: const char groupsMarker[7] = { 0, 0, 0, 1, 0, 0, 4 }; const char idMarker[7] = { 0, 0, 0, 2, 0, 0, 4 }; @@ -195,7 +187,7 @@ PackageInfo::Parse() const char splashScreenMarker[7] = { 0, 0, 0, 8, 0, 0, 3 }; const char disclaimerMarker[7] = { 0, 0, 0, 7, 0, 0, 3 }; - + const char nameMarker[7] = { 0, 0, 0, 13, 0, 0, 2 }; const char versionMarker[7] = { 0, 0, 0, 14, 0, 0, 2 }; const char devMarker[7] = { 0, 0, 0, 15, 0, 0, 2 }; @@ -211,7 +203,7 @@ PackageInfo::Parse() // everytime would be a good idea // Parse the package info section - while (1) { + while (true) { bytesRead = fPackageFile->Read(buffer, 7); if (bytesRead != 7) { parser_debug("EOF!\n"); @@ -222,45 +214,46 @@ PackageInfo::Parse() section = P_GROUPS_SECTION; parser_debug("Got to Groups section\n"); continue; - } - else if (!memcmp(buffer, pathMarker, 7)) { + } else if (!memcmp(buffer, pathMarker, 7)) { section = P_PATH_SECTION; parser_debug("Got to System Paths\n"); continue; - } - else if (!memcmp(buffer, upathMarker, 7)) { + } else if (!memcmp(buffer, upathMarker, 7)) { section = P_USER_PATH_SECTION; parser_debug("Got to User Paths\n"); continue; - } - else if (!memcmp(buffer, licenseMarker, 7)) { + } else if (!memcmp(buffer, licenseMarker, 7)) { section = P_LICENSE_SECTION; parser_debug("Got to License\n"); continue; - } // After this, non sectioned tags follow - else if (!memcmp(buffer, disclaimerMarker, 7)) { + // After this, non sectioned tags follow + } else if (!memcmp(buffer, disclaimerMarker, 7)) { uint64 length; fPackageFile->Read(&length, 8); - swap_data(B_UINT64_TYPE, &length, sizeof(uint64), B_SWAP_BENDIAN_TO_HOST); + swap_data(B_UINT64_TYPE, &length, sizeof(uint64), + B_SWAP_BENDIAN_TO_HOST); uint64 original; if (fPackageFile->Read(&original, 8) != 8) { fStatus = B_ERROR; return fStatus; } - swap_data(B_UINT64_TYPE, &original, sizeof(uint64), B_SWAP_BENDIAN_TO_HOST); + swap_data(B_UINT64_TYPE, &original, sizeof(uint64), + B_SWAP_BENDIAN_TO_HOST); fPackageFile->Seek(4, SEEK_CUR); uint8 *compressed = new uint8[length]; - if (fPackageFile->Read(compressed, length) != static_cast(length)) { + if (fPackageFile->Read(compressed, length) + != static_cast(length)) { fStatus = B_ERROR; delete compressed; return fStatus; } - + uint8 *disclaimer = new uint8[original + 1]; - status_t ret = inflate_data(compressed, length, disclaimer, original); + status_t ret = inflate_data(compressed, length, disclaimer, + original); disclaimer[original] = 0; delete compressed; if (ret != B_OK) { @@ -273,23 +266,25 @@ PackageInfo::Parse() delete disclaimer; continue; - } - else if (!memcmp(buffer, splashScreenMarker, 7)) { + } else if (!memcmp(buffer, splashScreenMarker, 7)) { uint64 length; fPackageFile->Read(&length, 8); - swap_data(B_UINT64_TYPE, &length, sizeof(uint64), B_SWAP_BENDIAN_TO_HOST); + swap_data(B_UINT64_TYPE, &length, sizeof(uint64), + B_SWAP_BENDIAN_TO_HOST); uint64 original; if (fPackageFile->Read(&original, 8) != 8) { fStatus = B_ERROR; return fStatus; } - swap_data(B_UINT64_TYPE, &original, sizeof(uint64), B_SWAP_BENDIAN_TO_HOST); + swap_data(B_UINT64_TYPE, &original, sizeof(uint64), + B_SWAP_BENDIAN_TO_HOST); fPackageFile->Seek(4, SEEK_CUR); uint8 *compressed = new uint8[length]; - if (fPackageFile->Read(compressed, length) != static_cast(length)) { + if (fPackageFile->Read(compressed, length) + != static_cast(length)) { fStatus = B_ERROR; delete compressed; return fStatus; @@ -297,7 +292,8 @@ PackageInfo::Parse() fImage.SetSize(original); status_t ret = inflate_data(compressed, length, - static_cast(const_cast(fImage.Buffer())), original); + static_cast(const_cast(fImage.Buffer())), + original); delete compressed; if (ret != B_OK) { fStatus = B_ERROR; @@ -313,15 +309,15 @@ PackageInfo::Parse() if (!memcmp(buffer, "DPat", 5)) { parser_debug("DPat\n"); continue; - } - else if (!memcmp(buffer, "FDst", 5)) { + } else if (!memcmp(buffer, "FDst", 5)) { parser_debug("FDst - "); directory_which dir; if (fPackageFile->Read(&dir, 4) != 4) { fStatus = B_ERROR; return fStatus; } - swap_data(B_UINT32_TYPE, &dir, sizeof(uint32), B_SWAP_BENDIAN_TO_HOST); + swap_data(B_UINT32_TYPE, &dir, sizeof(uint32), + B_SWAP_BENDIAN_TO_HOST); BPath *path = new BPath(); status_t ret = find_directory(dir, path); if (ret != B_OK) { @@ -332,23 +328,21 @@ PackageInfo::Parse() parser_debug("%s\n", path->Path()); systemPaths.AddItem(path); - } - else if (!memcmp(buffer, "PaNa", 5)) { + } else if (!memcmp(buffer, "PaNa", 5)) { parser_debug("PaNa\n"); if (fPackageFile->Read(&length, 4) != 4) { fStatus = B_ERROR; return fStatus; } - swap_data(B_UINT32_TYPE, &length, sizeof(uint32), B_SWAP_BENDIAN_TO_HOST); - // Since its a default, system path, we can ignore the path name - // - all information needed is beside the FDst tag. + swap_data(B_UINT32_TYPE, &length, sizeof(uint32), + B_SWAP_BENDIAN_TO_HOST); + // Since its a default, system path, we can ignore the path + // name - all information needed is beside the FDst tag. fPackageFile->Seek(length, SEEK_CUR); - } - else if (!memcmp(buffer, padding, 7)) { + } else if (!memcmp(buffer, padding, 7)) { parser_debug("Padding!\n"); continue; - } - else { + } else { fStatus = B_ERROR; return fStatus; } @@ -362,40 +356,39 @@ PackageInfo::Parse() groupStarted = true; group = pkg_profile(); parser_debug("IGrp\n"); - } - else if (!memcmp(buffer, "GrpN", 5)) { + } else if (!memcmp(buffer, "GrpN", 5)) { if (!groupStarted) { fStatus = B_ERROR; return fStatus; } - + parser_debug("GrpN\n"); fPackageFile->Read(&length, 4); - swap_data(B_UINT32_TYPE, &length, sizeof(uint32), B_SWAP_BENDIAN_TO_HOST); + swap_data(B_UINT32_TYPE, &length, sizeof(uint32), + B_SWAP_BENDIAN_TO_HOST); char *name = new char[length + 1]; fPackageFile->Read(name, length); name[length] = 0; group.name = name; delete name; - } - else if (!memcmp(buffer, "GrpD", 5)) { + } else if (!memcmp(buffer, "GrpD", 5)) { if (!groupStarted) { fStatus = B_ERROR; return fStatus; } - + parser_debug("GrpD\n"); fPackageFile->Read(&length, 4); - swap_data(B_UINT32_TYPE, &length, sizeof(uint32), B_SWAP_BENDIAN_TO_HOST); + swap_data(B_UINT32_TYPE, &length, sizeof(uint32), + B_SWAP_BENDIAN_TO_HOST); char *desc = new char[length + 1]; fPackageFile->Read(desc, length); desc[length] = 0; group.description = desc; delete desc; - } - else if (!memcmp(buffer, "GrHt", 5)) { + } else if (!memcmp(buffer, "GrHt", 5)) { if (!groupStarted) { fStatus = B_ERROR; return fStatus; @@ -404,10 +397,10 @@ PackageInfo::Parse() parser_debug("GrHt\n"); // For now, we don't need group help fPackageFile->Read(&length, 4); - swap_data(B_UINT32_TYPE, &length, sizeof(uint32), B_SWAP_BENDIAN_TO_HOST); + swap_data(B_UINT32_TYPE, &length, sizeof(uint32), + B_SWAP_BENDIAN_TO_HOST); fPackageFile->Seek(length, SEEK_CUR); - } - else if (!memcmp(buffer, padding, 5)) { + } else if (!memcmp(buffer, padding, 5)) { if (!groupStarted) { parser_debug("No group - padding!\n"); continue; @@ -415,28 +408,26 @@ PackageInfo::Parse() fProfiles.AddItem(new pkg_profile(group)); parser_debug("Group added: %s %s\n", group.name.String(), - group.description.String()); - + group.description.String()); + groupStarted = false; - } - else if (!memcmp(buffer, "GrId", 5)) { + } else if (!memcmp(buffer, "GrId", 5)) { uint32 id; fPackageFile->Read(&id, 4); - swap_data(B_UINT32_TYPE, &id, sizeof(uint32), B_SWAP_BENDIAN_TO_HOST); + swap_data(B_UINT32_TYPE, &id, sizeof(uint32), + B_SWAP_BENDIAN_TO_HOST); parser_debug("GrId\n"); - + if (id == 0xffffffff) groups.AddItem(NULL); else groups.AddItem(fProfiles.ItemAt(id)); - } - else if (!memcmp(buffer, idMarker, 7) || - !memcmp(buffer, groupsMarker, 7)) { + } else if (!memcmp(buffer, idMarker, 7) + || !memcmp(buffer, groupsMarker, 7)) { parser_debug("Marker, jumping!\n"); continue; - } - else { + } else { fStatus = B_ERROR; return fStatus; } @@ -447,25 +438,24 @@ PackageInfo::Parse() { if (!memcmp(buffer, "Lic?", 5)) { parser_debug("Lic?\n"); - // This tag informs whether a license is present in the package - // or not. Since we don't care about licenses right now, just - // skip this section + // This tag informs whether a license is present in the + // package or not. Since we don't care about licenses right + // now, just skip this section fPackageFile->Seek(4, SEEK_CUR); - } - else if (!memcmp(buffer, "LicP", 5)) { + } else if (!memcmp(buffer, "LicP", 5)) { parser_debug("LicP\n"); fPackageFile->Read(&length, 4); - swap_data(B_UINT32_TYPE, &length, sizeof(uint32), B_SWAP_BENDIAN_TO_HOST); - + swap_data(B_UINT32_TYPE, &length, sizeof(uint32), + B_SWAP_BENDIAN_TO_HOST); + fPackageFile->Seek(length, SEEK_CUR); - } - else if (!memcmp(buffer, padding, 7)) { + } else if (!memcmp(buffer, padding, 7)) { continue; - } - else if (!memcmp(buffer, descMarker, 7)) { + } else if (!memcmp(buffer, descMarker, 7)) { parser_debug("Description text reached\n"); fPackageFile->Read(&length, 4); - swap_data(B_UINT32_TYPE, &length, sizeof(uint32), B_SWAP_BENDIAN_TO_HOST); + swap_data(B_UINT32_TYPE, &length, sizeof(uint32), + B_SWAP_BENDIAN_TO_HOST); char *description = new char[length + 1]; fPackageFile->Read(description, length); @@ -473,22 +463,24 @@ PackageInfo::Parse() fDescription = description; // Truncate all leading newlines - for (i = 0;i < length;i++) + for (i = 0; i < length; i++) { if (fDescription[i] != '\n') break; + } fDescription.Remove(0, i); delete description; parser_debug("Description text reached\n"); - - // After this, there's a known size sequence of bytes, which meaning - // is yet to be determined. - // One is already known. The byte (or just its least significant bit) - // at offset 21 from the description text is responsible for the - // install folder existence information. If it is 0, there is no - // install folder, if it is 1 (or the least significant bit is set) - // it means we should install all 0xffffffff files/directories to + // After this, there's a known size sequence of bytes, which + // meaning is yet to be determined. + + // One is already known. The byte (or just its least + // significant bit) at offset 21 from the description text + // is responsible for the install folder existence + // information. If it is 0, there is no install folder, if + // it is 1 (or the least significant bit is set) it means + // we should install all 0xffffffff files/directories to // the first directory existing in the package fPackageFile->Seek(21, SEEK_CUR); if (fPackageFile->Read(&installDirectoryFlag, 1) != 1) { @@ -497,52 +489,51 @@ PackageInfo::Parse() } fPackageFile->Seek(11, SEEK_CUR); - } - else if (!memcmp(buffer, nameMarker, 7)) { + } else if (!memcmp(buffer, nameMarker, 7)) { parser_debug("Package name reached\n"); fPackageFile->Read(&length, 4); - swap_data(B_UINT32_TYPE, &length, sizeof(uint32), B_SWAP_BENDIAN_TO_HOST); + swap_data(B_UINT32_TYPE, &length, sizeof(uint32), + B_SWAP_BENDIAN_TO_HOST); char *name = new char[length + 1]; fPackageFile->Read(name, length); name[length] = 0; fName = name; delete name; - } - else if (!memcmp(buffer, versionMarker, 7)) { + } else if (!memcmp(buffer, versionMarker, 7)) { parser_debug("Package version reached\n"); fPackageFile->Read(&length, 4); - swap_data(B_UINT32_TYPE, &length, sizeof(uint32), B_SWAP_BENDIAN_TO_HOST); + swap_data(B_UINT32_TYPE, &length, sizeof(uint32), + B_SWAP_BENDIAN_TO_HOST); char *version = new char[length + 1]; fPackageFile->Read(version, length); version[length] = 0; fVersion = version; delete version; - } - else if (!memcmp(buffer, devMarker, 7)) { + } else if (!memcmp(buffer, devMarker, 7)) { parser_debug("Package developer reached\n"); fPackageFile->Read(&length, 4); - swap_data(B_UINT32_TYPE, &length, sizeof(uint32), B_SWAP_BENDIAN_TO_HOST); + swap_data(B_UINT32_TYPE, &length, sizeof(uint32), + B_SWAP_BENDIAN_TO_HOST); char *dev = new char[length + 1]; fPackageFile->Read(dev, length); dev[length] = 0; fDeveloper = dev; delete dev; - } - else if (!memcmp(buffer, shortDescMarker, 7)) { + } else if (!memcmp(buffer, shortDescMarker, 7)) { parser_debug("Package short description reached\n"); fPackageFile->Read(&length, 4); - swap_data(B_UINT32_TYPE, &length, sizeof(uint32), B_SWAP_BENDIAN_TO_HOST); + swap_data(B_UINT32_TYPE, &length, sizeof(uint32), + B_SWAP_BENDIAN_TO_HOST); char *desc = new char[length + 1]; fPackageFile->Read(desc, length); desc[length] = 0; fShortDesc = desc; delete desc; - } - else if (!memcmp(buffer, helpMarker, 7)) { + } else if (!memcmp(buffer, helpMarker, 7)) { // The help text is a stored in deflated state, preceded by a 64 bit // compressed size, 64 bit inflated size and a 32 bit integer // Since there was no discussion whether we need this help text, @@ -550,8 +541,9 @@ PackageInfo::Parse() parser_debug("Help text reached\n"); //uint64 length64; fPackageFile->Read(&length, 8); - swap_data(B_UINT64_TYPE, &length, sizeof(uint64), B_SWAP_BENDIAN_TO_HOST); - + swap_data(B_UINT64_TYPE, &length, sizeof(uint64), + B_SWAP_BENDIAN_TO_HOST); + fPackageFile->Seek(12 + length, SEEK_CUR); } break; @@ -562,12 +554,12 @@ PackageInfo::Parse() if (!memcmp(buffer, "DPat", 5)) { parser_debug("DPat\n"); continue; - } - else if (!memcmp(buffer, "PaNa", 5)) { + } else if (!memcmp(buffer, "PaNa", 5)) { parser_debug("PaNa\n"); fPackageFile->Read(&length, 4); - swap_data(B_UINT32_TYPE, &length, sizeof(uint32), B_SWAP_BENDIAN_TO_HOST); - + swap_data(B_UINT32_TYPE, &length, sizeof(uint32), + B_SWAP_BENDIAN_TO_HOST); + char *pathname = new char[length + 1]; fPackageFile->Read(pathname, length); pathname[length] = 0; @@ -576,12 +568,10 @@ PackageInfo::Parse() path->Remove(length - 1, 1); userPaths.AddItem(path); delete pathname; - } - else if (!memcmp(buffer, padding, 7)) { + } else if (!memcmp(buffer, padding, 7)) { parser_debug("Padding!\n"); continue; - } - else { + } else { fStatus = B_ERROR; return fStatus; } @@ -595,17 +585,16 @@ PackageInfo::Parse() uint32 directoryCount = 0; uint8 element = P_NONE; - uint32 itemGroups = 0, path = 0, cust = 0, ctime = 0, mtime = 0, - platform = 0xffffffff; + uint32 itemGroups = 0, path = 0, cust = 0, ctime = 0, mtime = 0; + uint32 platform = 0xffffffff; uint64 offset = 0, size = 0, originalSize = 0, mode = 0; uint8 pathType = P_INSTALL_PATH; - status_t ret; fPackageFile->Seek(infoOffset, SEEK_SET); // Parse package file data - while (1) { + while (true) { bytesRead = fPackageFile->Read(buffer, 7); if (bytesRead != 7) { fStatus = B_ERROR; @@ -613,14 +602,14 @@ PackageInfo::Parse() } // TODO: Here's the deal... there seems to be a strange ScrI tag that - // seems to mean script files (check this). It seems exaclty the same - // as a normal file (just as script files are normal files) so for - // now I'm treating those as files. Check if it's correct! - // No, it isn't and I will fix this soon. + // seems to mean script files (check this). It seems exaclty the same + // as a normal file (just as script files are normal files) so for + // now I'm treating those as files. Check if it's correct! + // No, it isn't and I will fix this soon. if (!memcmp(buffer, "FilI", 5) || !memcmp(buffer, "ScrI", 5)) { parser_debug("FilI\n"); element = P_FILE; - + mimeString = ""; nameString = ""; signatureString = ""; @@ -636,11 +625,10 @@ PackageInfo::Parse() size = 0; originalSize = 0; - } - else if (!memcmp(buffer, "FldI", 5)) { + } else if (!memcmp(buffer, "FldI", 5)) { parser_debug("FldI\n"); element = P_DIRECTORY; - + nameString = ""; itemGroups = 0; @@ -650,11 +638,10 @@ PackageInfo::Parse() itemGroups = 0; cust = 0; platform = 0xffffffff; - + size = 0; originalSize = 0; - } - else if (!memcmp(buffer, "LnkI", 5)) { + } else if (!memcmp(buffer, "LnkI", 5)) { parser_debug("LnkI\n"); element = P_LINK; @@ -668,11 +655,10 @@ PackageInfo::Parse() itemGroups = 0; cust = 0; platform = 0xffffffff; - + size = 0; originalSize = 0; - } - else if (!memcmp(buffer, "Name", 5)) { + } else if (!memcmp(buffer, "Name", 5)) { if (element == P_NONE) { fStatus = B_ERROR; return fStatus; @@ -680,7 +666,8 @@ PackageInfo::Parse() parser_debug("Name\n"); fPackageFile->Read(&length, 4); - swap_data(B_UINT32_TYPE, &length, sizeof(uint32), B_SWAP_BENDIAN_TO_HOST); + swap_data(B_UINT32_TYPE, &length, sizeof(uint32), + B_SWAP_BENDIAN_TO_HOST); char *name = new char[length + 1]; fPackageFile->Read(name, length); @@ -688,18 +675,17 @@ PackageInfo::Parse() nameString = name; delete name; - } - else if (!memcmp(buffer, "Grps", 5)) { + } else if (!memcmp(buffer, "Grps", 5)) { if (element == P_NONE) { fStatus = B_ERROR; return fStatus; } - + parser_debug("Grps\n"); fPackageFile->Read(&itemGroups, 4); - swap_data(B_UINT32_TYPE, &itemGroups, sizeof(uint32), B_SWAP_BENDIAN_TO_HOST); - } - else if (!memcmp(buffer, "Dest", 5)) { + swap_data(B_UINT32_TYPE, &itemGroups, sizeof(uint32), + B_SWAP_BENDIAN_TO_HOST); + } else if (!memcmp(buffer, "Dest", 5)) { if (element == P_NONE) { fStatus = B_ERROR; return fStatus; @@ -707,9 +693,9 @@ PackageInfo::Parse() parser_debug("Dest\n"); fPackageFile->Read(&path, 4); - swap_data(B_UINT32_TYPE, &path, sizeof(uint32), B_SWAP_BENDIAN_TO_HOST); - } - else if (!memcmp(buffer, "Cust", 5)) { + swap_data(B_UINT32_TYPE, &path, sizeof(uint32), + B_SWAP_BENDIAN_TO_HOST); + } else if (!memcmp(buffer, "Cust", 5)) { if (element == P_NONE) { fStatus = B_ERROR; return fStatus; @@ -717,9 +703,9 @@ PackageInfo::Parse() parser_debug("Cust\n"); fPackageFile->Read(&cust, 4); - swap_data(B_UINT32_TYPE, &cust, sizeof(uint32), B_SWAP_BENDIAN_TO_HOST); - } - else if (!memcmp(buffer, "Repl", 5)) { + swap_data(B_UINT32_TYPE, &cust, sizeof(uint32), + B_SWAP_BENDIAN_TO_HOST); + } else if (!memcmp(buffer, "Repl", 5)) { if (element == P_NONE) { fStatus = B_ERROR; return fStatus; @@ -729,18 +715,17 @@ PackageInfo::Parse() fPackageFile->Seek(4, SEEK_CUR); // TODO: Should the replace philosophy depend on this flag? For now // I always leave the decision to the user - } - else if (!memcmp(buffer, "Plat", 5)) { + } else if (!memcmp(buffer, "Plat", 5)) { if (element == P_NONE) { fStatus = B_ERROR; return fStatus; } - + parser_debug("Plat\n"); fPackageFile->Read(&platform, 4); - swap_data(B_UINT32_TYPE, &platform, sizeof(uint32), B_SWAP_BENDIAN_TO_HOST); - } - else if (!memcmp(buffer, "CTim", 5)) { + swap_data(B_UINT32_TYPE, &platform, sizeof(uint32), + B_SWAP_BENDIAN_TO_HOST); + } else if (!memcmp(buffer, "CTim", 5)) { if (element == P_NONE) { fStatus = B_ERROR; return fStatus; @@ -748,9 +733,9 @@ PackageInfo::Parse() parser_debug("CTim\n"); fPackageFile->Read(&ctime, 4); - swap_data(B_UINT32_TYPE, &ctime, sizeof(uint32), B_SWAP_BENDIAN_TO_HOST); - } - else if (!memcmp(buffer, "MTim", 5)) { + swap_data(B_UINT32_TYPE, &ctime, sizeof(uint32), + B_SWAP_BENDIAN_TO_HOST); + } else if (!memcmp(buffer, "MTim", 5)) { if (element == P_NONE) { fStatus = B_ERROR; return fStatus; @@ -758,9 +743,9 @@ PackageInfo::Parse() parser_debug("MTim\n"); fPackageFile->Read(&mtime, 4); - swap_data(B_UINT32_TYPE, &mtime, sizeof(uint32), B_SWAP_BENDIAN_TO_HOST); - } - else if (!memcmp(buffer, "OffT", 5)) { + swap_data(B_UINT32_TYPE, &mtime, sizeof(uint32), + B_SWAP_BENDIAN_TO_HOST); + } else if (!memcmp(buffer, "OffT", 5)) { if (element == P_NONE) { fStatus = B_ERROR; return fStatus; @@ -768,17 +753,18 @@ PackageInfo::Parse() parser_debug("OffT\n"); fPackageFile->Read(&offset, 8); - swap_data(B_UINT64_TYPE, &offset, sizeof(uint64), B_SWAP_BENDIAN_TO_HOST); - } - else if (!memcmp(buffer, "Mime", 5)) { + swap_data(B_UINT64_TYPE, &offset, sizeof(uint64), + B_SWAP_BENDIAN_TO_HOST); + } else if (!memcmp(buffer, "Mime", 5)) { if (element != P_FILE) { fStatus = B_ERROR; return fStatus; } fPackageFile->Read(&length, 4); - swap_data(B_UINT32_TYPE, &length, sizeof(uint32), B_SWAP_BENDIAN_TO_HOST); - + swap_data(B_UINT32_TYPE, &length, sizeof(uint32), + B_SWAP_BENDIAN_TO_HOST); + char *mime = new char[length + 1]; fPackageFile->Read(mime, length); mime[length] = 0; @@ -786,8 +772,7 @@ PackageInfo::Parse() mimeString = mime; delete mime; - } - else if (!memcmp(buffer, "CmpS", 5)) { + } else if (!memcmp(buffer, "CmpS", 5)) { if (element == P_NONE) { fStatus = B_ERROR; return fStatus; @@ -795,9 +780,9 @@ PackageInfo::Parse() parser_debug("CmpS\n"); fPackageFile->Read(&size, 8); - swap_data(B_UINT64_TYPE, &size, sizeof(uint64), B_SWAP_BENDIAN_TO_HOST); - } - else if (!memcmp(buffer, "OrgS", 5)) { + swap_data(B_UINT64_TYPE, &size, sizeof(uint64), + B_SWAP_BENDIAN_TO_HOST); + } else if (!memcmp(buffer, "OrgS", 5)) { if (element != P_FILE && element != P_LINK) { fStatus = B_ERROR; return fStatus; @@ -805,46 +790,45 @@ PackageInfo::Parse() parser_debug("OrgS\n"); fPackageFile->Read(&originalSize, 8); - swap_data(B_UINT64_TYPE, &originalSize, sizeof(uint64), B_SWAP_BENDIAN_TO_HOST); - } - else if (!memcmp(buffer, "VrsI", 5)) { + swap_data(B_UINT64_TYPE, &originalSize, sizeof(uint64), + B_SWAP_BENDIAN_TO_HOST); + } else if (!memcmp(buffer, "VrsI", 5)) { if (element != P_FILE) { fStatus = B_ERROR; return fStatus; } - + parser_debug("VrsI\n"); fPackageFile->Seek(24, SEEK_CUR); // TODO // Also, check what those empty 20 bytes mean - } - else if (!memcmp(buffer, "Mode", 5)) { + } else if (!memcmp(buffer, "Mode", 5)) { if (element != P_FILE && element != P_LINK) { fStatus = B_ERROR; return fStatus; } - + parser_debug("Mode\n"); fPackageFile->Read(&mode, 4); - swap_data(B_UINT32_TYPE, &mode, sizeof(uint32), B_SWAP_BENDIAN_TO_HOST); - } - else if (!memcmp(buffer, "FDat", 5)) { + swap_data(B_UINT32_TYPE, &mode, sizeof(uint32), + B_SWAP_BENDIAN_TO_HOST); + } else if (!memcmp(buffer, "FDat", 5)) { if (element != P_DIRECTORY) { fStatus = B_ERROR; return fStatus; } - + parser_debug("FDat\n"); - } - else if (!memcmp(buffer, "ASig", 5)) { + } else if (!memcmp(buffer, "ASig", 5)) { if (element != P_FILE) { fStatus = B_ERROR; return fStatus; } fPackageFile->Read(&length, 4); - swap_data(B_UINT32_TYPE, &length, sizeof(uint32), B_SWAP_BENDIAN_TO_HOST); - + swap_data(B_UINT32_TYPE, &length, sizeof(uint32), + B_SWAP_BENDIAN_TO_HOST); + char *signature = new char[length + 1]; fPackageFile->Read(signature, length); signature[length] = 0; @@ -852,16 +836,16 @@ PackageInfo::Parse() signatureString = signature; delete signature; - } - else if (!memcmp(buffer, "Link", 5)) { + } else if (!memcmp(buffer, "Link", 5)) { if (element != P_LINK) { fStatus = B_ERROR; return fStatus; } fPackageFile->Read(&length, 4); - swap_data(B_UINT32_TYPE, &length, sizeof(uint32), B_SWAP_BENDIAN_TO_HOST); - + swap_data(B_UINT32_TYPE, &length, sizeof(uint32), + B_SWAP_BENDIAN_TO_HOST); + char *link = new char[length + 1]; fPackageFile->Read(link, length); link[length] = 0; @@ -869,32 +853,31 @@ PackageInfo::Parse() linkString = link; delete link; - } - else if (!memcmp(buffer, padding, 7)) { - PkgItem *item = 0; - + } else if (!memcmp(buffer, padding, 7)) { + PackageItem *item = NULL; + parser_debug("Padding!\n"); - if (platform != 0xffffffff && - static_cast(platform) != sysinfo.platform_type) { + if (platform != 0xffffffff + && static_cast(platform) + != sysinfo.platform_type) { // If the file/directory/item's platform is different than the - // target platform (or different than the 'any' constant), ignore - // this file - } - else if (element == P_FILE) { + // target platform (or different than the 'any' constant), + // ignore this file + } else if (element == P_FILE) { if (itemGroups && offset && size) { BString dest = ""; uint8 localType = pathType; - + if (path == 0xfffffffe) dest << itemPath << "/" << nameString.String(); else if (path == 0xffffffff) { localType = P_INSTALL_PATH; dest = installDirectory; dest << nameString; - } - else { + } else { if (cust) { - BString *def = static_cast(userPaths.ItemAt(path)); + BString *def = static_cast( + userPaths.ItemAt(path)); if (!def) { fStatus = B_ERROR; return fStatus; @@ -903,11 +886,11 @@ PackageInfo::Parse() localType = P_SYSTEM_PATH; else localType = P_USER_PATH; - + dest << *def << "/" << nameString; - } - else { - BPath *def = static_cast(systemPaths.ItemAt(path)); + } else { + BPath *def = static_cast( + systemPaths.ItemAt(path)); if (!def) { fStatus = B_ERROR; return fStatus; @@ -918,28 +901,32 @@ PackageInfo::Parse() } } - item = new PkgFile(fPackageFile, dest, localType, ctime, mtime, - offset, size, originalSize, 0, mimeString, signatureString, mode); parser_debug("Adding file: %s!\n", dest.String()); + + item = new PackageFile(fPackageFile, dest, localType, ctime, + mtime, offset, size, originalSize, 0, mimeString, + signatureString, mode); } - } - else if (element == P_DIRECTORY) { + } else if (element == P_DIRECTORY) { if (itemGroups) { if (installDirectoryFlag != 0) { - if (installDirectoryFlag < 0) { // Normal directory - if (path == 0xfffffffe) { // Install to current directory + if (installDirectoryFlag < 0) { + // Normal directory + if (path == 0xfffffffe) { + // Install to current directory itemPath << "/" << nameString.String(); directoryCount++; - } - else if (path == 0xffffffff) { // Install to install directory + } else if (path == 0xffffffff) { + // Install to install directory pathType = P_INSTALL_PATH; itemPath = installDirectory; itemPath << nameString; directoryCount = 1; - } - else { // Install to defined directory + } else { + // Install to defined directory if (cust) { - BString *def = static_cast(userPaths.ItemAt(path)); + BString *def = static_cast( + userPaths.ItemAt(path)); if (!def) { fStatus = B_ERROR; return fStatus; @@ -950,60 +937,59 @@ PackageInfo::Parse() pathType = P_USER_PATH; itemPath = *def; - } - else { - BPath *def = static_cast(systemPaths.ItemAt(path)); + } else { + BPath *def = static_cast( + systemPaths.ItemAt(path)); if (!def) { fStatus = B_ERROR; return fStatus; } pathType = P_SYSTEM_PATH; - + itemPath = def->Path(); } - + itemPath << "/" << nameString; directoryCount = 1; } - } - else { // Install directory + } else { + // Install directory if (path != 0xffffffff) { fStatus = B_ERROR; return fStatus; } - + installDirectory = nameString; installDirectory << "/"; pathType = P_INSTALL_PATH; itemPath = nameString; - + installDirectoryFlag = -1; } - - parser_debug("Adding the directory %s!\n", itemPath.String()); - item = new PkgDirectory(fPackageFile, itemPath, pathType, ctime, - mtime, offset, size); - } - else { + + parser_debug("Adding the directory %s!\n", + itemPath.String()); + + item = new PackageDirectory(fPackageFile, itemPath, + pathType, ctime, mtime, offset, size); + } else installDirectoryFlag = -1; - } } - } - else if (element == P_LINK) { + } else if (element == P_LINK) { if (itemGroups && linkString.Length()) { BString dest = ""; uint8 localType = pathType; - + if (path == 0xfffffffe) dest << itemPath << "/" << nameString.String(); else if (path == 0xffffffff) { localType = P_INSTALL_PATH; dest = installDirectory; dest << nameString; - } - else { + } else { if (cust) { - BString *def = static_cast(userPaths.ItemAt(path)); + BString *def = static_cast( + userPaths.ItemAt(path)); if (!def) { fStatus = B_ERROR; return fStatus; @@ -1014,8 +1000,7 @@ PackageInfo::Parse() localType = P_USER_PATH; dest << *def << "/" << nameString; - } - else { + } else { BPath *def = static_cast(systemPaths.ItemAt(path)); if (!def) { fStatus = B_ERROR; @@ -1028,13 +1013,14 @@ PackageInfo::Parse() } parser_debug("Adding link: %s! (type %s)\n", dest.String(), - pathType == P_SYSTEM_PATH ? "System" - : (localType == P_INSTALL_PATH ? "Install" : "User")); - item = new PkgLink(fPackageFile, dest, linkString, localType, - ctime, mtime, mode, offset, size); + pathType == P_SYSTEM_PATH + ? "System" : localType == P_INSTALL_PATH + ? "Install" : "User"); + + item = new PackageLink(fPackageFile, dest, linkString, + localType, ctime, mtime, mode, offset, size); } - } - else { + } else { // If the directory tree count is equal to zero, this means all // directory trees have been closed and a padding sequence means the // end of the section @@ -1089,8 +1075,8 @@ PackageInfo::Parse() void -PackageInfo::_AddItem(PkgItem *item, uint64 size, uint32 groups, uint32 path, - uint32 cust) +PackageInfo::_AddItem(PackageItem *item, uint64 size, uint32 groups, + uint32 path, uint32 cust) { // Add the item to all groups it resides in uint32 i, n = fProfiles.CountItems(), mask = 1; diff --git a/src/apps/packageinstaller/PackageInfo.h b/src/apps/packageinstaller/PackageInfo.h index 81ab800294..a6e341a647 100644 --- a/src/apps/packageinstaller/PackageInfo.h +++ b/src/apps/packageinstaller/PackageInfo.h @@ -38,8 +38,8 @@ class PackageInfo { status_t InitCheck() { return fStatus; } private: - void _AddItem(PkgItem *item, uint64 size, uint32 groups, uint32 path, - uint32 cust); + void _AddItem(PackageItem *item, uint64 size, uint32 groups, + uint32 path, uint32 cust); status_t fStatus; diff --git a/src/apps/packageinstaller/PackageItem.cpp b/src/apps/packageinstaller/PackageItem.cpp index 44c4422620..98f32f87dd 100644 --- a/src/apps/packageinstaller/PackageItem.cpp +++ b/src/apps/packageinstaller/PackageItem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Haiku, Inc. + * Copyright (c) 2007-2009, Haiku, Inc. * Distributed under the terms of the MIT license. * * Author: @@ -36,13 +36,13 @@ enum { status_t -inflate_data(uint8 *in, uint32 in_size, uint8 *out, uint32 out_size) +inflate_data(uint8 *in, uint32 inSize, uint8 *out, uint32 outSize) { z_stream stream; stream.zalloc = Z_NULL; stream.zfree = Z_NULL; stream.opaque = Z_NULL; - stream.avail_in = in_size; + stream.avail_in = inSize; stream.next_in = in; status_t ret; @@ -52,17 +52,17 @@ inflate_data(uint8 *in, uint32 in_size, uint8 *out, uint32 out_size) return B_ERROR; } - stream.avail_out = out_size; + stream.avail_out = outSize; stream.next_out = out; ret = inflate(&stream, Z_NO_FLUSH); if (ret != Z_STREAM_END) { + // Uncompressed file size in package info corrupted parser_debug("Left: %d\n", stream.avail_out); - return B_ERROR; // Uncompressed file size in package info corrupted + return B_ERROR; } - (void)inflateEnd(&stream); - + inflateEnd(&stream); return B_OK; } @@ -130,30 +130,28 @@ inflate_file_to_file(BFile *in, uint64 in_size, BFile *out, uint64 out_size) } -// #pragma mark - +// #pragma mark - PackageItem -PkgDirectory::PkgDirectory(BFile *parent, BString path, uint8 type, uint32 ctime, - uint32 mtime, uint64 offset, uint64 size) - : - fPath(path), - fOffset(offset), - fSize(size), - fPathType(type), - fCreationTime(ctime), - fModificationTime(mtime), - fPackage(parent) +PackageItem::PackageItem(BFile *parent, const BString &path, uint8 type, + uint32 ctime, uint32 mtime, uint64 offset, uint64 size) +{ + SetTo(parent, path, type, ctime, mtime, offset, size); +} + + +PackageItem::~PackageItem() { } void -PkgDirectory::SetTo(BFile *parent, BString path, uint8 type, uint32 ctime, - uint32 mtime, uint64 offset, uint64 size) +PackageItem::SetTo(BFile *parent, const BString &path, uint8 type, uint32 ctime, + uint32 mtime, uint64 offset, uint64 size) { fPackage = parent; fPath = path; - + fOffset = offset; fSize = size; fPathType = type; @@ -162,55 +160,15 @@ PkgDirectory::SetTo(BFile *parent, BString path, uint8 type, uint32 ctime, } -PkgDirectory::~PkgDirectory() -{ -} - - -status_t -PkgDirectory::WriteToPath(const char *path, BPath *final) -{ - BPath destination; - status_t ret; - parser_debug("Directory: %s WriteToPath() called!\n", fPath.String()); - - ret = _InitPath(path, &destination); - if (ret != B_OK) - return ret; - - // Since Haiku is single-user right now, we give the newly - // created directory default permissions - ret = create_directory(destination.Path(), kDefaultMode); - if (ret != B_OK) - return ret; - BDirectory dir(destination.Path()); - parser_debug("Directory created!\n"); - - if (fCreationTime) - dir.SetCreationTime(static_cast(fCreationTime)); - - if (fModificationTime) - dir.SetModificationTime(static_cast(fModificationTime)); - - // Since directories can only have attributes in the offset section, - // we can check here whether it is necessary to continue - if (fOffset) { - ret = _HandleAttributes(&destination, &dir, "FoDa"); - } - - if (final) { - *final = destination; - } - - return ret; -} - - int32 -PkgDirectory::_ItemExists(const char *name) +PackageItem::ItemExists(const char *name) { - BString alertString = T("The file named"); - alertString << " \'" << name << "\' "; + // TODO: this function doesn't really fit in, the GUI should be separated + // from the package engine completely + + BString alertString = "The "; + + alertString << ItemKind() << " named \'" << name << "\' "; alertString << T("already exists in the given path. Should I replace " "the existing file with the one from this package?"); @@ -222,13 +180,13 @@ PkgDirectory::_ItemExists(const char *name) status_t -PkgDirectory::_InitPath(const char *path, BPath *destination) +PackageItem::InitPath(const char *path, BPath *destination) { status_t ret = B_OK; if (fPathType == P_INSTALL_PATH) { if (!path) { - parser_debug("_InitPath path is NULL\n"); + parser_debug("InitPath path is NULL\n"); return B_ERROR; } ret = destination->SetTo(path, fPath.String()); @@ -237,7 +195,7 @@ PkgDirectory::_InitPath(const char *path, BPath *destination) ret = destination->SetTo(fPath.String()); else { if (!path) { - parser_debug("_InitPath path is NULL\n"); + parser_debug("InitPath path is NULL\n"); return B_ERROR; } @@ -260,8 +218,8 @@ PkgDirectory::_InitPath(const char *path, BPath *destination) status_t -PkgDirectory::_HandleAttributes(BPath *destination, BNode *node, - const char *header) +PackageItem::HandleAttributes(BPath *destination, BNode *node, + const char *header) { status_t ret = B_OK; @@ -297,12 +255,14 @@ PkgDirectory::_HandleAttributes(BPath *destination, BNode *node, if (!memcmp(buffer, "FBeA", 5)) continue; - ret = _ParseAttribute(buffer, node, &attrName, &nameSize, &attrType, - &attrData, &dataSize, &temp, &tempSize, &attrCSize, &attrOSize, - &attrStarted, &done); + ret = ParseAttribute(buffer, node, &attrName, &nameSize, &attrType, + &attrData, &dataSize, &temp, &tempSize, &attrCSize, &attrOSize, + &attrStarted, &done); if (ret != B_OK || done) { - if (ret != B_OK) - parser_debug("_ParseAttribute failed for %s\n", destination->Path()); + if (ret != B_OK) { + parser_debug("_ParseAttribute failed for %s\n", + destination->Path()); + } break; } } @@ -315,11 +275,11 @@ PkgDirectory::_HandleAttributes(BPath *destination, BNode *node, } -inline status_t -PkgDirectory::_ParseAttribute(uint8 *buffer, BNode *node, char **attrName, - uint32 *nameSize, uint32 *attrType, uint8 **attrData, uint64 *dataSize, - uint8 **temp, uint64 *tempSize, uint64 *attrCSize, uint64 *attrOSize, - bool *attrStarted, bool *done) +status_t +PackageItem::ParseAttribute(uint8 *buffer, BNode *node, char **attrName, + uint32 *nameSize, uint32 *attrType, uint8 **attrData, uint64 *dataSize, + uint8 **temp, uint64 *tempSize, uint64 *attrCSize, uint64 *attrOSize, + bool *attrStarted, bool *done) { status_t ret = B_OK; uint32 length; @@ -332,8 +292,7 @@ PkgDirectory::_ParseAttribute(uint8 *buffer, BNode *node, char **attrName, *attrOSize = 0; *attrStarted = true; - } - else if (!memcmp(buffer, "BeAN", 5)) { + } else if (!memcmp(buffer, "BeAN", 5)) { if (!*attrStarted) { ret = B_ERROR; return ret; @@ -341,7 +300,8 @@ PkgDirectory::_ParseAttribute(uint8 *buffer, BNode *node, char **attrName, parser_debug(" BeAN.\n"); fPackage->Read(&length, 4); - swap_data(B_UINT32_TYPE, &length, sizeof(uint32), B_SWAP_BENDIAN_TO_HOST); + swap_data(B_UINT32_TYPE, &length, sizeof(uint32), + B_SWAP_BENDIAN_TO_HOST); if (*nameSize < (length + 1)) { delete *attrName; @@ -352,8 +312,7 @@ PkgDirectory::_ParseAttribute(uint8 *buffer, BNode *node, char **attrName, (*attrName)[length] = 0; parser_debug(" (%ld) = %s\n", length, *attrName); - } - else if (!memcmp(buffer, "BeAT", 5)) { + } else if (!memcmp(buffer, "BeAT", 5)) { if (!*attrStarted) { ret = B_ERROR; return ret; @@ -363,8 +322,7 @@ PkgDirectory::_ParseAttribute(uint8 *buffer, BNode *node, char **attrName, fPackage->Read(attrType, 4); swap_data(B_UINT32_TYPE, attrType, sizeof(*attrType), B_SWAP_BENDIAN_TO_HOST); - } - else if (!memcmp(buffer, "BeAD", 5)) { + } else if (!memcmp(buffer, "BeAD", 5)) { if (!*attrStarted) { ret = B_ERROR; return ret; @@ -380,7 +338,7 @@ PkgDirectory::_ParseAttribute(uint8 *buffer, BNode *node, char **attrName, B_SWAP_BENDIAN_TO_HOST); fPackage->Seek(4, SEEK_CUR); // TODO: Check what this means - + if (*tempSize < *attrCSize) { delete *temp; *tempSize = *attrCSize; @@ -402,8 +360,7 @@ PkgDirectory::_ParseAttribute(uint8 *buffer, BNode *node, char **attrName, ret = inflate_data(*temp, *tempSize, *attrData, *dataSize); if (ret != B_OK) return ret; - } - else if (!memcmp(buffer, padding, 7)) { + } else if (!memcmp(buffer, padding, 7)) { if (!*attrStarted) { *done = true; return ret; @@ -412,7 +369,7 @@ PkgDirectory::_ParseAttribute(uint8 *buffer, BNode *node, char **attrName, parser_debug(" Padding.\n"); ssize_t wrote = node->WriteAttr(*attrName, *attrType, 0, *attrData, *attrOSize); - if(wrote != static_cast(*attrOSize)) { + if (wrote != static_cast(*attrOSize)) { parser_debug("Failed to write attribute %s %s\n", *attrName, strerror(wrote)); return B_ERROR; } @@ -433,9 +390,9 @@ PkgDirectory::_ParseAttribute(uint8 *buffer, BNode *node, char **attrName, } -inline status_t -PkgDirectory::_ParseData(uint8 *buffer, BFile *file, uint64 originalSize, - bool *done) +status_t +PackageItem::ParseData(uint8 *buffer, BFile *file, uint64 originalSize, + bool *done) { status_t ret = B_OK; @@ -484,11 +441,68 @@ PkgDirectory::_ParseData(uint8 *buffer, BFile *file, uint64 originalSize, } +// #pragma mark - PackageDirectory -PkgFile::PkgFile(BFile *parent, BString path, uint8 type, uint32 ctime, - uint32 mtime, uint64 offset, uint64 size, uint64 originalSize, - uint32 platform, BString mime, BString signature, uint32 mode) - : PkgItem(parent, path, type, ctime, mtime, offset, size), + +PackageDirectory::PackageDirectory(BFile *parent, const BString &path, + uint8 type, uint32 ctime, uint32 mtime, uint64 offset, uint64 size) + : PackageItem(parent, path, type, ctime, mtime, offset, size) +{ +} + + +status_t +PackageDirectory::WriteToPath(const char *path, BPath *final) +{ + BPath destination; + status_t ret; + parser_debug("Directory: %s WriteToPath() called!\n", fPath.String()); + + ret = InitPath(path, &destination); + if (ret != B_OK) + return ret; + + // Since Haiku is single-user right now, we give the newly + // created directory default permissions + ret = create_directory(destination.Path(), kDefaultMode); + if (ret != B_OK) + return ret; + BDirectory dir(destination.Path()); + parser_debug("Directory created!\n"); + + if (fCreationTime) + dir.SetCreationTime(static_cast(fCreationTime)); + + if (fModificationTime) + dir.SetModificationTime(static_cast(fModificationTime)); + + // Since directories can only have attributes in the offset section, + // we can check here whether it is necessary to continue + if (fOffset) + ret = HandleAttributes(&destination, &dir, "FoDa"); + + if (final) + *final = destination; + + return ret; +} + + +const char* +PackageDirectory::ItemKind() +{ + return "directory"; +} + + +// #pragma mark - PackageFile + + +PackageFile::PackageFile(BFile *parent, const BString &path, uint8 type, + uint32 ctime, uint32 mtime, uint64 offset, uint64 size, + uint64 originalSize, uint32 platform, const BString &mime, + const BString &signature, uint32 mode) + : PackageItem(parent, path, type, ctime, mtime, offset, size), fOriginalSize(originalSize), fPlatform(platform), fMode(mode), @@ -498,29 +512,26 @@ PkgFile::PkgFile(BFile *parent, BString path, uint8 type, uint32 ctime, } -PkgFile::~PkgFile() -{ -} - - status_t -PkgFile::WriteToPath(const char *path, BPath *final) +PackageFile::WriteToPath(const char *path, BPath *final) { BPath destination; status_t ret; parser_debug("File: %s WriteToPath() called!\n", fPath.String()); - ret = _InitPath(path, &destination); + ret = InitPath(path, &destination); if (ret != B_OK) return ret; - BFile file(destination.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_FAIL_IF_EXISTS); + BFile file(destination.Path(), + B_WRITE_ONLY | B_CREATE_FILE | B_FAIL_IF_EXISTS); ret = file.InitCheck(); if (ret == B_FILE_EXISTS) { - int32 selection = _ItemExists(destination.Leaf()); + int32 selection = ItemExists(destination.Leaf()); switch (selection) { case 0: - ret = file.SetTo(destination.Path(), B_WRITE_ONLY | B_ERASE_FILE); + ret = file.SetTo(destination.Path(), + B_WRITE_ONLY | B_ERASE_FILE); if (ret != B_OK) return ret; break; @@ -529,8 +540,7 @@ PkgFile::WriteToPath(const char *path, BPath *final) default: return B_FILE_EXISTS; } - } - else if (ret == B_ENTRY_NOT_FOUND) { + } else if (ret == B_ENTRY_NOT_FOUND) { BPath directory; destination.GetParent(&directory); if (create_directory(directory.Path(), kDefaultMode) != B_OK) @@ -598,8 +608,7 @@ PkgFile::WriteToPath(const char *path, BPath *final) parser_debug("-> Attribute\n"); section = P_ATTRIBUTE; continue; - } - else if (!memcmp(buffer, "FiDa", 5)) { + } else if (!memcmp(buffer, "FiDa", 5)) { parser_debug("-> File data\n"); section = P_DATA; continue; @@ -607,17 +616,15 @@ PkgFile::WriteToPath(const char *path, BPath *final) switch (section) { case P_ATTRIBUTE: - { - ret = _ParseAttribute(buffer, &file, &attrName, &nameSize, &attrType, - &attrData, &dataSize, &temp, &tempSize, &attrCSize, &attrOSize, - &attrStarted, &done); + ret = ParseAttribute(buffer, &file, &attrName, &nameSize, + &attrType, &attrData, &dataSize, &temp, &tempSize, + &attrCSize, &attrOSize, &attrStarted, &done); break; - } + case P_DATA: - { - ret = _ParseData(buffer, &file, fOriginalSize, &done); + ret = ParseData(buffer, &file, fOriginalSize, &done); break; - } + default: return B_ERROR; } @@ -630,41 +637,47 @@ PkgFile::WriteToPath(const char *path, BPath *final) delete[] temp; } - if (final) { + if (final) *final = destination; - } return ret; } -PkgLink::PkgLink(BFile *parent, BString path, BString link, uint8 type, - uint32 ctime, uint32 mtime, uint32 mode, uint64 offset, uint64 size) - : PkgItem(parent, path, type, ctime, mtime, offset, size), +const char* +PackageFile::ItemKind() +{ + return "file"; +} + + +// #pragma mark - + + +PackageLink::PackageLink(BFile *parent, const BString &path, + const BString &link, uint8 type, uint32 ctime, uint32 mtime, + uint32 mode, uint64 offset, uint64 size) + : PackageItem(parent, path, type, ctime, mtime, offset, size), fMode(mode), fLink(link) { } -PkgLink::~PkgLink() -{ -} - - status_t -PkgLink::WriteToPath(const char *path, BPath *final) +PackageLink::WriteToPath(const char *path, BPath *final) { - BPath destination; - status_t ret; parser_debug("Symlink: %s WriteToPath() called!\n", fPath.String()); - ret = _InitPath(path, &destination); + BPath destination; + status_t ret = InitPath(path, &destination); if (ret != B_OK) return ret; BString linkName(destination.Leaf()); - parser_debug("%s:%s:%s\n", fPath.String(), destination.Path(), linkName.String()); + parser_debug("%s:%s:%s\n", fPath.String(), destination.Path(), + linkName.String()); + BPath dirPath; ret = destination.GetParent(&dirPath); BDirectory dir(dirPath.Path()); @@ -683,6 +696,42 @@ PkgLink::WriteToPath(const char *path, BPath *final) BSymLink symlink; ret = dir.CreateSymLink(destination.Path(), fLink.String(), &symlink); + if (ret == B_FILE_EXISTS) { + // We need to check if the existing symlink is pointing at the same path + // as our new one - if not, let's prompt the user + symlink.SetTo(destination.Path()); + BPath oldLink; + + ret = symlink.MakeLinkedPath(&dir, &oldLink); + chdir(dirPath.Path()); + + if (ret == B_BAD_VALUE || oldLink != fLink.String()) { + // The old symlink is different (or not a symlink) - ask the user + int32 selection = ItemExists(destination.Leaf()); + switch (selection) { + case 0: + { + symlink.Unset(); + BEntry entry; + ret = entry.SetTo(destination.Path()); + if (ret != B_OK) + return ret; + + entry.Remove(); + ret = dir.CreateSymLink(destination.Path(), fLink.String(), + &symlink); + break; + } + case 1: + parser_debug("Skipping already existent SymLink\n"); + return B_OK; + default: + ret = B_FILE_EXISTS; + } + } else { + ret = B_OK; + } + } if (ret != B_OK) { parser_debug("CreateSymLink failed\n"); return ret; @@ -695,8 +744,10 @@ PkgLink::WriteToPath(const char *path, BPath *final) if (fCreationTime && ret == B_OK) ret = symlink.SetCreationTime(static_cast(fCreationTime)); - if (fModificationTime && ret == B_OK) - ret = symlink.SetModificationTime(static_cast(fModificationTime)); + if (fModificationTime && ret == B_OK) { + ret = symlink.SetModificationTime(static_cast( + fModificationTime)); + } if (ret != B_OK) { parser_debug("Failed to set symlink attributes\n"); @@ -705,7 +756,7 @@ PkgLink::WriteToPath(const char *path, BPath *final) if (fOffset) { // Symlinks also seem to have attributes - so parse them - ret = _HandleAttributes(&destination, &symlink, "LnDa"); + ret = HandleAttributes(&destination, &symlink, "LnDa"); } if (final) { @@ -715,3 +766,9 @@ PkgLink::WriteToPath(const char *path, BPath *final) return ret; } + +const char* +PackageLink::ItemKind() +{ + return "symbolic link"; +} diff --git a/src/apps/packageinstaller/PackageItem.h b/src/apps/packageinstaller/PackageItem.h index c712478956..c57c342f08 100644 --- a/src/apps/packageinstaller/PackageItem.h +++ b/src/apps/packageinstaller/PackageItem.h @@ -5,110 +5,132 @@ * Author: * Ɓukasz 'Sil2100' Zemczak */ -#ifndef PACKAGEITEM_H -#define PACKAGEITEM_H +#ifndef PACKAGE_ITEM_H +#define PACKAGE_ITEM_H + + +#include -#include #include #include #include -#include +#include -//#define DEBUG_PARSER // Local macro for the parser debug output +//#define DEBUG_PARSER #ifdef DEBUG_PARSER - #define parser_debug(format, args...) fprintf(stderr, format, ##args) +# define parser_debug(format, args...) fprintf(stderr, format, ##args) #else - #define parser_debug(format, args...) +# define parser_debug(format, args...) #endif -class PkgDirectory; - -// Since files are derive from directories, which is not too obvious, -// we define a type PkgItem to use for base type iterations -typedef PkgDirectory PkgItem; - - enum { P_INSTALL_PATH = 0, P_SYSTEM_PATH, P_USER_PATH }; - -status_t inflate_data(uint8 *in, uint32 in_size, uint8 *out, uint32 out_size); +extern status_t inflate_data(uint8* in, uint32 inSize, uint8* out, + uint32 outSize); -class PkgDirectory { - public: - PkgDirectory(BFile *parent, BString path, uint8 type, uint32 ctime, - uint32 mtime, uint64 offset = 0, uint64 size = 0); - virtual ~PkgDirectory(); +class PackageItem { +public: + PackageItem(BFile* parent, const BString& path, + uint8 type, uint32 ctime, uint32 mtime, + uint64 offset = 0, uint64 size = 0); + virtual ~PackageItem(); - virtual status_t WriteToPath(const char *path = NULL, BPath *final = NULL); - virtual void SetTo(BFile *parent, BString path, uint8 type, - uint32 ctime, uint32 mtime, uint64 offset = 0, uint64 size = 0); + virtual status_t WriteToPath(const char* path = NULL, + BPath* final = NULL) = 0; + virtual void SetTo(BFile* parent, const BString& path, + uint8 type, uint32 ctime, uint32 mtime, + uint64 offset = 0, uint64 size = 0); - protected: - int32 _ItemExists(const char *name); - status_t _InitPath(const char *path, BPath *destination); - status_t _HandleAttributes(BPath *destination, BNode *node, - const char *header); +protected: + virtual const char* ItemKind() = 0; + int32 ItemExists(const char* name); + status_t InitPath(const char* path, BPath* destination); + status_t HandleAttributes(BPath* destination, BNode* node, + const char* header); - inline status_t _ParseAttribute(uint8 *buffer, BNode *node, char **attrName, - uint32 *nameSize, uint32 *attrType, uint8 **attrData, uint64 *dataSize, - uint8 **temp, uint64 *tempSize, uint64 *attrCSize, uint64 *attrOSize, - bool *attrStarted, bool *done); - inline status_t _ParseData(uint8 *buffer, BFile *file, uint64 originalSize, - bool *done); + status_t ParseAttribute(uint8* buffer, BNode* node, + char** attrName, uint32* nameSize, + uint32* attrType, uint8** attrData, + uint64* dataSize, uint8** temp, + uint64* tempSize, uint64* attrCSize, + uint64* attrOSize, bool* attrStarted, + bool* done); + status_t ParseData(uint8* buffer, BFile* file, + uint64 originalSize, bool* done); - BString fPath; - uint64 fOffset; - uint64 fSize; - uint8 fPathType; - uint32 fCreationTime; - uint32 fModificationTime; + BString fPath; + uint64 fOffset; + uint64 fSize; + uint8 fPathType; + uint32 fCreationTime; + uint32 fModificationTime; - BFile *fPackage; + BFile* fPackage; }; -class PkgFile : public PkgItem { - public: - PkgFile(BFile *parent, BString path, uint8 type, uint32 ctime, - uint32 mtime, uint64 offset, uint64 size, uint64 originalSize, - uint32 platform, BString mime, BString signature, uint32 mode); - ~PkgFile(); +class PackageDirectory : public PackageItem { +public: + PackageDirectory(BFile* parent, const BString& path, + uint8 type, uint32 ctime, uint32 mtime, + uint64 offset = 0, uint64 size = 0); - status_t WriteToPath(const char *path = NULL, BPath *final = NULL); + virtual status_t WriteToPath(const char* path = NULL, + BPath* final = NULL); - private: - uint64 fOriginalSize; - uint32 fPlatform; - uint32 fMode; +protected: + virtual const char* ItemKind(); +}; + + +class PackageFile : public PackageItem { +public: + PackageFile(BFile* parent, const BString& path, + uint8 type, uint32 ctime, uint32 mtime, + uint64 offset, uint64 size, uint64 originalSize, + uint32 platform, const BString& mime, + const BString& signature, uint32 mode); + + virtual status_t WriteToPath(const char* path = NULL, + BPath* final = NULL); + +protected: + virtual const char* ItemKind(); + +private: + uint64 fOriginalSize; + uint32 fPlatform; + uint32 fMode; - BString fMimeType; - BString fSignature; + BString fMimeType; + BString fSignature; }; -class PkgLink : public PkgItem { - public: - PkgLink(BFile *parent, BString path, BString link, uint8 type, - uint32 ctime, uint32 mtime, uint32 mode, uint64 offset = 0, - uint64 size = 0); - ~PkgLink(); +class PackageLink : public PackageItem { +public: + PackageLink(BFile* parent, const BString& path, + const BString& link, uint8 type, uint32 ctime, + uint32 mtime, uint32 mode, uint64 offset = 0, + uint64 size = 0); - status_t WriteToPath(const char *path = NULL, BPath *final = NULL); + virtual status_t WriteToPath(const char* path = NULL, + BPath* final = NULL); - private: - uint32 fMode; +protected: + virtual const char* ItemKind(); - BString fLink; +private: + uint32 fMode; + BString fLink; }; - -#endif - +#endif // PACKAGE_ITEM_H diff --git a/src/apps/packageinstaller/PackageView.cpp b/src/apps/packageinstaller/PackageView.cpp index 8a15d9c0ff..14a9734b90 100644 --- a/src/apps/packageinstaller/PackageView.cpp +++ b/src/apps/packageinstaller/PackageView.cpp @@ -260,6 +260,7 @@ PackageView::Install() InstalledPackageInfo packageInfo(fInfo.GetName(), fInfo.GetVersion()); status_t err = packageInfo.InitCheck(); + err = B_ENTRY_NOT_FOUND; if (err == B_OK) { // The package is already installed, inform the user BAlert *reinstall = new BAlert("reinstall", @@ -303,7 +304,7 @@ PackageView::Install() fStatusWindow->StageStep(1, "Installing files and directories"); // Install files and directories - PkgItem *iter; + PackageItem *iter; BPath installedTo; uint32 i; BString label; @@ -322,7 +323,7 @@ PackageView::Install() packageInfo.SetSpaceNeeded(type->space_needed); for (i = 0; i < n; i++) { - iter = static_cast(type->items.ItemAt(i)); + iter = static_cast(type->items.ItemAt(i)); err = iter->WriteToPath(fCurrentPath.Path(), &installedTo); if (err != B_OK) { fprintf(stderr, "Error while writing path %s\n", fCurrentPath.Path());