* 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:
File diff suppressed because it is too large
Load Diff
@@ -38,8 +38,8 @@ class PackageInfo {
|
|||||||
status_t InitCheck() { return fStatus; }
|
status_t InitCheck() { return fStatus; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _AddItem(PkgItem *item, uint64 size, uint32 groups, uint32 path,
|
void _AddItem(PackageItem *item, uint64 size, uint32 groups,
|
||||||
uint32 cust);
|
uint32 path, uint32 cust);
|
||||||
|
|
||||||
status_t fStatus;
|
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.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
* Author:
|
* Author:
|
||||||
@@ -36,13 +36,13 @@ enum {
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
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;
|
z_stream stream;
|
||||||
stream.zalloc = Z_NULL;
|
stream.zalloc = Z_NULL;
|
||||||
stream.zfree = Z_NULL;
|
stream.zfree = Z_NULL;
|
||||||
stream.opaque = Z_NULL;
|
stream.opaque = Z_NULL;
|
||||||
stream.avail_in = in_size;
|
stream.avail_in = inSize;
|
||||||
stream.next_in = in;
|
stream.next_in = in;
|
||||||
status_t ret;
|
status_t ret;
|
||||||
|
|
||||||
@@ -52,17 +52,17 @@ inflate_data(uint8 *in, uint32 in_size, uint8 *out, uint32 out_size)
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream.avail_out = out_size;
|
stream.avail_out = outSize;
|
||||||
stream.next_out = out;
|
stream.next_out = out;
|
||||||
|
|
||||||
ret = inflate(&stream, Z_NO_FLUSH);
|
ret = inflate(&stream, Z_NO_FLUSH);
|
||||||
if (ret != Z_STREAM_END) {
|
if (ret != Z_STREAM_END) {
|
||||||
|
// Uncompressed file size in package info corrupted
|
||||||
parser_debug("Left: %d\n", stream.avail_out);
|
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;
|
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,
|
PackageItem::PackageItem(BFile *parent, const BString &path, uint8 type,
|
||||||
uint32 mtime, uint64 offset, uint64 size)
|
uint32 ctime, uint32 mtime, uint64 offset, uint64 size)
|
||||||
:
|
{
|
||||||
fPath(path),
|
SetTo(parent, path, type, ctime, mtime, offset, size);
|
||||||
fOffset(offset),
|
}
|
||||||
fSize(size),
|
|
||||||
fPathType(type),
|
|
||||||
fCreationTime(ctime),
|
PackageItem::~PackageItem()
|
||||||
fModificationTime(mtime),
|
|
||||||
fPackage(parent)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
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)
|
uint32 mtime, uint64 offset, uint64 size)
|
||||||
{
|
{
|
||||||
fPackage = parent;
|
fPackage = parent;
|
||||||
fPath = path;
|
fPath = path;
|
||||||
|
|
||||||
fOffset = offset;
|
fOffset = offset;
|
||||||
fSize = size;
|
fSize = size;
|
||||||
fPathType = type;
|
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<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
|
int32
|
||||||
PkgDirectory::_ItemExists(const char *name)
|
PackageItem::ItemExists(const char *name)
|
||||||
{
|
{
|
||||||
BString alertString = T("The file named");
|
// TODO: this function doesn't really fit in, the GUI should be separated
|
||||||
alertString << " \'" << name << "\' ";
|
// from the package engine completely
|
||||||
|
|
||||||
|
BString alertString = "The ";
|
||||||
|
|
||||||
|
alertString << ItemKind() << " named \'" << name << "\' ";
|
||||||
alertString << T("already exists in the given path. Should I replace "
|
alertString << T("already exists in the given path. Should I replace "
|
||||||
"the existing file with the one from this package?");
|
"the existing file with the one from this package?");
|
||||||
|
|
||||||
@@ -222,13 +180,13 @@ PkgDirectory::_ItemExists(const char *name)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
PkgDirectory::_InitPath(const char *path, BPath *destination)
|
PackageItem::InitPath(const char *path, BPath *destination)
|
||||||
{
|
{
|
||||||
status_t ret = B_OK;
|
status_t ret = B_OK;
|
||||||
|
|
||||||
if (fPathType == P_INSTALL_PATH) {
|
if (fPathType == P_INSTALL_PATH) {
|
||||||
if (!path) {
|
if (!path) {
|
||||||
parser_debug("_InitPath path is NULL\n");
|
parser_debug("InitPath path is NULL\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
ret = destination->SetTo(path, fPath.String());
|
ret = destination->SetTo(path, fPath.String());
|
||||||
@@ -237,7 +195,7 @@ PkgDirectory::_InitPath(const char *path, BPath *destination)
|
|||||||
ret = destination->SetTo(fPath.String());
|
ret = destination->SetTo(fPath.String());
|
||||||
else {
|
else {
|
||||||
if (!path) {
|
if (!path) {
|
||||||
parser_debug("_InitPath path is NULL\n");
|
parser_debug("InitPath path is NULL\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,8 +218,8 @@ PkgDirectory::_InitPath(const char *path, BPath *destination)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
PkgDirectory::_HandleAttributes(BPath *destination, BNode *node,
|
PackageItem::HandleAttributes(BPath *destination, BNode *node,
|
||||||
const char *header)
|
const char *header)
|
||||||
{
|
{
|
||||||
status_t ret = B_OK;
|
status_t ret = B_OK;
|
||||||
|
|
||||||
@@ -297,12 +255,14 @@ PkgDirectory::_HandleAttributes(BPath *destination, BNode *node,
|
|||||||
if (!memcmp(buffer, "FBeA", 5))
|
if (!memcmp(buffer, "FBeA", 5))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ret = _ParseAttribute(buffer, node, &attrName, &nameSize, &attrType,
|
ret = ParseAttribute(buffer, node, &attrName, &nameSize, &attrType,
|
||||||
&attrData, &dataSize, &temp, &tempSize, &attrCSize, &attrOSize,
|
&attrData, &dataSize, &temp, &tempSize, &attrCSize, &attrOSize,
|
||||||
&attrStarted, &done);
|
&attrStarted, &done);
|
||||||
if (ret != B_OK || done) {
|
if (ret != B_OK || done) {
|
||||||
if (ret != B_OK)
|
if (ret != B_OK) {
|
||||||
parser_debug("_ParseAttribute failed for %s\n", destination->Path());
|
parser_debug("_ParseAttribute failed for %s\n",
|
||||||
|
destination->Path());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -315,11 +275,11 @@ PkgDirectory::_HandleAttributes(BPath *destination, BNode *node,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline status_t
|
status_t
|
||||||
PkgDirectory::_ParseAttribute(uint8 *buffer, BNode *node, char **attrName,
|
PackageItem::ParseAttribute(uint8 *buffer, BNode *node, char **attrName,
|
||||||
uint32 *nameSize, uint32 *attrType, uint8 **attrData, uint64 *dataSize,
|
uint32 *nameSize, uint32 *attrType, uint8 **attrData, uint64 *dataSize,
|
||||||
uint8 **temp, uint64 *tempSize, uint64 *attrCSize, uint64 *attrOSize,
|
uint8 **temp, uint64 *tempSize, uint64 *attrCSize, uint64 *attrOSize,
|
||||||
bool *attrStarted, bool *done)
|
bool *attrStarted, bool *done)
|
||||||
{
|
{
|
||||||
status_t ret = B_OK;
|
status_t ret = B_OK;
|
||||||
uint32 length;
|
uint32 length;
|
||||||
@@ -332,8 +292,7 @@ PkgDirectory::_ParseAttribute(uint8 *buffer, BNode *node, char **attrName,
|
|||||||
*attrOSize = 0;
|
*attrOSize = 0;
|
||||||
|
|
||||||
*attrStarted = true;
|
*attrStarted = true;
|
||||||
}
|
} else if (!memcmp(buffer, "BeAN", 5)) {
|
||||||
else if (!memcmp(buffer, "BeAN", 5)) {
|
|
||||||
if (!*attrStarted) {
|
if (!*attrStarted) {
|
||||||
ret = B_ERROR;
|
ret = B_ERROR;
|
||||||
return ret;
|
return ret;
|
||||||
@@ -341,7 +300,8 @@ PkgDirectory::_ParseAttribute(uint8 *buffer, BNode *node, char **attrName,
|
|||||||
|
|
||||||
parser_debug(" BeAN.\n");
|
parser_debug(" BeAN.\n");
|
||||||
fPackage->Read(&length, 4);
|
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)) {
|
if (*nameSize < (length + 1)) {
|
||||||
delete *attrName;
|
delete *attrName;
|
||||||
@@ -352,8 +312,7 @@ PkgDirectory::_ParseAttribute(uint8 *buffer, BNode *node, char **attrName,
|
|||||||
(*attrName)[length] = 0;
|
(*attrName)[length] = 0;
|
||||||
|
|
||||||
parser_debug(" (%ld) = %s\n", length, *attrName);
|
parser_debug(" (%ld) = %s\n", length, *attrName);
|
||||||
}
|
} else if (!memcmp(buffer, "BeAT", 5)) {
|
||||||
else if (!memcmp(buffer, "BeAT", 5)) {
|
|
||||||
if (!*attrStarted) {
|
if (!*attrStarted) {
|
||||||
ret = B_ERROR;
|
ret = B_ERROR;
|
||||||
return ret;
|
return ret;
|
||||||
@@ -363,8 +322,7 @@ PkgDirectory::_ParseAttribute(uint8 *buffer, BNode *node, char **attrName,
|
|||||||
fPackage->Read(attrType, 4);
|
fPackage->Read(attrType, 4);
|
||||||
swap_data(B_UINT32_TYPE, attrType, sizeof(*attrType),
|
swap_data(B_UINT32_TYPE, attrType, sizeof(*attrType),
|
||||||
B_SWAP_BENDIAN_TO_HOST);
|
B_SWAP_BENDIAN_TO_HOST);
|
||||||
}
|
} else if (!memcmp(buffer, "BeAD", 5)) {
|
||||||
else if (!memcmp(buffer, "BeAD", 5)) {
|
|
||||||
if (!*attrStarted) {
|
if (!*attrStarted) {
|
||||||
ret = B_ERROR;
|
ret = B_ERROR;
|
||||||
return ret;
|
return ret;
|
||||||
@@ -380,7 +338,7 @@ PkgDirectory::_ParseAttribute(uint8 *buffer, BNode *node, char **attrName,
|
|||||||
B_SWAP_BENDIAN_TO_HOST);
|
B_SWAP_BENDIAN_TO_HOST);
|
||||||
|
|
||||||
fPackage->Seek(4, SEEK_CUR); // TODO: Check what this means
|
fPackage->Seek(4, SEEK_CUR); // TODO: Check what this means
|
||||||
|
|
||||||
if (*tempSize < *attrCSize) {
|
if (*tempSize < *attrCSize) {
|
||||||
delete *temp;
|
delete *temp;
|
||||||
*tempSize = *attrCSize;
|
*tempSize = *attrCSize;
|
||||||
@@ -402,8 +360,7 @@ PkgDirectory::_ParseAttribute(uint8 *buffer, BNode *node, char **attrName,
|
|||||||
ret = inflate_data(*temp, *tempSize, *attrData, *dataSize);
|
ret = inflate_data(*temp, *tempSize, *attrData, *dataSize);
|
||||||
if (ret != B_OK)
|
if (ret != B_OK)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
} else if (!memcmp(buffer, padding, 7)) {
|
||||||
else if (!memcmp(buffer, padding, 7)) {
|
|
||||||
if (!*attrStarted) {
|
if (!*attrStarted) {
|
||||||
*done = true;
|
*done = true;
|
||||||
return ret;
|
return ret;
|
||||||
@@ -412,7 +369,7 @@ PkgDirectory::_ParseAttribute(uint8 *buffer, BNode *node, char **attrName,
|
|||||||
parser_debug(" Padding.\n");
|
parser_debug(" Padding.\n");
|
||||||
ssize_t wrote = node->WriteAttr(*attrName, *attrType, 0, *attrData,
|
ssize_t wrote = node->WriteAttr(*attrName, *attrType, 0, *attrData,
|
||||||
*attrOSize);
|
*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));
|
parser_debug("Failed to write attribute %s %s\n", *attrName, strerror(wrote));
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
@@ -433,9 +390,9 @@ PkgDirectory::_ParseAttribute(uint8 *buffer, BNode *node, char **attrName,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline status_t
|
status_t
|
||||||
PkgDirectory::_ParseData(uint8 *buffer, BFile *file, uint64 originalSize,
|
PackageItem::ParseData(uint8 *buffer, BFile *file, uint64 originalSize,
|
||||||
bool *done)
|
bool *done)
|
||||||
{
|
{
|
||||||
status_t ret = B_OK;
|
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,
|
PackageDirectory::PackageDirectory(BFile *parent, const BString &path,
|
||||||
uint32 platform, BString mime, BString signature, uint32 mode)
|
uint8 type, uint32 ctime, uint32 mtime, uint64 offset, uint64 size)
|
||||||
: PkgItem(parent, path, type, ctime, mtime, offset, 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),
|
fOriginalSize(originalSize),
|
||||||
fPlatform(platform),
|
fPlatform(platform),
|
||||||
fMode(mode),
|
fMode(mode),
|
||||||
@@ -498,29 +512,26 @@ PkgFile::PkgFile(BFile *parent, BString path, uint8 type, uint32 ctime,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PkgFile::~PkgFile()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
PkgFile::WriteToPath(const char *path, BPath *final)
|
PackageFile::WriteToPath(const char *path, BPath *final)
|
||||||
{
|
{
|
||||||
BPath destination;
|
BPath destination;
|
||||||
status_t ret;
|
status_t ret;
|
||||||
parser_debug("File: %s WriteToPath() called!\n", fPath.String());
|
parser_debug("File: %s WriteToPath() called!\n", fPath.String());
|
||||||
|
|
||||||
ret = _InitPath(path, &destination);
|
ret = InitPath(path, &destination);
|
||||||
if (ret != B_OK)
|
if (ret != B_OK)
|
||||||
return ret;
|
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();
|
ret = file.InitCheck();
|
||||||
if (ret == B_FILE_EXISTS) {
|
if (ret == B_FILE_EXISTS) {
|
||||||
int32 selection = _ItemExists(destination.Leaf());
|
int32 selection = ItemExists(destination.Leaf());
|
||||||
switch (selection) {
|
switch (selection) {
|
||||||
case 0:
|
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)
|
if (ret != B_OK)
|
||||||
return ret;
|
return ret;
|
||||||
break;
|
break;
|
||||||
@@ -529,8 +540,7 @@ PkgFile::WriteToPath(const char *path, BPath *final)
|
|||||||
default:
|
default:
|
||||||
return B_FILE_EXISTS;
|
return B_FILE_EXISTS;
|
||||||
}
|
}
|
||||||
}
|
} else if (ret == B_ENTRY_NOT_FOUND) {
|
||||||
else if (ret == B_ENTRY_NOT_FOUND) {
|
|
||||||
BPath directory;
|
BPath directory;
|
||||||
destination.GetParent(&directory);
|
destination.GetParent(&directory);
|
||||||
if (create_directory(directory.Path(), kDefaultMode) != B_OK)
|
if (create_directory(directory.Path(), kDefaultMode) != B_OK)
|
||||||
@@ -598,8 +608,7 @@ PkgFile::WriteToPath(const char *path, BPath *final)
|
|||||||
parser_debug("-> Attribute\n");
|
parser_debug("-> Attribute\n");
|
||||||
section = P_ATTRIBUTE;
|
section = P_ATTRIBUTE;
|
||||||
continue;
|
continue;
|
||||||
}
|
} else if (!memcmp(buffer, "FiDa", 5)) {
|
||||||
else if (!memcmp(buffer, "FiDa", 5)) {
|
|
||||||
parser_debug("-> File data\n");
|
parser_debug("-> File data\n");
|
||||||
section = P_DATA;
|
section = P_DATA;
|
||||||
continue;
|
continue;
|
||||||
@@ -607,17 +616,15 @@ PkgFile::WriteToPath(const char *path, BPath *final)
|
|||||||
|
|
||||||
switch (section) {
|
switch (section) {
|
||||||
case P_ATTRIBUTE:
|
case P_ATTRIBUTE:
|
||||||
{
|
ret = ParseAttribute(buffer, &file, &attrName, &nameSize,
|
||||||
ret = _ParseAttribute(buffer, &file, &attrName, &nameSize, &attrType,
|
&attrType, &attrData, &dataSize, &temp, &tempSize,
|
||||||
&attrData, &dataSize, &temp, &tempSize, &attrCSize, &attrOSize,
|
&attrCSize, &attrOSize, &attrStarted, &done);
|
||||||
&attrStarted, &done);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case P_DATA:
|
case P_DATA:
|
||||||
{
|
ret = ParseData(buffer, &file, fOriginalSize, &done);
|
||||||
ret = _ParseData(buffer, &file, fOriginalSize, &done);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
@@ -630,41 +637,47 @@ PkgFile::WriteToPath(const char *path, BPath *final)
|
|||||||
delete[] temp;
|
delete[] temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (final) {
|
if (final)
|
||||||
*final = destination;
|
*final = destination;
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PkgLink::PkgLink(BFile *parent, BString path, BString link, uint8 type,
|
const char*
|
||||||
uint32 ctime, uint32 mtime, uint32 mode, uint64 offset, uint64 size)
|
PackageFile::ItemKind()
|
||||||
: PkgItem(parent, path, type, ctime, mtime, offset, size),
|
{
|
||||||
|
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),
|
fMode(mode),
|
||||||
fLink(link)
|
fLink(link)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PkgLink::~PkgLink()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
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());
|
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)
|
if (ret != B_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
BString linkName(destination.Leaf());
|
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;
|
BPath dirPath;
|
||||||
ret = destination.GetParent(&dirPath);
|
ret = destination.GetParent(&dirPath);
|
||||||
BDirectory dir(dirPath.Path());
|
BDirectory dir(dirPath.Path());
|
||||||
@@ -683,6 +696,42 @@ PkgLink::WriteToPath(const char *path, BPath *final)
|
|||||||
|
|
||||||
BSymLink symlink;
|
BSymLink symlink;
|
||||||
ret = dir.CreateSymLink(destination.Path(), fLink.String(), &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) {
|
if (ret != B_OK) {
|
||||||
parser_debug("CreateSymLink failed\n");
|
parser_debug("CreateSymLink failed\n");
|
||||||
return ret;
|
return ret;
|
||||||
@@ -695,8 +744,10 @@ PkgLink::WriteToPath(const char *path, BPath *final)
|
|||||||
if (fCreationTime && ret == B_OK)
|
if (fCreationTime && ret == B_OK)
|
||||||
ret = symlink.SetCreationTime(static_cast<time_t>(fCreationTime));
|
ret = symlink.SetCreationTime(static_cast<time_t>(fCreationTime));
|
||||||
|
|
||||||
if (fModificationTime && ret == B_OK)
|
if (fModificationTime && ret == B_OK) {
|
||||||
ret = symlink.SetModificationTime(static_cast<time_t>(fModificationTime));
|
ret = symlink.SetModificationTime(static_cast<time_t>(
|
||||||
|
fModificationTime));
|
||||||
|
}
|
||||||
|
|
||||||
if (ret != B_OK) {
|
if (ret != B_OK) {
|
||||||
parser_debug("Failed to set symlink attributes\n");
|
parser_debug("Failed to set symlink attributes\n");
|
||||||
@@ -705,7 +756,7 @@ PkgLink::WriteToPath(const char *path, BPath *final)
|
|||||||
|
|
||||||
if (fOffset) {
|
if (fOffset) {
|
||||||
// Symlinks also seem to have attributes - so parse them
|
// Symlinks also seem to have attributes - so parse them
|
||||||
ret = _HandleAttributes(&destination, &symlink, "LnDa");
|
ret = HandleAttributes(&destination, &symlink, "LnDa");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (final) {
|
if (final) {
|
||||||
@@ -715,3 +766,9 @@ PkgLink::WriteToPath(const char *path, BPath *final)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char*
|
||||||
|
PackageLink::ItemKind()
|
||||||
|
{
|
||||||
|
return "symbolic link";
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,110 +5,132 @@
|
|||||||
* Author:
|
* Author:
|
||||||
* Łukasz 'Sil2100' Zemczak <sil2100@vexillium.org>
|
* Łukasz 'Sil2100' Zemczak <sil2100@vexillium.org>
|
||||||
*/
|
*/
|
||||||
#ifndef PACKAGEITEM_H
|
#ifndef PACKAGE_ITEM_H
|
||||||
#define PACKAGEITEM_H
|
#define PACKAGE_ITEM_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <String.h>
|
|
||||||
#include <Entry.h>
|
#include <Entry.h>
|
||||||
#include <File.h>
|
#include <File.h>
|
||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
#include <stdio.h>
|
#include <String.h>
|
||||||
|
|
||||||
//#define DEBUG_PARSER
|
|
||||||
|
|
||||||
// Local macro for the parser debug output
|
// Local macro for the parser debug output
|
||||||
|
//#define DEBUG_PARSER
|
||||||
#ifdef DEBUG_PARSER
|
#ifdef DEBUG_PARSER
|
||||||
#define parser_debug(format, args...) fprintf(stderr, format, ##args)
|
# define parser_debug(format, args...) fprintf(stderr, format, ##args)
|
||||||
#else
|
#else
|
||||||
#define parser_debug(format, args...)
|
# define parser_debug(format, args...)
|
||||||
#endif
|
#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 {
|
enum {
|
||||||
P_INSTALL_PATH = 0,
|
P_INSTALL_PATH = 0,
|
||||||
P_SYSTEM_PATH,
|
P_SYSTEM_PATH,
|
||||||
P_USER_PATH
|
P_USER_PATH
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern status_t inflate_data(uint8* in, uint32 inSize, uint8* out,
|
||||||
status_t inflate_data(uint8 *in, uint32 in_size, uint8 *out, uint32 out_size);
|
uint32 outSize);
|
||||||
|
|
||||||
|
|
||||||
class PkgDirectory {
|
class PackageItem {
|
||||||
public:
|
public:
|
||||||
PkgDirectory(BFile *parent, BString path, uint8 type, uint32 ctime,
|
PackageItem(BFile* parent, const BString& path,
|
||||||
uint32 mtime, uint64 offset = 0, uint64 size = 0);
|
uint8 type, uint32 ctime, uint32 mtime,
|
||||||
virtual ~PkgDirectory();
|
uint64 offset = 0, uint64 size = 0);
|
||||||
|
virtual ~PackageItem();
|
||||||
|
|
||||||
virtual status_t WriteToPath(const char *path = NULL, BPath *final = NULL);
|
virtual status_t WriteToPath(const char* path = NULL,
|
||||||
virtual void SetTo(BFile *parent, BString path, uint8 type,
|
BPath* final = NULL) = 0;
|
||||||
uint32 ctime, uint32 mtime, uint64 offset = 0, uint64 size = 0);
|
virtual void SetTo(BFile* parent, const BString& path,
|
||||||
|
uint8 type, uint32 ctime, uint32 mtime,
|
||||||
|
uint64 offset = 0, uint64 size = 0);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int32 _ItemExists(const char *name);
|
virtual const char* ItemKind() = 0;
|
||||||
status_t _InitPath(const char *path, BPath *destination);
|
int32 ItemExists(const char* name);
|
||||||
status_t _HandleAttributes(BPath *destination, BNode *node,
|
status_t InitPath(const char* path, BPath* destination);
|
||||||
const char *header);
|
status_t HandleAttributes(BPath* destination, BNode* node,
|
||||||
|
const char* header);
|
||||||
|
|
||||||
inline status_t _ParseAttribute(uint8 *buffer, BNode *node, char **attrName,
|
status_t ParseAttribute(uint8* buffer, BNode* node,
|
||||||
uint32 *nameSize, uint32 *attrType, uint8 **attrData, uint64 *dataSize,
|
char** attrName, uint32* nameSize,
|
||||||
uint8 **temp, uint64 *tempSize, uint64 *attrCSize, uint64 *attrOSize,
|
uint32* attrType, uint8** attrData,
|
||||||
bool *attrStarted, bool *done);
|
uint64* dataSize, uint8** temp,
|
||||||
inline status_t _ParseData(uint8 *buffer, BFile *file, uint64 originalSize,
|
uint64* tempSize, uint64* attrCSize,
|
||||||
bool *done);
|
uint64* attrOSize, bool* attrStarted,
|
||||||
|
bool* done);
|
||||||
|
status_t ParseData(uint8* buffer, BFile* file,
|
||||||
|
uint64 originalSize, bool* done);
|
||||||
|
|
||||||
BString fPath;
|
BString fPath;
|
||||||
uint64 fOffset;
|
uint64 fOffset;
|
||||||
uint64 fSize;
|
uint64 fSize;
|
||||||
uint8 fPathType;
|
uint8 fPathType;
|
||||||
uint32 fCreationTime;
|
uint32 fCreationTime;
|
||||||
uint32 fModificationTime;
|
uint32 fModificationTime;
|
||||||
|
|
||||||
BFile *fPackage;
|
BFile* fPackage;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class PkgFile : public PkgItem {
|
class PackageDirectory : public PackageItem {
|
||||||
public:
|
public:
|
||||||
PkgFile(BFile *parent, BString path, uint8 type, uint32 ctime,
|
PackageDirectory(BFile* parent, const BString& path,
|
||||||
uint32 mtime, uint64 offset, uint64 size, uint64 originalSize,
|
uint8 type, uint32 ctime, uint32 mtime,
|
||||||
uint32 platform, BString mime, BString signature, uint32 mode);
|
uint64 offset = 0, uint64 size = 0);
|
||||||
~PkgFile();
|
|
||||||
|
|
||||||
status_t WriteToPath(const char *path = NULL, BPath *final = NULL);
|
virtual status_t WriteToPath(const char* path = NULL,
|
||||||
|
BPath* final = NULL);
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
uint64 fOriginalSize;
|
virtual const char* ItemKind();
|
||||||
uint32 fPlatform;
|
};
|
||||||
uint32 fMode;
|
|
||||||
|
|
||||||
|
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 fMimeType;
|
||||||
BString fSignature;
|
BString fSignature;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class PkgLink : public PkgItem {
|
class PackageLink : public PackageItem {
|
||||||
public:
|
public:
|
||||||
PkgLink(BFile *parent, BString path, BString link, uint8 type,
|
PackageLink(BFile* parent, const BString& path,
|
||||||
uint32 ctime, uint32 mtime, uint32 mode, uint64 offset = 0,
|
const BString& link, uint8 type, uint32 ctime,
|
||||||
uint64 size = 0);
|
uint32 mtime, uint32 mode, uint64 offset = 0,
|
||||||
~PkgLink();
|
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:
|
||||||
uint32 fMode;
|
virtual const char* ItemKind();
|
||||||
|
|
||||||
BString fLink;
|
private:
|
||||||
|
uint32 fMode;
|
||||||
|
BString fLink;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // PACKAGE_ITEM_H
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|||||||
@@ -260,6 +260,7 @@ PackageView::Install()
|
|||||||
InstalledPackageInfo packageInfo(fInfo.GetName(), fInfo.GetVersion());
|
InstalledPackageInfo packageInfo(fInfo.GetName(), fInfo.GetVersion());
|
||||||
|
|
||||||
status_t err = packageInfo.InitCheck();
|
status_t err = packageInfo.InitCheck();
|
||||||
|
err = B_ENTRY_NOT_FOUND;
|
||||||
if (err == B_OK) {
|
if (err == B_OK) {
|
||||||
// The package is already installed, inform the user
|
// The package is already installed, inform the user
|
||||||
BAlert *reinstall = new BAlert("reinstall",
|
BAlert *reinstall = new BAlert("reinstall",
|
||||||
@@ -303,7 +304,7 @@ PackageView::Install()
|
|||||||
fStatusWindow->StageStep(1, "Installing files and directories");
|
fStatusWindow->StageStep(1, "Installing files and directories");
|
||||||
|
|
||||||
// Install files and directories
|
// Install files and directories
|
||||||
PkgItem *iter;
|
PackageItem *iter;
|
||||||
BPath installedTo;
|
BPath installedTo;
|
||||||
uint32 i;
|
uint32 i;
|
||||||
BString label;
|
BString label;
|
||||||
@@ -322,7 +323,7 @@ PackageView::Install()
|
|||||||
packageInfo.SetSpaceNeeded(type->space_needed);
|
packageInfo.SetSpaceNeeded(type->space_needed);
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
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);
|
err = iter->WriteToPath(fCurrentPath.Path(), &installedTo);
|
||||||
if (err != B_OK) {
|
if (err != B_OK) {
|
||||||
fprintf(stderr, "Error while writing path %s\n", fCurrentPath.Path());
|
fprintf(stderr, "Error while writing path %s\n", fCurrentPath.Path());
|
||||||
|
|||||||
Reference in New Issue
Block a user