mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-21 06:33:31 +00:00
vfs: GNU long file name support for tar
This commit is contained in:
parent
67869a697b
commit
89a9e88a7e
@ -72,24 +72,63 @@ class Vfs::Tar_file_system : public File_system
|
||||
return value;
|
||||
}
|
||||
|
||||
char const *_data_begin() const { return (char const *)this + BLOCK_LEN; }
|
||||
|
||||
/*
|
||||
* GNU extension for long path names, which support unlimited sizes using
|
||||
* separate records
|
||||
*/
|
||||
bool _long_name() const
|
||||
{
|
||||
return _type[0] == TYPE_LONG_LINK || _type[0] == TYPE_LONG_NAME;
|
||||
}
|
||||
|
||||
/*
|
||||
* Round up up next block
|
||||
*/
|
||||
file_size _block_align(file_size size) const {
|
||||
return Genode::align_addr(size, BLOCK_SHIFT); }
|
||||
|
||||
/*
|
||||
* Next record header
|
||||
*/
|
||||
Record *_next() const {
|
||||
return (Record *)(_data_begin() + _block_align(_read(_size))); }
|
||||
|
||||
public:
|
||||
|
||||
/* length of on data block in tar */
|
||||
enum { BLOCK_LEN = 512 };
|
||||
/* length of one data block in tar */
|
||||
enum {
|
||||
BLOCK_SHIFT = 9, /* 512 bytes */
|
||||
BLOCK_LEN = 1ul << BLOCK_SHIFT,
|
||||
};
|
||||
|
||||
/* record type values */
|
||||
enum { TYPE_FILE = 0, TYPE_HARDLINK = 1,
|
||||
TYPE_SYMLINK = 2, TYPE_DIR = 5 };
|
||||
enum {
|
||||
TYPE_FILE = 0, TYPE_HARDLINK = 1, TYPE_SYMLINK = 2, TYPE_DIR = 5,
|
||||
/* GNU extensions */
|
||||
TYPE_LONG_LINK = 75, TYPE_LONG_NAME = 76
|
||||
};
|
||||
|
||||
file_size size() const { return _read(_size); }
|
||||
unsigned uid() const { return _read(_uid); }
|
||||
unsigned gid() const { return _read(_gid); }
|
||||
unsigned mode() const { return _read(_mode); }
|
||||
unsigned type() const { return _read(_type); }
|
||||
char const *name() const { return _name; }
|
||||
char const *linked_name() const { return _linked_name; }
|
||||
file_size size() const { return _long_name() ? _next()->size() : _read(_size); }
|
||||
unsigned uid() const { return _long_name() ? _next()->uid() : _read(_uid); }
|
||||
unsigned gid() const { return _long_name() ? _next()->gid() : _read(_gid); }
|
||||
unsigned mode() const { return _long_name() ? _next()->mode() : _read(_mode); }
|
||||
unsigned type() const { return _long_name() ? _next()->type() : _read(_type); }
|
||||
void *data() const { return _long_name() ? _next()->data() : (void *)_data_begin(); }
|
||||
|
||||
void *data() const { return (char *)this + BLOCK_LEN; }
|
||||
char const *name() const { return _long_name() ? _data_begin() : _name; }
|
||||
char const *linked_name() const { return _long_name() ? _data_begin() : _linked_name; }
|
||||
|
||||
file_size storage_size()
|
||||
{
|
||||
if (_long_name()) {
|
||||
/* this size + next header + next size */
|
||||
return _block_align(_read(_size)) + BLOCK_LEN + _block_align(_next()->size());
|
||||
}
|
||||
|
||||
return _read(_size);
|
||||
}
|
||||
};
|
||||
|
||||
class Node;
|
||||
@ -392,7 +431,7 @@ class Vfs::Tar_file_system : public File_system
|
||||
|
||||
tar_record_action(record);
|
||||
|
||||
file_size size = record->size();
|
||||
file_size size = record->storage_size();
|
||||
|
||||
/* some datablocks */ /* one metablock */
|
||||
block_id = block_id + (size / Record::BLOCK_LEN) + 1;
|
||||
|
Loading…
Reference in New Issue
Block a user