* Applied patch by sil2001 that fixes bug #3666 (handling of existing symlinks).
* Refactored PkgItem classes, and pulled out a PackageItem base class. Renamed other classes to Package*. * The ItemExists() method should really get a "Apply this choice to all files" kind of option... * Style cleanups. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30125 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -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,22 +67,21 @@ PackageInfo::~PackageInfo()
|
||||
pkg_profile *iter = 0;
|
||||
while (1) {
|
||||
iter = static_cast<pkg_profile *>(fProfiles.RemoveItem((long int)0));
|
||||
if (iter)
|
||||
if (iter == NULL)
|
||||
break;
|
||||
|
||||
delete iter;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
PkgItem *file = 0;
|
||||
while (1) {
|
||||
file = static_cast<PkgItem *>(fFiles.RemoveItem((long int)0));
|
||||
if (file)
|
||||
PackageItem *file = 0;
|
||||
while (true) {
|
||||
file = static_cast<PackageItem *>(fFiles.RemoveItem((long int)0));
|
||||
if (file == NULL)
|
||||
break;
|
||||
|
||||
delete file;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (fPackageFile)
|
||||
delete fPackageFile;
|
||||
}
|
||||
|
||||
@@ -126,7 +125,7 @@ PackageInfo::Parse()
|
||||
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;
|
||||
}
|
||||
@@ -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<int64>(length)) {
|
||||
if (fPackageFile->Read(compressed, length)
|
||||
!= static_cast<int64>(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<int64>(length)) {
|
||||
if (fPackageFile->Read(compressed, length)
|
||||
!= static_cast<int64>(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<uint8 *>(const_cast<void *>(fImage.Buffer())), original);
|
||||
static_cast<uint8 *>(const_cast<void *>(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,8 +356,7 @@ 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;
|
||||
@@ -371,15 +364,15 @@ PackageInfo::Parse()
|
||||
|
||||
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;
|
||||
@@ -387,15 +380,15 @@ PackageInfo::Parse()
|
||||
|
||||
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;
|
||||
@@ -418,11 +411,11 @@ PackageInfo::Parse()
|
||||
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");
|
||||
|
||||
@@ -430,13 +423,11 @@ PackageInfo::Parse()
|
||||
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.
|
||||
// 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
|
||||
// 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,7 +541,8 @@ 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);
|
||||
}
|
||||
@@ -562,11 +554,11 @@ 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);
|
||||
@@ -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;
|
||||
@@ -636,8 +625,7 @@ 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;
|
||||
|
||||
@@ -653,8 +641,7 @@ PackageInfo::Parse()
|
||||
|
||||
size = 0;
|
||||
originalSize = 0;
|
||||
}
|
||||
else if (!memcmp(buffer, "LnkI", 5)) {
|
||||
} else if (!memcmp(buffer, "LnkI", 5)) {
|
||||
parser_debug("LnkI\n");
|
||||
element = P_LINK;
|
||||
|
||||
@@ -671,8 +658,7 @@ PackageInfo::Parse()
|
||||
|
||||
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,8 +675,7 @@ 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;
|
||||
@@ -697,9 +683,9 @@ PackageInfo::Parse()
|
||||
|
||||
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,8 +715,7 @@ 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;
|
||||
@@ -738,9 +723,9 @@ PackageInfo::Parse()
|
||||
|
||||
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,16 +753,17 @@ 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);
|
||||
@@ -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,9 +790,9 @@ 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;
|
||||
@@ -817,8 +802,7 @@ PackageInfo::Parse()
|
||||
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;
|
||||
@@ -826,24 +810,24 @@ PackageInfo::Parse()
|
||||
|
||||
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);
|
||||
@@ -852,15 +836,15 @@ 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);
|
||||
@@ -869,18 +853,17 @@ 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_types>(platform) != sysinfo.platform_type) {
|
||||
if (platform != 0xffffffff
|
||||
&& static_cast<platform_types>(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;
|
||||
@@ -891,10 +874,10 @@ PackageInfo::Parse()
|
||||
localType = P_INSTALL_PATH;
|
||||
dest = installDirectory;
|
||||
dest << nameString;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (cust) {
|
||||
BString *def = static_cast<BString *>(userPaths.ItemAt(path));
|
||||
BString *def = static_cast<BString *>(
|
||||
userPaths.ItemAt(path));
|
||||
if (!def) {
|
||||
fStatus = B_ERROR;
|
||||
return fStatus;
|
||||
@@ -905,9 +888,9 @@ PackageInfo::Parse()
|
||||
localType = P_USER_PATH;
|
||||
|
||||
dest << *def << "/" << nameString;
|
||||
}
|
||||
else {
|
||||
BPath *def = static_cast<BPath *>(systemPaths.ItemAt(path));
|
||||
} else {
|
||||
BPath *def = static_cast<BPath *>(
|
||||
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<BString *>(userPaths.ItemAt(path));
|
||||
BString *def = static_cast<BString *>(
|
||||
userPaths.ItemAt(path));
|
||||
if (!def) {
|
||||
fStatus = B_ERROR;
|
||||
return fStatus;
|
||||
@@ -950,9 +937,9 @@ PackageInfo::Parse()
|
||||
pathType = P_USER_PATH;
|
||||
|
||||
itemPath = *def;
|
||||
}
|
||||
else {
|
||||
BPath *def = static_cast<BPath *>(systemPaths.ItemAt(path));
|
||||
} else {
|
||||
BPath *def = static_cast<BPath *>(
|
||||
systemPaths.ItemAt(path));
|
||||
if (!def) {
|
||||
fStatus = B_ERROR;
|
||||
return fStatus;
|
||||
@@ -965,8 +952,8 @@ PackageInfo::Parse()
|
||||
itemPath << "/" << nameString;
|
||||
directoryCount = 1;
|
||||
}
|
||||
}
|
||||
else { // Install directory
|
||||
} else {
|
||||
// Install directory
|
||||
if (path != 0xffffffff) {
|
||||
fStatus = B_ERROR;
|
||||
return fStatus;
|
||||
@@ -980,16 +967,15 @@ PackageInfo::Parse()
|
||||
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;
|
||||
@@ -1000,10 +986,10 @@ PackageInfo::Parse()
|
||||
localType = P_INSTALL_PATH;
|
||||
dest = installDirectory;
|
||||
dest << nameString;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (cust) {
|
||||
BString *def = static_cast<BString *>(userPaths.ItemAt(path));
|
||||
BString *def = static_cast<BString *>(
|
||||
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<BPath *>(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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,25 +130,23 @@ 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,
|
||||
PackageItem::SetTo(BFile *parent, const BString &path, uint8 type, uint32 ctime,
|
||||
uint32 mtime, uint64 offset, uint64 size)
|
||||
{
|
||||
fPackage = parent;
|
||||
@@ -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<time_t>(fCreationTime));
|
||||
|
||||
if (fModificationTime)
|
||||
dir.SetModificationTime(static_cast<time_t>(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,7 +218,7 @@ PkgDirectory::_InitPath(const char *path, BPath *destination)
|
||||
|
||||
|
||||
status_t
|
||||
PkgDirectory::_HandleAttributes(BPath *destination, BNode *node,
|
||||
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,
|
||||
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,8 +275,8 @@ PkgDirectory::_HandleAttributes(BPath *destination, BNode *node,
|
||||
}
|
||||
|
||||
|
||||
inline status_t
|
||||
PkgDirectory::_ParseAttribute(uint8 *buffer, BNode *node, char **attrName,
|
||||
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)
|
||||
@@ -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;
|
||||
@@ -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<ssize_t>(*attrOSize)) {
|
||||
if (wrote != static_cast<ssize_t>(*attrOSize)) {
|
||||
parser_debug("Failed to write attribute %s %s\n", *attrName, strerror(wrote));
|
||||
return B_ERROR;
|
||||
}
|
||||
@@ -433,8 +390,8 @@ PkgDirectory::_ParseAttribute(uint8 *buffer, BNode *node, char **attrName,
|
||||
}
|
||||
|
||||
|
||||
inline status_t
|
||||
PkgDirectory::_ParseData(uint8 *buffer, BFile *file, uint64 originalSize,
|
||||
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<time_t>(fCreationTime));
|
||||
|
||||
if (fModificationTime)
|
||||
dir.SetModificationTime(static_cast<time_t>(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<time_t>(fCreationTime));
|
||||
|
||||
if (fModificationTime && ret == B_OK)
|
||||
ret = symlink.SetModificationTime(static_cast<time_t>(fModificationTime));
|
||||
if (fModificationTime && ret == B_OK) {
|
||||
ret = symlink.SetModificationTime(static_cast<time_t>(
|
||||
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";
|
||||
}
|
||||
|
||||
@@ -5,64 +5,66 @@
|
||||
* Author:
|
||||
* Łukasz 'Sil2100' Zemczak <sil2100@vexillium.org>
|
||||
*/
|
||||
#ifndef PACKAGEITEM_H
|
||||
#define PACKAGEITEM_H
|
||||
#ifndef PACKAGE_ITEM_H
|
||||
#define PACKAGE_ITEM_H
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <String.h>
|
||||
#include <Entry.h>
|
||||
#include <File.h>
|
||||
#include <Path.h>
|
||||
#include <stdio.h>
|
||||
#include <String.h>
|
||||
|
||||
//#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;
|
||||
@@ -71,20 +73,39 @@ class PkgDirectory {
|
||||
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:
|
||||
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;
|
||||
@@ -94,21 +115,22 @@ class PkgFile : public PkgItem {
|
||||
};
|
||||
|
||||
|
||||
class PkgLink : public PkgItem {
|
||||
public:
|
||||
PkgLink(BFile *parent, BString path, BString link, uint8 type,
|
||||
uint32 ctime, uint32 mtime, uint32 mode, uint64 offset = 0,
|
||||
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);
|
||||
~PkgLink();
|
||||
|
||||
status_t WriteToPath(const char *path = NULL, BPath *final = NULL);
|
||||
virtual status_t WriteToPath(const char* path = NULL,
|
||||
BPath* final = NULL);
|
||||
|
||||
private:
|
||||
protected:
|
||||
virtual const char* ItemKind();
|
||||
|
||||
private:
|
||||
uint32 fMode;
|
||||
|
||||
BString fLink;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif // PACKAGE_ITEM_H
|
||||
|
||||
@@ -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<PkgItem *>(type->items.ItemAt(i));
|
||||
iter = static_cast<PackageItem *>(type->items.ItemAt(i));
|
||||
err = iter->WriteToPath(fCurrentPath.Path(), &installedTo);
|
||||
if (err != B_OK) {
|
||||
fprintf(stderr, "Error while writing path %s\n", fCurrentPath.Path());
|
||||
|
||||
Reference in New Issue
Block a user