* Cleanup.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32281 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2005-2007, Ingo Weinhold, [email protected].
|
* Copyright 2005-2007, Ingo Weinhold, [email protected].
|
||||||
* Copyright 2005, Axel Dörfler, [email protected]. All rights reserved.
|
* Copyright 2005-2009, Axel Dörfler, [email protected].
|
||||||
*
|
*
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
@@ -33,13 +33,14 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static const uint32 kFloppyArchiveOffset = BOOT_ARCHIVE_IMAGE_OFFSET * 1024; // initially at 192 kB, now defined at build time
|
static const uint32 kFloppyArchiveOffset = BOOT_ARCHIVE_IMAGE_OFFSET * 1024;
|
||||||
|
// defined at build time, see build/jam/BuildSetup
|
||||||
static const size_t kTarRegionSize = 16 * 1024 * 1024; // 16 MB
|
static const size_t kTarRegionSize = 16 * 1024 * 1024; // 16 MB
|
||||||
|
|
||||||
namespace TarFS {
|
namespace TarFS {
|
||||||
|
|
||||||
struct RegionDelete {
|
struct RegionDelete {
|
||||||
inline void operator()(void *memory)
|
inline void operator()(void* memory)
|
||||||
{
|
{
|
||||||
if (memory != NULL)
|
if (memory != NULL)
|
||||||
platform_free_region(memory, kTarRegionSize);
|
platform_free_region(memory, kTarRegionSize);
|
||||||
@@ -47,24 +48,33 @@ struct RegionDelete {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct RegionDeleter : BPrivate::AutoDeleter<void, RegionDelete> {
|
struct RegionDeleter : BPrivate::AutoDeleter<void, RegionDelete> {
|
||||||
RegionDeleter() : BPrivate::AutoDeleter<void, RegionDelete>() {}
|
RegionDeleter()
|
||||||
RegionDeleter(void *memory) : BPrivate::AutoDeleter<void, RegionDelete>(memory) {}
|
:
|
||||||
|
BPrivate::AutoDeleter<void, RegionDelete>()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionDeleter(void* memory)
|
||||||
|
:
|
||||||
|
BPrivate::AutoDeleter<void, RegionDelete>(memory)
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Directory;
|
class Directory;
|
||||||
|
|
||||||
class Entry : public DoublyLinkedListLinkImpl<Entry> {
|
class Entry : public DoublyLinkedListLinkImpl<Entry> {
|
||||||
public:
|
public:
|
||||||
Entry(const char *name);
|
Entry(const char* name);
|
||||||
virtual ~Entry() {}
|
virtual ~Entry() {}
|
||||||
|
|
||||||
const char *Name() const { return fName; }
|
const char* Name() const { return fName; }
|
||||||
virtual ::Node *ToNode() = 0;
|
virtual ::Node* ToNode() = 0;
|
||||||
virtual TarFS::Directory *ToTarDirectory() { return NULL; }
|
virtual TarFS::Directory* ToTarDirectory() { return NULL; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const char *fName;
|
const char* fName;
|
||||||
int32 fID;
|
int32 fID;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -73,52 +83,58 @@ typedef EntryList::Iterator EntryIterator;
|
|||||||
|
|
||||||
|
|
||||||
class File : public ::Node, public Entry {
|
class File : public ::Node, public Entry {
|
||||||
public:
|
public:
|
||||||
File(tar_header *header, const char *name);
|
File(tar_header* header, const char* name);
|
||||||
virtual ~File();
|
virtual ~File();
|
||||||
|
|
||||||
virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize);
|
virtual ssize_t ReadAt(void* cookie, off_t pos, void* buffer,
|
||||||
virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize);
|
size_t bufferSize);
|
||||||
|
virtual ssize_t WriteAt(void* cookie, off_t pos,
|
||||||
|
const void* buffer, size_t bufferSize);
|
||||||
|
|
||||||
virtual status_t GetName(char *nameBuffer, size_t bufferSize) const;
|
virtual status_t GetName(char* nameBuffer,
|
||||||
|
size_t bufferSize) const;
|
||||||
|
|
||||||
virtual int32 Type() const;
|
virtual int32 Type() const;
|
||||||
virtual off_t Size() const;
|
virtual off_t Size() const;
|
||||||
virtual ino_t Inode() const;
|
virtual ino_t Inode() const;
|
||||||
|
|
||||||
virtual ::Node *ToNode() { return this; }
|
virtual ::Node* ToNode() { return this; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
tar_header *fHeader;
|
tar_header* fHeader;
|
||||||
off_t fSize;
|
off_t fSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Directory : public ::Directory, public Entry {
|
class Directory : public ::Directory, public Entry {
|
||||||
public:
|
public:
|
||||||
Directory(const char *name);
|
Directory(const char* name);
|
||||||
virtual ~Directory();
|
virtual ~Directory();
|
||||||
|
|
||||||
virtual status_t Open(void **_cookie, int mode);
|
virtual status_t Open(void** _cookie, int mode);
|
||||||
virtual status_t Close(void *cookie);
|
virtual status_t Close(void* cookie);
|
||||||
|
|
||||||
virtual status_t GetName(char *nameBuffer, size_t bufferSize) const;
|
virtual status_t GetName(char* nameBuffer,
|
||||||
|
size_t bufferSize) const;
|
||||||
|
|
||||||
virtual TarFS::Entry *LookupEntry(const char *name);
|
virtual TarFS::Entry* LookupEntry(const char* name);
|
||||||
virtual ::Node *Lookup(const char *name, bool traverseLinks);
|
virtual ::Node* Lookup(const char* name, bool traverseLinks);
|
||||||
|
|
||||||
virtual status_t GetNextEntry(void *cookie, char *nameBuffer, size_t bufferSize);
|
virtual status_t GetNextEntry(void* cookie, char* nameBuffer,
|
||||||
virtual status_t GetNextNode(void *cookie, Node **_node);
|
size_t bufferSize);
|
||||||
virtual status_t Rewind(void *cookie);
|
virtual status_t GetNextNode(void* cookie, Node** _node);
|
||||||
virtual bool IsEmpty();
|
virtual status_t Rewind(void* cookie);
|
||||||
|
virtual bool IsEmpty();
|
||||||
|
|
||||||
virtual ino_t Inode() const;
|
virtual ino_t Inode() const;
|
||||||
|
|
||||||
virtual ::Node *ToNode() { return this; };
|
virtual ::Node* ToNode() { return this; };
|
||||||
virtual TarFS::Directory *ToTarDirectory() { return this; }
|
virtual TarFS::Directory* ToTarDirectory() { return this; }
|
||||||
|
|
||||||
status_t AddDirectory(char *dirName, TarFS::Directory **_dir = NULL);
|
status_t AddDirectory(char* dirName,
|
||||||
status_t AddFile(tar_header *header);
|
TarFS::Directory** _dir = NULL);
|
||||||
|
status_t AddFile(tar_header* header);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef ::Directory _inherited;
|
typedef ::Directory _inherited;
|
||||||
@@ -128,44 +144,46 @@ class Directory : public ::Directory, public Entry {
|
|||||||
|
|
||||||
|
|
||||||
class Symlink : public ::Node, public Entry {
|
class Symlink : public ::Node, public Entry {
|
||||||
public:
|
public:
|
||||||
Symlink(tar_header *header, const char *name);
|
Symlink(tar_header* header, const char* name);
|
||||||
virtual ~Symlink();
|
virtual ~Symlink();
|
||||||
|
|
||||||
virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer,
|
virtual ssize_t ReadAt(void* cookie, off_t pos, void* buffer,
|
||||||
size_t bufferSize);
|
size_t bufferSize);
|
||||||
virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer,
|
virtual ssize_t WriteAt(void* cookie, off_t pos,
|
||||||
size_t bufferSize);
|
const void* buffer, size_t bufferSize);
|
||||||
|
|
||||||
virtual status_t GetName(char *nameBuffer, size_t bufferSize) const;
|
virtual status_t GetName(char* nameBuffer,
|
||||||
|
size_t bufferSize) const;
|
||||||
|
|
||||||
virtual int32 Type() const;
|
virtual int32 Type() const;
|
||||||
virtual off_t Size() const;
|
virtual off_t Size() const;
|
||||||
virtual ino_t Inode() const;
|
virtual ino_t Inode() const;
|
||||||
|
|
||||||
const char* LinkPath() const { return fHeader->linkname; }
|
const char* LinkPath() const { return fHeader->linkname; }
|
||||||
|
|
||||||
virtual ::Node *ToNode() { return this; }
|
virtual ::Node* ToNode() { return this; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
tar_header *fHeader;
|
tar_header* fHeader;
|
||||||
size_t fSize;
|
size_t fSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Volume : public TarFS::Directory {
|
class Volume : public TarFS::Directory {
|
||||||
public:
|
public:
|
||||||
Volume();
|
Volume();
|
||||||
~Volume();
|
~Volume();
|
||||||
|
|
||||||
status_t Init(boot::Partition *partition);
|
status_t Init(boot::Partition* partition);
|
||||||
|
|
||||||
TarFS::Directory *Root() { return this; }
|
TarFS::Directory* Root() { return this; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
status_t _Inflate(boot::Partition *partition, void* cookie,
|
status_t _Inflate(boot::Partition* partition,
|
||||||
off_t offset, RegionDeleter& regionDeleter,
|
void* cookie, off_t offset,
|
||||||
size_t* inflatedBytes);
|
RegionDeleter& regionDeleter,
|
||||||
|
size_t* inflatedBytes);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace TarFS
|
} // namespace TarFS
|
||||||
@@ -178,10 +196,10 @@ static int32 sNextID = 1;
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
skip_gzip_header(z_stream *stream)
|
skip_gzip_header(z_stream* stream)
|
||||||
{
|
{
|
||||||
uint8 *buffer = (uint8 *)stream->next_in;
|
uint8* buffer = (uint8*)stream->next_in;
|
||||||
|
|
||||||
// check magic and skip method
|
// check magic and skip method
|
||||||
if (buffer[0] != 0x1f || buffer[1] != 0x8b)
|
if (buffer[0] != 0x1f || buffer[1] != 0x8b)
|
||||||
return false;
|
return false;
|
||||||
@@ -224,7 +242,7 @@ skip_gzip_header(z_stream *stream)
|
|||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
TarFS::Entry::Entry(const char *name)
|
TarFS::Entry::Entry(const char* name)
|
||||||
:
|
:
|
||||||
fName(name),
|
fName(name),
|
||||||
fID(sNextID++)
|
fID(sNextID++)
|
||||||
@@ -235,7 +253,7 @@ TarFS::Entry::Entry(const char *name)
|
|||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
TarFS::File::File(tar_header *header, const char *name)
|
TarFS::File::File(tar_header* header, const char* name)
|
||||||
: TarFS::Entry(name),
|
: TarFS::Entry(name),
|
||||||
fHeader(header)
|
fHeader(header)
|
||||||
{
|
{
|
||||||
@@ -249,9 +267,10 @@ TarFS::File::~File()
|
|||||||
|
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
TarFS::File::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize)
|
TarFS::File::ReadAt(void* cookie, off_t pos, void* buffer, size_t bufferSize)
|
||||||
{
|
{
|
||||||
TRACE(("tarfs: read at %Ld, %lu bytes, fSize = %Ld\n", pos, bufferSize, fSize));
|
TRACE(("tarfs: read at %Ld, %lu bytes, fSize = %Ld\n", pos, bufferSize,
|
||||||
|
fSize));
|
||||||
|
|
||||||
if (pos < 0 || !buffer)
|
if (pos < 0 || !buffer)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
@@ -270,16 +289,18 @@ TarFS::File::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize)
|
|||||||
|
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
TarFS::File::WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize)
|
TarFS::File::WriteAt(void* cookie, off_t pos, const void* buffer,
|
||||||
|
size_t bufferSize)
|
||||||
{
|
{
|
||||||
return B_NOT_ALLOWED;
|
return B_NOT_ALLOWED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
TarFS::File::GetName(char *nameBuffer, size_t bufferSize) const
|
TarFS::File::GetName(char* nameBuffer, size_t bufferSize) const
|
||||||
{
|
{
|
||||||
return strlcpy(nameBuffer, Name(), bufferSize) >= bufferSize ? B_BUFFER_OVERFLOW : B_OK;
|
return strlcpy(nameBuffer, Name(), bufferSize) >= bufferSize
|
||||||
|
? B_BUFFER_OVERFLOW : B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -306,7 +327,7 @@ TarFS::File::Inode() const
|
|||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
TarFS::Directory::Directory(const char *name)
|
TarFS::Directory::Directory(const char* name)
|
||||||
: TarFS::Entry(name)
|
: TarFS::Entry(name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -314,19 +335,20 @@ TarFS::Directory::Directory(const char *name)
|
|||||||
|
|
||||||
TarFS::Directory::~Directory()
|
TarFS::Directory::~Directory()
|
||||||
{
|
{
|
||||||
while (TarFS::Entry *entry = fEntries.Head()) {
|
while (TarFS::Entry* entry = fEntries.Head()) {
|
||||||
fEntries.Remove(entry);
|
fEntries.Remove(entry);
|
||||||
delete entry;
|
delete entry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
TarFS::Directory::Open(void **_cookie, int mode)
|
TarFS::Directory::Open(void** _cookie, int mode)
|
||||||
{
|
{
|
||||||
_inherited::Open(_cookie, mode);
|
_inherited::Open(_cookie, mode);
|
||||||
|
|
||||||
EntryIterator *iterator = new(nothrow) EntryIterator(fEntries.GetIterator());
|
EntryIterator* iterator
|
||||||
|
= new(std::nothrow) EntryIterator(fEntries.GetIterator());
|
||||||
if (iterator == NULL)
|
if (iterator == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
@@ -336,30 +358,31 @@ TarFS::Directory::Open(void **_cookie, int mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
TarFS::Directory::Close(void *cookie)
|
TarFS::Directory::Close(void* cookie)
|
||||||
{
|
{
|
||||||
_inherited::Close(cookie);
|
_inherited::Close(cookie);
|
||||||
|
|
||||||
delete (EntryIterator *)cookie;
|
delete (EntryIterator*)cookie;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
TarFS::Directory::GetName(char *nameBuffer, size_t bufferSize) const
|
TarFS::Directory::GetName(char* nameBuffer, size_t bufferSize) const
|
||||||
{
|
{
|
||||||
return strlcpy(nameBuffer, Name(), bufferSize) >= bufferSize ? B_BUFFER_OVERFLOW : B_OK;
|
return strlcpy(nameBuffer, Name(), bufferSize) >= bufferSize
|
||||||
|
? B_BUFFER_OVERFLOW : B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TarFS::Entry *
|
TarFS::Entry*
|
||||||
TarFS::Directory::LookupEntry(const char *name)
|
TarFS::Directory::LookupEntry(const char* name)
|
||||||
{
|
{
|
||||||
EntryIterator iterator(fEntries.GetIterator());
|
EntryIterator iterator(fEntries.GetIterator());
|
||||||
|
|
||||||
while (iterator.HasNext()) {
|
while (iterator.HasNext()) {
|
||||||
TarFS::Entry *entry = iterator.Next();
|
TarFS::Entry* entry = iterator.Next();
|
||||||
if (strcmp(name, entry->Name()) == 0)
|
if (strcmp(name, entry->Name()) == 0)
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
@@ -368,10 +391,10 @@ TarFS::Directory::LookupEntry(const char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
::Node *
|
::Node*
|
||||||
TarFS::Directory::Lookup(const char *name, bool traverseLinks)
|
TarFS::Directory::Lookup(const char* name, bool traverseLinks)
|
||||||
{
|
{
|
||||||
TarFS::Entry *entry = LookupEntry(name);
|
TarFS::Entry* entry = LookupEntry(name);
|
||||||
if (!entry)
|
if (!entry)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -395,11 +418,11 @@ TarFS::Directory::Lookup(const char *name, bool traverseLinks)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
TarFS::Directory::GetNextEntry(void *_cookie, char *name, size_t size)
|
TarFS::Directory::GetNextEntry(void* _cookie, char* name, size_t size)
|
||||||
{
|
{
|
||||||
EntryIterator *iterator = (EntryIterator *)_cookie;
|
EntryIterator* iterator = (EntryIterator*)_cookie;
|
||||||
TarFS::Entry *entry = iterator->Next();
|
TarFS::Entry* entry = iterator->Next();
|
||||||
|
|
||||||
if (entry != NULL) {
|
if (entry != NULL) {
|
||||||
strlcpy(name, entry->Name(), size);
|
strlcpy(name, entry->Name(), size);
|
||||||
@@ -410,11 +433,11 @@ TarFS::Directory::GetNextEntry(void *_cookie, char *name, size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
TarFS::Directory::GetNextNode(void *_cookie, Node **_node)
|
TarFS::Directory::GetNextNode(void* _cookie, Node** _node)
|
||||||
{
|
{
|
||||||
EntryIterator *iterator = (EntryIterator *)_cookie;
|
EntryIterator* iterator = (EntryIterator*)_cookie;
|
||||||
TarFS::Entry *entry = iterator->Next();
|
TarFS::Entry* entry = iterator->Next();
|
||||||
|
|
||||||
if (entry != NULL) {
|
if (entry != NULL) {
|
||||||
*_node = entry->ToNode();
|
*_node = entry->ToNode();
|
||||||
@@ -424,19 +447,19 @@ TarFS::Directory::GetNextNode(void *_cookie, Node **_node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
TarFS::Directory::Rewind(void *_cookie)
|
TarFS::Directory::Rewind(void* _cookie)
|
||||||
{
|
{
|
||||||
EntryIterator *iterator = (EntryIterator *)_cookie;
|
EntryIterator* iterator = (EntryIterator*)_cookie;
|
||||||
*iterator = fEntries.GetIterator();
|
*iterator = fEntries.GetIterator();
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
TarFS::Directory::AddDirectory(char *dirName, TarFS::Directory **_dir)
|
TarFS::Directory::AddDirectory(char* dirName, TarFS::Directory** _dir)
|
||||||
{
|
{
|
||||||
char *subDir = strchr(dirName, '/');
|
char* subDir = strchr(dirName, '/');
|
||||||
if (subDir) {
|
if (subDir) {
|
||||||
// skip slashes
|
// skip slashes
|
||||||
while (*subDir == '/') {
|
while (*subDir == '/') {
|
||||||
@@ -451,8 +474,8 @@ TarFS::Directory::AddDirectory(char *dirName, TarFS::Directory **_dir)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check, whether the directory does already exist
|
// check, whether the directory does already exist
|
||||||
Entry *entry = LookupEntry(dirName);
|
Entry* entry = LookupEntry(dirName);
|
||||||
TarFS::Directory *dir = (entry ? entry->ToTarDirectory() : NULL);
|
TarFS::Directory* dir = (entry ? entry->ToTarDirectory() : NULL);
|
||||||
if (entry) {
|
if (entry) {
|
||||||
if (!dir)
|
if (!dir)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@@ -480,10 +503,10 @@ TarFS::Directory::AddDirectory(char *dirName, TarFS::Directory **_dir)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
TarFS::Directory::AddFile(tar_header *header)
|
TarFS::Directory::AddFile(tar_header* header)
|
||||||
{
|
{
|
||||||
char *leaf = strrchr(header->name, '/');
|
char* leaf = strrchr(header->name, '/');
|
||||||
char *dirName = NULL;
|
char* dirName = NULL;
|
||||||
if (leaf) {
|
if (leaf) {
|
||||||
dirName = header->name;
|
dirName = header->name;
|
||||||
*leaf = '\0';
|
*leaf = '\0';
|
||||||
@@ -492,7 +515,7 @@ TarFS::Directory::AddFile(tar_header *header)
|
|||||||
leaf = header->name;
|
leaf = header->name;
|
||||||
|
|
||||||
// create the parent directory
|
// create the parent directory
|
||||||
TarFS::Directory *dir = this;
|
TarFS::Directory* dir = this;
|
||||||
if (dirName) {
|
if (dirName) {
|
||||||
status_t error = AddDirectory(dirName, &dir);
|
status_t error = AddDirectory(dirName, &dir);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
@@ -500,7 +523,7 @@ TarFS::Directory::AddFile(tar_header *header)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create the entry
|
// create the entry
|
||||||
TarFS::Entry *entry;
|
TarFS::Entry* entry;
|
||||||
if (header->type == TAR_FILE || header->type == TAR_FILE2)
|
if (header->type == TAR_FILE || header->type == TAR_FILE2)
|
||||||
entry = new(nothrow) TarFS::File(header, leaf);
|
entry = new(nothrow) TarFS::File(header, leaf);
|
||||||
else if (header->type == TAR_SYMLINK)
|
else if (header->type == TAR_SYMLINK)
|
||||||
@@ -517,7 +540,7 @@ TarFS::Directory::AddFile(tar_header *header)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TarFS::Directory::IsEmpty()
|
TarFS::Directory::IsEmpty()
|
||||||
{
|
{
|
||||||
return fEntries.IsEmpty();
|
return fEntries.IsEmpty();
|
||||||
@@ -534,7 +557,7 @@ TarFS::Directory::Inode() const
|
|||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
TarFS::Symlink::Symlink(tar_header *header, const char *name)
|
TarFS::Symlink::Symlink(tar_header* header, const char* name)
|
||||||
: TarFS::Entry(name),
|
: TarFS::Entry(name),
|
||||||
fHeader(header)
|
fHeader(header)
|
||||||
{
|
{
|
||||||
@@ -550,14 +573,14 @@ TarFS::Symlink::~Symlink()
|
|||||||
|
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
TarFS::Symlink::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize)
|
TarFS::Symlink::ReadAt(void* cookie, off_t pos, void* buffer, size_t bufferSize)
|
||||||
{
|
{
|
||||||
return B_NOT_ALLOWED;
|
return B_NOT_ALLOWED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
TarFS::Symlink::WriteAt(void *cookie, off_t pos, const void *buffer,
|
TarFS::Symlink::WriteAt(void* cookie, off_t pos, const void* buffer,
|
||||||
size_t bufferSize)
|
size_t bufferSize)
|
||||||
{
|
{
|
||||||
return B_NOT_ALLOWED;
|
return B_NOT_ALLOWED;
|
||||||
@@ -565,7 +588,7 @@ TarFS::Symlink::WriteAt(void *cookie, off_t pos, const void *buffer,
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
TarFS::Symlink::GetName(char *nameBuffer, size_t bufferSize) const
|
TarFS::Symlink::GetName(char* nameBuffer, size_t bufferSize) const
|
||||||
{
|
{
|
||||||
return strlcpy(nameBuffer, Name(), bufferSize) >= bufferSize
|
return strlcpy(nameBuffer, Name(), bufferSize) >= bufferSize
|
||||||
? B_BUFFER_OVERFLOW : B_OK;
|
? B_BUFFER_OVERFLOW : B_OK;
|
||||||
@@ -608,9 +631,9 @@ TarFS::Volume::~Volume()
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
TarFS::Volume::Init(boot::Partition *partition)
|
TarFS::Volume::Init(boot::Partition* partition)
|
||||||
{
|
{
|
||||||
void *cookie;
|
void* cookie;
|
||||||
status_t error = partition->Open(&cookie, O_RDONLY);
|
status_t error = partition->Open(&cookie, O_RDONLY);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
@@ -619,7 +642,7 @@ TarFS::Volume::Init(boot::Partition *partition)
|
|||||||
boot::Partition *partition;
|
boot::Partition *partition;
|
||||||
void *cookie;
|
void *cookie;
|
||||||
|
|
||||||
PartitionCloser(boot::Partition *partition, void *cookie)
|
PartitionCloser(boot::Partition* partition, void* cookie)
|
||||||
: partition(partition),
|
: partition(partition),
|
||||||
cookie(cookie)
|
cookie(cookie)
|
||||||
{
|
{
|
||||||
@@ -645,13 +668,13 @@ TarFS::Volume::Init(boot::Partition *partition)
|
|||||||
return status;
|
return status;
|
||||||
|
|
||||||
// parse the tar file
|
// parse the tar file
|
||||||
char *block = (char*)regionDeleter.Get();
|
char* block = (char*)regionDeleter.Get();
|
||||||
int blockCount = inflatedBytes / BLOCK_SIZE;
|
int blockCount = inflatedBytes / BLOCK_SIZE;
|
||||||
int blockIndex = 0;
|
int blockIndex = 0;
|
||||||
|
|
||||||
while (blockIndex < blockCount) {
|
while (blockIndex < blockCount) {
|
||||||
// check header
|
// check header
|
||||||
tar_header *header = (tar_header*)(block + blockIndex * BLOCK_SIZE);
|
tar_header* header = (tar_header*)(block + blockIndex * BLOCK_SIZE);
|
||||||
//dump_header(*header);
|
//dump_header(*header);
|
||||||
|
|
||||||
if (header->magic[0] == '\0')
|
if (header->magic[0] == '\0')
|
||||||
@@ -669,7 +692,8 @@ TarFS::Volume::Init(boot::Partition *partition)
|
|||||||
|
|
||||||
TRACE(("tarfs: \"%s\", %Ld bytes\n", header->name, size));
|
TRACE(("tarfs: \"%s\", %Ld bytes\n", header->name, size));
|
||||||
|
|
||||||
// TODO: this is old-style GNU tar which probably won't work with newer ones...
|
// TODO: this is old-style GNU tar which probably won't work with newer
|
||||||
|
// ones...
|
||||||
switch (header->type) {
|
switch (header->type) {
|
||||||
case TAR_FILE:
|
case TAR_FILE:
|
||||||
case TAR_FILE2:
|
case TAR_FILE2:
|
||||||
@@ -685,7 +709,8 @@ TarFS::Volume::Init(boot::Partition *partition)
|
|||||||
// this is a long file name
|
// this is a long file name
|
||||||
// TODO: read long name
|
// TODO: read long name
|
||||||
default:
|
default:
|
||||||
dprintf("tarfs: unsupported file type: %d ('%c')\n", header->type, header->type);
|
dprintf("tarfs: unsupported file type: %d ('%c')\n",
|
||||||
|
header->type, header->type);
|
||||||
// unsupported type
|
// unsupported type
|
||||||
status = B_ERROR;
|
status = B_ERROR;
|
||||||
break;
|
break;
|
||||||
@@ -707,7 +732,7 @@ TarFS::Volume::Init(boot::Partition *partition)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
TarFS::Volume::_Inflate(boot::Partition *partition, void* cookie, off_t offset,
|
TarFS::Volume::_Inflate(boot::Partition* partition, void* cookie, off_t offset,
|
||||||
RegionDeleter& regionDeleter, size_t* inflatedBytes)
|
RegionDeleter& regionDeleter, size_t* inflatedBytes)
|
||||||
{
|
{
|
||||||
char in[2048];
|
char in[2048];
|
||||||
@@ -742,7 +767,7 @@ TarFS::Volume::_Inflate(boot::Partition *partition, void* cookie, off_t offset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
zStream.avail_in = bytesRead;
|
zStream.avail_in = bytesRead;
|
||||||
zStream.next_in = (Bytef *)in;
|
zStream.next_in = (Bytef*)in;
|
||||||
|
|
||||||
if (!headerRead) {
|
if (!headerRead) {
|
||||||
// check and skip gzip header
|
// check and skip gzip header
|
||||||
@@ -752,7 +777,7 @@ TarFS::Volume::_Inflate(boot::Partition *partition, void* cookie, off_t offset,
|
|||||||
|
|
||||||
if (!out) {
|
if (!out) {
|
||||||
// allocate memory for the uncompressed data
|
// allocate memory for the uncompressed data
|
||||||
if (platform_allocate_region((void **)&out, kTarRegionSize,
|
if (platform_allocate_region((void**)&out, kTarRegionSize,
|
||||||
B_READ_AREA | B_WRITE_AREA, false) != B_OK) {
|
B_READ_AREA | B_WRITE_AREA, false) != B_OK) {
|
||||||
TRACE(("tarfs: allocating region failed!\n"));
|
TRACE(("tarfs: allocating region failed!\n"));
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
@@ -761,7 +786,7 @@ TarFS::Volume::_Inflate(boot::Partition *partition, void* cookie, off_t offset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
zStream.avail_out = kTarRegionSize;
|
zStream.avail_out = kTarRegionSize;
|
||||||
zStream.next_out = (Bytef *)out;
|
zStream.next_out = (Bytef*)out;
|
||||||
|
|
||||||
status = inflateInit2(&zStream, -15);
|
status = inflateInit2(&zStream, -15);
|
||||||
if (status != Z_OK)
|
if (status != Z_OK)
|
||||||
@@ -793,9 +818,9 @@ TarFS::Volume::_Inflate(boot::Partition *partition, void* cookie, off_t offset,
|
|||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
tarfs_get_file_system(boot::Partition *partition, ::Directory **_root)
|
tarfs_get_file_system(boot::Partition* partition, ::Directory** _root)
|
||||||
{
|
{
|
||||||
TarFS::Volume *volume = new(nothrow) TarFS::Volume;
|
TarFS::Volume* volume = new(nothrow) TarFS::Volume;
|
||||||
if (volume == NULL)
|
if (volume == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user